summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcodeworkx <codeworkx@cyanogenmod.org>2013-02-11 17:29:55 +0000
committercodeworkx <codeworkx@cyanogenmod.org>2013-02-13 18:55:29 +0000
commit222b794ae146b4e0d61958c55a518396e293e6d7 (patch)
tree744f1fc5d63e8669de1018dc7c42c4e863ceae85
downloaddevice_samsung_omap4-common-222b794ae146b4e0d61958c55a518396e293e6d7.zip
device_samsung_omap4-common-222b794ae146b4e0d61958c55a518396e293e6d7.tar.gz
device_samsung_omap4-common-222b794ae146b4e0d61958c55a518396e293e6d7.tar.bz2
initial commit
sources from http://omapzoom.org
-rw-r--r--Android.mk23
-rw-r--r--BoardConfigCommon.mk90
-rw-r--r--bltsville/Android.mk17
-rwxr-xr-xbltsville/bltsville/README1
-rw-r--r--bltsville/bltsville/blend-854x480-bad.jpgbin0 -> 77198 bytes
-rw-r--r--bltsville/bltsville/blend-854x480-bad2.jpgbin0 -> 69838 bytes
-rw-r--r--bltsville/bltsville/blend-854x480-roundingerror.jpgbin0 -> 69458 bytes
-rw-r--r--bltsville/bltsville/blend-854x480-threeblts.jpgbin0 -> 76246 bytes
-rw-r--r--bltsville/bltsville/blend-854x480.jpgbin0 -> 69281 bytes
-rw-r--r--bltsville/bltsville/bvlogo.pngbin0 -> 98635 bytes
-rw-r--r--bltsville/bltsville/clock-720x480_4x3-fauxtrans.jpgbin0 -> 70563 bytes
-rw-r--r--bltsville/bltsville/clock-720x480_4x3.pngbin0 -> 560594 bytes
-rw-r--r--bltsville/bltsville/concrete-64x36.pngbin0 -> 4783 bytes
-rw-r--r--bltsville/bltsville/include/bltsville.h602
-rw-r--r--bltsville/bltsville/include/bvblend.h508
-rw-r--r--bltsville/bltsville/include/bvbuffdesc.h61
-rw-r--r--bltsville/bltsville/include/bvcache.h45
-rw-r--r--bltsville/bltsville/include/bventry.h32
-rw-r--r--bltsville/bltsville/include/bverror.h307
-rw-r--r--bltsville/bltsville/include/bvfilter.h51
-rw-r--r--bltsville/bltsville/include/bvinternal.h47
-rw-r--r--bltsville/bltsville/include/bvsurfgeom.h41
-rw-r--r--bltsville/bltsville/index.html4362
-rw-r--r--bltsville/bltsville/ocdtab.pngbin0 -> 11854 bytes
-rw-r--r--bltsville/gcbv/Android.mk86
-rw-r--r--bltsville/gcbv/gcmain.c531
-rw-r--r--bltsville/gcbv/gcmain.h143
-rw-r--r--bltsville/gcbv/mirror/gcblit.c771
-rw-r--r--bltsville/gcbv/mirror/gcbuffer.c383
-rw-r--r--bltsville/gcbv/mirror/gcbv.c2008
-rw-r--r--bltsville/gcbv/mirror/gcbv.h590
-rw-r--r--bltsville/gcbv/mirror/gcdbglog.c1684
-rw-r--r--bltsville/gcbv/mirror/gcfill.c258
-rw-r--r--bltsville/gcbv/mirror/gcfilter.c1788
-rw-r--r--bltsville/gcbv/mirror/gcmap.c342
-rw-r--r--bltsville/gcbv/mirror/gcparser.c2090
-rw-r--r--bltsville/gcbv/mirror/include/cache-2dmanager.h75
-rw-r--r--bltsville/gcbv/mirror/include/gcdbglog.h384
-rw-r--r--bltsville/gcbv/mirror/include/gcerror.h226
-rw-r--r--bltsville/gcbv/mirror/include/gcioctl.h293
-rw-r--r--bltsville/gcbv/mirror/include/gclist.h594
-rw-r--r--bltsville/gcbv/mirror/include/gcreg.h10269
-rw-r--r--bltsville/gcbv/mirror/include/gcx.h87
-rw-r--r--bltsville/gcbv/version.h33
-rw-r--r--bltsville/ocd/README1
-rwxr-xr-xbltsville/ocd/include/ocd.h801
-rwxr-xr-xbltsville/ocd/index.html617
-rwxr-xr-xbltsville/ocd/ocdlogo.jpgbin0 -> 45982 bytes
-rwxr-xr-xbltsville/ticpu/Android.mk53
-rwxr-xr-xbltsville/ticpu/doc/android/BLTsville-Android-Release-Notes.html15129
-rwxr-xr-xbltsville/ticpu/doc/android/check.pngbin0 -> 419 bytes
-rwxr-xr-xbltsville/ticpu/doc/linux/BLTsville-Linux-Release-Notes.html15127
-rwxr-xr-xbltsville/ticpu/doc/linux/check.pngbin0 -> 419 bytes
l---------bltsville/ticpu/lib/android/libbltsville_cpu.so1
-rwxr-xr-xbltsville/ticpu/lib/android/libbltsville_ticpu.2.1.0.0.sobin0 -> 162310 bytes
l---------bltsville/ticpu/lib/android/libbltsville_ticpu.so1
-rwxr-xr-xbltsville/ticpu/lib/android/libbltsville_ticpu_license.txt172
l---------bltsville/ticpu/lib/linux/libbltsville_cpu.so1
l---------bltsville/ticpu/lib/linux/libbltsville_ticpu.so1
-rwxr-xr-xbltsville/ticpu/lib/linux/libbltsville_ticpu.so.2.1.0.0bin0 -> 166468 bytes
-rwxr-xr-xbltsville/ticpu/lib/linux/libbltsville_ticpu_license.txt172
-rwxr-xr-xbltsville/ticpu/license173
-rw-r--r--common.mk56
-rw-r--r--edid/Android.mk45
-rw-r--r--edid/cmd/parse_hdmi_edid.c154
-rw-r--r--edid/inc/edid_parser.h113
-rw-r--r--edid/lib/edid_parser.c410
-rw-r--r--edid/lib/edid_parser_priv.h31
-rwxr-xr-xextract-files.sh142
-rw-r--r--hwc/Android.mk31
-rw-r--r--hwc/dock_image.c196
-rw-r--r--hwc/dock_image.h38
-rw-r--r--hwc/hal_public.h188
-rw-r--r--hwc/hwc.c2747
-rw-r--r--hwc/hwc_dev.h180
-rw-r--r--hwc/rgz_2d.c1997
-rw-r--r--hwc/rgz_2d.h306
-rw-r--r--hwc/sw_vsync.c145
-rw-r--r--hwc/sw_vsync.h25
-rw-r--r--include/gralloc/ti_handle_wrapper.h85
-rw-r--r--include/hardware/gps.h686
-rw-r--r--include/hardware/hwcomposer.h643
-rw-r--r--include/hardware/hwcomposer_defs.h204
-rw-r--r--include/hardware/hwcomposer_v0.h272
-rw-r--r--include/ion_ti/ion.h49
-rw-r--r--include/ion_ti/linux_ion.h76
-rw-r--r--include/ion_ti/omap_ion.h61
-rw-r--r--kernel-headers/linux/android_alarm.h112
-rw-r--r--kernel-headers/linux/bltsville.h592
-rw-r--r--kernel-headers/linux/bvblend.h507
-rw-r--r--kernel-headers/linux/bvbuffdesc.h68
-rw-r--r--kernel-headers/linux/bvcache.h44
-rw-r--r--kernel-headers/linux/bventry.h38
-rw-r--r--kernel-headers/linux/bverror.h306
-rw-r--r--kernel-headers/linux/bvfilter.h50
-rw-r--r--kernel-headers/linux/bvinternal.h46
-rw-r--r--kernel-headers/linux/bvsurfgeom.h40
-rw-r--r--kernel-headers/linux/ocd.h781
-rw-r--r--kernel-headers/linux/omap_ion.h106
-rw-r--r--kernel-headers/linux/omapfb.h274
-rw-r--r--kernel-headers/linux/rpmsg_omx.h156
-rw-r--r--kernel-headers/video/dsscomp.h709
-rw-r--r--kernel-headers/video/omap_hwc.h99
-rw-r--r--libion_ti/Android.mk23
-rw-r--r--libion_ti/ion.c201
-rw-r--r--libion_ti/ion.h49
-rw-r--r--libion_ti/ion_test.c319
-rw-r--r--libion_ti/ion_test_2.c479
-rw-r--r--libion_ti/linux_ion.h76
-rw-r--r--libion_ti/omap_ion.h61
-rw-r--r--libpower/Android.mk25
-rw-r--r--libpower/power.c231
-rw-r--r--proprietary-files.txt29
-rw-r--r--pvr-source/GPL-COPYING344
-rw-r--r--pvr-source/INSTALL72
-rw-r--r--pvr-source/MIT-COPYING41
-rw-r--r--pvr-source/README49
-rw-r--r--pvr-source/eurasiacon/build/linux2/bits.mk112
-rw-r--r--pvr-source/eurasiacon/build/linux2/buildvars.mk217
-rw-r--r--pvr-source/eurasiacon/build/linux2/commands.mk219
-rw-r--r--pvr-source/eurasiacon/build/linux2/common/android/arch_common.mk59
-rw-r--r--pvr-source/eurasiacon/build/linux2/common/android/armv7-a.mk68
-rw-r--r--pvr-source/eurasiacon/build/linux2/common/android/extra_config.mk47
-rw-r--r--pvr-source/eurasiacon/build/linux2/common/android/features.mk319
-rw-r--r--pvr-source/eurasiacon/build/linux2/common/android/paths.mk53
-rw-r--r--pvr-source/eurasiacon/build/linux2/common/android/platform_version.mk156
-rw-r--r--pvr-source/eurasiacon/build/linux2/common/dridrm.mk63
-rw-r--r--pvr-source/eurasiacon/build/linux2/common/omap4.mk43
-rw-r--r--pvr-source/eurasiacon/build/linux2/common/opencl.mk40
-rw-r--r--pvr-source/eurasiacon/build/linux2/config/core.mk604
-rw-r--r--pvr-source/eurasiacon/build/linux2/defs.mk140
-rw-r--r--pvr-source/eurasiacon/build/linux2/kbuild/Makefile.template92
-rw-r--r--pvr-source/eurasiacon/build/linux2/kbuild/external_tarball.mk49
-rw-r--r--pvr-source/eurasiacon/build/linux2/kbuild/kbuild.mk91
-rw-r--r--pvr-source/eurasiacon/build/linux2/kernel_module.mk75
-rw-r--r--pvr-source/eurasiacon/build/linux2/kernel_version.mk100
-rw-r--r--pvr-source/eurasiacon/build/linux2/moduledefs.mk96
-rw-r--r--pvr-source/eurasiacon/build/linux2/modules.mk49
-rw-r--r--pvr-source/eurasiacon/build/linux2/omap4430_android/Makefile185
-rw-r--r--pvr-source/eurasiacon/build/linux2/omap4430_android/products.mk46
-rw-r--r--pvr-source/eurasiacon/build/linux2/prepare_tree.mk60
-rw-r--r--pvr-source/eurasiacon/build/linux2/this_makefile.mk68
-rwxr-xr-xpvr-source/eurasiacon/build/linux2/tools/cc-check.sh99
-rw-r--r--pvr-source/eurasiacon/build/linux2/toplevel.mk226
-rw-r--r--pvr-source/include4/dbgdrvif.h381
-rw-r--r--pvr-source/include4/img_defs.h153
-rw-r--r--pvr-source/include4/img_types.h214
-rw-r--r--pvr-source/include4/pdumpdefs.h126
-rw-r--r--pvr-source/include4/pvr_debug.h235
-rw-r--r--pvr-source/include4/pvrmodule.h48
-rw-r--r--pvr-source/include4/pvrversion.h69
-rw-r--r--pvr-source/include4/services.h1870
-rw-r--r--pvr-source/include4/servicesext.h965
-rw-r--r--pvr-source/include4/sgx_options.h258
-rw-r--r--pvr-source/include4/sgxapi_km.h524
-rw-r--r--pvr-source/include4/sgxscript.h99
-rw-r--r--pvr-source/services4/3rdparty/dc_nohw/Kbuild.mk47
-rw-r--r--pvr-source/services4/3rdparty/dc_nohw/Linux.mk45
-rw-r--r--pvr-source/services4/3rdparty/dc_nohw/dc_nohw.h288
-rw-r--r--pvr-source/services4/3rdparty/dc_nohw/dc_nohw_displayclass.c982
-rw-r--r--pvr-source/services4/3rdparty/dc_nohw/dc_nohw_linux.c376
-rw-r--r--pvr-source/services4/3rdparty/dc_omapfb3_linux/Kbuild.mk48
-rw-r--r--pvr-source/services4/3rdparty/dc_omapfb3_linux/Linux.mk45
-rw-r--r--pvr-source/services4/3rdparty/dc_omapfb3_linux/omaplfb.h323
-rw-r--r--pvr-source/services4/3rdparty/dc_omapfb3_linux/omaplfb_displayclass.c1722
-rw-r--r--pvr-source/services4/3rdparty/dc_omapfb3_linux/omaplfb_linux.c1165
-rw-r--r--pvr-source/services4/include/kernelbuffer.h97
-rw-r--r--pvr-source/services4/include/kerneldisplay.h243
-rw-r--r--pvr-source/services4/include/pdump.h51
-rw-r--r--pvr-source/services4/include/pvr_bridge.h2255
-rw-r--r--pvr-source/services4/include/pvr_bridge_km.h409
-rw-r--r--pvr-source/services4/include/pvrmmap.h81
-rw-r--r--pvr-source/services4/include/pvrsrv_errors.h311
-rw-r--r--pvr-source/services4/include/servicesint.h556
-rw-r--r--pvr-source/services4/include/sgx_bridge.h779
-rw-r--r--pvr-source/services4/include/sgx_mkif_km.h475
-rw-r--r--pvr-source/services4/include/sgx_ukernel_status_codes.h966
-rw-r--r--pvr-source/services4/include/sgxinfo.h493
-rw-r--r--pvr-source/services4/srvkm/bridged/bridged_pvr_bridge.c5512
-rw-r--r--pvr-source/services4/srvkm/bridged/bridged_pvr_bridge.h257
-rw-r--r--pvr-source/services4/srvkm/bridged/bridged_support.c117
-rw-r--r--pvr-source/services4/srvkm/bridged/bridged_support.h72
-rw-r--r--pvr-source/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c3864
-rw-r--r--pvr-source/services4/srvkm/bridged/sgx/bridged_sgx_bridge.h61
-rw-r--r--pvr-source/services4/srvkm/common/buffer_manager.c3573
-rw-r--r--pvr-source/services4/srvkm/common/deviceclass.c2863
-rw-r--r--pvr-source/services4/srvkm/common/deviceid.h51
-rw-r--r--pvr-source/services4/srvkm/common/devicemem.c2580
-rw-r--r--pvr-source/services4/srvkm/common/handle.c2689
-rw-r--r--pvr-source/services4/srvkm/common/hash.c738
-rw-r--r--pvr-source/services4/srvkm/common/lists.c156
-rw-r--r--pvr-source/services4/srvkm/common/mem.c175
-rw-r--r--pvr-source/services4/srvkm/common/mem_debug.c272
-rw-r--r--pvr-source/services4/srvkm/common/metrics.c209
-rw-r--r--pvr-source/services4/srvkm/common/osfunc_common.c48
-rw-r--r--pvr-source/services4/srvkm/common/pdump_common.c2967
-rw-r--r--pvr-source/services4/srvkm/common/perproc.c398
-rw-r--r--pvr-source/services4/srvkm/common/power.c996
-rw-r--r--pvr-source/services4/srvkm/common/pvrsrv.c1846
-rw-r--r--pvr-source/services4/srvkm/common/queue.c1500
-rw-r--r--pvr-source/services4/srvkm/common/ra.c2427
-rw-r--r--pvr-source/services4/srvkm/common/refcount.c588
-rw-r--r--pvr-source/services4/srvkm/common/resman.c985
-rw-r--r--pvr-source/services4/srvkm/common/ttrace.c597
-rw-r--r--pvr-source/services4/srvkm/devices/sgx/mmu.c4600
-rw-r--r--pvr-source/services4/srvkm/devices/sgx/mmu.h501
-rw-r--r--pvr-source/services4/srvkm/devices/sgx/pb.c493
-rw-r--r--pvr-source/services4/srvkm/devices/sgx/sgx_bridge_km.h279
-rw-r--r--pvr-source/services4/srvkm/devices/sgx/sgxconfig.h481
-rw-r--r--pvr-source/services4/srvkm/devices/sgx/sgxinfokm.h610
-rw-r--r--pvr-source/services4/srvkm/devices/sgx/sgxinit.c3428
-rw-r--r--pvr-source/services4/srvkm/devices/sgx/sgxkick.c899
-rw-r--r--pvr-source/services4/srvkm/devices/sgx/sgxpower.c630
-rw-r--r--pvr-source/services4/srvkm/devices/sgx/sgxreset.c808
-rw-r--r--pvr-source/services4/srvkm/devices/sgx/sgxtransfer.c814
-rw-r--r--pvr-source/services4/srvkm/devices/sgx/sgxutils.c1912
-rw-r--r--pvr-source/services4/srvkm/devices/sgx/sgxutils.h195
-rw-r--r--pvr-source/services4/srvkm/env/linux/Kbuild.mk166
-rw-r--r--pvr-source/services4/srvkm/env/linux/Linux.mk45
-rw-r--r--pvr-source/services4/srvkm/env/linux/env_data.h93
-rw-r--r--pvr-source/services4/srvkm/env/linux/env_perproc.h79
-rw-r--r--pvr-source/services4/srvkm/env/linux/event.c414
-rw-r--r--pvr-source/services4/srvkm/env/linux/event.h48
-rw-r--r--pvr-source/services4/srvkm/env/linux/gc_bvmapping.c147
-rw-r--r--pvr-source/services4/srvkm/env/linux/gc_bvmapping.h27
-rw-r--r--pvr-source/services4/srvkm/env/linux/ion.c363
-rw-r--r--pvr-source/services4/srvkm/env/linux/ion.h74
-rw-r--r--pvr-source/services4/srvkm/env/linux/linkage.h72
-rw-r--r--pvr-source/services4/srvkm/env/linux/lock.h56
-rw-r--r--pvr-source/services4/srvkm/env/linux/mm.c2945
-rw-r--r--pvr-source/services4/srvkm/env/linux/mm.h751
-rw-r--r--pvr-source/services4/srvkm/env/linux/mmap.c1656
-rw-r--r--pvr-source/services4/srvkm/env/linux/mmap.h240
-rw-r--r--pvr-source/services4/srvkm/env/linux/module.c1214
-rw-r--r--pvr-source/services4/srvkm/env/linux/mutex.c153
-rw-r--r--pvr-source/services4/srvkm/env/linux/mutex.h90
-rw-r--r--pvr-source/services4/srvkm/env/linux/mutils.c166
-rw-r--r--pvr-source/services4/srvkm/env/linux/mutils.h119
-rw-r--r--pvr-source/services4/srvkm/env/linux/osfunc.c4714
-rw-r--r--pvr-source/services4/srvkm/env/linux/osperproc.c146
-rw-r--r--pvr-source/services4/srvkm/env/linux/pdump.c804
-rw-r--r--pvr-source/services4/srvkm/env/linux/private_data.h95
-rw-r--r--pvr-source/services4/srvkm/env/linux/proc.c1414
-rw-r--r--pvr-source/services4/srvkm/env/linux/proc.h127
-rw-r--r--pvr-source/services4/srvkm/env/linux/pvr_bridge_k.c524
-rw-r--r--pvr-source/services4/srvkm/env/linux/pvr_debug.c506
-rw-r--r--pvr-source/services4/srvkm/env/linux/pvr_uaccess.h88
-rw-r--r--pvr-source/services4/srvkm/env/linux/sysfs.c90
-rw-r--r--pvr-source/services4/srvkm/env/linux/sysfs.h22
-rw-r--r--pvr-source/services4/srvkm/hwdefs/mnemedefs.h117
-rw-r--r--pvr-source/services4/srvkm/hwdefs/ocpdefs.h308
-rw-r--r--pvr-source/services4/srvkm/hwdefs/sgx520defs.h555
-rw-r--r--pvr-source/services4/srvkm/hwdefs/sgx530defs.h542
-rw-r--r--pvr-source/services4/srvkm/hwdefs/sgx531defs.h601
-rw-r--r--pvr-source/services4/srvkm/hwdefs/sgx535defs.h739
-rw-r--r--pvr-source/services4/srvkm/hwdefs/sgx540defs.h605
-rw-r--r--pvr-source/services4/srvkm/hwdefs/sgx543_v1.164defs.h1396
-rw-r--r--pvr-source/services4/srvkm/hwdefs/sgx543defs.h1487
-rw-r--r--pvr-source/services4/srvkm/hwdefs/sgx544defs.h1487
-rw-r--r--pvr-source/services4/srvkm/hwdefs/sgx545defs.h1290
-rw-r--r--pvr-source/services4/srvkm/hwdefs/sgxdefs.h112
-rw-r--r--pvr-source/services4/srvkm/hwdefs/sgxerrata.h518
-rw-r--r--pvr-source/services4/srvkm/hwdefs/sgxfeaturedefs.h274
-rw-r--r--pvr-source/services4/srvkm/hwdefs/sgxmmu.h99
-rw-r--r--pvr-source/services4/srvkm/hwdefs/sgxmpdefs.h365
-rw-r--r--pvr-source/services4/srvkm/include/buffer_manager.h674
-rw-r--r--pvr-source/services4/srvkm/include/device.h409
-rw-r--r--pvr-source/services4/srvkm/include/handle.h567
-rw-r--r--pvr-source/services4/srvkm/include/hash.h277
-rw-r--r--pvr-source/services4/srvkm/include/lists.h349
-rw-r--r--pvr-source/services4/srvkm/include/metrics.h146
-rw-r--r--pvr-source/services4/srvkm/include/osfunc.h799
-rw-r--r--pvr-source/services4/srvkm/include/osperproc.h94
-rw-r--r--pvr-source/services4/srvkm/include/pdump_int.h100
-rw-r--r--pvr-source/services4/srvkm/include/pdump_km.h441
-rw-r--r--pvr-source/services4/srvkm/include/pdump_osfunc.h337
-rw-r--r--pvr-source/services4/srvkm/include/perfkm.h53
-rw-r--r--pvr-source/services4/srvkm/include/perproc.h150
-rw-r--r--pvr-source/services4/srvkm/include/power.h140
-rw-r--r--pvr-source/services4/srvkm/include/queue.h145
-rw-r--r--pvr-source/services4/srvkm/include/ra.h293
-rw-r--r--pvr-source/services4/srvkm/include/refcount.h203
-rw-r--r--pvr-source/services4/srvkm/include/resman.h152
-rw-r--r--pvr-source/services4/srvkm/include/services_headers.h68
-rw-r--r--pvr-source/services4/srvkm/include/srvkm.h129
-rw-r--r--pvr-source/services4/srvkm/include/ttrace.h200
-rw-r--r--pvr-source/services4/srvkm/include/ttrace_common.h146
-rw-r--r--pvr-source/services4/srvkm/include/ttrace_tokens.h119
-rw-r--r--pvr-source/services4/system/include/syscommon.h397
-rw-r--r--pvr-source/services4/system/omap4/oemfuncs.h80
-rw-r--r--pvr-source/services4/system/omap4/sgxfreq.c590
-rw-r--r--pvr-source/services4/system/omap4/sgxfreq.h97
-rw-r--r--pvr-source/services4/system/omap4/sgxfreq_activeidle.c181
-rw-r--r--pvr-source/services4/system/omap4/sgxfreq_cool.c104
-rw-r--r--pvr-source/services4/system/omap4/sgxfreq_on3demand.c324
-rw-r--r--pvr-source/services4/system/omap4/sgxfreq_onoff.c180
-rw-r--r--pvr-source/services4/system/omap4/sgxfreq_userspace.c180
-rw-r--r--pvr-source/services4/system/omap4/sysconfig.c1329
-rw-r--r--pvr-source/services4/system/omap4/sysconfig.h110
-rw-r--r--pvr-source/services4/system/omap4/sysinfo.h64
-rw-r--r--pvr-source/services4/system/omap4/syslocal.h265
-rw-r--r--pvr-source/services4/system/omap4/sysutils.c59
-rw-r--r--pvr-source/services4/system/omap4/sysutils_linux.c745
-rw-r--r--pvr-source/tools/intern/debug/client/linuxsrv.h64
-rw-r--r--pvr-source/tools/intern/debug/dbgdriv/Kbuild.mk51
-rw-r--r--pvr-source/tools/intern/debug/dbgdriv/Linux.mk45
-rw-r--r--pvr-source/tools/intern/debug/dbgdriv/common/dbgdriv.c2883
-rw-r--r--pvr-source/tools/intern/debug/dbgdriv/common/dbgdriv.h155
-rw-r--r--pvr-source/tools/intern/debug/dbgdriv/common/dbgdriv_ioctl.h57
-rw-r--r--pvr-source/tools/intern/debug/dbgdriv/common/handle.c141
-rw-r--r--pvr-source/tools/intern/debug/dbgdriv/common/hostfunc.h82
-rw-r--r--pvr-source/tools/intern/debug/dbgdriv/common/hotkey.c199
-rw-r--r--pvr-source/tools/intern/debug/dbgdriv/common/hotkey.h82
-rw-r--r--pvr-source/tools/intern/debug/dbgdriv/common/ioctl.c827
-rw-r--r--pvr-source/tools/intern/debug/dbgdriv/linux/hostfunc.c395
-rw-r--r--pvr-source/tools/intern/debug/dbgdriv/linux/main.c355
316 files changed, 191119 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..f35559b
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,23 @@
+#
+# Copyright (C) 2013 The CyanogenMod Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+ifneq ($(filter i9100g p3100 p3110 p5100 p5110,$(TARGET_DEVICE)),)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
+endif
diff --git a/BoardConfigCommon.mk b/BoardConfigCommon.mk
new file mode 100644
index 0000000..a44100e
--- /dev/null
+++ b/BoardConfigCommon.mk
@@ -0,0 +1,90 @@
+#
+# Copyright (C) 2013 The CyanogenMod Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+COMMON_PATH := device/samsung/omap4-common
+
+BOARD_VENDOR := samsung
+
+PRODUCT_VENDOR_KERNEL_HEADERS := $(COMMON_PATH)/kernel-headers
+TARGET_SPECIFIC_HEADER_PATH := $(COMMON_PATH)/include
+
+# HWComposer
+BOARD_USES_HWCOMPOSER := true
+BOARD_USE_SYSFS_VSYNC_NOTIFICATION := true
+# set if the target supports FBIO_WAITFORVSYNC
+TARGET_HAS_WAITFORVSYNC := true
+
+# Setup custom omap4xxx defines
+BOARD_USE_CUSTOM_LIBION := true
+
+# TI Enhancement Settings (Part 1)
+OMAP_ENHANCEMENT := true
+#OMAP_ENHANCEMENT_BURST_CAPTURE := true
+#OMAP_ENHANCEMENT_S3D := true
+#OMAP_ENHANCEMENT_CPCAM := true
+#OMAP_ENHANCEMENT_VTC := true
+OMAP_ENHANCEMENT_MULTIGPU := true
+BOARD_USE_TI_ENHANCED_DOMX := true
+
+# External SGX Module
+SGX_MODULES:
+ make clean -C $(COMMON_PATH)/pvr-source/eurasiacon/build/linux2/omap4430_android
+ cp $(TARGET_KERNEL_SOURCE)/drivers/video/omap2/omapfb/omapfb.h $(KERNEL_OUT)/drivers/video/omap2/omapfb/omapfb.h
+ make -j8 -C $(COMMON_PATH)/pvr-source/eurasiacon/build/linux2/omap4430_android ARCH=arm KERNEL_CROSS_COMPILE=arm-eabi- CROSS_COMPILE=arm-eabi- KERNELDIR=$(KERNEL_OUT) TARGET_PRODUCT="blaze_tablet" BUILD=release TARGET_SGX=540 PLATFORM_VERSION=4.0
+ mv $(KERNEL_OUT)/../../target/kbuild/pvrsrvkm_sgx540_120.ko $(KERNEL_MODULES_OUT)
+
+TARGET_KERNEL_MODULES += SGX_MODULES
+
+# TI Enhancement Settings (Part 2)
+ifdef BOARD_USE_TI_ENHANCED_DOMX
+ BOARD_USE_TI_DUCATI_H264_PROFILE := true
+ COMMON_GLOBAL_CFLAGS += -DENHANCED_DOMX
+ ENHANCED_DOMX := true
+else
+ DOMX_PATH := hardware/ti/omap4xxx/domx
+endif
+
+ifdef OMAP_ENHANCEMENT
+ COMMON_GLOBAL_CFLAGS += -DOMAP_ENHANCEMENT -DTARGET_OMAP4
+endif
+
+ifdef OMAP_ENHANCEMENT_BURST_CAPTURE
+ COMMON_GLOBAL_CFLAGS += -DOMAP_ENHANCEMENT_BURST_CAPTURE
+endif
+
+ifdef OMAP_ENHANCEMENT_S3D
+ COMMON_GLOBAL_CFLAGS += -DOMAP_ENHANCEMENT_S3D
+endif
+
+ifdef OMAP_ENHANCEMENT_CPCAM
+ COMMON_GLOBAL_CFLAGS += -DOMAP_ENHANCEMENT_CPCAM
+ PRODUCT_MAKEFILES += $(LOCAL_DIR)/sdk_addon/ti_omap_addon.mk
+endif
+
+ifdef OMAP_ENHANCEMENT_VTC
+ COMMON_GLOBAL_CFLAGS += -DOMAP_ENHANCEMENT_VTC
+endif
+
+ifdef USE_ITTIAM_AAC
+ COMMON_GLOBAL_CFLAGS += -DUSE_ITTIAM_AAC
+endif
+
+ifdef OMAP_ENHANCEMENT_MULTIGPU
+ COMMON_GLOBAL_CFLAGS += -DOMAP_ENHANCEMENT_MULTIGPU
+endif
+
+# inherit from the proprietary version
+-include vendor/samsung/omap4-common/BoardConfigVendor.mk
diff --git a/bltsville/Android.mk b/bltsville/Android.mk
new file mode 100644
index 0000000..56a3fa8
--- /dev/null
+++ b/bltsville/Android.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+include $(call all-subdir-makefiles)
diff --git a/bltsville/bltsville/README b/bltsville/bltsville/README
new file mode 100755
index 0000000..bf5751b
--- /dev/null
+++ b/bltsville/bltsville/README
@@ -0,0 +1 @@
+git://github.com/graphics/bltsville.git
diff --git a/bltsville/bltsville/blend-854x480-bad.jpg b/bltsville/bltsville/blend-854x480-bad.jpg
new file mode 100644
index 0000000..adc2d6d
--- /dev/null
+++ b/bltsville/bltsville/blend-854x480-bad.jpg
Binary files differ
diff --git a/bltsville/bltsville/blend-854x480-bad2.jpg b/bltsville/bltsville/blend-854x480-bad2.jpg
new file mode 100644
index 0000000..67a01f3
--- /dev/null
+++ b/bltsville/bltsville/blend-854x480-bad2.jpg
Binary files differ
diff --git a/bltsville/bltsville/blend-854x480-roundingerror.jpg b/bltsville/bltsville/blend-854x480-roundingerror.jpg
new file mode 100644
index 0000000..9a12713
--- /dev/null
+++ b/bltsville/bltsville/blend-854x480-roundingerror.jpg
Binary files differ
diff --git a/bltsville/bltsville/blend-854x480-threeblts.jpg b/bltsville/bltsville/blend-854x480-threeblts.jpg
new file mode 100644
index 0000000..3790a29
--- /dev/null
+++ b/bltsville/bltsville/blend-854x480-threeblts.jpg
Binary files differ
diff --git a/bltsville/bltsville/blend-854x480.jpg b/bltsville/bltsville/blend-854x480.jpg
new file mode 100644
index 0000000..c76a433
--- /dev/null
+++ b/bltsville/bltsville/blend-854x480.jpg
Binary files differ
diff --git a/bltsville/bltsville/bvlogo.png b/bltsville/bltsville/bvlogo.png
new file mode 100644
index 0000000..7f9944e
--- /dev/null
+++ b/bltsville/bltsville/bvlogo.png
Binary files differ
diff --git a/bltsville/bltsville/clock-720x480_4x3-fauxtrans.jpg b/bltsville/bltsville/clock-720x480_4x3-fauxtrans.jpg
new file mode 100644
index 0000000..fa3aa68
--- /dev/null
+++ b/bltsville/bltsville/clock-720x480_4x3-fauxtrans.jpg
Binary files differ
diff --git a/bltsville/bltsville/clock-720x480_4x3.png b/bltsville/bltsville/clock-720x480_4x3.png
new file mode 100644
index 0000000..3a7f566
--- /dev/null
+++ b/bltsville/bltsville/clock-720x480_4x3.png
Binary files differ
diff --git a/bltsville/bltsville/concrete-64x36.png b/bltsville/bltsville/concrete-64x36.png
new file mode 100644
index 0000000..cf21f0f
--- /dev/null
+++ b/bltsville/bltsville/concrete-64x36.png
Binary files differ
diff --git a/bltsville/bltsville/include/bltsville.h b/bltsville/bltsville/include/bltsville.h
new file mode 100644
index 0000000..632628e
--- /dev/null
+++ b/bltsville/bltsville/include/bltsville.h
@@ -0,0 +1,602 @@
+/*
+ * bltsville.h
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This file is part of BLTsville, an open application programming interface
+ * (API) for accessing 2-D software or hardware implementations.
+ *
+ * This work is licensed under the Creative Commons Attribution-NoDerivs 3.0
+ * Unported License. To view a copy of this license, visit
+ * http://creativecommons.org/licenses/by-nd/3.0/ or send a letter to
+ * Creative Commons, 444 Castro Street, Suite 900, Mountain View, California,
+ * 94041, USA.
+ */
+
+#ifndef BLTSVILLE_H
+#define BLTSVILLE_H
+
+#include "ocd.h"
+#include "bverror.h"
+#include "bvblend.h"
+#include "bvfilter.h"
+#include "bvbuffdesc.h"
+#include "bvcache.h"
+#include "bventry.h"
+#include "bvsurfgeom.h"
+
+/*
+ * bvrect - This structure is used to specify rectangles in BLTsville.
+ */
+struct bvrect {
+ int left;
+ int top;
+ unsigned int width;
+ unsigned int height;
+};
+
+
+/*
+ * BVFLAG_* - These define the type of BLT to be performed and are placed in
+ * the bvparams.flags element.
+ */
+#define BVFLAG_OP_SHIFT 0
+#define BVFLAG_OP_MASK (0xF << BVFLAG_OP_SHIFT)
+
+/* 0 reserved */
+#define BVFLAG_ROP (0x1 << BVFLAG_OP_SHIFT) /* ROP4 spec'd in rop */
+#define BVFLAG_BLEND (0x2 << BVFLAG_OP_SHIFT) /* blend spec'd in blend */
+/* 3 reserved */
+#define BVFLAG_FILTER (0x4 << BVFLAG_OP_SHIFT) /* filter spec'd in filter */
+/* 5-F reserved */
+
+#define BVFLAG_KEY_SRC 0x00000010 /* source color key - value spec'd
+ by pcolorkey; Mutually exclusive
+ with BVFLAG_KEY_DST */
+#define BVFLAG_KEY_DST 0x00000020 /* dest color key - value spec'd
+ by pcolorkey; Mutually exclusive
+ with BVFLAG_KEY_SRC */
+#define BVFLAG_CLIP 0x00000040 /* clipping rectangle spec'd by
+ cliprect */
+#define BVFLAG_SRCMASK 0x00000080 /* when scaling a masked copy, mask
+ at the source instead of the
+ (default) destination */
+
+#define BVFLAG_ASYNC 0x00000100 /* call should return once queued */
+
+#define BVFLAG_TILE_SRC1 0x00000200 /* source 1 is tiled */
+#define BVFLAG_TILE_SRC2 0x00000400 /* source 2 is tiled */
+#define BVFLAG_TILE_MASK 0x00000800 /* mask is tiled */
+
+
+#define BVFLAG_BATCH_SHIFT 12
+#define BVFLAG_BATCH_MASK (3 << BVFLAG_BATCH_SHIFT)
+
+#define BVFLAG_BATCH_NONE (0 << BVFLAG_BATCH_SHIFT) /* not batched */
+#define BVFLAG_BATCH_BEGIN (1 << BVFLAG_BATCH_SHIFT) /* begin batch */
+#define BVFLAG_BATCH_CONTINUE (2 << BVFLAG_BATCH_SHIFT) /* continue batch */
+#define BVFLAG_BATCH_END (3 << BVFLAG_BATCH_SHIFT) /* end batch */
+
+
+#define BVFLAG_HORZ_FLIP_SRC1 0x00004000 /* flip src1 horizontally */
+#define BVFLAG_VERT_FLIP_SRC1 0x00008000 /* flip src1 vertically */
+#define BVFLAG_HORZ_FLIP_SRC2 0x00010000 /* flip src2 horizontally */
+#define BVFLAG_VERT_FLIP_SRC2 0x00020000 /* flip src2 vertically */
+#define BVFLAG_HORZ_FLIP_MASK 0x00040000 /* flip mask horizontally */
+#define BVFLAG_VERT_FLIP_MASK 0x00080000 /* flip mask vertically */
+
+
+#define BVFLAG_SCALE_RETURN 0x00100000 /* return scale type used */
+#define BVFLAG_DITHER_RETURN 0x00200000 /* return dither type used */
+
+
+#define BVFLAG_SRC2_AUXDSTRECT 0x00400000 /* src2auxdstrect used */
+#define BVFLAG_MASK_AUXDSTRECT 0x00800000 /* maskauxdstrect used */
+
+#define BVFLAG_TESTPARAMS_NOP 0x01000000 /* test params only - no BLT */
+/**** Bits 25-31 reserved ****/
+
+/*
+ * BVIMPL_* - BLTsville implementations may be combined under managers to
+ * allow clients to take advantage of multiple implementations without doing
+ * so explicitly. The BVIMPL_* definition are placed into the
+ * bvparams.implementation member by the client to override the manager's
+ * choice of implementation.
+ */
+#define BVIMPL_ANY 0
+#define BVIMPL_FIRST_HW (1 << 31) /* Continues to the right */
+#define BVIMPL_FIRST_CPU (1 << 0) /* Continues to the left */
+
+
+/*
+ * bvscalemode - This specifies the type of scaling to perform.
+ */
+#define BVSCALEDEF_VENDOR_SHIFT 24
+#define BVSCALEDEF_VENDOR_MASK (0xFF << BVSCALEDEF_VENDOR_SHIFT)
+
+#define BVSCALEDEF_VENDOR_ALL (0 << BVSCALEDEF_VENDOR_SHIFT)
+#define BVSCALEDEF_VENDOR_TI (1 << BVSCALEDEF_VENDOR_SHIFT)
+/* 0xF0-0xFE reserved */
+#define BVSCALEDEF_VENDOR_GENERIC (0xFF << BVSCALEDEF_VENDOR_SHIFT)
+
+/***** VENDOR_GENERIC definitions *****/
+/**** Bits 23-22 indicate classification ****/
+#define BVSCALEDEF_CLASS_SHIFT 22
+#define BVSCALEDEF_IMPLICIT (0 << BVSCALEDEF_CLASS_SHIFT)
+#define BVSCALEDEF_EXPLICIT (1 << BVSCALEDEF_CLASS_SHIFT)
+/* 2-3 reserved */
+#define BVSCALEDEF_CLASS_MASK (3 << BVSCALEDEF_CLASS_SHIFT)
+
+/**** IMPLICIT definitions ****/
+/*** Bits 21-16 indicate the quality (speed) desired ***/
+#define BVSCALEDEF_QUALITY_SHIFT 16
+#define BVSCALEDEF_FASTEST (0x00 << BVSCALEDEF_QUALITY_SHIFT)
+#define BVSCALEDEF_GOOD (0x15 << BVSCALEDEF_QUALITY_SHIFT)
+#define BVSCALEDEF_BETTER (0x2A << BVSCALEDEF_QUALITY_SHIFT)
+#define BVSCALEDEF_BEST (0x3F << BVSCALEDEF_QUALITY_SHIFT)
+#define BVSCALEDEF_QUALITY_MASK (0x3F << BVSCALEDEF_QUALITY_SHIFT)
+/* Bits 12-15 are reserved */
+/*** Bits 11-8 indicate the desired technique ***/
+#define BVSCALEDEF_TECHNIQUE_SHIFT 8
+#define BVSCALEDEF_DONT_CARE (0x0 << BVSCALEDEF_TECHNIQUE_SHIFT)
+#define BVSCALEDEF_NOT_NEAREST_NEIGHBOR (0x1 << BVSCALEDEF_TECHNIQUE_SHIFT)
+#define BVSCALEDEF_POINT_SAMPLE (0x2 << BVSCALEDEF_TECHNIQUE_SHIFT)
+#define BVSCALEDEF_INTERPOLATED (0x3 << BVSCALEDEF_TECHNIQUE_SHIFT)
+#define BVSCALEDEF_TECHNIQUE_MASK (0xF << BVSCALEDEF_TECHNIQUE_SHIFT)
+/* Bits 2-7 reserved */
+/*** Bits 1-0 indicate the type of image ***/
+#define BVSCALEDEF_TYPE_SHIFT 0
+/* 0 don't know */
+#define BVSCALEDEF_PHOTO (1 << BVSCALEDEF_TYPE_SHIFT)
+#define BVSCALEDEF_DRAWING (2 << BVSCALEDEF_TYPE_SHIFT)
+/* 3 reserved */
+#define BVSCALEDEF_TYPE_MASK (3 << BVSCALEDEF_TYPE_SHIFT)
+
+/**** EXPLICIT definitions ****/
+/* Bits 16-21 reserved */
+#define BVSCALEDEF_HORZ_SHIFT 8
+#define BVSCALEDEF_HORZ_MASK (0xFF << BVSCALEDEF_HORZ_SHIFT)
+
+#define BVSCALEDEF_VERT_SHIFT 0
+#define BVSCALEDEF_VERT_MASK (0xFF << BVSCALEDEF_VERT_SHIFT)
+
+#define BVSCALEDEF_NEAREST_NEIGHBOR 0x00
+#define BVSCALEDEF_LINEAR 0x01
+#define BVSCALEDEF_CUBIC 0x02
+#define BVSCALEDEF_3_TAP 0x03
+/* 0x04 reserved */
+#define BVSCALEDEF_5_TAP 0x05
+/* 0x06 reserved */
+#define BVSCALEDEF_7_TAP 0x07
+/* 0x08 reserved */
+#define BVSCALEDEF_9_TAP 0x09
+/* 0x0A-0xFF reserved */
+
+enum bvscalemode {
+ BVSCALE_FASTEST = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_FASTEST |
+ BVSCALEDEF_DONT_CARE,
+ BVSCALE_FASTEST_NOT_NEAREST_NEIGHBOR = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_FASTEST |
+ BVSCALEDEF_NOT_NEAREST_NEIGHBOR,
+ BVSCALE_FASTEST_POINT_SAMPLE = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_FASTEST |
+ BVSCALEDEF_POINT_SAMPLE,
+ BVSCALE_FASTEST_INTERPOLATED = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_FASTEST |
+ BVSCALEDEF_INTERPOLATED,
+ BVSCALE_FASTEST_PHOTO = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_FASTEST |
+ BVSCALEDEF_PHOTO,
+ BVSCALE_FASTEST_DRAWING = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_FASTEST |
+ BVSCALEDEF_DRAWING,
+ BVSCALE_GOOD = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_GOOD |
+ BVSCALEDEF_DONT_CARE,
+ BVSCALE_GOOD_POINT_SAMPLE = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_GOOD |
+ BVSCALEDEF_POINT_SAMPLE,
+ BVSCALE_GOOD_INTERPOLATED = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_GOOD |
+ BVSCALEDEF_INTERPOLATED,
+ BVSCALE_GOOD_PHOTO = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_GOOD |
+ BVSCALEDEF_PHOTO,
+ BVSCALE_GOOD_DRAWING = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_GOOD |
+ BVSCALEDEF_DRAWING,
+ BVSCALE_BETTER = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_BETTER |
+ BVSCALEDEF_DONT_CARE,
+ BVSCALE_BETTER_POINT_SAMPLE = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_BETTER |
+ BVSCALEDEF_POINT_SAMPLE,
+ BVSCALE_BETTER_INTERPOLATED = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_BETTER |
+ BVSCALEDEF_INTERPOLATED,
+ BVSCALE_BETTER_PHOTO = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_BETTER |
+ BVSCALEDEF_PHOTO,
+ BVSCALE_BETTER_DRAWING = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_BETTER |
+ BVSCALEDEF_DRAWING,
+ BVSCALE_BEST = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_BEST |
+ BVSCALEDEF_DONT_CARE,
+ BVSCALE_BEST_POINT_SAMPLE = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_BEST |
+ BVSCALEDEF_POINT_SAMPLE,
+ BVSCALE_BEST_INTERPOLATED = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_BEST |
+ BVSCALEDEF_INTERPOLATED,
+ BVSCALE_BEST_PHOTO = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_BEST |
+ BVSCALEDEF_PHOTO,
+ BVSCALE_BEST_DRAWING = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_BEST |
+ BVSCALEDEF_DRAWING,
+
+ BVSCALE_NEAREST_NEIGHBOR = BVSCALEDEF_VENDOR_GENERIC |
+ BVSCALEDEF_EXPLICIT |
+ (BVSCALEDEF_NEAREST_NEIGHBOR << BVSCALEDEF_HORZ_SHIFT) |
+ (BVSCALEDEF_NEAREST_NEIGHBOR << BVSCALEDEF_VERT_SHIFT),
+ BVSCALE_BILINEAR = BVSCALEDEF_VENDOR_GENERIC |
+ BVSCALEDEF_EXPLICIT |
+ (BVSCALEDEF_LINEAR << BVSCALEDEF_HORZ_SHIFT) |
+ (BVSCALEDEF_LINEAR << BVSCALEDEF_VERT_SHIFT),
+ BVSCALE_BICUBIC = BVSCALEDEF_VENDOR_GENERIC |
+ BVSCALEDEF_EXPLICIT |
+ (BVSCALEDEF_CUBIC << BVSCALEDEF_HORZ_SHIFT) |
+ (BVSCALEDEF_CUBIC << BVSCALEDEF_VERT_SHIFT),
+ BVSCALE_3x3_TAP = BVSCALEDEF_VENDOR_GENERIC |
+ BVSCALEDEF_EXPLICIT |
+ (BVSCALEDEF_3_TAP << BVSCALEDEF_HORZ_SHIFT) |
+ (BVSCALEDEF_3_TAP << BVSCALEDEF_VERT_SHIFT),
+ BVSCALE_5x5_TAP = BVSCALEDEF_VENDOR_GENERIC |
+ BVSCALEDEF_EXPLICIT |
+ (BVSCALEDEF_5_TAP << BVSCALEDEF_HORZ_SHIFT) |
+ (BVSCALEDEF_5_TAP << BVSCALEDEF_VERT_SHIFT),
+ BVSCALE_7x7_TAP = BVSCALEDEF_VENDOR_GENERIC |
+ BVSCALEDEF_EXPLICIT |
+ (BVSCALEDEF_7_TAP << BVSCALEDEF_HORZ_SHIFT) |
+ (BVSCALEDEF_7_TAP << BVSCALEDEF_VERT_SHIFT),
+ BVSCALE_9x9_TAP = BVSCALEDEF_VENDOR_GENERIC |
+ BVSCALEDEF_EXPLICIT |
+ (BVSCALEDEF_9_TAP << BVSCALEDEF_HORZ_SHIFT) |
+ (BVSCALEDEF_9_TAP << BVSCALEDEF_VERT_SHIFT),
+
+#ifdef BVSCALE_EXTERNAL_INCLUDE
+#include BVSCALE_EXTERNAL_INCLUDE
+#endif
+};
+
+
+/*
+ * bvdithermode - This defines the type of dithering to use.
+ */
+#define BVDITHERDEF_VENDOR_SHIFT 24
+#define BVDITHERDEF_VENDOR_MASK (0xFF << BVDITHERDEF_VENDOR_SHIFT)
+
+#define BVDITHERDEF_VENDOR_ALL (0 << BVDITHERDEF_VENDOR_SHIFT)
+#define BVDITHERDEF_VENDOR_TI (1 << BVDITHERDEF_VENDOR_SHIFT)
+/* 0xF0-0xFE reserved */
+#define BVDITHERDEF_VENDOR_GENERIC (0xFF << BVDITHERDEF_VENDOR_SHIFT)
+
+/***** VENDOR_GENERIC definitions *****/
+/* Bits 18-23 reserved */
+/**** Bits 17-16 indicate the type of image - 0 = don't know ****/
+#define BVDITHERDEF_TYPE_SHIFT 16
+#define BVDITHERDEF_PHOTO (0x01 << BVDITHERDEF_TYPE_SHIFT)
+#define BVDITHERDEF_DRAWING (0x02 << BVDITHERDEF_TYPE_SHIFT)
+/**** Bits 15-8 indicate the desired technique ****/
+#define BVDITHERDEF_TECHNIQUE_SHIFT 8
+#define BVDITHERDEF_DONT_CARE (0x00 << BVDITHERDEF_TECHNIQUE_SHIFT)
+#define BVDITHERDEF_RANDOM (0x01 << BVDITHERDEF_TECHNIQUE_SHIFT)
+#define BVDITHERDEF_ORDERED (0x02 << BVDITHERDEF_TECHNIQUE_SHIFT)
+#define BVDITHERDEF_DIFFUSED (0x04 << BVDITHERDEF_TECHNIQUE_SHIFT)
+#define BVDITHERDEF_ON (0xFF << BVDITHERDEF_TECHNIQUE_SHIFT)
+/**** Bits 7-0 indicate the quality (speed) desired ****/
+#define BVDITHERDEF_QUALITY_SHIFT 0
+#define BVDITHERDEF_FASTEST (0x00 << BVDITHERDEF_QUALITY_SHIFT)
+#define BVDITHERDEF_GOOD (0x55 << BVDITHERDEF_QUALITY_SHIFT)
+#define BVDITHERDEF_BETTER (0xAA << BVDITHERDEF_QUALITY_SHIFT)
+#define BVDITHERDEF_BEST (0xFF << BVDITHERDEF_QUALITY_SHIFT)
+
+enum bvdithermode {
+ BVDITHER_FASTEST = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_FASTEST |
+ BVDITHERDEF_DONT_CARE,
+ BVDITHER_FASTEST_ON = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_FASTEST |
+ BVDITHERDEF_ON,
+ BVDITHER_FASTEST_RANDOM = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_FASTEST |
+ BVDITHERDEF_RANDOM,
+ BVDITHER_FASTEST_ORDERED = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_FASTEST |
+ BVDITHERDEF_ORDERED,
+ BVDITHER_FASTEST_DIFFUSED = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_FASTEST |
+ BVDITHERDEF_DIFFUSED,
+ BVDITHER_FASTEST_PHOTO = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_FASTEST |
+ BVDITHERDEF_PHOTO,
+ BVDITHER_FASTEST_DRAWING = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_FASTEST |
+ BVDITHERDEF_DRAWING,
+ BVDITHER_GOOD = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_GOOD |
+ BVDITHERDEF_DONT_CARE,
+ BVDITHER_GOOD_ON = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_GOOD |
+ BVDITHERDEF_ON,
+ BVDITHER_GOOD_RANDOM = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_GOOD |
+ BVDITHERDEF_RANDOM,
+ BVDITHER_GOOD_ORDERED = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_GOOD |
+ BVDITHERDEF_ORDERED,
+ BVDITHER_GOOD_DIFFUSED = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_GOOD |
+ BVDITHERDEF_DIFFUSED,
+ BVDITHER_GOOD_PHOTO = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_GOOD |
+ BVDITHERDEF_PHOTO,
+ BVDITHER_GOOD_DRAWING = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_GOOD |
+ BVDITHERDEF_DRAWING,
+ BVDITHER_BETTER = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BETTER |
+ BVDITHERDEF_DONT_CARE,
+ BVDITHER_BETTER_ON = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BETTER |
+ BVDITHERDEF_ON,
+ BVDITHER_BETTER_RANDOM = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BETTER |
+ BVDITHERDEF_RANDOM,
+ BVDITHER_BETTER_ORDERED = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BETTER |
+ BVDITHERDEF_ORDERED,
+ BVDITHER_BETTER_DIFFUSED = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BETTER |
+ BVDITHERDEF_DIFFUSED,
+ BVDITHER_BETTER_PHOTO = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BETTER |
+ BVDITHERDEF_PHOTO,
+ BVDITHER_BETTER_DRAWING = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BETTER |
+ BVDITHERDEF_DRAWING,
+ BVDITHER_BEST = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BEST |
+ BVDITHERDEF_DONT_CARE,
+ BVDITHER_BEST_ON = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BEST |
+ BVDITHERDEF_ON,
+ BVDITHER_BEST_RANDOM = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BEST |
+ BVDITHERDEF_RANDOM,
+ BVDITHER_BEST_ORDERED = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BEST |
+ BVDITHERDEF_ORDERED,
+ BVDITHER_BEST_DIFFUSED = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BEST |
+ BVDITHERDEF_DIFFUSED,
+ BVDITHER_BEST_PHOTO = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BEST |
+ BVDITHERDEF_PHOTO,
+ BVDITHER_BEST_DRAWING = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BEST |
+ BVDITHERDEF_DRAWING,
+
+ BVDITHER_NONE = BVDITHERDEF_VENDOR_GENERIC + 0,
+ BVDITHER_ORDERED_2x2 = BVDITHERDEF_VENDOR_GENERIC + 4,
+ BVDITHER_ORDERED_4x4 = BVDITHERDEF_VENDOR_GENERIC + 16,
+ BVDITHER_ORDERED_2x2_4x4 = BVDITHERDEF_VENDOR_GENERIC + 4 + 16,
+ /* 2x2 for 6->8, 4x4 for 5->8 */
+
+#ifdef BVDITHER_EXTERNAL_INCLUDE
+#include BVDITHER_EXTERNAL_INCLUDE
+#endif
+};
+
+
+/*
+ * BVTILE_* flags - These specify parameters used when tiling.
+ */
+#define BVTILE_LEFT_SHIFT 0
+#define BVTILE_TOP_SHIFT (BVTILE_LEFT_SHIFT + 2)
+#define BVTILE_RIGHT_SHIFT (BVTILE_TOP_SHIFT + 2)
+#define BVTILE_BOTTOM_SHIFT (BVTILE_RIGHT_SHIFT + 2)
+#define BVTILE_LEFT_REPEAT (0 << BVTILE_LEFT_SHIFT) /* ...012301230123 */
+#define BVTILE_TOP_REPEAT (0 << BVTILE_TOP_SHIFT) /* ...012301230123 */
+#define BVTILE_RIGHT_REPEAT (0 << BVTILE_RIGHT_SHIFT) /* 012301230123... */
+#define BVTILE_BOTTOM_REPEAT (0 << BVTILE_BOTTOM_SHIFT) /* 012301230123... */
+#define BVTILE_LEFT_MIRROR (1 << BVTILE_LEFT_SHIFT) /* ...012332100123 */
+#define BVTILE_TOP_MIRROR (1 << BVTILE_TOP_SHIFT) /* ...012332100123 */
+#define BVTILE_RIGHT_MIRROR (1 << BVTILE_RIGHT_SHIFT) /* 012332100123... */
+#define BVTILE_BOTTOM_MIRROR (1 << BVTILE_BOTTOM_SHIFT) /* 012332100123... */
+
+/*
+ * bvtileparams - This structure provides additional parameters needed when
+ * tiling. This structure replaces the bvbuffdesc in bvbltparams when the
+ * associated BVFLAG_TILE_* flag is set in bvbltparams.flags.
+ */
+struct bvtileparams {
+ unsigned int structsize; /* used to ID structure version */
+ unsigned long flags; /* tile flags */
+ void *virtaddr; /* pointer to the brush */
+ int dstleft; /* horizontal offset */
+ int dsttop; /* vertical offset */
+ unsigned int srcwidth; /* w/dst width to spec horz scale */
+ unsigned int srcheight; /* w/dst height to spec vert scale */
+};
+
+/*
+ * BVBATCH_* - These flags specify the parameters that change between
+ * batched BLTs, when BVFLAG_CONTINUE or BVFLAG_END set.
+ */
+#define BVBATCH_OP 0x00000001 /* type of operation changed */
+#define BVBATCH_KEY 0x00000002 /* color key changed */
+#define BVBATCH_MISCFLAGS 0x00000004 /* other flags changed */
+#define BVBATCH_ALPHA 0x00000008 /* global alpha changed */
+#define BVBATCH_DITHER 0x00000010 /* dither changed */
+#define BVBATCH_SCALE 0x00000020 /* scaling type changed */
+/* Bits 6-7 reserved */
+#define BVBATCH_DST 0x00000100 /* destination surface changed */
+#define BVBATCH_SRC1 0x00000200 /* source 1 surface changed */
+#define BVBATCH_SRC2 0x00000400 /* source 2 surface changed */
+#define BVBATCH_MASK 0x00000800 /* mask surface changed */
+#define BVBATCH_DSTRECT_ORIGIN 0x00001000 /* dest rect origin changed */
+#define BVBATCH_DSTRECT_SIZE 0x00002000 /* dest rect dimensions changed */
+#define BVBATCH_SRC1RECT_ORIGIN 0x00004000 /* src 1 rect origin changed */
+#define BVBATCH_SRC1RECT_SIZE 0x00008000 /* src 1 rect dimensions changed */
+#define BVBATCH_SRC2RECT_ORIGIN 0x00010000 /* src 2 rect origin changed */
+#define BVBATCH_SRC2RECT_SIZE 0x00020000 /* src 2 rect dimensions changed */
+#define BVBATCH_MASKRECT_ORIGIN 0x00040000 /* mask rect origin changed */
+#define BVBATCH_MASKRECT_SIZE 0x00080000 /* mask rect dimensions changed */
+#define BVBATCH_CLIPRECT_ORIGIN 0x00100000 /* Clip rect origin changed */
+#define BVBATCH_CLIPRECT_SIZE 0x00200000 /* Clip rect dimensions changed */
+#define BVBATCH_CLIPRECT (BVBATCH_CLIPRECT_ORIGIN | \
+ BVBATCH_CLIPRECT_SIZE) /* clip rect... */
+ /* ...changed */
+#define BVBATCH_TILE_SRC1 0x00400000 /* tile params for src 1 changed */
+#define BVBATCH_TILE_SRC2 0x00800000 /* tile params for src 2 changed */
+#define BVBATCH_TILE_MASK 0x00100000 /* tile params for mask changed */
+/* Bits 21-30 reserved */
+#define BVBATCH_ENDNOP 0x80000000 /* just end batch, don't do BLT;
+ only with BVFLAG_BATCH_END */
+
+/*
+ * bvcallbackerror - This structure is passed into the callback function
+ * if an error occurs.
+ */
+struct bvcallbackerror {
+ unsigned int structsize; /* used to ID structure version */
+ enum bverror error; /* error during async BLT */
+ char *errdesc; /* 0-terminated ASCII string
+ with extended error info (not
+ for end users) */
+};
+
+/*
+ * bvbatch - an implementation-specific container for batch information;
+ * not used by client; forward declaration here
+ */
+struct bvbatch;
+
+/*
+ * bvinbuff - provides the buffer in bvbltparams
+ */
+union bvinbuff {
+ struct bvbuffdesc *desc; /* buffer description when
+ associated BVFLAG_TILE_*
+ is not set */
+ struct bvtileparams *tileparams; /* tile params when associated
+ BVFLAG_TILE_* flag is set */
+};
+
+/*
+ * bvop - used to hold the operation in bvbltparams
+ */
+union bvop {
+ unsigned short rop; /* when BVFLAG_ROP set */
+ enum bvblend blend; /* when BVFLAG_BLEND set */
+ struct bvfilter *filter; /* when BVFLAG_FILTER set */
+};
+
+
+/*
+ * bvbltparams - This structure is passed into bv_blt() to specify the
+ * parameters for a BLT.
+ */
+struct bvbltparams {
+ unsigned int structsize; /* (i) used to ID structure version */
+ char *errdesc; /* (o) 0-terminated ASCII string
+ with extended error info (not
+ for end users) */
+
+ unsigned long implementation; /* (i) override manager choice */
+
+ unsigned long flags; /* (i) see BVFLAG_* above */
+
+ union bvop op; /* (i) operation; determined by
+ BVFLAG_OP_MASK bits in flags */
+
+ void *colorkey; /* (i) pointer to color key pixel
+ matching non-SUBSAMPLE format
+ of the keyed surface when
+ BVFLAG_KEY_* is set */
+
+ union bvalpha globalalpha; /* (i) global alpha when BVFLAG_BLEND
+ set in flags and
+ BVBLENDDEF_GLOBAL_* is set in
+ blend; typed determined by
+ BVBLENDDEF_GLOBAL_* */
+
+ enum bvscalemode scalemode; /* (i/o) type of scaling */
+ enum bvdithermode dithermode; /* (i/o) type of dither */
+
+ struct bvbuffdesc *dstdesc; /* (i) dest after bv_map() */
+ struct bvsurfgeom *dstgeom; /* (i) dest surf fmt and geometry */
+ struct bvrect dstrect; /* (i) rect into which data written */
+
+ union bvinbuff src1; /* (i) src1 buffer */
+ struct bvsurfgeom *src1geom; /* (i) src1 surf fmt and geometry */
+ struct bvrect src1rect; /* (i) rect from which data is read */
+
+ union bvinbuff src2; /* (i) src2 buffer */
+ struct bvsurfgeom *src2geom; /* (i) src2 surf fmt and geometry */
+ struct bvrect src2rect; /* (i) rect from which data is read */
+
+ union bvinbuff mask; /* (i) mask buffer */
+ struct bvsurfgeom *maskgeom; /* (i) mask surf fmt and geometry */
+ struct bvrect maskrect; /* (i) rect from which data is read */
+
+ struct bvrect cliprect; /* (i) dest clipping rect when
+ BVFLAG_CLIP flag set */
+
+ unsigned long batchflags; /* (i) BVBATCH_* flags used to
+ indicate params changed between
+ batch BLTs */
+ struct bvbatch *batch; /* (i/o) handle for associated batch;
+ returned when
+ BVFLAG_BATCH_BEGIN set;
+ provided to subsequent BLTs
+ with BVFLAG_BATCH_CONTINUE */
+
+ void (*callbackfn)(struct bvcallbackerror *err,
+ unsigned long callbackdata); /* (i) callback
+ function when
+ BVFLAG_ASYNC is set -
+ err is 0 when no
+ error; handle contains
+ callbackdata below */
+ unsigned long callbackdata; /* (i) callback data */
+
+ struct bvrect src2auxdstrect;
+ struct bvrect maskauxdstrect;
+};
+
+#endif /* BLTSVILLE_H */
diff --git a/bltsville/bltsville/include/bvblend.h b/bltsville/bltsville/include/bvblend.h
new file mode 100644
index 0000000..f187d81
--- /dev/null
+++ b/bltsville/bltsville/include/bvblend.h
@@ -0,0 +1,508 @@
+/*
+ * bvblend.h
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This file is part of BLTsville, an open application programming interface
+ * (API) for accessing 2-D software or hardware implementations.
+ *
+ * This work is licensed under the Creative Commons Attribution-NoDerivs 3.0
+ * Unported License. To view a copy of this license, visit
+ * http://creativecommons.org/licenses/by-nd/3.0/ or send a letter to
+ * Creative Commons, 444 Castro Street, Suite 900, Mountain View, California,
+ * 94041, USA.
+ */
+
+/*
+ * This file defines the types of shared blends available.
+ *
+ * To extend the list of blends, create a file containing additional
+ * enumerations to be added to enum bvblend below. Then #define
+ * BVBLEND_EXTERNAL_INCLUDE as the name of that file before including
+ * this file in your project.
+ */
+
+#ifndef BVBLEND_H
+#define BVBLEND_H
+
+/*
+ * bvblend - specifies the type of blending operation to perform; only valid
+ * when BVFLAG_BLEND is set in the bvbltparams.flags field.
+ */
+
+/*
+ * The blendmode value is divided into two sections.
+ *
+ * [31:28] The most significant 4 bits indicate the blend format.
+ *
+ * [27:0] The remainder of the bits is defined by the format chosen.
+ *
+ * 3322222222221111111111
+ * 10987654321098765432109876543210
+ * [ ][ ]
+ * | |
+ * format defined by format
+ */
+
+#define BVBLENDDEF_FORMAT_SHIFT 28
+#define BVBLENDDEF_FORMAT_MASK (0xF << BVBLENDDEF_FORMAT_SHIFT)
+
+#define BVBLENDDEF_FORMAT_CLASSIC (0x0 << BVBLENDDEF_FORMAT_SHIFT)
+#define BVBLENDDEF_FORMAT_ESSENTIAL (0x1 << BVBLENDDEF_FORMAT_SHIFT)
+
+/*
+ * The BVBLENDDEF_FORMAT_CLASSIC is meant to handle the classic Porter-Duff
+ * equations. It can also handle the DirectFB blending.
+ * BVBLENDDEF_FORMAT_CLASSIC is based on the following equations:
+ *
+ * Cd = K1 x C1 + K2 x C2
+ * Ad = K3 x A1 + K4 x A2
+ *
+ * where:
+ * Cd: destination color
+ * C1: source 1 color
+ * C2: source 2 color
+ * Ad: destination alpha
+ * A1: source 1 alpha
+ * A2: source 2 alpha
+ * K#: one of the constants defined using the bitfields below.
+ */
+
+/*
+ * The 28 bits for BVBLENDDEF_FORMAT_CLASSIC are divided into 5 sections.
+ *
+ * The most significant 4 bits are modifiers, used to include additional
+ * alpha values from global or remote sources.
+ *
+ * [27] The most significant bit indicates that a remote alpha is to be
+ * included in the blend. The format of this is defined by
+ * bvbltparams.maskgeom.format.
+ *
+ * [26] The next bit is reserved.
+ *
+ * [25:24] The next 2 bits are used to indicate that a global alpha is to be
+ * included, and what its format is:
+ * 00: no global included
+ * 01: global included; bvbltparams.globalalpha.size8 is used (0 -> 255)
+ * 10: this value is reserved
+ * 11: global included; bvbltparams.flogalalpha.fp is used (0.0 -> 1.0)
+ *
+ * The remaining bits are divided into 4 sections, one to define each of the
+ * constants:
+ *
+ * [23:18] - K1
+ * [17:12] - K2
+ * [11:6] - K3
+ * [5:0] - K4
+ *
+ * The format is the same for all 4 constant fields:
+ *
+ * [5:4] The first 2 bits of each field indicates the way in which the other
+ * 2 fields are interpreted:
+ * 00: only As: the other two fields contain only As; there should be only
+ * one valid A value between the two fields
+ * 01: minimum: the value of the constant is the minimum of the two fields
+ * 10: maximum: the value of the constant is the maximum of the two fields
+ * 11: only Cs: the other two fields contain only Cs; there should be only
+ * one valid C value between the two fields
+ *
+ * [3:2] The middle 2 bits of each field contain the inverse field:
+ * 00: 1-C1 ("don't care" for "only As")
+ * 01: 1-A1 ("don't care" for "only Cs")
+ * 10: 1-C2 ("don't care" for "only As")
+ * 11: 1-A2 ("don't care" for "only Cs")
+ *
+ * [1:0] The last 2 bits if each field contain the normal field:
+ * 00: C1 ("don't care" for "only As")
+ * 01: A1 ("don't care" for "only Cs")
+ * 10: C2 ("don't care" for "only As")
+ * 11: A2 ("don't care" for "only Cs")
+ *
+ * EXCEPTIONS:
+ *
+ * 00 00 00 - The value 00 00 00, which normally would indicate "only As"
+ * with two "don't care" fields, is interpreted as a 0.
+ *
+ * 11 11 11 - The value 11 11 11, which normally would indicate "only Cs"
+ * with two "don't care" fields, is interpreted as a 1.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Put together, these can define portions of the blend equations that can be
+ * put together in a variety of ways:
+ *
+ * 00 00 00: undefined -> zero
+ * 00 00 01: A1 (preferred)
+ * 00 00 10: undefined
+ * 00 00 11: A2 (preferred)
+ * 00 01 00: 1-A1 (preferred)
+ * 00 01 01: undefined
+ * 00 01 10: 1-A1 (use 00 01 00)
+ * 00 01 11: undefined
+ * 00 10 00: undefined
+ * 00 10 01: A1 (use 00 00 01)
+ * 00 10 10: undefined
+ * 00 10 11: A2 (use 00 00 11)
+ * 00 11 00: 1-A2 (preferred)
+ * 00 11 01: undefined
+ * 00 11 10: 1-A2 (use 00 11 00)
+ * 00 11 11: undefined
+ *
+ * 01 00 00: min(C1,1-C1)
+ * 01 00 01: min(A1,1-C1)
+ * 01 00 10: min(C2,1-C1)
+ * 01 00 11: min(A2,1-C1)
+ * 01 01 00: min(C1,1-A1)
+ * 01 01 01: min(A1,1-A1)
+ * 01 01 10: min(C2,1-A1)
+ * 01 01 11: min(A2,1-A1)
+ * 01 10 00: min(C1,1-C2)
+ * 01 10 01: min(A1,1-C2)
+ * 01 10 10: min(C2,1-C2)
+ * 01 10 11: min(A2,1-C2)
+ * 01 11 00: min(C1,1-A2)
+ * 01 11 01: min(A1,1-A2)
+ * 01 11 10: min(C2,1-A2)
+ * 01 11 11: min(A2,1-A2)
+ *
+ * 10 00 00: max(C1,1-C1)
+ * 10 00 01: max(A1,1-C1)
+ * 10 00 10: max(C2,1-C1)
+ * 10 00 11: max(A2,1-C1)
+ * 10 01 00: max(C1,1-A1)
+ * 10 01 01: max(A1,1-A1)
+ * 10 01 10: max(C2,1-A1)
+ * 10 01 11: max(A2,1-A1)
+ * 10 10 00: max(C1,1-C2)
+ * 10 10 01: max(A1,1-C2)
+ * 10 10 10: max(C2,1-C2)
+ * 10 10 11: max(A2,1-C2)
+ * 10 11 00: max(C1,1-A2)
+ * 10 11 01: max(A1,1-A2)
+ * 10 11 10: max(C2,1-A2)
+ * 10 11 11: max(A2,1-A2)
+ *
+ * 11 00 00: undefined
+ * 11 00 01: 1-C1 (use 11 00 11)
+ * 11 00 10: undefined
+ * 11 00 11: 1-C1 (preferred)
+ * 11 01 00: C1 (use 11 11 00)
+ * 11 01 01: undefined
+ * 11 01 10: C2 (use 11 11 10)
+ * 11 01 11: undefined
+ * 11 10 00: undefined
+ * 11 10 01: 1-C2 (use 11 10 11)
+ * 11 10 10: undefined
+ * 11 10 11: 1-C2 (preferred)
+ * 11 11 00: C1 (preferred)
+ * 11 11 01: undefined
+ * 11 11 10: C2 (preferred)
+ * 11 11 11: undefined -> one
+ *
+ * ==========================================================================
+ * DirectFB
+ * ==========================================================================
+ *
+ * Putting these together into the proper constants, the blending equations
+ * can be built for DirectFB as well:
+ *
+ * For DirectFB, the SetSrcBlendFunction() and SetDstBlendFunction() can
+ * specify 121 combinations of blends (11 x 11). It's impractical to
+ * specify these combinations individually. Instead, the settings indicated
+ * by each call should be bitwise OR'd to make the proper single value used in
+ * BLTsville.
+ *
+ * binary value <- SetSrcBlendFunction()
+ * [--K1--] [--K2--] [--K3--] [--K4--]
+ * 0000 0000 00 00 00 xx xx xx 00 00 00 xx xx xx <- DSBF_ZERO
+ * 0000 0000 11 11 11 xx xx xx 11 11 11 xx xx xx <- DSBF_ONE
+ * 0000 0000 11 11 00 xx xx xx 00 00 01 xx xx xx <- DSBF_SRCCOLOR
+ * 0000 0000 11 00 11 xx xx xx 00 01 00 xx xx xx <- DSBF_INVSRCCOLOR
+ * 0000 0000 00 00 01 xx xx xx 00 00 01 xx xx xx <- DSBF_SRCALPHA
+ * 0000 0000 00 01 00 xx xx xx 00 01 00 xx xx xx <- DSBF_INVSRCALPHA
+ * 0000 0000 11 11 10 xx xx xx 00 00 11 xx xx xx <- DSBF_DESTCOLOR
+ * 0000 0000 11 10 11 xx xx xx 00 11 00 xx xx xx <- DSBF_INVDESTCOLOR
+ * 0000 0000 00 00 11 xx xx xx 00 00 11 xx xx xx <- DSBF_DESTALPHA
+ * 0000 0000 00 11 00 xx xx xx 00 11 00 xx xx xx <- DSBF_INVDESTALPHA
+ * 0000 0000 01 11 01 xx xx xx 11 11 11 xx xx xx <- DSBF_SRCALPHASAT
+ *
+ * binary value <- SetDstBlendFunction()
+ * [--K1--] [--K2--] [--K3--] [--K4--]
+ * 0000 0000 xx xx xx 00 00 00 xx xx xx 00 00 00 <- DSBF_ZERO
+ * 0000 0000 xx xx xx 11 11 11 xx xx xx 11 11 11 <- DSBF_ONE
+ * 0000 0000 xx xx xx 11 11 00 xx xx xx 00 00 01 <- DSBF_SRCCOLOR
+ * etc.
+ *
+ * ==========================================================================
+ * Porter-Duff
+ * ==========================================================================
+ *
+ * For Porter-Duff, the equations can be more specifically defined. For
+ * convenience, these are enumerated below. These utilize the local alpha as
+ * indicated. To use global or remote alpha, these enumerations need to be
+ * modified. For example, to include the global alpha in the Porter-Duff
+ * SRC1OVER blend, the blend could be defined like this:
+ * params.op.blend = BVBLEND_SRC1OVER +
+ * BVBLENDDEF_GLOBAL_UCHAR;
+ *
+ * To include the remote alpha, the blend could be defined like this:
+ * params.op.blend = BVBLEND_SRC1OVER +
+ * BVBLENDDEF_REMOTE;
+ *
+ * And to include both:
+ * params.op.blend = BVBLEND_SRC1OVER +
+ * BVBLENDDEF_GLOBAL_UCHAR +
+ * BVBLENDDEF_REMOTE;
+ *
+ * Note that if the source color formats include local alphas, the local
+ * alphas, global alpha, and remote alpha will be used together.
+ *
+ * Note also that the equations assume the surfaces are premultiplied. So
+ * if the surface formats indicate that they are not premultiplied, the
+ * alpha multiplication of each color is done prior to using the surface
+ * values in the equations.
+ *
+ * For example, BVBLEND_SRC1OVER specifies the equations:
+ * Cd = 1 x C1 + (1 - A1) x C2
+ * Ad = 1 x A1 + (1 - A1) x A2
+ *
+ * If the format of surface 1 is non-premultiplied, the equations
+ * are modified to include the multiplication explicitly:
+ * Cd = 1 x A1 x C1 + (1 - A1) x C2
+ * Ad = 1 x A1 + (1 - A1) x A2
+ *
+ * Likewise, if the format of surface 2 is non-premultiplied, the
+ * equations are modified for this:
+ * Cd = 1 x C1 + (1 - A1) x A2 x C2
+ * Ad = 1 x A1 + (1 - A1) x A2
+ *
+ * When including global or remote alphas, these values are used to modify
+ * the source 1 value values before being used in the blend equation:
+ * C1 = Ag x C1
+ * A1 = Ag x A1
+ * -or-
+ * C1 = Ar x C1
+ * A1 = Ar x A1
+ * -or-
+ * C1 = Ag x Ar x C1
+ * A1 = Ag x Ar x A1
+ *
+ */
+
+#define BVBLENDDEF_MODE_SHIFT 4
+#define BVBLENDDEF_INV_SHIFT 2
+#define BVBLENDDEF_NORM_SHIFT 0
+
+#define BVBLENDDEF_ONLY_A (0 << BVBLENDDEF_MODE_SHIFT)
+#define BVBLENDDEF_MIN (1 << BVBLENDDEF_MODE_SHIFT)
+#define BVBLENDDEF_MAX (2 << BVBLENDDEF_MODE_SHIFT)
+#define BVBLENDDEF_ONLY_C (3 << BVBLENDDEF_MODE_SHIFT)
+#define BVBLENDDEF_MODE_MASK (3 << BVBLENDDEF_MODE_SHIFT)
+
+#define BVBLENDDEF_NORM_C1 (0 << BVBLENDDEF_NORM_SHIFT)
+#define BVBLENDDEF_NORM_A1 (1 << BVBLENDDEF_NORM_SHIFT)
+#define BVBLENDDEF_NORM_C2 (2 << BVBLENDDEF_NORM_SHIFT)
+#define BVBLENDDEF_NORM_A2 (3 << BVBLENDDEF_NORM_SHIFT)
+#define BVBLENDDEF_NORM_MASK (3 << BVBLENDDEF_NORM_SHIFT)
+
+#define BVBLENDDEF_INV_C1 (0 << BVBLENDDEF_INV_SHIFT)
+#define BVBLENDDEF_INV_A1 (1 << BVBLENDDEF_INV_SHIFT)
+#define BVBLENDDEF_INV_C2 (2 << BVBLENDDEF_INV_SHIFT)
+#define BVBLENDDEF_INV_A2 (3 << BVBLENDDEF_INV_SHIFT)
+#define BVBLENDDEF_INV_MASK (3 << BVBLENDDEF_INV_SHIFT)
+
+#define BVBLENDDEF_ONLY_A_NORM_xx BVBLENDDEF_NORM_C1
+#define BVBLENDDEF_ONLY_A_INV_xx BVBLENDDEF_INV_C1
+#define BVBLENDDEF_ONLY_C_NORM_xx BVBLENDDEF_NORM_A2
+#define BVBLENDDEF_ONLY_C_INV_xx BVBLENDDEF_INV_A2
+
+#define BVBLENDDEF_ZERO \
+ (BVBLENDDEF_ONLY_A | \
+ BVBLENDDEF_ONLY_A_NORM_xx | \
+ BVBLENDDEF_ONLY_A_INV_xx)
+#define BVBLENDDEF_C1 \
+ (BVBLENDDEF_ONLY_C | \
+ BVBLENDDEF_NORM_C1 | \
+ BVBLENDDEF_ONLY_C_INV_xx)
+#define BVBLENDDEF_A1 \
+ (BVBLENDDEF_ONLY_A | \
+ BVBLENDDEF_NORM_A1 | \
+ BVBLENDDEF_ONLY_A_INV_xx)
+#define BVBLENDDEF_C2 \
+ (BVBLENDDEF_ONLY_C | \
+ BVBLENDDEF_NORM_C2 | \
+ BVBLENDDEF_ONLY_C_INV_xx)
+#define BVBLENDDEF_A2 \
+ (BVBLENDDEF_ONLY_A | \
+ BVBLENDDEF_NORM_A2 | \
+ BVBLENDDEF_ONLY_A_INV_xx)
+#define BVBLENDDEF_ONE_MINUS_C1 \
+ (BVBLENDDEF_ONLY_C | \
+ BVBLENDDEF_ONLY_C_NORM_xx | \
+ BVBLENDDEF_INV_C1)
+#define BVBLENDDEF_ONE_MINUS_A1 \
+ (BVBLENDDEF_ONLY_A | \
+ BVBLENDDEF_ONLY_A_NORM_xx | \
+ BVBLENDDEF_INV_A1)
+#define BVBLENDDEF_ONE_MINUS_C2 \
+ (BVBLENDDEF_ONLY_C | \
+ BVBLENDDEF_ONLY_C_NORM_xx | \
+ BVBLENDDEF_INV_C2)
+#define BVBLENDDEF_ONE_MINUS_A2 \
+ (BVBLENDDEF_ONLY_A | \
+ BVBLENDDEF_ONLY_A_NORM_xx | \
+ BVBLENDDEF_INV_A2)
+#define BVBLENDDEF_ONE \
+ (BVBLENDDEF_ONLY_C | \
+ BVBLENDDEF_ONLY_C_NORM_xx | \
+ BVBLENDDEF_ONLY_C_INV_xx)
+
+#define BVBLENDDEF_K_MASK \
+ (BVBLENDDEF_MODE_MASK | \
+ BVBLENDDEF_INV_MASK | \
+ BVBLENDDEF_NORM_MASK)
+
+#define BVBLENDDEF_K1_SHIFT 18
+#define BVBLENDDEF_K2_SHIFT 12
+#define BVBLENDDEF_K3_SHIFT 6
+#define BVBLENDDEF_K4_SHIFT 0
+
+#define BVBLENDDEF_K1_MASK \
+ (BVBLENDDEF_K_MASK << BVBLENDDEF_K1_SHIFT)
+#define BVBLENDDEF_K2_MASK \
+ (BVBLENDDEF_K_MASK << BVBLENDDEF_K2_SHIFT)
+#define BVBLENDDEF_K3_MASK \
+ (BVBLENDDEF_K_MASK << BVBLENDDEF_K3_SHIFT)
+#define BVBLENDDEF_K4_MASK \
+ (BVBLENDDEF_K_MASK << BVBLENDDEF_K4_SHIFT)
+
+#define BVBLENDDEF_CLASSIC_EQUATION_MASK 0x00FFFFFF
+
+/*
+ * The following definitions are be used to modify the enumerations.
+ */
+#define BVBLENDDEF_REMOTE 0x08000000 /* mask surface provides alpha
+ for source 1 */
+
+/* Bit 26 reserved */
+
+/* These enable global alpha and define the type of globalalpha */
+#define BVBLENDDEF_GLOBAL_SHIFT 24
+#define BVBLENDDEF_GLOBAL_MASK (3 << BVBLENDDEF_GLOBAL_SHIFT)
+
+#define BVBLENDDEF_GLOBAL_NONE (0 << BVBLENDDEF_GLOBAL_SHIFT)
+#define BVBLENDDEF_GLOBAL_UCHAR (1 << BVBLENDDEF_GLOBAL_SHIFT)
+/* 2 reserved */
+#define BVBLENDDEF_GLOBAL_FLOAT (3 << BVBLENDDEF_GLOBAL_SHIFT)
+
+union bvalpha {
+ unsigned char size8; /* btwn 0 (0.0) and 255 (1.0) */
+ float fp; /* btwn 0.0 and 1.0 */
+};
+
+
+enum bvblend {
+ /* Porter-Duff blending equations */
+ BVBLEND_CLEAR = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_SRC1 = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_SRC2 = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_SRC1OVER = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A1 << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A1 << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_SRC2OVER = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ONE_MINUS_A2 << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A2 << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_SRC1IN = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_A2 << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_A2 << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_SRC2IN = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_A1 << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_A1 << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_SRC1OUT = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ONE_MINUS_A2 << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A2 << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_SRC2OUT = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A1 << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A1 << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_SRC1ATOP = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_A2 << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A1 << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_A2 << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A1 << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_SRC2ATOP = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ONE_MINUS_A2 << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_A1 << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A2 << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_A1 << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_XOR = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ONE_MINUS_A2 << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A1 << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A2 << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A1 << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_PLUS = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K4_SHIFT),
+
+/*
+ * For FORMAT_ESSENTIAL, the variety of well-known blending functions from
+ * popular image manipulation programs are specified.
+ */
+
+ BVBLEND_NORMAL = BVBLENDDEF_FORMAT_ESSENTIAL + 0,
+ BVBLEND_LIGHTEN = BVBLENDDEF_FORMAT_ESSENTIAL + 1,
+ BVBLEND_DARKEN = BVBLENDDEF_FORMAT_ESSENTIAL + 2,
+ BVBLEND_MULTIPLY = BVBLENDDEF_FORMAT_ESSENTIAL + 3,
+ BVBLEND_AVERAGE = BVBLENDDEF_FORMAT_ESSENTIAL + 4,
+ BVBLEND_ADD = BVBLENDDEF_FORMAT_ESSENTIAL + 5,
+ BVBLEND_LINEAR_DODGE = BVBLEND_ADD,
+ BVBLEND_SUBTRACT = BVBLENDDEF_FORMAT_ESSENTIAL + 6,
+ BVBLEND_LINEAR_BURN = BVBLEND_SUBTRACT,
+ BVBLEND_DIFFERENCE = BVBLENDDEF_FORMAT_ESSENTIAL + 7,
+ BVBLEND_NEGATE = BVBLENDDEF_FORMAT_ESSENTIAL + 8,
+ BVBLEND_SCREEN = BVBLENDDEF_FORMAT_ESSENTIAL + 9,
+ BVBLEND_EXCLUSION = BVBLENDDEF_FORMAT_ESSENTIAL + 10,
+ BVBLEND_OVERLAY = BVBLENDDEF_FORMAT_ESSENTIAL + 11,
+ BVBLEND_SOFT_LIGHT = BVBLENDDEF_FORMAT_ESSENTIAL + 12,
+ BVBLEND_HARD_LIGHT = BVBLENDDEF_FORMAT_ESSENTIAL + 13,
+ BVBLEND_COLOR_DODGE = BVBLENDDEF_FORMAT_ESSENTIAL + 14,
+ BVBLEND_COLOR_BURN = BVBLENDDEF_FORMAT_ESSENTIAL + 15,
+ BVBLEND_LINEAR_LIGHT = BVBLENDDEF_FORMAT_ESSENTIAL + 16,
+ BVBLEND_VIVID_LIGHT = BVBLENDDEF_FORMAT_ESSENTIAL + 17,
+ BVBLEND_PIN_LIGHT = BVBLENDDEF_FORMAT_ESSENTIAL + 18,
+ BVBLEND_HARD_MIX = BVBLENDDEF_FORMAT_ESSENTIAL + 19,
+ BVBLEND_REFLECT = BVBLENDDEF_FORMAT_ESSENTIAL + 20,
+ BVBLEND_GLOW = BVBLENDDEF_FORMAT_ESSENTIAL + 21,
+ BVBLEND_PHOENIX = BVBLENDDEF_FORMAT_ESSENTIAL + 22,
+
+#ifdef BVBLEND_EXTERNAL_INCLUDE
+#define BVBLEND_EXTERNAL_INCLUDE
+#endif
+};
+
+#endif /* BVBLEND_H */
diff --git a/bltsville/bltsville/include/bvbuffdesc.h b/bltsville/bltsville/include/bvbuffdesc.h
new file mode 100644
index 0000000..98934bc
--- /dev/null
+++ b/bltsville/bltsville/include/bvbuffdesc.h
@@ -0,0 +1,61 @@
+/*
+ * bvbuffdesc.h
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This file is part of BLTsville, an open application programming interface
+ * (API) for accessing 2-D software or hardware implementations.
+ *
+ * This work is licensed under the Creative Commons Attribution-NoDerivs 3.0
+ * Unported License. To view a copy of this license, visit
+ * http://creativecommons.org/licenses/by-nd/3.0/ or send a letter to
+ * Creative Commons, 444 Castro Street, Suite 900, Mountain View, California,
+ * 94041, USA.
+ */
+
+#ifndef BVBUFFDESC_H
+#define BVBUFFDESC_H
+
+/*
+ * bvbuffmap - This is a private structure used by BLTsville
+ * implementations to manage resources associated with a buffer. A pointer
+ * to this is returned from bv_map() and used in subsequent bv_blt() and
+ * bv_unmap() calls.
+ */
+struct bvbuffmap;
+
+#define BVATDEF_VENDOR_SHIFT 24
+#define BVATDEF_VENDOR_MASK (0xFF << BVATDEF_VENDOR_SHIFT)
+
+/* Common aux type */
+#define BVATDEF_VENDOR_ALL (0x00 << BVATDEF_VENDOR_SHIFT)
+
+/* Texas Instruments, Inc. */
+#define BVATDEF_VENDOR_TI (0x01 << BVATDEF_VENDOR_SHIFT)
+
+enum bvauxtype {
+ BVAT_NONE = 0, /* auxptr not used */
+ BVAT_reserved1 = /* reserved */
+ BVATDEF_VENDOR_ALL + 1,
+ BVAT_reserved2 = /* reserved */
+ BVATDEF_VENDOR_ALL + 2,
+#ifdef BVAT_EXTERNAL_INCLUDE
+#include BVAT_EXTERNAL_INCLUDE
+#endif
+};
+
+/*
+ * bvbuffdesc - This structure is used to specify the buffer parameters
+ * in a call to bv_map().
+ */
+struct bvbuffdesc {
+ unsigned int structsize; /* used to identify struct version */
+ void *virtaddr; /* virtual ptr to start of buffer */
+ unsigned long length; /* length of the buffer in bytes */
+ struct bvbuffmap *map; /* resource(s) associated w/buffer */
+ enum bvauxtype auxtype; /* type of auxptr */
+ void *auxptr; /* additional buffer description data;
+ type depends on auxtype */
+};
+
+#endif /* BVBUFFDESC_H */
diff --git a/bltsville/bltsville/include/bvcache.h b/bltsville/bltsville/include/bvcache.h
new file mode 100644
index 0000000..d9a3f6d
--- /dev/null
+++ b/bltsville/bltsville/include/bvcache.h
@@ -0,0 +1,45 @@
+/*
+ * bvcache.h
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * This file is part of BLTsville, an open application programming interface
+ * (API) for accessing 2-D software or hardware implementations.
+ *
+ * This work is licensed under the Creative Commons Attribution-NoDerivs 3.0
+ * Unported License. To view a copy of this license, visit
+ * http://creativecommons.org/licenses/by-nd/3.0/ or send a letter to
+ * Creative Commons, 444 Castro Street, Suite 900, Mountain View, California,
+ * 94041, USA.
+ */
+
+#ifndef BVCACHE_H_
+#define BVCACHE_H_
+
+/* Forward declarations */
+struct bvbuffdesc;
+struct bvsurfgeom;
+struct bvrect;
+
+/*
+ * This defines which cache operation the user intends to use
+ * BVCACHE_CPU_TO_DEVICE = clean
+ * BVCACHE_CPU_FROM_DEVICE = invalidate
+ * BVCACHE_BIDIRECTIONAL = flush
+ */
+enum bvcacheop {
+ BVCACHE_BIDIRECTIONAL = 0,
+ BVCACHE_CPU_TO_DEVICE = 1,
+ BVCACHE_CPU_FROM_DEVICE = 2,
+ BVCACHE_RESERVED3 = 3,
+};
+
+struct bvcopparams {
+ unsigned int structsize; /* used to identify struct version */
+ struct bvbuffdesc *desc;
+ struct bvsurfgeom *geom;
+ struct bvrect *rect;
+ enum bvcacheop cacheop;
+};
+
+#endif /* BVCACHE_H_ */
diff --git a/bltsville/bltsville/include/bventry.h b/bltsville/bltsville/include/bventry.h
new file mode 100644
index 0000000..0ccfc05
--- /dev/null
+++ b/bltsville/bltsville/include/bventry.h
@@ -0,0 +1,32 @@
+/*
+ * bventry.h
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This file is part of BLTsville, an open application programming interface
+ * (API) for accessing 2-D software or hardware implementations.
+ *
+ * This work is licensed under the Creative Commons Attribution-NoDerivs 3.0
+ * Unported License. To view a copy of this license, visit
+ * http://creativecommons.org/licenses/by-nd/3.0/ or send a letter to
+ * Creative Commons, 444 Castro Street, Suite 900, Mountain View, California,
+ * 94041, USA.
+ */
+
+#ifndef BVENTRY_H
+#define BVENTRY_H
+
+/* Forward declarations */
+struct bvbuffdesc;
+struct bvbltparams;
+struct bvcopparams;
+/*
+ * bv_*() - These are the API calls for BLTsville. The client needs to
+ * import these from the shared library.
+ */
+typedef enum bverror (*BVFN_MAP)(struct bvbuffdesc *buffdesc);
+typedef enum bverror (*BVFN_BLT)(struct bvbltparams *bltparms);
+typedef enum bverror (*BVFN_UNMAP)(struct bvbuffdesc *buffdesc);
+typedef enum bverror (*BVFN_CACHE)(struct bvcopparams *copparams);
+
+#endif /* BVENTRY_H */
diff --git a/bltsville/bltsville/include/bverror.h b/bltsville/bltsville/include/bverror.h
new file mode 100644
index 0000000..15c3ba7
--- /dev/null
+++ b/bltsville/bltsville/include/bverror.h
@@ -0,0 +1,307 @@
+/*
+ * bverror.h
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This file is part of BLTsville, an open application programming interface
+ * (API) for accessing 2-D software or hardware implementations.
+ *
+ * This work is licensed under the Creative Commons Attribution-NoDerivs 3.0
+ * Unported License. To view a copy of this license, visit
+ * http://creativecommons.org/licenses/by-nd/3.0/ or send a letter to
+ * Creative Commons, 444 Castro Street, Suite 900, Mountain View, California,
+ * 94041, USA.
+ */
+
+#ifndef BVERROR_H
+#define BVERROR_H
+
+/*
+ * bverror - These are error codes returned by BLTsville functions.
+ */
+#define BVERRDEF_VENDOR_SHIFT 24
+#define BVERRDEF_VENDOR_MASK (0xFF << BVERRDEF_VENDOR_SHIFT)
+
+#define BVERRDEF_VENDOR_ALL (0x00 << BVERRDEF_VENDOR_SHIFT)
+#define BVERRDEF_VENDOR_TI (0x01 << BVERRDEF_VENDOR_SHIFT)
+/* 0xF0-0xFF reserved */
+
+enum bverror {
+ BVERR_NONE = 0, /* no error */
+
+ BVERR_UNK = /* unknown error */
+ BVERRDEF_VENDOR_ALL + 1,
+ BVERR_OOM = /* memory allocation failure */
+ BVERRDEF_VENDOR_ALL + 2,
+ BVERR_RSRC = /* required resource unavailable */
+ BVERRDEF_VENDOR_ALL + 3,
+
+ BVERR_VIRTADDR = /* virtaddr is bad */
+ BVERRDEF_VENDOR_ALL + 1000,
+ BVERR_VIRTPTR =
+ BVERR_VIRTADDR, /* for backwards compatibility*/
+
+ BVERR_BUFFERDESC = /* invalid bvbufferdesc */
+ BVERRDEF_VENDOR_ALL + 10000,
+ BVERR_BUFFERDESC_VERS = /* bvbufferdesc.structsize too small */
+ BVERRDEF_VENDOR_ALL + 11000,
+ BVERR_BUFFERDESC_VIRTADDR = /* bad bvbufferdesc.virtaddr */
+ BVERRDEF_VENDOR_ALL + 12000,
+ BVERR_BUFFERDESC_LEN = /* bvbufferdesc.length not supported */
+ BVERRDEF_VENDOR_ALL + 13000,
+ BVERR_BUFFERDESC_ALIGNMENT = /* unsupported buffer base address */
+ BVERRDEF_VENDOR_ALL + 14000,
+
+ BVERR_BLTPARAMS_VERS = /* bvbltparams.structsize too small */
+ BVERRDEF_VENDOR_ALL + 20000,
+ BVERR_IMPLEMENTATION = /* bvbltparams.implementation unsupported */
+ BVERRDEF_VENDOR_ALL + 21000,
+ BVERR_FLAGS = /* bvbltparams.flags unsupported */
+ BVERRDEF_VENDOR_ALL + 22000,
+ BVERR_OP = /* unsupported operation */
+ BVERRDEF_VENDOR_ALL + 22100,
+ BVERR_KEY = /* type of color key not supported */
+ BVERRDEF_VENDOR_ALL + 22200,
+ BVERR_SRC1_TILE = /* src1 tiling not supported */
+ BVERRDEF_VENDOR_ALL + 22300,
+ BVERR_SRC2_TILE = /* src2 tiling not supported */
+ BVERRDEF_VENDOR_ALL + 22310,
+ BVERR_MASK_TILE = /* mask tiling not supported */
+ BVERRDEF_VENDOR_ALL + 22320,
+ BVERR_FLIP = /* flipping not supported */
+ BVERRDEF_VENDOR_ALL + 22400,
+ BVERR_ROP = /* ROP code not supported */
+ BVERRDEF_VENDOR_ALL + 23000,
+ BVERR_BLEND = /* blend not supported */
+ BVERRDEF_VENDOR_ALL + 23100,
+ BVERR_GLOBAL_ALPHA = /* type of global alpha not supported */
+ BVERRDEF_VENDOR_ALL + 23110,
+ BVERR_FILTER = /* filter type not supported */
+ BVERRDEF_VENDOR_ALL + 23200,
+ BVERR_FILTER_PARAMS_VERS = /* filter parameter structsize too small */
+ BVERRDEF_VENDOR_ALL + 23210,
+ BVERR_FILTER_PARAMS = /* filter parameters not supported */
+ BVERRDEF_VENDOR_ALL + 23220,
+ BVERR_SCALE_MODE = /* bvbltparams.scalemode not supported */
+ BVERRDEF_VENDOR_ALL + 24000,
+ BVERR_DITHER_MODE = /* bvbltparams.dithermode not supported */
+ BVERRDEF_VENDOR_ALL + 25000,
+
+ BVERR_DSTDESC = /* invalid bvbltparams.dstdesc */
+ BVERRDEF_VENDOR_ALL + 26000,
+ BVERR_DSTDESC_VERS = /* bvbufferdesc.structsize too small */
+ BVERRDEF_VENDOR_ALL + 26100,
+ BVERR_DSTDESC_VIRTADDR = /* bad bvbufferdesc.virtaddr */
+ BVERRDEF_VENDOR_ALL + 26200,
+ BVERR_DSTDESC_LEN = /* bvbufferdesc.length not supported */
+ BVERRDEF_VENDOR_ALL + 26300,
+ BVERR_DST_ALIGNMENT = /* unsupported buffer base address */
+ BVERRDEF_VENDOR_ALL + 26400,
+
+ BVERR_DSTGEOM = /* invalid bvbltparams.dstgeom */
+ BVERRDEF_VENDOR_ALL + 27000,
+ BVERR_DSTGEOM_VERS = /* dstgeom.structsize too small */
+ BVERRDEF_VENDOR_ALL + 27100,
+ BVERR_DSTGEOM_FORMAT = /* bltparams.dstgeom.format not supported */
+ BVERRDEF_VENDOR_ALL + 27200,
+ BVERR_DSTGEOM_STRIDE = /* bltparams.dstgeom.stride not supported */
+ BVERRDEF_VENDOR_ALL + 27300,
+ BVERR_DSTGEOM_PALETTE = /* dstgeom.paletteformat not supported */
+ BVERRDEF_VENDOR_ALL + 27400,
+
+
+ BVERR_DSTRECT = /* bvbltparams.dstrect not supported */
+ BVERRDEF_VENDOR_ALL + 28000,
+
+ BVERR_SRC1DESC = /* invalid bvbltparams.src1.desc */
+ BVERRDEF_VENDOR_ALL + 29000,
+ BVERR_SRC1DESC_VERS = /* bvbufferdesc.structsize too small */
+ BVERRDEF_VENDOR_ALL + 29100,
+ BVERR_SRC1DESC_VIRTADDR = /* bad bvbufferdesc.virtaddr */
+ BVERRDEF_VENDOR_ALL + 29200,
+ BVERR_SRC1DESC_LEN = /* bvbufferdesc.length not supported */
+ BVERRDEF_VENDOR_ALL + 29300,
+ BVERR_SRC1DESC_ALIGNMENT = /* unsupported buffer base address */
+ BVERRDEF_VENDOR_ALL + 29400,
+
+ BVERR_SRC1GEOM = /* invalid bvbltparams.src1geom */
+ BVERRDEF_VENDOR_ALL + 30000,
+ BVERR_SRC1GEOM_VERS = /* src1geom.structsize too small */
+ BVERRDEF_VENDOR_ALL + 30100,
+ BVERR_SRC1GEOM_FORMAT = /* bltparams.src1geom.format not supported */
+ BVERRDEF_VENDOR_ALL + 30200,
+ BVERR_SRC1GEOM_STRIDE = /* bltparams.src1geom.stride not supported */
+ BVERRDEF_VENDOR_ALL + 30300,
+ BVERR_SRC1GEOM_PALETTE = /* src1geom.paletteformat not supported */
+ BVERRDEF_VENDOR_ALL + 30400,
+
+ BVERR_SRC1RECT = /* bvbltparams.src1rect not supported */
+ BVERRDEF_VENDOR_ALL + 31000,
+
+ BVERR_SRC1_HORZSCALE = /* horz scale for src1->dst not supported */
+ BVERRDEF_VENDOR_ALL + 31100,
+ BVERR_SRC1_VERTSCALE = /* vert scale for src1->dst not supported */
+ BVERRDEF_VENDOR_ALL + 31200,
+ BVERR_SRC1_ROT = /* src1->dst rotation angle not supported */
+ BVERRDEF_VENDOR_ALL + 31300,
+
+ BVERR_SRC1_TILEPARAMS = /* invalid src1.tileparams */
+ BVERR_SRC1DESC,
+ BVERR_SRC1_TILE_VERS = /* src1.tileparams.structsize too small */
+ BVERRDEF_VENDOR_ALL + 32000,
+ BVERR_SRC1_TILEPARAMS_VERS =
+ BVERR_SRC1_TILE_VERS,
+ BVERR_SRC1_TILE_FLAGS = /* tileparams.flags not supported */
+ BVERRDEF_VENDOR_ALL + 32100,
+ BVERR_SRC1_TILEPARAMS_FLAGS =
+ BVERR_SRC1_TILE_FLAGS,
+ BVERR_SRC1_TILE_VIRTADDR =
+ BVERR_SRC1DESC_VIRTADDR,
+ BVERR_SRC1_TILEPARAMS_VIRTADDR =
+ BVERR_SRC1_TILE_VIRTADDR,
+ BVERR_SRC1_TILE_ORIGIN = /* tileparams.left or .top not supported */
+ BVERRDEF_VENDOR_ALL + 32200,
+ BVERR_SRC1_TILEPARAMS_ORIGIN =
+ BVERR_SRC1_TILE_ORIGIN,
+ BVERR_SRC1_TILE_SIZE = /* tileparams.width or .height not supported */
+ BVERRDEF_VENDOR_ALL + 32300,
+ BVERR_SRC1_TILEPARAMS_SIZE =
+ BVERR_SRC1_TILE_SIZE,
+
+ BVERR_SRC2DESC = /* invalid bvbltparams.src2.desc */
+ BVERRDEF_VENDOR_ALL + 33000,
+ BVERR_SRC2DESC_VERS = /* bvbufferdesc.structsize too small */
+ BVERRDEF_VENDOR_ALL + 33100,
+ BVERR_SRC2DESC_VIRTADDR = /* bad bvbufferdesc.virtaddr */
+ BVERRDEF_VENDOR_ALL + 33200,
+ BVERR_SRC2DESC_LEN = /* bvbufferdesc.length not supported */
+ BVERRDEF_VENDOR_ALL + 33300,
+ BVERR_SRC2DESC_ALIGNMENT = /* unsupported buffer base address */
+ BVERRDEF_VENDOR_ALL + 33400,
+
+ BVERR_SRC2GEOM = /* invalid bvbltparams.src2geom */
+ BVERRDEF_VENDOR_ALL + 34000,
+ BVERR_SRC2GEOM_VERS = /* src2geom.structsize too small */
+ BVERRDEF_VENDOR_ALL + 34100,
+ BVERR_SRC2GEOM_FORMAT = /* bltparams.src2geom.format not supported */
+ BVERRDEF_VENDOR_ALL + 34200,
+ BVERR_SRC2GEOM_STRIDE = /* bltparams.src2geom.stride not supported */
+ BVERRDEF_VENDOR_ALL + 34300,
+ BVERR_SRC2GEOM_PALETTE = /* src2geom.paletteformat not supported */
+ BVERRDEF_VENDOR_ALL + 34400,
+
+ BVERR_SRC2RECT = /* bvbltparams.src2rect not supported */
+ BVERRDEF_VENDOR_ALL + 35000,
+
+ BVERR_SRC2_HORZSCALE = /* horz scale for src2->dst not supported */
+ BVERRDEF_VENDOR_ALL + 35100,
+ BVERR_SRC2_VERTSCALE = /* vert scale for src2->dst not supported */
+ BVERRDEF_VENDOR_ALL + 35200,
+ BVERR_SRC2_ROT = /* src2->dst rotation angle not supported */
+ BVERRDEF_VENDOR_ALL + 35300,
+
+ BVERR_SRC2_TILEPARAMS = /* invalid src2.tileparams */
+ BVERR_SRC2DESC,
+ BVERR_SRC2_TILE_VERS = /* src2.tileparams.structsize too small */
+ BVERRDEF_VENDOR_ALL + 36000,
+ BVERR_SRC2_TILEPARAMS_VERS =
+ BVERR_SRC2_TILE_VERS,
+ BVERR_SRC2_TILE_FLAGS = /* tileparams.flags not supported */
+ BVERRDEF_VENDOR_ALL + 36100,
+ BVERR_SRC2_TILEPARAMS_FLAGS =
+ BVERR_SRC2_TILE_FLAGS,
+ BVERR_SRC2_TILE_VIRTADDR =
+ BVERR_SRC2DESC_VIRTADDR,
+ BVERR_SRC2_TILEPARAMS_VIRTADDR =
+ BVERR_SRC2_TILE_VIRTADDR,
+ BVERR_SRC2_TILE_ORIGIN = /* tileparams.left or .top not supported */
+ BVERRDEF_VENDOR_ALL + 36200,
+ BVERR_SRC2_TILEPARAMS_ORIGIN =
+ BVERR_SRC2_TILE_ORIGIN,
+ BVERR_SRC2_TILE_SIZE = /* tileparams.width or .height not supported */
+ BVERRDEF_VENDOR_ALL + 36300,
+ BVERR_SRC2_TILEPARAMS_SIZE =
+ BVERR_SRC2_TILE_SIZE,
+
+ BVERR_MASKDESC = /* invalid bvbltparams.mask.desc */
+ BVERRDEF_VENDOR_ALL + 37000,
+ BVERR_MASKDESC_VERS = /* bvbufferdesc.structsize too small */
+ BVERRDEF_VENDOR_ALL + 37100,
+ BVERR_MASKDESC_VIRTADDR = /* bad bvbufferdesc.virtaddr */
+ BVERRDEF_VENDOR_ALL + 37200,
+ BVERR_MASKDESC_LEN = /* bvbufferdesc.length not supported */
+ BVERRDEF_VENDOR_ALL + 37300,
+ BVERR_MASKDESC_ALIGNMENT = /* unsupported buffer base address */
+ BVERRDEF_VENDOR_ALL + 37400,
+
+ BVERR_MASKGEOM = /* invalid bvbltparams.maskgeom */
+ BVERRDEF_VENDOR_ALL + 38000,
+ BVERR_MASKGEOM_VERS = /* maskgeom.structsize too small */
+ BVERRDEF_VENDOR_ALL + 38100,
+ BVERR_MASKGEOM_FORMAT = /* bltparams.maskgeom.format not supported */
+ BVERRDEF_VENDOR_ALL + 38200,
+ BVERR_MASKGEOM_STRIDE = /* bltparams.maskgeom.stride not supported */
+ BVERRDEF_VENDOR_ALL + 38300,
+ BVERR_MASKGEOM_PALETTE = /* maskgeom.paletteformat not supported */
+ BVERRDEF_VENDOR_ALL + 38400,
+
+ BVERR_MASKRECT = /* bvbltparams.maskrect not supported */
+ BVERRDEF_VENDOR_ALL + 39000,
+
+ BVERR_MASK_HORZSCALE = /* horz scale for mask->dst not supported */
+ BVERRDEF_VENDOR_ALL + 39100,
+ BVERR_MASK_VERTSCALE = /* vert scale for mask->dst not supported */
+ BVERRDEF_VENDOR_ALL + 39200,
+ BVERR_MASK_ROT = /* mask->dst rotation angle not supported */
+ BVERRDEF_VENDOR_ALL + 39300,
+
+ BVERR_MASK_TILEPARAMS = /* invalid mask.tileparams */
+ BVERR_MASKDESC,
+ BVERR_MASK_TILE_VERS = /* mask.tileparams.structsize too small */
+ BVERRDEF_VENDOR_ALL + 40000,
+ BVERR_MASK_TILEPARAMS_VERS =
+ BVERR_MASK_TILE_VERS,
+ BVERR_MASK_TILE_FLAGS = /* tileparams.flags not supported */
+ BVERRDEF_VENDOR_ALL + 40100,
+ BVERR_MASK_TILEPARAMS_FLAGS =
+ BVERR_MASK_TILE_FLAGS,
+ BVERR_MASK_TILE_VIRTADDR =
+ BVERR_MASKDESC_VIRTADDR,
+ BVERR_MASK_TILEPARAMS_VIRTADDR =
+ BVERR_MASK_TILE_VIRTADDR,
+ BVERR_MASK_TILE_ORIGIN = /* tileparams.left or .top not supported */
+ BVERRDEF_VENDOR_ALL + 40200,
+ BVERR_MASK_TILEPARAMS_ORIGIN =
+ BVERR_MASK_TILE_ORIGIN,
+ BVERR_MASK_TILE_SIZE = /* tileparams.width or .height not supported */
+ BVERRDEF_VENDOR_ALL + 40300,
+ BVERR_MASK_TILEPARAMS_SIZE =
+ BVERR_MASK_TILE_SIZE,
+
+ BVERR_CLIP_RECT = /* bvbltparams.cliprect not supported */
+ BVERRDEF_VENDOR_ALL + 41000,
+
+ BVERR_BATCH_FLAGS = /* bvbltparams.batchflags not supported */
+ BVERRDEF_VENDOR_ALL + 42000,
+ BVERR_BATCH = /* bvbltparams.batch not valid */
+ BVERRDEF_VENDOR_ALL + 43000,
+
+ BVERR_OP_FAILED = /* async operation failed to start */
+ BVERRDEF_VENDOR_ALL + 50000,
+ BVERR_OP_INCOMPLETE = /* async operation failed mid-way */
+ BVERRDEF_VENDOR_ALL + 50001,
+ BVERR_MEMORY_ERROR = /* async operation triggered memory error */
+ BVERRDEF_VENDOR_ALL + 51000,
+
+ BVERR_FORMAT = /* unsupported format */
+ BVERRDEF_VENDOR_ALL + 52000,
+
+ BVERR_CACHEOP = /* unsupported cache operation */
+ BVERRDEF_VENDOR_ALL + 60000,
+
+#ifdef BVERR_EXTERNAL_INCLUDE
+#include BVERR_EXTERNAL_INCLUDE
+#endif
+};
+
+#endif /* BVERROR_H */
diff --git a/bltsville/bltsville/include/bvfilter.h b/bltsville/bltsville/include/bvfilter.h
new file mode 100644
index 0000000..2c98d94
--- /dev/null
+++ b/bltsville/bltsville/include/bvfilter.h
@@ -0,0 +1,51 @@
+/*
+ * bvfilter.h
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This file is part of BLTsville, an open application programming interface
+ * (API) for accessing 2-D software or hardware implementations.
+ *
+ * This work is licensed under the Creative Commons Attribution-NoDerivs 3.0
+ * Unported License. To view a copy of this license, visit
+ * http://creativecommons.org/licenses/by-nd/3.0/ or send a letter to
+ * Creative Commons, 444 Castro Street, Suite 900, Mountain View, California,
+ * 94041, USA.
+ */
+
+/*
+ * This file defines the types of shared filters available and the associated
+ * parameters.
+ *
+ * To extend the list of filters, create a file containing additional
+ * enumerations to be added to enum bvfilter below. Then #define
+ * BVFILTER_EXTERNAL_INCLUDE as the name of that file before including
+ * this file in your project. Parameters need to be in a different file.
+ */
+
+#ifndef BVFILTER_H
+#define BVFILTER_H
+
+/*
+ * bvfilter is an enumeration used to designate the type of filter being used.
+ */
+enum bvfiltertype {
+ BVFILTER_DUMMY
+ /* TBD */
+
+#ifdef BVFILTER_EXTERNAL_INCLUDE
+#include BVFILTER_EXTERNAL_INCLUDE
+#endif
+};
+
+/*
+ * bvfilterop contains the filter type and a pointer to the associated
+ * parameters when the BVFLAG_FILTER operation is specified in
+ * bvbltparams.flags.
+ */
+struct bvfilter {
+ enum bvfiltertype filter;
+ void *params;
+};
+
+#endif /* BVFILTER_H */
diff --git a/bltsville/bltsville/include/bvinternal.h b/bltsville/bltsville/include/bvinternal.h
new file mode 100644
index 0000000..06e1bed
--- /dev/null
+++ b/bltsville/bltsville/include/bvinternal.h
@@ -0,0 +1,47 @@
+/*
+ * bvinternal.h
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This file is part of BLTsville, an open application programming interface
+ * (API) for accessing 2-D software or hardware implementations.
+ *
+ * This work is licensed under the Creative Commons Attribution-NoDerivs 3.0
+ * Unported License. To view a copy of this license, visit
+ * http://creativecommons.org/licenses/by-nd/3.0/ or send a letter to
+ * Creative Commons, 444 Castro Street, Suite 900, Mountain View, California,
+ * 94041, USA.
+ */
+
+/*
+ * This file contains definitions used by implementations of BLTsville
+ * 2-D libraries. It should not be used by clients.
+ */
+
+#ifndef BVINTERNAL_H
+#define BVINTENRAL_H
+
+/*
+ * bvbuffmap - The bvbuffmap structure is used to track resources
+ * associated with a buffer, such as a h/w MMU entry. The implementations
+ * add bvbuffmap objects when they allocate the resources. Then when a
+ * buffer is accessed, the implementations can regain access to the
+ * associated resources. The implementations allocate and populate this
+ * structure when a bv_map() call is made. It is used in subsequent
+ * bv_blt() and bv_unmap() calls. The latter frees the associated resource
+ * and the structure (if applicable). Note that a given resource might be
+ * used by more than one implementation.
+ */
+struct bvbuffmap {
+ unsigned int structsize; /* used to ID structure ver */
+
+ /* function to unmap this resource */
+ BVFN_UNMAP bv_unmap;
+
+ unsigned long handle; /* resource-specific info */
+
+ /* pointer to next resource mapping structure */
+ struct bvbuffmap *nextmap;
+};
+
+#endif /* BVINTERNAL_H */
diff --git a/bltsville/bltsville/include/bvsurfgeom.h b/bltsville/bltsville/include/bvsurfgeom.h
new file mode 100644
index 0000000..70029fc
--- /dev/null
+++ b/bltsville/bltsville/include/bvsurfgeom.h
@@ -0,0 +1,41 @@
+/*
+ * bvsurfgeom.h
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This file is part of BLTsville, an open application programming interface
+ * (API) for accessing 2-D software or hardware implementations.
+ *
+ * This work is licensed under the Creative Commons Attribution-NoDerivs 3.0
+ * Unported License. To view a copy of this license, visit
+ * http://creativecommons.org/licenses/by-nd/3.0/ or send a letter to
+ * Creative Commons, 444 Castro Street, Suite 900, Mountain View, California,
+ * 94041, USA.
+ */
+
+#ifndef BVSURFGEOM_H
+#define BVSURFGEOM_H
+
+/*
+ * bvsurfdesc - This structure specifies the way a buffer should be used in a
+ * 2-D context.
+ */
+
+struct bvsurfgeom {
+ unsigned int structsize; /* used to identify struct version */
+ enum ocdformat format; /* color format of surface */
+ unsigned int width; /* width of the surface in pixels */
+ unsigned int height; /* height of the surface in lines */
+ int orientation; /* angle of the surface in degrees
+ (multiple of 90 only) */
+ long virtstride; /* distance from one pixel to the
+ pixel immediately below it in
+ virtual space */
+ enum ocdformat paletteformat; /* format of palette */
+ void *palette; /* array of palette entries of
+ paletteformat; only valid when
+ format includes BVFMTDEF_LUT;
+ number of entries is 2^bpp. */
+};
+
+#endif /* BVSURFGEOM_H */
diff --git a/bltsville/bltsville/index.html b/bltsville/bltsville/index.html
new file mode 100644
index 0000000..4b3a96c
--- /dev/null
+++ b/bltsville/bltsville/index.html
@@ -0,0 +1,4362 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
+
+<head>
+<meta http-equiv="Content-Language" content="en-us" />
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Welcome to BLTsville</title>
+<style type="text/css">
+.cmd_line {
+ background: #000;
+ color: #fff;
+ padding: 10px;
+}
+.inline_code {
+ font-family: "Courier New", Courier, monospace;
+ font-size: small;
+}
+.code_block {
+ margin-left: 40px;
+ font-family: "Courier New", Courier, monospace;
+ font-size: small;
+}
+.small_code_block_in_table {
+ font-family: "Courier New", Courier, monospace;
+ font-size: x-small;
+}
+.small_code_block {
+ font-family: "Courier New", Courier, monospace;
+ font-size: x-small;
+ margin-left: 40px;
+}
+.underline_code {
+ font-family: "Courier New", Courier, monospace;
+ font-size: small;
+ text-decoration: underline;
+}
+.Code_Header {
+ font-size: xx-large;
+ font-weight: bold;
+ text-align: left;
+ font-family: "Courier New", Courier, monospace;
+}
+.Code_Header_2 {
+ font-size: x-large;
+ font-weight: bold;
+ text-align: left;
+ font-family: "Courier New", Courier, monospace;
+}
+.Code_Header_3 {
+ font-size: large;
+ font-weight: bold;
+ text-align: left;
+ font-family: "Courier New", Courier, monospace;
+}
+.imponly {
+ border: thin solid #666666;
+ margin-left: 40px;
+ background-color: #E5E5E5;
+ font-family: Arial, Helvetica, sans-serif;
+ color: #333333;
+}
+.Header1 {
+ margin: 0px 0 0 0;
+ font-size: xx-large;
+ font-weight: bold;
+ text-align: left;
+ line-height: normal;
+ background-color: #E0E0E0;
+}
+.Header2 {
+ font-size: xx-large;
+ font-weight: bold;
+ margin: 0px;
+ line-height: 100%;
+}
+.Header3 {
+ font-size: x-large;
+ font-weight: bold;
+ margin: 0px;
+ line-height: 100%;
+}
+.Header4 {
+ font-size: large;
+ font-weight: bold;
+ margin: 0px;
+ line-height: 100%;
+}
+.strong_emphasis {
+ text-decoration: underline;
+ font-weight: bold;
+}
+.filename {
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: small;
+}
+.underline {
+ text-decoration: underline;
+}
+.grn_left {
+ text-align: left;
+ color: #009900;
+}
+.left_topbord {
+ text-align: left;
+ border-top-style: solid;
+ border-top-width: 1px;
+}
+.center_topbord {
+ text-align: center;
+ border-top-style: solid;
+ border-top-width: 1px;
+}
+.blue_left_botbord {
+ text-align: left;
+ border-bottom-style: solid;
+ border-bottom-width: 1px;
+ color: #0000FF;
+}
+.blue_center_botbord {
+ text-align: center;
+ border-bottom-style: solid;
+ border-bottom-width: 1px;
+ color: #0000FF;
+}
+.red_center {
+ text-align: center;
+ color: #FF0000;
+}
+.red_left {
+ text-align: left;
+ color: #FF0000;
+}
+.grn_center {
+ text-align: center;
+ color: #009900;
+}
+.red_center_topbord {
+ text-align: center;
+ border-top-style: solid;
+ border-top-width: 1px;
+ color: #FF0000;
+}
+.blu_center_topbord {
+ text-align: center;
+ border-top-style: solid;
+ border-top-width: 1px;
+ color: #0000FF;
+}
+.indent_thick_bord {
+ border-color: #000000;
+ border-style: solid;
+ margin-left: 40px;
+}
+.thin_bord {
+ border-style: solid;
+ border-width: 1px;
+}
+.thin_bord_dbl_botbord {
+ border-left-style: solid;
+ border-left-width: 1px;
+ border-right-style: solid;
+ border-right-width: 1px;
+ border-top-style: solid;
+ border-top-width: 1px;
+ border-bottom-style: double;
+ border-bottom-width: 3px;
+}
+.dl_link {
+ float: right;
+}
+.note {
+ font-family: Arial, Helvetica, sans-serif;
+ font-weight: bold;
+ margin-left: 40px;
+}
+.small_note {
+ font-size: xx-small;
+ line-height: 100%;
+}
+.ctr {
+ text-align: center;
+}
+.glyph_cache {
+ font-family: "Courier New", Courier, monospace;
+ font-size: medium;
+ font-weight: normal;
+ font-style: normal;
+ margin-left: 40px;
+ background-color: #000000;
+ color: #FFFFFF;
+}
+.example {
+ border-style: solid;
+ border-width: 1px;
+ margin-left: 40px;
+ margin-right: 40px;
+}
+.rt_thick_bord {
+ border-right-style: solid;
+ border-right-color: #000000;
+}
+.indent {
+ margin-left: 40px;
+}
+.ctr_thin_bord {
+ border-style: solid;
+ border-width: 1px;
+ text-align: center;
+}
+.indent_thin_bord {
+ border-style: solid;
+ border-width: 1px;
+ margin-left: 40px;
+}
+.bold_sans {
+ font-family: Arial, Helvetica, sans-serif;
+ font-weight: bold;
+}
+.nowrap {
+ border-style: solid;
+ border-width: 1px;
+ white-space: nowrap;
+ font-size: small;
+}
+</style>
+</head>
+
+<body>
+
+<table style="width: 100%; line-height: 100%;">
+ <tr>
+ <td style="width: 484px">
+ <table>
+ <tr>
+ <td>
+ <div style="background-position: center; background-image: url('bvlogo.png'); width: 484px; height: 400px; background-repeat: no-repeat;">
+ <div style="position: relative; left: 0; top: 0;">
+ <a href="http://graphics.github.com/ocd">
+ <img src="ocdtab.png" alt="Now With OCD" style="border-width: 0; position: absolute; top: 0; right: 0;" /></a>
+ </div>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td class="ctr"><span class="Header2">Version 2.2</span></td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <p>BLTsville is the open 2-D API designed to provide an abstract interface for both hardware and software 2-D implementations.</p>
+ <p>BLTs (BLock Transfers) involve the moving around of blocks (rectangles) of pixels.&nbsp; BLTsville is the place
+ to go for BLTs.</p>
+ <hr />
+ <table style="width: 100%">
+ <tr>
+ <td>
+ <div class="dl_link">
+ <img alt="CC BY-ND" longdesc="Creative Commons Attribution-NoDerivs 3.0 Unported License" src="http://i.creativecommons.org/l/by-nd/3.0/88x31.png" width="88" height="31" /></div>
+ <p class="Header2">License</p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <div>
+ <p class="small_note">The API is designed and maintained by Texas Instruments, Inc., but anyone is free
+ to use it with no cost or obligation.</p>
+ <p>This project is licensed under the <a href="http://creativecommons.org/licenses/by-nd/3.0/">Creative
+ Commons Attribution-NoDerivs 3.0 Unported License</a> (user mode), and the
+ <a href="http://www.gnu.org/licenses/gpl-2.0.html">GNU General Public License version 2</a> (kernel
+ mode).</p>
+ </div>
+ </td>
+ </tr>
+ </table>
+ <hr />
+ <table style="width: 100%">
+ <tr>
+ <td>
+ <p class="Header2">Dependencies</p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>This project is dependent on the <a href="http://graphics.github.com/ocd">Open Color format Defintions
+ (OCD) project</a>.</p>
+ </td>
+ </tr>
+ </table>
+ <hr />
+ <table style="width: 100%">
+ <tr>
+ <td>
+ <p class="Header2">Source</p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <div class="dl_link">
+ <a href="http://github.com/graphics/bltsville/zipball/master">
+ <img width="90" alt="download zip" src="http://github.com/images/modules/download/zip.png" /></a>
+ <a href="http://github.com/graphics/bltsville/tarball/master">
+ <img width="90" alt="download tar" src="http://github.com/images/modules/download/tar.png" /></a>
+ </div>
+ <div>
+ Get the source code (headers) from GitHub at <a href="http://github.com/graphics/bltsville">github.com/graphics/bltsville</a>,
+ or download the project in <a href="http://github.com/graphics/bltsville/zipball/master">zip</a> or
+ <a href="http://github.com/graphics/bltsville/tarball/master">tar</a> format.</div>
+ <p>You can also clone the project with <a href="http://git-scm.com">Git</a> by running:</p>
+ <pre><a class="cmd_line">$ git clone git://github.com/graphics/bltsville</a></pre>
+ </td>
+ </tr>
+ <tr>
+ <td><hr />
+ <table style="width: 100%">
+ <tr>
+ <td class="Header2">Wiki</td>
+ </tr>
+ <tr>
+ <td><a href="https://github.com/graphics/bltsville/wiki">https://github.com/graphics/bltsville/wiki</a></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+</table>
+<hr />
+<p class="Header1">Points of Interest in BLTsville</p>
+<table style="width: 100%">
+ <tr>
+ <td style="width: 50%" valign="top">
+ <ul>
+ <li>Solid fills</li>
+ <li>Pattern fills</li>
+ <li>Copies</li>
+ <li>Color format conversion<ul>
+ <li>Extensive color format support<ul>
+ <li>RGB, BGR</li>
+ <li>RGBA, ARGB, etc.</li>
+ <li>YCbCr (YUV)<ul>
+ <li>subsampling</li>
+ <li>packed</li>
+ <li>planar</li>
+ </ul>
+ </li>
+ <li>Monochrome</li>
+ <li>Alpha-only</li>
+ <li>Look-Up Table (LUT)</li>
+ </ul>
+ </li>
+ <li>Extensible color format</li>
+ </ul>
+ </li>
+ <li>ROP4<ul>
+ <li>Three inputs</li>
+ </ul>
+ </li>
+ <li>Blends<ul>
+ <li>Pre-defined Porter-Duff blends</li>
+ <li>Pre-defined DirectFB support</li>
+ <li>Extensible blends</li>
+ </ul>
+ </li>
+ <li>Multiple </li>
+ <li>Filters<ul>
+ <li>Extensible filters</li>
+ </ul>
+ </li>
+ <li>Independent horizontal and vertical <strong>flipping</strong></li>
+ <li>Independent <strong>scaling</strong> of all three inputs</li>
+ <li>Clipping</li>
+ <li>Independent <strong>rotation</strong> of all three inputs (multiples of 90 degrees)</li>
+ </ul>
+ </td>
+ <td style="width: 50%" valign="top">
+ <ul>
+ <li>Choice of <strong>scaling</strong> type<ul>
+ <li>Quality based choice</li>
+ <li>Speed based choice</li>
+ <li>Image type based choice</li>
+ <li>Specific scale type choice</li>
+ <li>Extensible scale type</li>
+ </ul>
+ </li>
+ <li>Synchronous operations</li>
+ <li>Asynchronous operations<ul>
+ <li>Client notification of BLT completion</li>
+ </ul>
+ </li>
+ <li>Batching<ul>
+ <li>Combine multiple BLTs into group that can be handled more efficiently by implementations<ul>
+ <li>Character BLTs</li>
+ <li>Multi-layer blending</li>
+ <li>ROP/Blend combination with specified ordering</li>
+ <li>etc.</li>
+ </ul>
+ </li>
+ <li>Delta BLTs</li>
+ </ul>
+ </li>
+ <li>Dithering<ul>
+ <li>Quality based choice</li>
+ <li>Speed based choice</li>
+ <li>Image type based choice</li>
+ <li>Specific dither type choice</li>
+ <li>Extensible dither type</li>
+ </ul>
+ </li>
+ <li>Any implementation support<ul>
+ <li>CPU</li>
+ <li>2-D Accelerator</li>
+ </ul>
+ </li>
+ </ul>
+ </td>
+ </tr>
+</table>
+<hr />
+<ul>
+ <li>BLTsville does not dictate capabilities of the implementations<ul>
+ <li>Operations specified either work or return an error indicating that the operation is not supported</li>
+ </ul>
+ </li>
+</ul>
+<hr />
+<p class="Header1">How to Get to BLTsville</p>
+<p>BLTsville&#39;s API is defined in the BLTsville header files.&nbsp; A client must include <span class="inline_code">bltsville.h</span>
+to access the implementations.&nbsp; This header includes the remaining headers (including <span class="inline_code">ocd.h</span>).</p>
+<p class="note">NOTE:&nbsp; The <span class="underline_code">bvinternal.h</span><span class="underline"> header is for implementations
+only</span> and should not be used by clients.</p>
+<p>BLTsville has both user mode and a kernel mode interaces.&nbsp; The kernel mode interface is quite similar to (and compatible
+with) the user mode, but due to the minor differences and license issues, there are two different sets of header files.</p>
+<hr />
+<p class="Header1">History of BLTsville</p>
+<br />
+<p class="Header4">Versions 1.x</p>
+<p>BLTsville was based on a previous closed interface, which had a few implementations and shipped on a few devices.&nbsp;
+That interface represented the 1.x versions.&nbsp; A lot was learned from that work, and these lessons were used in the
+founding of BLTsville.</p>
+<p class="Header4">Version 2.0</p>
+<p>This was the initial release of the user mode interface.&nbsp; This version is not compatible with the 1.x versions.&nbsp;
+Several minor updates were posted, but the API itself did not change, so no changes to the client or implementation were
+required.</p>
+<p class="Header4">Version 2.1</p>
+<p>This is a minor update to the API, and it adds the kernel mode interface.&nbsp; Some additions to the API have been made.&nbsp;
+Details of the changes are below with their compatibility matrices.</p>
+<ul>
+ <li><span class="inline_code"><a href="#bv_cache">bv_cache()</a></span> was added to allow manipulation of the CPU cache.&nbsp;
+ This is an optional interface meant for hardware implementations.</li>
+</ul>
+<table class="indent_thin_bord">
+ <tr>
+ <td class="thin_bord">&nbsp;</td>
+ <td class="ctr_thin_bord"><strong>2.0 Client</strong></td>
+ <td class="ctr_thin_bord"><strong>2.0 Client</strong><br />
+ (w/2.1 Headers)</td>
+ <td class="ctr_thin_bord"><strong>2.1 Client</strong></td>
+ </tr>
+ <tr>
+ <td class="thin_bord"><strong>2.0 Implementation</strong></td>
+ <td class="ctr_thin_bord">compatible</td>
+ <td class="ctr_thin_bord">New function and structure definitions have no effect.</td>
+ <td class="ctr_thin_bord">Client must deal with lack of <span class="inline_code"><a href="#bv_cache">bv_cache()</a></span>.</td>
+ </tr>
+ <tr>
+ <td class="thin_bord"><strong>2.0 Implementation</strong><br />
+ (w/2.1 Headers)</td>
+ <td class="ctr_thin_bord">New function and structure definitions have no effect.</td>
+ <td class="ctr_thin_bord">New function and structure definitions have no effect.</td>
+ <td class="ctr_thin_bord">Client must deal with lack of <span class="inline_code"><a href="#bv_cache">bv_cache()</a></span>.</td>
+ </tr>
+ <tr>
+ <td class="thin_bord"><strong>2.1 Implementation</strong></td>
+ <td class="ctr_thin_bord">New function and structures have no effect.</td>
+ <td class="ctr_thin_bord">New function and structures have no effect.</td>
+ <td class="ctr_thin_bord">compatible</td>
+ </tr>
+</table>
+<ul>
+ <li><span class="inline_code"><a href="#bvbuffdesc">bvbuffdesc</a></span> was extended with the
+ <span class="inline_code"><a href="#bvbuffdesc.auxtype">auxtype</a></span> and <span class="inline_code">
+ <a href="#bvbuffdesc.auxptr">auxptr</a></span> members to allow buffer descriptions beyond a virtual address.&nbsp;
+ Note that only the kernel mode interface currently includes a standard <span class="inline_code">auxtype</span>, but
+ user mode interface <span class="inline_code">auxtype</span>s may be added later.&nbsp; Both interfaces provide a mechanism
+ for individual vendors to add their own <span class="inline_code">auxtype</span>, using the same vendor ID mechanism
+ as the rest of BLTsville.</li>
+</ul>
+<table class="indent_thin_bord">
+ <tr>
+ <td class="thin_bord">&nbsp;</td>
+ <td class="ctr_thin_bord"><strong>2.0 Client</strong></td>
+ <td class="ctr_thin_bord"><strong>2.0 Client</strong><br />
+ (w/2.1 Headers)</td>
+ <td class="ctr_thin_bord"><strong>2.1 Client</strong></td>
+ </tr>
+ <tr>
+ <td class="thin_bord"><strong>2.0 Implementation</strong></td>
+ <td class="ctr_thin_bord">compatible</td>
+ <td class="ctr_thin_bord">Client must clear <span class="inline_code"><a href="#bvbuffdesc">bvbuffdesc</a></span>
+ using <span class="inline_code"><span style="white-space: nowrap">sizeof(<a href="#bvbuffdesc">bvbuffdesc</a>)</span></span>.</td>
+ <td class="ctr_thin_bord">Implementation must handle <span class="inline_code">
+ <a href="#bvbuffdesc.structsize">bvbuffdesc.structsize</a> &gt; <span style="white-space: nowrap">sizeof(<a href="#bvbuffdesc">bvbuffdesc</a>)</span></span>.</td>
+ </tr>
+ <tr>
+ <td class="thin_bord"><strong>2.0 Implementation</strong><br />
+ (w/2.1 Headers)</td>
+ <td class="ctr_thin_bord">Implementation must handle <span class="inline_code">
+ <a href="#bvbuffdesc.structsize">bvbuffdesc.structsize</a> &lt; <span style="white-space: nowrap">sizeof(<a href="#bvbuffdesc">bvbuffdesc</a>)</span></span>.</td>
+ <td class="ctr_thin_bord">Client must clear <span class="inline_code"><a href="#bvbuffdesc">bvbuffdesc</a></span>
+ using <span class="inline_code"><span style="white-space: nowrap">sizeof(<a href="#bvbuffdesc">bvbuffdesc</a>)</span></span>.</td>
+ <td class="ctr_thin_bord">Client must deal with implementation that uses <span class="inline_code">
+ <a href="#bvbuffdesc.virtaddr">bvbuffdesc.virtaddr</a></span> or returns error if <span class="inline_code">
+ <a href="#bvbuffdesc.virtaddr">bvbuffdesc.virtaddr</a></span> is 0.</td>
+ </tr>
+ <tr>
+ <td class="thin_bord"><strong>2.1 Implementation</strong></td>
+ <td class="ctr_thin_bord">Implementation must handle <span class="inline_code">
+ <a href="#bvbuffdesc.structsize">bvbuffdesc.structsize</a> &lt; <span style="white-space: nowrap">sizeof(<a href="#bvbuffdesc">bvbuffdesc</a>)</span></span>.</td>
+ <td class="ctr_thin_bord">Client must clear <span class="inline_code"><a href="#bvbuffdesc">bvbuffdesc</a></span>
+ using <span class="inline_code"><span style="white-space: nowrap">sizeof(<a href="#bvbuffdesc">bvbuffdesc</a>)</span></span>.</td>
+ <td class="ctr_thin_bord">compatible</td>
+ </tr>
+</table>
+<ul>
+ <li>Added documentation of <a href="#NOP">NOP BLT</a> used as synchronization mechanism for <a href="#BVFLAG_ASYNC">
+ asynchronous BLTs</a>.<ul>
+ <li>Clients that do not use <a href="#BVFLAG_ASYNC">asynchronous BLTs</a> or the <a href="#NOP">NOP BLT</a> will
+ not be affected.</li>
+ <li>Implementations that do not support the NOP BLT will return an error.&nbsp; This will not cause a problem
+ for clients when using implementations which are actually synchronous.&nbsp; For clients using asynchronous
+ implementations, an alternate supported but innocuous BLT will be necessary (e.g. copying a pixel to itself).</li>
+ </ul>
+ </li>
+</ul>
+<p class="Header4">Version 2.2</p>
+<p>This is a minor update which includes the following:</p>
+<ul>
+ <li>Addition of the <span class="inline_code"><a href="#src2auxdstrect">src2auxdstrect</a></span> and
+ <span class="inline_code"><a href="#maskauxdstrect">maskauxdstrect</a></span> members to <span class="inline_code">
+ <a href="#bvbltparams">bvbltparams</a></span> with example.</li>
+ <li>Addition of <span class="inline_code"><a href="#BVFLAG_SRC2_AUXDSTRECT">BVFLAG_SRC2_AUXDSTRECT</a></span> and <span class="inline_code">
+ <a href="#BVFLAG_MASK_AUXDSTRECT">BVFLAG_MASK_AUXDSTRECT</a></span> flags.</li>
+ <li>Added <span class="inline_code"><a href="#BVAT_PHYSADDR">BVAT_PHYSADDR</a></span> to the kernel mode
+ <span class="inline_code"><a href="#bvbuffdesc.auxtype">bvbuffdesc.auxtype</a></span> enumerations.</li>
+ <li>Added clarification to the <span class="inline_code"><a href="#bvphysdesc">bvphysdesc</a></span> documentation.</li>
+</ul>
+<p>Compatibility</p>
+<ul>
+ <li>Clients that do not use the <span class="inline_code"><a href="#BVFLAG_SRC1_AUXDSTRECT">BVFLAG_*_AUXDSTRECT</a></span>
+ flags will not be affected.</li>
+ <li>Clients using the new (long) <span class="inline_code"><a href="#bvbltparams">bvbltparams</a></span> will work with
+ older implementations.&nbsp; If the clients set the <span class="inline_code"><a href="#BVFLAG_SRC2_AUXDSTRECT">
+ BVFLAG_*_AUXDSTRECT</a></span> flags, the implementations will return <span class="inline_code">BVERR_FLAGS</span>,
+ indicating the lack of support for this feature.</li>
+ <li>Implementations supporting the new <span class="inline_code"><a href="#bvbltparams">bvbltparams</a></span> will
+ accept the older (smaller) version, distinguished by the <span class="inline_code">
+ <a href="#bvbltparams.structsize">structsize</a></span> member.&nbsp; Clients using the older versions will not set
+ the <span class="inline_code"><a href="#BVFLAG_SRC2_AUXDSTRECT">BVFLAG_*_AUXDSTRECT</a></span> flags, so the new
+ members will not be utilized.</li>
+ <li>Clients using <span class="inline_code"><a href="#BVAT_PHYSADDR">BVAT_PHYSADDR</a></span> will get an error from
+ implementations that do not support this enumeration.&nbsp; The <span class="inline_code"><a href="#BVAT_PHYSDESC">
+ BVAT_PHYSDESC</a></span> may be used if supported by the implementation, but care must be taken to ensure the buffer
+ is defined properly.&nbsp; See <span class="inline_code"><a href="#bvphysdesc">bvphysdesc</a></span> for details.</li>
+</ul>
+<hr />
+<p class="Header1">BLTsville Neighborhoods</p>
+<p>Implementations may be software (CPU) or 2-D hardware, and many may coexist.&nbsp; Each implementation will have an individual
+entry point, so it can be directly addressed.&nbsp; But there will also be a more general interface for each of these two
+types of implementations so that system integrators can choose the most appropriate implementation.&nbsp; In other words,
+the system integrator will choose one software and one 2-D hardware implementation to be the &quot;default&quot; used when a client
+does not need to choose a specific implementation.</p>
+<p class="Header2">User Mode Interface</p>
+<p>Clients use the standard names below to access the default implementations.&nbsp; The client then imports the pointers
+to the functions.&nbsp; (The specific name decoration and import method will be dictated by the host Operating System (O/S).)&nbsp;
+Some examples:</p>
+<ul>
+ <li>CPU:&nbsp; <span class="filename">bltsville_cpu</span><ul>
+ <li>Linux/Android:&nbsp; <span class="filename">libbltsville_cpu.so</span></li>
+ <li>Windows:&nbsp; <span class="filename">bltsville_cpu.dll</span></li>
+ <li>etc.</li>
+ </ul>
+ </li>
+ <li>2-D hardware:&nbsp; <span class="filename">bltsville_hw2d</span><ul>
+ <li>Linux/Android:&nbsp; <span class="filename">libbltsville_hw2d.so</span></li>
+ <li>Windows:&nbsp; <span class="filename">bltsville_hw2d.dll</span></li>
+ <li>etc.</li>
+ </ul>
+ </li>
+</ul>
+<p>Usually these entry points will be symbolic links (either explicit in systems like Linux which support them, or implicit
+using a thin wrapper) to the specific implementation.&nbsp; This allows system integrators to connect the client with the
+most capable implementation available in the system.&nbsp; For example, <span class="filename">bltsville_hw2d</span> might
+be a symbolic link to <span class="filename">bltsville_gc2d</span>.</p>
+<p>In addition, there may be more implementations co-existing in a given system.&nbsp; These will have additional unique
+names as determined by the vendors.&nbsp; For example:</p>
+<ul>
+ <li>Reference CPU software implementation:&nbsp; <span class="filename">bltsville_refcpu</span></li>
+ <li>System DMA 2-D hardware implementation:&nbsp; <span class="filename">bltsville_mydma</span></li>
+</ul>
+<p class="Header3">Initialization</p>
+<p>In general, each O/S has the ability to manually load a library.&nbsp; This in turn causes a function in the library
+to be called so the library can perform initialization.&nbsp; Unfortunately, not all O/Ss allow this initialization
+function to return an error if the initialization fails.&nbsp; Equally unfortunately, it may be necessary for the
+initialization to be performed in that function.&nbsp; To accommodate this, BLTsville defers the specific initialization
+to the O/S environment.</p>
+<p class="Header4">Linux/Android</p>
+<p>The client will call <span class="inline_code">dlopen()</span> to open the library.&nbsp; It will then import the
+<span class="inline_code">bv_*()</span> functions, and call them as desired.&nbsp; Initialization will occur in
+association with one or more of these activities.&nbsp; If the initialization fails, the bv_*() functions will return
+the <span class="inline_code">BVERR_RSRC</span> error, indicating that a required resource was not obtained.</p>
+<p class="imponly"><strong>Implementations Only<br />
+</strong><br />
+If the library has designated a function with the <span class="inline_code">__attribute__ ((constructor))</span>, that
+function will be called.&nbsp; Linux implementations may use this function to perform initialization (including opening
+an interface to an associated kernel module).&nbsp; However, since this function cannot return an error, and thus cannot
+fail, if the initialization fails, this must be recorded.&nbsp; Then, when the client calls any of the
+<span class="inline_code">bv_*()</span> functions, these should immediately return the <span class="inline_code">
+BVERR_RSRC</span> error, indicating that the library was unable to initialize (obtain a necessary resource).<br />
+<br />
+Linux implementations may also choose to initialize on the first call to a <span class="inline_code">bv_*()</span>
+function.&nbsp; Failure is likewise indicated by returning the <span class="inline_code">BVERR_RSRC</span> error.<br />
+<br />
+<strong>NOTE:&nbsp; Be careful not to repeatedly attempt initialization when a failure is encountered.&nbsp; Some
+initializations, and especially initialization failures, can take a long time.&nbsp; This means clients trying to call
+</strong><span class="inline_code"><strong>bv_*()</strong></span><strong> functions (presumably before falling back to
+alternatives) will be repeatedly penalized if the library can&#39;t initialize.&nbsp; Instead, attempt initialization
+once, and from them on return <span class="inline_code">BVERR_RSRC</span>.</strong></p>
+<p class="Header2">Kernel Mode Interface</p>
+<p>For most kernel space BLTsville clients, only a 2-D hardware implementation will be used.&nbsp; However, both types of
+implementations are supported.&nbsp; Clients use the standard names below to access the default implementations and obtain
+pointers to the functions.&nbsp; (The specific method of obtaining the interface will be dictated by the host Operating
+System (O/S).)&nbsp; Some examples:</p>
+<ul>
+ <li>CPU<ul>
+ <li>Linux/Android <span class="inline_code">bvcpu_entry()</span></li>
+ <li>etc.</li>
+ </ul>
+ </li>
+ <li>2-D hardware<ul>
+ <li>Linux/Android <span class="inline_code">bv2d_entry()</span></li>
+ <li>etc.</li>
+ </ul>
+ </li>
+</ul>
+<p>These entry points may represent the implementations themselves, but more likely they will link the client to the implementations
+using more specific names.&nbsp; For example, <span class="inline_code">bv2d_entry()</span> may link the client to
+<span class="inline_code">gcbv_entry()</span>.</p>
+<p>In addition, there may be more implementations co-existing in the kernel.&nbsp; These will require additional unique
+names as determined by the vendors.&nbsp; For example:</p>
+<ul>
+ <li>Reference CPU software implementation:&nbsp; <span class="inline_code">cpurefbv_entry()</span></li>
+ <li>Vivante GC320 2-D hardware implementation:&nbsp; <span class="inline_code">gcbv_entry()</span></li>
+</ul>
+<hr />
+<p class="Header1">Things To Do In BLTsville</p>
+<p>BLTsville&#39;s interface consists of three or four functions per implementation, which must be imported by the
+client at run time:</p>
+<ul>
+ <li><span class="inline_code"><a href="#bv_map">bv_map()</a></span></li>
+ <li><span class="inline_code"><a href="#bv_blt">bv_blt()</a></span></li>
+ <li><span class="inline_code"><a href="#bv_unmap">bv_unmap()</a></span></li>
+ <li><span class="inline_code"><a href="#bv_cache">bv_cache()</a></span> (optional)</li>
+</ul>
+<p class="note">NOTE:&nbsp; If the library failed to initialize, these functions will return <span class="inline_code">
+BVERR_RSRC</span>, indicating that a required resource was not obtained.</p>
+<a name="bv_map" class="Code_Header">bv_map()</a>
+<p class="code_block">enum bverror bv_map(<a href="#bvbuffdesc">struct bvbuffdesc* buffdesc</a>);</p>
+<p><span class="strong_emphasis">BLTsville does not allocate buffers.</span>&nbsp;&nbsp; Clients must describe a buffer
+in BLTsville using the <span class="inline_code"><a href="#bvbuffdesc">bvbuffdesc</a></span> structure so a given implementation
+can access the buffer.</p>
+<p><span class="inline_code">bv_map()</span> is used to provide the implementation an opportunity to associate hardware
+resources with the specified buffer.&nbsp; Most hardware requires this type of mapping, and there is usually appreciable
+overhead associated with it.&nbsp; By providing a separate call for this operation, BLTsville allows the client to move
+this overhead to the most appropriate time in its execution.</p>
+<p>For a given buffer, the client can call the <span class="inline_code">bv_map()</span> function imported from each implementation
+to establish the mapping immediately.&nbsp; But this is not required.</p>
+<p>As a special bonus, BLTsville clients can call to any implementation&#39;s <span class="inline_code">bv_map()</span>.&nbsp;
+This is sufficient to indicate that the client can be trusted to make the corresponding call to
+<span class="inline_code"><a href="#bv_unmap">bv_unmap()</a></span> upon destruction of the buffer.&nbsp; Then when a client
+calls an implementation&#39;s <span class="inline_code"><a href="#bv_blt">bv_blt()</a></span>, if the mapping needs to be done,
+it&#39;s done at that time.&nbsp; But the mapping is maintained, so that the overhead is avoided on subsequent
+<span class="inline_code"><a href="#bv_blt">bv_blt()</a></span> calls.&nbsp; This lets implementations use <em>lazy mapping</em>
+only as necessary.&nbsp; If an implementation is not called, the mapping is not done.</p>
+<p><em>Normally, the lowest overhead </em><span class="inline_code"><em>bv_map()</em></span><em> call will be in the CPU-based
+implementation.&nbsp; So most clients will want to make a single, low overhead </em><span class="inline_code"><em>bv_map()</em></span><em>
+call to the bltsville_cpu implementation to avoid the mapping/unmapping overhead on each </em><span class="inline_code">
+<a href="#bv_blt"><em>bv_blt()</em></a></span><em> call, while avoiding the mapping overhead when possible.</em></p>
+<p><em><strong>Calling </strong></em><span class="inline_code"><em><strong>bv_map()</strong></em></span><em><strong> is
+actually optional prior to calling </strong></em><span class="inline_code"><a href="#bv_blt"><em><strong>bv_blt()</strong></em></a></span><em><strong>.&nbsp;
+However, if it is not called at least once for a given buffer, it must be assumed that </strong></em>
+<span class="inline_code"><a href="#bv_unmap"><strong><em>bv_unmap()</em></strong></a></span><em><strong> will not be called.&nbsp;
+So the mapping must be done when </strong></em><span class="inline_code"><a href="#bv_blt"><em><strong>bv_blt()</strong></em></a></span><em><strong>
+is called, and unmapping done when it is complete.&nbsp; This means the overhead will be incurred for every </strong>
+</em><a href="#bv_blt" class="inline_code"><em><strong>bv_blt()</strong></em></a><em><strong> call which uses that buffer.</strong></em></p>
+<p class="note">NOTE: Obviously any API cannot add capabilities beyond an implementation&#39;s capabilities.&nbsp; So, for example,
+if an implementation requires memory to be allocated from a special pool of memory, that responsibility falls upon the client.&nbsp;
+The <span class="inline_code">bv_map()</span> function for that implementation will need to check the characteristics of
+the memory and return an error if it does not meet the necessary criteria.</p>
+<p class="Header4"><a name="bv_map_Function_Sequences">Function Sequences</a></p>
+<p>To clarify, here are some function sequences and the operations associated with them:</p>
+<table class="indent">
+ <tr>
+ <td class="ctr_thin_bord"><strong>Implementation</strong></td>
+ <td class="ctr_thin_bord"><strong>Function</strong></td>
+ <td class="ctr_thin_bord"><strong>Operation</strong></td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">A</td>
+ <td class="thin_bord"><span class="inline_code"><a href="#bv_blt">bv_blt()</a></span></td>
+ <td class="thin_bord">map A<br />
+ BLT A<br />
+ unmap A</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">A</td>
+ <td class="thin_bord"><span class="inline_code"><a href="#bv_blt">bv_blt()</a></span></td>
+ <td class="thin_bord">map A<br />
+ BLT A<br />
+ unmap A</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">B</td>
+ <td class="thin_bord"><span class="inline_code"><a href="#bv_blt">bv_blt()</a></span></td>
+ <td class="thin_bord">map B<br />
+ BLT B<br />
+ unmap B</td>
+ </tr>
+</table>
+<br />
+<table class="indent">
+ <tr>
+ <td class="ctr_thin_bord"><strong>Implementation</strong></td>
+ <td class="ctr_thin_bord"><strong>Function</strong></td>
+ <td class="ctr_thin_bord"><strong>Operation</strong></td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">A</td>
+ <td class="thin_bord"><span class="inline_code"><a href="#bv_map">bv_map()</a></span></td>
+ <td class="thin_bord">map A</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">A</td>
+ <td class="thin_bord"><span class="inline_code"><a href="#bv_blt">bv_blt()</a></span></td>
+ <td class="thin_bord">BLT A</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">A</td>
+ <td class="thin_bord"><span class="inline_code"><a href="#bv_blt">bv_blt()</a></span></td>
+ <td class="thin_bord">BLT A</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">A</td>
+ <td class="thin_bord"><span class="inline_code"><a href="#bv_unmap">bv_unmap()</a></span></td>
+ <td class="thin_bord">unmap A</td>
+ </tr>
+</table>
+<br />
+<table class="indent">
+ <tr>
+ <td class="ctr_thin_bord"><strong>Implementation</strong></td>
+ <td class="ctr_thin_bord"><strong>Function</strong></td>
+ <td class="ctr_thin_bord"><strong>Operation</strong></td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">A</td>
+ <td class="thin_bord"><span class="inline_code"><a href="#bv_map">bv_map()</a></span></td>
+ <td class="thin_bord">map A</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">B</td>
+ <td class="thin_bord"><span class="inline_code"><a href="#bv_map">bv_map()</a></span></td>
+ <td class="thin_bord">map B</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">A</td>
+ <td class="thin_bord"><span class="inline_code"><a href="#bv_blt">bv_blt()</a></span></td>
+ <td class="thin_bord">BLT A</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">B</td>
+ <td class="thin_bord"><span class="inline_code"><a href="#bv_blt">bv_blt()</a></span></td>
+ <td class="thin_bord">BLT B</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">A</td>
+ <td class="thin_bord"><span class="inline_code"><a href="#bv_unmap">bv_unmap()</a></span></td>
+ <td class="thin_bord">unmap A</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">B</td>
+ <td class="thin_bord"><span class="inline_code"><a href="#bv_unmap">bv_unmap()</a></span></td>
+ <td class="thin_bord">unmap B</td>
+ </tr>
+</table>
+<br />
+<table class="indent">
+ <tr>
+ <td class="ctr_thin_bord"><strong>Implementation</strong></td>
+ <td class="ctr_thin_bord"><strong>Function</strong></td>
+ <td class="ctr_thin_bord"><strong>Operation</strong></td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">A</td>
+ <td class="thin_bord"><span class="inline_code"><a href="#bv_map">bv_map()</a></span></td>
+ <td class="thin_bord">map A</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">B</td>
+ <td class="thin_bord"><span class="inline_code"><a href="#bv_blt">bv_blt()</a></span></td>
+ <td class="thin_bord">map B<br />
+ BLT B</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">B</td>
+ <td class="thin_bord"><span class="inline_code"><a href="#bv_blt">bv_blt()</a></span></td>
+ <td class="thin_bord">BLT B</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">A</td>
+ <td class="thin_bord"><span class="inline_code"><a href="#bv_unmap">bv_unmap()</a></span></td>
+ <td class="thin_bord">unmap A<br />
+ unmap B</td>
+ </tr>
+</table>
+<br />
+<div class="note">
+ NOTE:&nbsp; Calling <span class="inline_code">bv_map()</span> and <span class="inline_code"><a href="#bv_unmap">
+ bv_unmap()</a></span> with the same <span class="inline_code"><a href="#bvbuffdesc">bvbuffdesc</a></span> from
+ different, unsynchronized threads, even (especially) from different implementations, will result in undefined
+ behavior.&nbsp; This is similar to calling <span class="inline_code">malloc()</span> and <span class="inline_code">
+ free()</span> using the same buffer pointer in different, unsynchronized threads.&nbsp; While this may work
+ sometimes and for some implementations and combinations of implementations, BLTsville does not provide any
+ synchronization mechanism to make this safe.&nbsp; Clients must ensure that these calls are synchronized in cases
+ where such behavior appears to be necessary.</div>
+<br />
+<a name="bv_blt" class="Code_Header">bv_blt()</a>
+<p class="code_block">enum bverror bv_blt(<a href="#bvbltparams">struct bvbltparams* bltparams</a>);</p>
+<p>The main function of BLTsville is <span class="inline_code">bv_blt()</span>.&nbsp; A <span class="inline_code">
+<a href="#bvbltparams">bvbltparams</a></span> structure is passed into <span class="inline_code">bv_blt()</span> to trigger
+the desired 2-D operation.</p>
+<a name="bv_unmap" class="Code_Header">bv_unmap()</a>
+<p class="code_block">enum bverror bv_unmap(<a href="#bvbuffdesc">struct bvbuffdesc* buffdesc</a>);</p>
+<p><span class="inline_code">bv_unmap()</span> is used to free implementation resources associated with a buffer.&nbsp;
+Normally, if <span class="inline_code"><a href="#bv_map">bv_map()</a></span> was called for a given buffer,
+<span class="inline_code">bv_unmap()</span> should be called as well.</p>
+<p>For convenience, only one <span class="inline_code">bv_unmap()</span> needs to be called for each buffer, regardless
+of how many implementations were used, including multiple calls to <span class="inline_code"><a href="#bv_map">bv_map()</a></span>.</p>
+<p>Also for convenience, <span class="inline_code">bv_unmap()</span> may be called multiple times on the same buffer.&nbsp;
+Note that only the first call will actually free (all) the associated resources.&nbsp; See the
+<a href="#bv_map_Function_Sequences">Function Sequences</a> under <span class="inline_code"><a href="#bv_map">bv_map()</a></span>
+for more details.</p>
+<p class="imponly"><strong>Implementations Only</strong><br />
+<br />
+Implementations must ensure that unmapping of buffers which are in use by asynchronous BLTs are appropriately delayed to
+avoid improper access.</p>
+<a name="bv_cache" class="Code_Header">bv_cache()</a>
+<p class="code_block">enum bverror bv_cache(<a href="#bvcopprams">struct bvcopparams *copparams</a>);</p>
+<p><span class="inline_code">bv_cache()</span> provides manual CPU cache control to maintain cache coherence of surfaces
+between the CPU and other hardware.&nbsp; The <a href="#bvbuffdesc">bvcopparams</a> structure provides the information needed
+to properly manipulate the CPU cache.</p>
+<p>This function is <em>optional</em>.&nbsp; If this function fails to import, it means the implementation does not provide
+it, but <span class="inline_code"><a href="#bv_map">bv_map()</a></span>,&nbsp; <span class="inline_code">
+<a href="#bv_blt">bv_blt()</a></span>, and <span class="inline_code"><a href="#bv_unmap">bv_unmap()</a></span> may still
+be used.</p>
+<p><em>In general, this function will be provided with BLTsville implementations which utilize 2-D hardware, even though
+it manipulates the CPU cache.&nbsp; This is because most systems require a kernel module to manipulate the cache, and this
+is not always practical to include with a user-mode CPU implementation.</em></p>
+<p><strong>BEWARE:&nbsp; Manipulation of the CPU cache is tricky.&nbsp; Moreover, different CPUs behave differently, so
+cache manipulation that works on one device may fail on another.&nbsp; Also, mismanaged operation of the cache can have
+significant impact on overall system performance.&nbsp; And incorrect manipulation of the cache can cause instability or
+crashes.&nbsp; Please read and understand all of the discussions below before using this function.</strong></p>
+<ol>
+ <li>To avoid system instability, do not perform cache operations on buffers which would not be accessed by BLTsville.</li>
+ <li>For maximum performance, combine adjacent rectangles into one <span class="inline_code">bv_cache()</span> call.&nbsp;
+ For example, when BLTing a line of characters, do not issue a <span class="inline_code">bv_cache()</span> call for each
+ character.&nbsp; Instead, make one call to bv_cache() which includes all the characters.</li>
+ <li>When using a hardware BLTsville implementation to read data written into a cached surface by the CPU, use the
+ <span class="inline_code"><a href="#CPU_TO_DEVICE">BVCACHE_CPU_TO_DEVICE</a></span> operation after the CPU has completed
+ its operation and before the hardware BLTsville operation is initiated.</li>
+ <li>When using a hardware BLTsville implementation to write data into a cached surface that will be read by the CPU,
+ use the <span class="inline_code"><a href="#CPU_FROM_DEVICE">BVCACHE_CPU_FROM_DEVICE</a></span> operation after the
+ hardware BLTsville operation has completed (note this means after the callback if the BLT is asynchronous) and before
+ the CPU accesses the surface.</li>
+ <li>When using a hardware BLTsville implementation to write data into a cached surface that has been written by the
+ CPU, using the <span class="inline_code"><a href="#CPU_TO_DEVICE">BVCACHE_CPU_TO_DEVICE</a></span> operation after the
+ CPU has completed its operation and before the hardware BLTsville operation is initiated.<ul>
+ <li class="bold_sans">NOTE:&nbsp; This cache operation may not be necessary on all hardware, but it is good practice to perform it
+ anyway.&nbsp; This operation will be necessary for a CPU with a write allocation policy on the cache, but may not
+ be necessary for CPUs without such a configuration.</li>
+ <li class="bold_sans"><strong>NOTE WELL:&nbsp; CPU access to a destination buffer is not always initiated by the client.&nbsp; Buffers
+ recently allocated may be cleared by the CPU on behalf of the client via the allocation call.&nbsp; Failure to perform
+ this operation may result in image corruption even if no further CPU accesses are performed on the surface!</strong></li>
+ </ul>
+ </li>
+</ol>
+<table class="example">
+ <tr>
+ <td>
+ <p><strong>Example</strong>:&nbsp; On one particular device, a surface was allocated using the standard user mode
+ <span class="inline_code">malloc()</span>.&nbsp; An image was copied into a portion of this surface using a hardware
+ implementation of BLTsville.&nbsp; The result was then read by the CPU.</p>
+ <p>Logically, <span class="inline_code">bv_cache()</span> was used to perform a <span class="inline_code">
+ <a href="#CPU_FROM_DEVICE">BVCACHE_CPU_FROM_DEVICE</a></span> operation after the hardware-based BLTsville operation
+ completed, but before the CPU read was performed.&nbsp; However, corruption appeared both inside the image copied,
+ as well as outside the image!</p>
+ <p>Both corruptions were caused by not realizing that there was a CPU operation (clear) performed on behalf of the
+ <span class="inline_code">malloc()</span>, for which the proper cache manipulation was not performed.</p>
+ <p>The corruption outside the image was due to data in the cache being invalidated before it reached the memory.&nbsp;
+ As mentioned above, buffers allocated are normally cleared by the system.&nbsp; In this case, since the buffer used
+ for the surface was configured with a write allocated cache, this meant that not all writes to clear the buffer
+ were in memory when the&nbsp; <span class="inline_code"><a href="#CPU_FROM_DEVICE">BVCACHE_CPU_FROM_DEVICE</a></span>
+ operation was performed.&nbsp; As a result, the uncommitted data in the cache was invalidated and lost, and the
+ previous contents of the memory remained for the CPU to read.</p>
+ <p>The corruption inside the image was caused by data in the cache being committed to memory after the hardware
+ BLT completed, but before the <span class="inline_code"><a href="#CPU_FROM_DEVICE">BVCACHE_CPU_FROM_DEVICE</a></span>
+ operation was executed.</p>
+ <p>Both corruptions were corrected by performing a <span class="inline_code"><a href="#CPU_TO_DEVICE">BVCACHE_CPU_TO_DEVICE</a></span>
+ operation on the <span class="underline">destination</span> surface <strong>before</strong> performing the BLT (item
+ 5 above), in addition to the <span class="inline_code"><a href="#CPU_FROM_DEVICE">BVCACHE_CPU_FROM_DEVICE</a></span>
+ operation performed <strong>after</strong> the BLT (item 3 above).</p>
+ </td>
+ </tr>
+</table>
+<br />
+<hr /><a name="bvbltparams" class="Code_Header">bvbltparams</a>
+<p><span class="inline_code">bvbltparams</span> is the central structure in BLTsville.&nbsp; This structure holds the details
+of the BLT being requested by the client.</p>
+<p class="small_code_block">union bvop {<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned short <a href="#rop">rop</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enum bvblend <a href="#blend">blend</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct bvfilter *<a href="#filter">filter</a>;<br />
+};<br />
+<br />
+struct bvinbuff {<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bvbuffdesc">struct bvbuffdesc</a> *<a href="#src1.desc">desc</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bvtileparams">struct bvtileparams</a> *<a href="#src1.tileparams">tileparams</a>;<br />
+};<br />
+<br />
+struct bvbltparams {<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int <a href="#bvbltparams.structsize">structsize</a>;<br />
+<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char *<a href="#errdesc">errdesc</a>;<br />
+<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long <a href="#implementation">implementation</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long <a href="#flags">flags</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; union bvop <a href="#op">op</a>;<br />
+<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void *<a href="#colorkey">colorkey</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; union bvalpha <a href="#globalalpha">globalalpha</a>;<br />
+<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enum bvscalemode <a href="#scalemode">scalemode</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enum bvdithermode <a href="#dithermode">dithermode</a>;<br />
+<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bvbuffdesc">struct bvbuffdesc</a> *<a href="#dstdesc">dstdesc</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bvsurfgeom">struct bvsurfgeom</a> *<a href="#dstgeom">dstgeom</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bvrect">struct bvrect</a> <a href="#dstrect">dstrect</a>;<br />
+<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; union bvinbuff <a href="#src1">src1</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bvsurfgeom">struct bvsurfgeom</a> *<a href="#src1geom">src1geom</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bvrect">struct bvrect</a> <a href="#src1rect">src1rect</a>;<br />
+<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; union bvinbuff <a href="#src2">src2</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bvsurfgeom">struct bvsurfgeom</a> *<a href="#src2geom">src2geom</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bvrect">struct bvrect</a> <a href="#src2rect">src2rect</a>;<br />
+<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; union bvinbuff <a href="#mask">mask</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bvsurfgeom">struct bvsurfgeom</a> *<a href="#maskgeom">maskgeom</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bvrect">struct bvrect</a> <a href="#maskrect">maskrect</a>;<br />
+<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bvrect">struct bvrect</a> <a href="#cliprect">cliprect</a>;<br />
+<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long <a href="#batchflags">batchflags</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct bvbatch *<a href="#batch">batch</a>;<br />
+<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void (*<a href="#callbackfn">callbackfn</a>)(<a href="#bvcallbackerror">struct
+bvcallbackerror</a> *err,<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+unsigned long callbackdata);<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long <a href="#callbackdata">callbackdata</a>;<br />
+<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bvrect">struct bvrect</a> <a href="#src2auxdstrect">src2auxdstrect</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bvrect">struct bvrect</a> <a href="#maskauxdstrect">maskauxdstrect</a>;<br />
+};</p>
+<a name="bvbltparams.structsize" class="Code_Header_2">bvbltparams.structsize</a>
+<p><span class="code_block">unsigned long structsize; /* input */</span></p>
+<p>This member is used to allow backwards and forwards compatibility between versions of BLTsville.&nbsp; It should be set
+to the <span class="inline_code">sizeof()</span> the structure by the client or implementation, whichever allocated the
+structure.</p>
+<p>BLTsville is designed to be forwards and backwards compatible between client and library versions.&nbsp; But this compatibility
+would be eliminated if clients chose to check for a specific version of the BLTsville implementations and fail if the specific
+version requested was not in place.&nbsp; So, instead of exporting a version number, BLTsville structures use the
+<span class="inline_code">structsize</span> member to indicate the number of bytes in the structure.&nbsp; This is used
+to communicate between the client and implementation which portions of the structure exist.&nbsp; This effectively bypasses
+the concept of a version and focuses on the specifics of what changes need to be considered to maintain compatibility.</p>
+<ol>
+ <li>When an old client calls into a new implementation, that implementation will realize if the client only provides
+ a subset of an updated structure.&nbsp; The implementation will handle this and utilize only that information which
+ has been provided.&nbsp; New features will be disabled, but functionality will be maintained.</li>
+ <li>When a new client calls into an old implementation, that implementation will ignore the extra members of the structure
+ and operate in ignorance of them.&nbsp; If these members are necessary for some new functionality, this will be evident
+ from other fields in the structure, so that the implementation can gracefully fail.</li>
+</ol>
+<p>If <span class="inline_code">structsize</span> is set to a value that is too small for an implementation, it may return
+a <span class="inline_code"><a href="#BVERR_BLTPARAMS_VERS">BVERR_BLTPARAMS_VERS</a></span> error.</p>
+<p class="Code_Header_2"><a name="bvbltparams.errdesc">bvbltparams.errdesc</a></p>
+<p><span class="code_block">char* errdesc; /* output */</span></p>
+<p><span class="inline_code">errdesc</span> is optionally used by implementations to pass a 0-terminated string with additional
+debugging information back to clients for debugging purposes.&nbsp; <span class="inline_code">errdesc</span> is not localized
+or otherwise meant to provide information that is displayed to users.</p>
+<p class="Code_Header_2"><a name="implementation">bvbltparams.implementation</a></p>
+<p class="code_block">unsigned long implementation; /* input */</p>
+<p>Multiple implementations of BLTsville can be combined under managers which can distribute the BLT requests to the implementations
+based on whatever criteria the manager chooses.&nbsp; This might include availability of the operation, performance, loading,
+or power state.&nbsp; In such a scenario, the client may need to override or augment the choice made by the manager.&nbsp;
+This field allows that control.</p>
+<p><strong><em>Note that this feature is extremely complicated, and more detailed documentation needs to be created to allow
+creation of managers and smooth integration by a client.&nbsp; There are serious issues that must be understood before any
+manager can be put into place, such as CPU cache coherence and multiple implementation operation interdependence.&nbsp;
+For now, this field should be set to 0 by clients.</em></strong></p>
+<p>If the implementation cannot respond to the <span class="inline_code">implementation</span> flags set, it may return
+a <span class="inline_code"><a href="#BVERR_IMPLEMENTATION">BVERR_IMPLEMENTATION</a></span> error.</p>
+<p class="Code_Header_2"><a name="flags">bvbltparams.flags</a></p>
+<p class="code_block">unsigned long flags; /* input */</p>
+<p>The <span class="inline_code">flags</span> member provides the baseline of information to <span class="inline_code">
+<a href="#bv_blt">bv_blt()</a></span> about the type of BLT being requested.</p>
+<p>To maintain compatibility, unused bits in the flags member should be set to 0.</p>
+<p>If the flags set are not supported by the implementation, it may return <span class="inline_code">
+<a href="#BVERR_FLAGS">BVERR_FLAGS</a></span>, or a more specific <a href="#bverror">error code</a>.</p>
+<p class="Code_Header_3"><a name="BVFLAG_OP_">bvbltparams.flags - BVFLAG_OP_*</a></p>
+<p>The <span class="inline_code">op</span> field of the flags member specifies the type of BLT operation to perform.&nbsp;
+Currently there are three types of BLT operations defined:</p>
+<table class="indent">
+ <tr>
+ <td valign="top">1.</td>
+ <td><span class="inline_code"><strong><a name="BVFLAG_ROP">BVFLAG_ROP</a></strong></span><br />
+ <p>This flag indicates the operation being performed is a raster operation, and the <span class="inline_code">
+ <a href="#op">bvbltparams.op</a></span> union is treated as <span class="inline_code"><a href="#rop">rop</a></span>.&nbsp;
+ Raster OPerations are binary operations performed on the bits of the inputs.&nbsp; See <span class="inline_code">
+ <a href="#rop">bvbltparams.op.rop</a></span> for details.<br />
+ <br />
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">2.</td>
+ <td>
+ <p><span class="inline_code"><strong><a name="BVFLAG_BLEND">BVFLAG_BLEND</a></strong></span><br />
+ </p>
+ <p>This flag indicates the operation being performed is a blend, and the <span class="inline_code">
+ <a href="#op">bvbltparams.op</a></span> union is treated as <span class="inline_code"><a href="#blend">blend</a></span>.&nbsp;
+ Blending involves mixing multiple layers of pixels using the specified equations.&nbsp; Surrounding pixels are not
+ involved in blend operations.&nbsp; See <span class="inline_code"><a href="#blend">bvbltparams.op.blend</a></span>
+ for details.<br />
+ <br />
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">3.</td>
+ <td><span class="inline_code"><strong><a name="BVFLAG_FILTER">BVFLAG_FILTER</a></strong></span><br />
+ <br />
+ This flag indicates the operation being performed is a filter, and the <span class="inline_code"><a href="#op">bvbltparams.op</a></span>
+ union is treated as <span class="inline_code"><a href="#filter">filter</a></span>.&nbsp; Filtering involves mixing
+ multiple layers of pixels.&nbsp; Surrounding pixels are involved in filter operations.&nbsp; See
+ <span class="inline_code"><a href="#filter">bvbltparams.op.filter</a></span> for details.<br />
+ </td>
+ </tr>
+</table>
+<p class="Code_Header_3"><a name="BVFLAG_KEY_SRC">bvbltparams.flags - BVFLAG_KEY_SRC</a>/<a name="BVFLAG_KEY_DST">DST</a></p>
+<p>The <span class="inline_code">BVFLAG_KEY_SRC</span> and <span class="inline_code">BVFLAG_KEY_DST</span> enable source
+and destination color keying, respectively.&nbsp; When either flag is set, the <span class="inline_code">
+<a href="#colorkey">colorkey</a></span> member of <span class="inline_code"><a href="#bvbltparams">bvbltparams</a></span>
+is used.</p>
+<p><span class="inline_code">BVFLAG_KEY_SRC</span> and <span class="inline_code">BVFLAG_KEY_DST</span> are mutually exclusive.</p>
+<p>See <span class="inline_code"><a href="#colorkey">bvbltparams.colorkey</a></span> for details.</p>
+<p class="Code_Header_3"><a name="BVFLAG_CLIP">bvbltparams.flags - BVFLAG_CLIP</a></p>
+<p>When <span class="inline_code">BVFLAG_CLIP</span> is set, the <span class="inline_code"><a href="#cliprect">cliprect</a></span>
+member of <span class="inline_code"><a href="#bvbltparams">bvbltparams</a></span> is used by the implementation as a limiting
+rectangle on data written to the destination.&nbsp; See <span class="inline_code"><a href="#cliprect">cliprect</a></span>
+for details.</p>
+<p class="Code_Header_3"><a name="BVFLAG_SRCMASK">bvbltparams.flags - BVFLAG_SRCMASK</a></p>
+<p>Normally, the mask is applied at the destination, after all scaling has been completed (including scaling the mask if
+necessary).&nbsp; But some environments require that the mask be applied at the sources, before scaling occurs.&nbsp; The
+<span class="inline_code">BVFLAG_SRCMASK</span> flag requests that the implementation use this method if supported.</p>
+<p class="Code_Header_3">bvbltparams.flags - BVFLAG_TILE_*</p>
+<p>Normally, when a source&#39;s size does not match the destination, the source is scaled to fill the destination.&nbsp; But
+when the corresponding <span class="inline_code">BVFLAG_TILE_*</span> flag is set, this behavior is modified.</p>
+<p>First, the source&#39;s size specifies a tile (or pattern, or brush) to be used to fill the destination.&nbsp; This tile
+is replicated instead of scaled.</p>
+<p>The origin of the source&#39;s rectangle is used to locate the tile within a larger surface. </p>
+<p>Second, a <span class="inline_code"><a href="#bvbuffdesc">bvbuffdesc</a></span> object is no longer supplied by the client
+in the bvbltparams structure.&nbsp; In its place is a <span class="inline_code"><a href="#bvtileparams">bvtileparams</a></span>
+object.</p>
+<p>Refer to the <span class="inline_code"><a href="#bvtileparams">bvtileparams</a></span> structure definition for details.</p>
+<p class="Code_Header_3">bvbltparams.flags - <a name="BVFLAG_HORZ_FLIP">BVFLAG_HORZ</a>/<a name="BVFLAG_VERT_FLIP">VERT_FLIP_*</a></p>
+<p>These flags indicate that the corresponding image is flipped horizontally or vertically as it is used by the operation.</p>
+<p class="Code_Header_3">bvbltparams.flags - BVFLAG_SCALE/DITHER_RETURN</p>
+<p>The scale and dither types can be specified with an implicit type.&nbsp; The implementation will then convert that internally
+to an explicit scale or dither type.&nbsp; These flags request that the implementation return the explicit type chosen to
+the client in the corresponding <span class="inline_code"><a href="#scalemode">bvbltparams.scalemode</a></span> and
+<span class="inline_code"><a href="#dithermode">bvbltparams.dithermode</a></span> members.</p>
+<p class="Code_Header_3">bvbltparams.flags - BVFLAG_ASYNC</p>
+<p>This flag allows the client to inform the implementation that it can queue the requested BLT and return from
+<span class="inline_code"><a href="#bv_blt">bv_blt()</a></span> before it has completed.&nbsp; If this bit is not set, when
+the <span class="inline_code"><a href="#bv_blt">bv_blt()</a></span> returns, the operation is complete.</p>
+<p>Normally, a client will also utilize the <span class="inline_code"><a href="#callbackfn">bvbltparams.callbackfn</a></span>
+and <span class="inline_code"><a href="#callbackdata">bvbltparams.callbackdata</a></span> members to receive a notification
+when the BLT has completed.</p>
+<p class="note">NOTE:&nbsp; Asynchronous BLTs are performed in the order in which they are submitted within an implementation.&nbsp;
+This was done to provide a simple dependency mechanism.&nbsp;
+However, synchronization between implementations must be handled by the client, using the callback mechanism.</p>
+<p class="note">NOTE:&nbsp; Since asynchronous BLTs are performed in the order in which they are submitted, it follows
+that a synchronized BLT after a set of asynchronous BLTs may be used as synchronization as well.</p>
+<p class="note"><a name="NOP">NOTE</a>:&nbsp; Certain situations may require manual synchronization without an associated BLT.&nbsp;
+Rather than introduce an additional BLTsville function call, the method of handling this will be via a NOP BLT.&nbsp; To
+accomplish a NOP BLT, the client should issue a BLT using the <span class="inline_code"><a href="#rop">
+bvbltparams.op.rop</a></span> code of <span class="inline_code">0xAAAA</span> (copy destination to destination), and
+with the <span class="inline_code">BVFLAG_ASYNC</span> flag <span class="underline">not</span> set.&nbsp; Alternatively, the NOP BLT may set the
+<span class="inline_code">BVFLAG_ASYNC</span> and provide a <span class="inline_code"><a href="#callbackfn">
+bvbltparams.callbackfn</a></span>.&nbsp; <em>To facilitate implementations, a valid destination surface should be
+specified.</em></p>
+<p class="imponly"><strong>Implementations Only<br />
+<br />
+</strong>In general, this BLTsville specification has avoided placing any requirement on implementations for specific
+operations.&nbsp; However, in support of this special case, support for these NOP BLTs will need to be an implementation
+<span class="underline"><strong>requirement</strong></span>. </p>
+<p class="Code_Header_3">bvbltparams.flags - BVFLAG_BATCH_BEGIN/CONTINUE/END</p>
+<p>These flags are used to control batching of BLTs for two main reasons:</p>
+<ol>
+ <li>To group small, similar BLTs to consolidate overhead.&nbsp; For example, the BLTs associated with rendering each
+ character in a word.</li>
+ <li>To group related BLTs, which may allow an implementation to perform a more efficient, but equivalent set of operations.</li>
+</ol>
+<p>See <a href="#batching">Batching</a> for details.</p>
+<p class="Code_Header_3">bvbltparams.flags - <a name="BVFLAG_SRC2_AUXDSTRECT">BVFLAG_SRC2</a>/<a name="BVFLAG_MASK_AUXDSTRECT">MASK_AUXDSTRECT</a></p>
+<p>These flags are used to indicate that the bvbltparams.src2auxdstrect and bvbltparams.maskauxdstrect are to be used.&nbsp;
+See these entries below for details. These flags are likely to be ignored except for the special case explained below,
+so they should be used only when necessary.</p>
+<p class="Code_Header_2"><a name="rop">bvbltparams.op.rop</a></p>
+<p class="code_block">unsigned short op; /* input */ </p>
+<p>When <span class="inline_code"><a href="#BVFLAG_ROP">BVFLAG_ROP</a></span> is set in the <span class="inline_code">
+<a href="#flags">bvbltparams.flags</a></span> member, the <span class="inline_code"><a href="#op">bvbltparams.op</a></span>
+union is treated as <span class="inline_code">rop</span>.&nbsp; Raster OPerations are binary operations performed on the
+bits of the inputs:</p>
+<ul>
+ <li>ROP1s have one source:&nbsp; the destination.&nbsp; Two bits are sufficient to specify the four possible (2<sup>2</sup>)
+ ROP1 operations.</li>
+ <li>ROP2s have two sources:&nbsp; the destination and a source.&nbsp; Four bits are used to specify the sixteen (2<sup>2+2</sup>)
+ ROP2 operations.</li>
+ <li>ROP3s have three sources:&nbsp; the destination, a source (source 1), and a pattern (a.k.a. brush), which we call
+ source 2 in BLTsville.&nbsp; Eight bits are used to specify the 256 (2<sup>2+2+2</sup>) ROP3 operations.</li>
+ <li>ROP4s have four sources:&nbsp; the destination, two sources, and a mask.&nbsp; Sixteen bits are used to specify
+ the 65,536 (2<sup>2+2+2+2</sup>) ROP4 operations.</li>
+</ul>
+<p>BLTsville&#39;s <span class="inline_code">rop</span> element is used to specify a ROP4, but anything from ROP1 up to ROP4
+can be defined using this member:</p>
+<ul>
+ <li>To specify an 8-bit ROP3 as a 16-bit ROP4, replicate the 8 bits twice:&nbsp; 0x2323.</li>
+ <li>To specify a 4-bit ROP2 as a 16-bit ROP4, replicate the 4 bits four times:&nbsp; 0x2222.</li>
+ <li>To specify a 2-bit ROP1 as a 16-bit ROP4, replicate the 2 bits eight times:&nbsp; 0x5555.</li>
+</ul>
+<p class="note">NOTE:&nbsp;
+By far the most common ROP used will be 0xCCCC, which indicates a simple copy from source 1 to the destination.</p>
+<p>The table below is the magic decoder ring: </p>
+<table class="indent">
+ <tr>
+ <td>Mask</td>
+ <td class="ctr">&nbsp;1&nbsp;</td>
+ <td class="ctr">&nbsp;1&nbsp;</td>
+ <td class="ctr">&nbsp;1&nbsp;</td>
+ <td class="ctr">&nbsp;1&nbsp;</td>
+ <td class="ctr">&nbsp;1&nbsp;</td>
+ <td class="ctr">&nbsp;1&nbsp;</td>
+ <td class="ctr">&nbsp;1&nbsp;</td>
+ <td class="ctr">&nbsp;1&nbsp;</td>
+ <td class="ctr">&nbsp;0&nbsp;</td>
+ <td class="ctr">&nbsp;0&nbsp;</td>
+ <td class="ctr">&nbsp;0&nbsp;</td>
+ <td class="ctr">&nbsp;0&nbsp;</td>
+ <td class="ctr">&nbsp;0&nbsp;</td>
+ <td class="ctr">&nbsp;0&nbsp;</td>
+ <td class="ctr">&nbsp;0&nbsp;</td>
+ <td class="ctr">&nbsp;0&nbsp;</td>
+ </tr>
+ <tr>
+ <td class="red_left">Source 2 </td>
+ <td class="red_center">&nbsp;1&nbsp;</td>
+ <td class="red_center">&nbsp;1&nbsp;</td>
+ <td class="red_center">&nbsp;1&nbsp;</td>
+ <td class="red_center">&nbsp;1&nbsp;</td>
+ <td class="red_center">&nbsp;0&nbsp;</td>
+ <td class="red_center">&nbsp;0&nbsp;</td>
+ <td class="red_center">&nbsp;0&nbsp;</td>
+ <td class="red_center">&nbsp;0&nbsp;</td>
+ <td class="red_center">&nbsp;1&nbsp;</td>
+ <td class="red_center">&nbsp;1&nbsp;</td>
+ <td class="red_center">&nbsp;1&nbsp;</td>
+ <td class="red_center">&nbsp;1&nbsp;</td>
+ <td class="red_center">&nbsp;0&nbsp;</td>
+ <td class="red_center">&nbsp;0&nbsp;</td>
+ <td class="red_center">&nbsp;0&nbsp;</td>
+ <td class="red_center">&nbsp;0&nbsp;</td>
+ </tr>
+ <tr>
+ <td class="grn_left">Source 1 </td>
+ <td class="grn_center">&nbsp;1&nbsp;</td>
+ <td class="grn_center">&nbsp;1&nbsp;</td>
+ <td class="grn_center">&nbsp;0&nbsp;</td>
+ <td class="grn_center">&nbsp;0&nbsp;</td>
+ <td class="grn_center">&nbsp;1&nbsp;</td>
+ <td class="grn_center">&nbsp;1&nbsp;</td>
+ <td class="grn_center">&nbsp;0&nbsp;</td>
+ <td class="grn_center">&nbsp;0&nbsp;</td>
+ <td class="grn_center">&nbsp;1&nbsp;</td>
+ <td class="grn_center">&nbsp;1&nbsp;</td>
+ <td class="grn_center">&nbsp;0&nbsp;</td>
+ <td class="grn_center">&nbsp;0&nbsp;</td>
+ <td class="grn_center">&nbsp;1&nbsp;</td>
+ <td class="grn_center">&nbsp;1&nbsp;</td>
+ <td class="grn_center">&nbsp;0&nbsp;</td>
+ <td class="grn_center">&nbsp;0&nbsp;</td>
+ </tr>
+ <tr>
+ <td class="blue_left_botbord">Destination </td>
+ <td class="blue_center_botbord">&nbsp;1&nbsp;</td>
+ <td class="blue_center_botbord">&nbsp;0&nbsp;</td>
+ <td class="blue_center_botbord">&nbsp;1&nbsp;</td>
+ <td class="blue_center_botbord">&nbsp;0&nbsp;</td>
+ <td class="blue_center_botbord">&nbsp;1&nbsp;</td>
+ <td class="blue_center_botbord">&nbsp;0&nbsp;</td>
+ <td class="blue_center_botbord">&nbsp;1&nbsp;</td>
+ <td class="blue_center_botbord">&nbsp;0&nbsp;</td>
+ <td class="blue_center_botbord">&nbsp;1&nbsp;</td>
+ <td class="blue_center_botbord">&nbsp;0&nbsp;</td>
+ <td class="blue_center_botbord">&nbsp;1&nbsp;</td>
+ <td class="blue_center_botbord">&nbsp;0&nbsp;</td>
+ <td class="blue_center_botbord">&nbsp;1&nbsp;</td>
+ <td class="blue_center_botbord">&nbsp;0&nbsp;</td>
+ <td class="blue_center_botbord">&nbsp;1&nbsp;</td>
+ <td class="blue_center_botbord">&nbsp;0&nbsp;</td>
+ </tr>
+ <tr>
+ <td class="left_topbord">Raster Operation </td>
+ <td class="center_topbord">&nbsp;15&nbsp;</td>
+ <td class="center_topbord">&nbsp;14&nbsp;</td>
+ <td class="center_topbord">&nbsp;13&nbsp;</td>
+ <td class="center_topbord">&nbsp;12&nbsp;</td>
+ <td class="center_topbord">&nbsp;11&nbsp;</td>
+ <td class="center_topbord">&nbsp;10&nbsp;</td>
+ <td class="center_topbord">&nbsp;&nbsp;9&nbsp;</td>
+ <td class="center_topbord">&nbsp;&nbsp;8&nbsp;</td>
+ <td class="center_topbord">&nbsp;&nbsp;7&nbsp;</td>
+ <td class="center_topbord">&nbsp;&nbsp;6&nbsp;</td>
+ <td class="center_topbord">&nbsp;&nbsp;5&nbsp;</td>
+ <td class="center_topbord">&nbsp;&nbsp;4&nbsp;</td>
+ <td class="center_topbord">&nbsp;&nbsp;3&nbsp;</td>
+ <td class="center_topbord">&nbsp;&nbsp;2&nbsp;</td>
+ <td class="center_topbord">&nbsp;&nbsp;1&nbsp;</td>
+ <td class="center_topbord">&nbsp;&nbsp;0&nbsp;</td>
+ </tr>
+</table>
+<br />
+For example, to specify an operation that uses the mask to choose between source 1 and destination (source 1 when mask is
+1, destination when mask is 0), a client would calculate the bottom line by parsing each column:<br />
+<br />
+When mask is 1 (the first eight columns), the <span class="inline_code">rop</span> matches the source 1 row.&nbsp; When
+mask is 0 (the last eight columns), the <span class="inline_code">rop</span> matches the destination row.<br />
+<br />
+<table class="indent">
+ <tr>
+ <td class="left_topbord">Raster Operation </td>
+ <td class="red_center_topbord">&nbsp;1&nbsp;</td>
+ <td class="red_center_topbord">&nbsp;1&nbsp;</td>
+ <td class="red_center_topbord">&nbsp;1&nbsp;</td>
+ <td class="red_center_topbord">&nbsp;1&nbsp;</td>
+ <td class="red_center_topbord">&nbsp;0&nbsp;</td>
+ <td class="red_center_topbord">&nbsp;0&nbsp;</td>
+ <td class="red_center_topbord">&nbsp;0&nbsp;</td>
+ <td class="red_center_topbord">&nbsp;0&nbsp;</td>
+ <td class="blu_center_topbord">&nbsp;1&nbsp;</td>
+ <td class="blu_center_topbord">&nbsp;0&nbsp;</td>
+ <td class="blu_center_topbord">&nbsp;1&nbsp;</td>
+ <td class="blu_center_topbord">&nbsp;0&nbsp;</td>
+ <td class="blu_center_topbord">&nbsp;1&nbsp;</td>
+ <td class="blu_center_topbord">&nbsp;0&nbsp;</td>
+ <td class="blu_center_topbord">&nbsp;1&nbsp;</td>
+ <td class="blu_center_topbord">&nbsp;0&nbsp;</td>
+ </tr>
+</table>
+<br />
+So the <span class="inline_code">rop</span> for this operation would be 0xF0AA.<br />
+<br />
+Here is a list of some commonly used raster operations that have been given names:<br />
+<br />
+<table class="indent_thick_bord">
+ <tr>
+ <td class="thin_bord_dbl_botbord"><strong>ROP </strong></td>
+ <td class="thin_bord_dbl_botbord"><strong>Constant</strong></td>
+ <td class="thin_bord_dbl_botbord"><strong>Description</strong></td>
+ </tr>
+ <tr>
+ <td class="thin_bord">BLACKNESS</td>
+ <td class="thin_bord">0x0000</td>
+ <td class="thin_bord">Set all destination bits to black (0).&nbsp; Dest = 0</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">NOTSRCERASE</td>
+ <td class="thin_bord">0x1111</td>
+ <td class="thin_bord">Dest = ~Src1 &amp; ~Dest = ~(Src1 | Dest)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">NOTSRCCOPY</td>
+ <td class="thin_bord">0x3333</td>
+ <td class="thin_bord">Dest = ~Src1</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">SRCERASE</td>
+ <td class="thin_bord">0x4444</td>
+ <td class="thin_bord">Dest = Src1 &amp; ~Dest</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">DSTINVERT</td>
+ <td class="thin_bord">0x5555</td>
+ <td class="thin_bord">Invert (NOT) the destination bits.&nbsp; Dest = ~Dest</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">PATINVERT</td>
+ <td class="thin_bord">0x5A5A</td>
+ <td class="thin_bord">XOR with Src2.&nbsp; Dest = Src2 ^ Dest</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">SRCINVERT</td>
+ <td class="thin_bord">0x6666</td>
+ <td class="thin_bord">XOR with Src1.&nbsp; Dest = Src1 ^ Dest</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">SRCAND</td>
+ <td class="thin_bord">0x8888</td>
+ <td class="thin_bord">Dest = Src1 &amp; Dest</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">NOP</td>
+ <td class="thin_bord">0xAAAA</td>
+ <td class="thin_bord">Dest = Dest</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">MERGEPAINT</td>
+ <td class="thin_bord">0xBBBB</td>
+ <td class="thin_bord">Dest = ~Src1 | Dest</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">MERGECOPY</td>
+ <td class="thin_bord">0xC0C0</td>
+ <td class="thin_bord">Dest = Src1 &amp; Src2</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">SRCCOPY</td>
+ <td class="thin_bord">0xCCCC</td>
+ <td class="thin_bord">Dest = Src1</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">SRCPAINT</td>
+ <td class="thin_bord">0xEEEE</td>
+ <td class="thin_bord">OR with Src1.&nbsp; Dest = Src1 | Dest</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">PATCOPY</td>
+ <td class="thin_bord">0xF0F0</td>
+ <td class="thin_bord">Copy source 2 to destination.&nbsp; Dest = Src2</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">PATPAINT</td>
+ <td class="thin_bord">0xFBFB</td>
+ <td class="thin_bord">Dest =&nbsp; ~Src1 | Src2 | Dest</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">WHITENESS</td>
+ <td class="thin_bord">0xFFFF</td>
+ <td class="thin_bord">Set all destination bits to white (1).&nbsp; Dest = 1</td>
+ </tr>
+</table>
+<br />
+<span class="Code_Header_2"><a name="blend">bvbltparams.op.blend</a></span>
+<p class="code_block">enum bvblend blend; /* input */</p>
+<p>When <span class="inline_code"><a href="#BVFLAG_BLEND">BVFLAG_BLEND</a></span> is set in the
+<span class="inline_code"><a href="#flags">bvbltparams.flags</a></span> member, the <span class="inline_code">
+<a href="#op">bvbltparams.op</a></span> union is treated as a <span class="inline_code">blend</span>.</p>
+<p>To specify the blend, the client fills in <span class="inline_code">blend</span> with one of the
+<span class="inline_code"><a href="#bvblend">bvblend</a></span> values.</p>
+<p><span class="inline_code"><a href="#bvblend">bvblend</a></span> is an enumeration assembled from sets of fields.&nbsp;
+The values specified may be extended beyond those that are explicitly defined using the definitions in the
+<span class="filename">bvblend.h</span> header file.</p>
+<p>The first 4 bits are the format.&nbsp; Currently two format groups are defined, but others can be added.&nbsp; The remainder
+of the bits are used as defined by the individual format:</p>
+<table class="indent">
+ <tr>
+ <td valign="top">1.</td>
+ <td><span class="Code_Header_3">BVBLENDDEF_FORMAT_CLASSIC</span><br />
+ <br />
+ The <span class="inline_code">BVBLENDDEF_FORMAT_CLASSIC</span> is meant to handle the classic Porter-Duff equations.
+ It can also handle the DirectFB blending.<br />
+ <br />
+ <span class="inline_code">BVBLENDDEF_FORMAT_CLASSIC</span> is based on the following equations:<br />
+ <div>
+ <p class="indent">C<sub>d</sub> = K<sub>1</sub>C<sub>1</sub> + K<sub>2</sub>C<sub>2</sub><br />
+ A<sub>d</sub> = K<sub>3</sub>A<sub>1</sub> + K<sub>4</sub>A<sub>2</sub></p>
+ </div>
+ where:<br />
+ <div>
+ <p class="indent">C<sub>d</sub>: destination color<br />
+ C<sub>1</sub>: source 1 color<br />
+ C<sub>2</sub>: source 2 color<br />
+ A<sub>d</sub>: destination alpha<br />
+ A<sub>1</sub>: source 1 alpha<br />
+ A<sub>2</sub>: source 2 alpha<br />
+ K<sub>#</sub>: one of the constants defined using the bitfields below</p>
+ </div>
+ The 28 bits for <span class="inline_code">BVBLENDDEF_FORMAT_CLASSIC</span> are divided into 5 sections.<br />
+ <br />
+ The most significant 4 bits are modifiers, used to include additional alpha values from global or remote sources.<br />
+ <br />
+ [27] The most significant bit indicates that a remote alpha is to be included in the blend. The format of this is
+ defined by <span class="inline_code"><a href="#maskgeom">bvbltparams.maskgeom.format</a></span>.<br />
+ <br />
+ [26] The next bit is reserved.<br />
+ <br />
+ [25:24] The next 2 bits are used to indicate that a global alpha is to be included, and what its format is:<br />
+ <div>
+ <p class="indent">00: no global included<br />
+ 01: global included; bvbltparams.globalalpha.size8 is used (0 -&gt; 255)<br />
+ 10: this value is reserved<br />
+ 11: global included; bvbltparams.flogalalpha.fp is used (0.0 -&gt; 1.0) </p>
+ </div>
+ The remaining bits are divided into 4 sections, one to define each of the constants:<br />
+ <br />
+ [23:18] - K1<br />
+ [17:12] - K2<br />
+ [11:6] - K3<br />
+ [5:0] - K4<br />
+ <br />
+ The format is the same for all 4 constant fields:<br />
+ <br />
+ [5:4] The first 2 bits of each field indicates the way in which the other 2 fields are interpreted:<br />
+ <div>
+ <p class="indent">00: only As: the other two fields contain only As; there should be only one valid A value
+ between the two fields<br />
+ 01: minimum: the value of the constant is the minimum of the two fields<br />
+ 10: maximum: the value of the constant is the maximum of the two fields<br />
+ 11: only Cs: the other two fields contain only Cs; there should be only one valid C value between the two fields</p>
+ </div>
+ [3:2] The middle 2 bits of each field contain the inverse field:<br />
+ <div>
+ <p class="indent">00: 1-C1 (&quot;don&#39;t care&quot; for &quot;only As&quot;)<br />
+ 01: 1-A1 (&quot;don&#39;t care&quot; for &quot;only Cs&quot;)<br />
+ 10: 1-C2 (&quot;don&#39;t care&quot; for &quot;only As&quot;)<br />
+ 11: 1-A2 (&quot;don&#39;t care&quot; for &quot;only Cs&quot;)</p>
+ </div>
+ [1:0] The last 2 bits if each field contain the normal field:<br />
+ <div>
+ <p class="indent">00: C1 (&quot;don&#39;t care&quot; for &quot;only As&quot;)<br />
+ 01: A1 (&quot;don&#39;t care&quot; for &quot;only Cs&quot;)<br />
+ 10: C2 (&quot;don&#39;t care&quot; for &quot;only As&quot;)<br />
+ 11: A2 (&quot;don&#39;t care&quot; for &quot;only Cs&quot;)</p>
+ </div>
+ EXCEPTIONS:<br />
+ <br />
+ 00 00 00 - The value 00 00 00, which normally would indicate &quot;only As&quot; with two &quot;don&#39;t care&quot; fields, is interpreted
+ as a constant of 0.<br />
+ <br />
+ 11 11 11 - The value 11 11 11, which normally would indicate &quot;only Cs&quot; with two &quot;don&#39;t care&quot; fields, is interpreted
+ as a constant of 1.<br />
+ <br />
+ <span class="Header4">Constants</span><br />
+ <br />
+ Put together, these can define portions of the blend equations that can be put together in a variety of ways:<br />
+ <br />
+ <table class="indent_thick_bord">
+ <tr>
+ <td class="rt_thick_bord">
+ <table>
+ <tr>
+ <td class="thin_bord">00 00 00</td>
+ <td class="thin_bord">undefined -&gt; zero</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">00 00 01</td>
+ <td class="thin_bord">A1 (preferred)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">00 00 10</td>
+ <td class="thin_bord">undefined</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">00 00 11</td>
+ <td class="thin_bord">A2 (preferred)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">00 01 00</td>
+ <td class="thin_bord">1-A1 (preferred)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">00 01 01</td>
+ <td class="thin_bord">undefined</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">00 01 10</td>
+ <td class="thin_bord">1-A1 (use 00 01 00)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">00 01 11</td>
+ <td class="thin_bord">undefined</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">00 10 00</td>
+ <td class="thin_bord">undefined</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">00 10 01</td>
+ <td class="thin_bord">A1 (use 00 00 01)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">00 10 10</td>
+ <td class="thin_bord">undefined</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">00 10 11</td>
+ <td class="thin_bord">A2 (use 00 00 11)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">00 11 00</td>
+ <td class="thin_bord">1-A2 (preferred)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">00 11 01</td>
+ <td class="thin_bord">undefined</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">00 11 10</td>
+ <td class="thin_bord">1-A2 (use 00 11 00)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">00 11 11</td>
+ <td class="thin_bord">undefined</td>
+ </tr>
+ </table>
+ </td>
+ <td class="rt_thick_bord">
+ <table>
+ <tr>
+ <td class="thin_bord">01 00 00</td>
+ <td class="thin_bord">min(C1,1-C1)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">01 00 01</td>
+ <td class="thin_bord">min(A1,1-C1)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">01 00 10</td>
+ <td class="thin_bord">min(C2,1-C1)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">01 00 11</td>
+ <td class="thin_bord">min(A2,1-C1)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">01 01 00</td>
+ <td class="thin_bord">min(C1,1-A1)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">01 01 01</td>
+ <td class="thin_bord">min(A1,1-A1)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">01 01 10</td>
+ <td class="thin_bord">min(C2,1-A1)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">01 01 11</td>
+ <td class="thin_bord">min(A2,1-A1)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">01 10 00</td>
+ <td class="thin_bord">min(C1,1-C2)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">01 10 01</td>
+ <td class="thin_bord">min(A1,1-C2)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">01 10 10</td>
+ <td class="thin_bord">min(C2,1-C2)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">01 10 11</td>
+ <td class="thin_bord">min(A2,1-C2)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">01 11 00</td>
+ <td class="thin_bord">min(C1,1-A2)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">01 11 01</td>
+ <td class="thin_bord">min(A1,1-A2)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">01 11 10</td>
+ <td class="thin_bord">min(C2,1-A2)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">01 11 11</td>
+ <td class="thin_bord">min(A2,1-A2)</td>
+ </tr>
+ </table>
+ </td>
+ <td class="rt_thick_bord">
+ <table>
+ <tr>
+ <td class="thin_bord">10 00 00</td>
+ <td class="thin_bord">max(C1,1-C1)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">10 00 01</td>
+ <td class="thin_bord">max(A1,1-C1)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">10 00 10</td>
+ <td class="thin_bord">max(C2,1-C1)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">10 00 11</td>
+ <td class="thin_bord">max(A2,1-C1)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">10 01 00</td>
+ <td class="thin_bord">max(C1,1-A1)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">10 01 01</td>
+ <td class="thin_bord">max(A1,1-A1)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">10 01 10</td>
+ <td class="thin_bord">max(C2,1-A1)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">10 01 11</td>
+ <td class="thin_bord">max(A2,1-A1)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">10 10 00</td>
+ <td class="thin_bord">max(C1,1-C2)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">10 10 01</td>
+ <td class="thin_bord">max(A1,1-C2)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">10 10 10</td>
+ <td class="thin_bord">max(C2,1-C2)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">10 10 11</td>
+ <td class="thin_bord">max(A2,1-C2)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">10 11 00</td>
+ <td class="thin_bord">max(C1,1-A2)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">10 11 01</td>
+ <td class="thin_bord">max(A1,1-A2)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">10 11 10</td>
+ <td class="thin_bord">max(C2,1-A2)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">10 11 11</td>
+ <td class="thin_bord">max(A2,1-A2)</td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table>
+ <tr>
+ <td class="thin_bord">11 00 00</td>
+ <td class="thin_bord">undefined</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">11 00 01</td>
+ <td class="thin_bord">1-C1 (use 11 00 11)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">11 00 10</td>
+ <td class="thin_bord">undefined</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">11 00 11</td>
+ <td class="thin_bord">1-C1 (preferred)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">11 01 00</td>
+ <td class="thin_bord">C1 (use 11 11 00)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">11 01 01</td>
+ <td class="thin_bord">undefined</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">11 01 10</td>
+ <td class="thin_bord">C2 (use 11 11 10)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">11 01 11</td>
+ <td class="thin_bord">undefined</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">11 10 00</td>
+ <td class="thin_bord">undefined</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">11 10 01</td>
+ <td class="thin_bord">1-C2 (use 11 10 11)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">11 10 10</td>
+ <td class="thin_bord">undefined</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">11 10 11</td>
+ <td class="thin_bord">1-C2 (preferred)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">11 11 00</td>
+ <td class="thin_bord">C1 (preferred)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">11 11 01</td>
+ <td class="thin_bord">undefined</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">11 11 10</td>
+ <td class="thin_bord">C2 (preferred)</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">11 11 11</td>
+ <td class="thin_bord">undefined -&gt; one</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ <span class="Header4"><br />
+ DirectFB Example</span><br />
+ <br />
+ Putting these together into the proper constants, the blending equations can be built for different APIs.&nbsp;
+ Here is how DirectFB would be mapped:<br />
+ <br />
+ For DirectFB, the
+ <a href="http://directfb.org/docs/DirectFB_Reference_1_2/IDirectFBSurface_SetSrcBlendFunction.html" class="inline_code">
+ SetSrcBlendFunction()</a> and
+ <a href="http://directfb.org/docs/DirectFB_Reference_1_2/IDirectFBSurface_SetDstBlendFunction.html" class="inline_code">
+ SetDstBlendFunction()</a> can specify 121 combinations of blends (11 x 11). It&#39;s impractical to specify these combinations
+ individually. Instead, the settings indicated by each call should be bitwise OR&#39;d to make the proper single value
+ used in BLTsville.<br />
+ <br />
+ <table class="code_block">
+ <tr>
+ <td class="ctr">&nbsp;</td>
+ <td colspan="5" class="ctr"><strong>32-bit Binary Value</strong></td>
+ </tr>
+ <tr>
+ <td><strong>
+ <a href="http://directfb.org/docs/DirectFB_Reference_1_2/IDirectFBSurface_SetSrcBlendFunction.html">SetSrcBlendFunction()</a></strong></td>
+ <td class="ctr"><strong>[VendorID]</strong></td>
+ <td class="ctr"><strong>&nbsp;[--K1--] </strong></td>
+ <td class="ctr"><strong>&nbsp;[--K2--] </strong></td>
+ <td class="ctr"><strong>&nbsp;[--K3--] </strong></td>
+ <td class="ctr"><strong>&nbsp;[--K4--] </strong></td>
+ </tr>
+ <tr>
+ <td>DSBF_ZERO</td>
+ <td class="ctr">0000 0000</td>
+ <td class="ctr">00 00 00</td>
+ <td class="ctr">xx xx xx</td>
+ <td class="ctr">00 00 00</td>
+ <td class="ctr">xx xx xx</td>
+ </tr>
+ <tr>
+ <td>DSBF_ONE</td>
+ <td class="ctr">0000 0000</td>
+ <td class="ctr">11 11 11</td>
+ <td class="ctr">xx xx xx</td>
+ <td class="ctr">11 11 11</td>
+ <td class="ctr">xx xx xx</td>
+ </tr>
+ <tr>
+ <td>DSBF_SRCCOLOR</td>
+ <td class="ctr">0000 0000</td>
+ <td class="ctr">11 11 00</td>
+ <td class="ctr">xx xx xx</td>
+ <td class="ctr">00 00 01</td>
+ <td class="ctr">xx xx xx</td>
+ </tr>
+ <tr>
+ <td>DSBF_INVSRCCOLOR</td>
+ <td class="ctr">0000 0000</td>
+ <td class="ctr">11 00 11</td>
+ <td class="ctr">xx xx xx</td>
+ <td class="ctr">00 01 00</td>
+ <td class="ctr">xx xx xx</td>
+ </tr>
+ <tr>
+ <td>DSBF_SRCALPHA</td>
+ <td class="ctr">0000 0000</td>
+ <td class="ctr">00 00 01</td>
+ <td class="ctr">xx xx xx</td>
+ <td class="ctr">00 00 01</td>
+ <td class="ctr">xx xx xx</td>
+ </tr>
+ <tr>
+ <td>DSBF_INVSRCALPHA</td>
+ <td class="ctr">0000 0000</td>
+ <td class="ctr">00 01 00</td>
+ <td class="ctr">xx xx xx</td>
+ <td class="ctr">00 01 00</td>
+ <td class="ctr">xx xx xx</td>
+ </tr>
+ <tr>
+ <td>DSBF_DESTCOLOR</td>
+ <td class="ctr">0000 0000</td>
+ <td class="ctr">11 11 10</td>
+ <td class="ctr">xx xx xx</td>
+ <td class="ctr">00 00 11</td>
+ <td class="ctr">xx xx xx</td>
+ </tr>
+ <tr>
+ <td>DSBF_INVDESTCOLOR</td>
+ <td class="ctr">0000 0000</td>
+ <td class="ctr">11 10 11</td>
+ <td class="ctr">xx xx xx</td>
+ <td class="ctr">00 11 00</td>
+ <td class="ctr">xx xx xx</td>
+ </tr>
+ <tr>
+ <td>DSBF_DESTALPHA</td>
+ <td class="ctr">0000 0000</td>
+ <td class="ctr">00 00 11</td>
+ <td class="ctr">xx xx xx</td>
+ <td class="ctr">00 00 11</td>
+ <td class="ctr">xx xx xx</td>
+ </tr>
+ <tr>
+ <td>DSBF_INVDESTALPHA</td>
+ <td class="ctr">0000 0000</td>
+ <td class="ctr">00 11 00</td>
+ <td class="ctr">xx xx xx</td>
+ <td class="ctr">00 11 00</td>
+ <td class="ctr">xx xx xx</td>
+ </tr>
+ <tr>
+ <td>DSBF_SRCALPHASAT</td>
+ <td class="ctr">0000 0000</td>
+ <td class="ctr">01 11 01</td>
+ <td class="ctr">xx xx xx</td>
+ <td class="ctr">11 11 11</td>
+ <td class="ctr">xx xx xx</td>
+ </tr>
+ </table>
+ <br />
+ <table class="code_block">
+ <tr>
+ <td class="ctr">&nbsp;</td>
+ <td colspan="5" class="ctr"><strong>32-bit Binary Value</strong></td>
+ </tr>
+ <tr>
+ <td><strong>
+ <a href="http://directfb.org/docs/DirectFB_Reference_1_2/IDirectFBSurface_SetDstBlendFunction.html">SetDstBlendFunction()</a></strong></td>
+ <td class="ctr"><strong>[VendorID]</strong></td>
+ <td class="ctr"><strong>&nbsp;[--K1--] </strong></td>
+ <td class="ctr"><strong>&nbsp;[--K2--] </strong></td>
+ <td class="ctr"><strong>&nbsp;[--K3--] </strong></td>
+ <td class="ctr"><strong>&nbsp;[--K4--] </strong></td>
+ </tr>
+ <tr>
+ <td>DSBF_ZERO</td>
+ <td class="ctr">0000 0000</td>
+ <td class="ctr">xx xx xx</td>
+ <td class="ctr">00 00 00</td>
+ <td class="ctr">xx xx xx</td>
+ <td class="ctr">00 00 00</td>
+ </tr>
+ <tr>
+ <td>DSBF_ONE</td>
+ <td class="ctr">0000 0000</td>
+ <td class="ctr">xx xx xx</td>
+ <td class="ctr">11 11 11</td>
+ <td class="ctr">xx xx xx</td>
+ <td class="ctr">11 11 11</td>
+ </tr>
+ <tr>
+ <td>DSBF_SRCCOLOR</td>
+ <td class="ctr">0000 0000</td>
+ <td class="ctr">xx xx xx</td>
+ <td class="ctr">11 11 00</td>
+ <td class="ctr">xx xx xx</td>
+ <td class="ctr">00 00 01</td>
+ </tr>
+ <tr>
+ <td>etc.</td>
+ <td class="ctr">&nbsp;</td>
+ <td class="ctr">&nbsp;</td>
+ <td class="ctr">&nbsp;</td>
+ <td class="ctr">&nbsp;</td>
+ <td>&nbsp;</td>
+ </tr>
+ </table>
+ <br />
+ <span class="Header4">Porter-Duff</span><br />
+ <br />
+ For Porter-Duff blends, the equations can be more specifically defined. For convenience, these are enumerated in
+ the <span class="inline_code">bvblend.h</span> header. These enumerations utilize only the local alpha in the equations
+ as indicated. To use global or remote alpha, these enumerations need to be modified. For example, to include the
+ global alpha in the Porter-Duff <span class="inline_code">BVBLEND_SRC1OVER</span> blend, the blend could be defined
+ like this:<br />
+ <br />
+ <div>
+ <table class="indent">
+ <tr>
+ <td valign="top"><span class="inline_code">params.op.blend =</span></td>
+ <td><span class="inline_code">BVBLEND_SRC1OVER +<br />
+ BVBLENDDEF_GLOBAL_UCHAR;</span></td>
+ </tr>
+ </table>
+ </div>
+ <br />
+ To include the remote alpha, the blend could be defined like this:<br />
+ <br />
+ <div>
+ <table class="indent">
+ <tr>
+ <td valign="top"><span class="inline_code">params.op.blend =</span></td>
+ <td><span class="inline_code">BVBLEND_SRC1OVER +<br />
+ BVBLENDDEF_REMOTE;</span></td>
+ </tr>
+ </table>
+ </div>
+ <br />
+ And to include both:<br />
+ <br />
+ <div>
+ <table class="indent">
+ <tr>
+ <td valign="top"><span class="inline_code">params.op.blend =</span></td>
+ <td><span class="inline_code">BVBLEND_SRC1OVER +<br />
+ BVBLENDDEF_GLOBAL_UCHAR +<br />
+ BVBLENDDEF_REMOTE;</span></td>
+ </tr>
+ </table>
+ </div>
+ <br />
+ Note that if the source color formats include local alphas, the local alphas, global alpha, and remote alpha will
+ be used together.<br />
+ <br />
+ Note also that the equations assume the surfaces are premultiplied. So if the surface formats indicate that they
+ are not premultiplied, the alpha multiplication of each color is done prior to using the surface values in the equations.<br />
+ <br />
+ For example, <span class="inline_code">BVBLEND_SRC1OVER</span> specifies the equations:<br />
+ <table class="indent">
+ <tr>
+ <td>C<sub>d</sub> = C<sub>1</sub> + (1 - A<sub>1</sub>)C<sub>2</sub><br />
+ A<sub>d</sub> = A<sub>1</sub> + (1 - A<sub>1</sub>)A<sub>2</sub> </td>
+ </tr>
+ </table>
+ <br />
+ If the format of surface 1 is non-premultiplied, the equations are modified to include the multiplication explicitly:<br />
+ <br />
+ <table class="indent">
+ <tr>
+ <td>C<sub>d</sub> = A<sub>1</sub>C<sub>1</sub> + (1 - A<sub>1</sub>)C<sub>2</sub><br />
+ A<sub>d</sub> = A<sub>1</sub> + (1 - A<sub>1</sub>)A<sub>2</sub> </td>
+ </tr>
+ </table>
+ <br />
+ Likewise, if the format of surface 2 is non-premultiplied, the equations are modified for this:<br />
+ <br />
+ <table class="indent">
+ <tr>
+ <td>
+ <div>
+ C<sub>d</sub> = C<sub>1</sub> + (1 - A<sub>1</sub>)A<sub>2</sub>C<sub>2</sub><br />
+ A<sub>d</sub> = A<sub>1</sub> + (1 - A<sub>1</sub>)A<sub>2</sub> </div>
+ </td>
+ </tr>
+ </table>
+ <br />
+ When including global or remote alphas, these values are used to modify the source 1 value values before being used
+ in the blend equation:<br />
+ <br />
+ <table class="indent">
+ <tr>
+ <td class="ctr">C<sub>1</sub> = A<sub>g</sub>C<sub>1</sub><br />
+ A<sub>1</sub> = A<sub>g</sub>A<sub>1</sub></td>
+ <td style="width: 20%" class="ctr">-or-</td>
+ <td class="ctr">C<sub>1</sub> = A<sub>r</sub>C<sub>1</sub><br />
+ A<sub>1</sub> = A<sub>r</sub>A<sub>1</sub></td>
+ <td class="ctr">-or-</td>
+ <td class="ctr">C<sub>1</sub> = A<sub>r</sub>A<sub>g</sub>C<sub>1</sub><br />
+ A<sub>1</sub> = A<sub>r</sub>A<sub>g</sub>A<sub>1</sub></td>
+ </tr>
+ </table>
+ <br />
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">2.</td>
+ <td><span class="Code_Header_3"><strong><a name="BVBLENDDEF_FORMAT_ESSENTIAL0">BVBLENDDEF_FORMAT_ESSENTIAL</a></strong></span><br />
+ <br />
+ The essential blending equations are based on the blending equations in common image manipulation programs.<pre class="indent"><code>BVBLEND_LIGHTEN max(src1, src2)
+BVBLEND_DARKEN min(src1, src2)
+BVBLEND_MULTIPLY (src1 * src2) / 255
+BVBLEND_AVERAGE (src1 + src2) / 2
+BVBLEND_ADD src1 + src2 (saturated)
+BVBLEND_SUBTRACT src1 + src2 - 255 (saturated)
+BVBLEND_DIFFERENCE abs(src - src2)
+BVBLEND_NEGATION 255 - abs(255 - src1 - src2)
+BVBLEND_SCREEN 255 - (((255 - src1) * (255 - src2)) / 256)
+BVBLEND_EXCLUSION src1 + src2 - ((2 * src1 * src2) / 255)
+BVBLEND_OVERLAY (src2 &lt; 128) ? (2 * src1 * src2 / 255) : (255 - 2 * (255 - src1) * (255 - src2) / 255)
+BVBLEND_SOFT_LIGHT (src2 &lt; 128) ? (2 * ((src1 &gt;&gt; 1) + 64)) * ((float)src2 / 255) : (255 - (2 * (255 - ((src1 &gt;&gt; 1) + 64)) * (float)(255 - src2) / 255))
+BVBLEND_HARD_LIGHT (src1 &lt; 128) ? (2 * src2 * src1 / 255) : (255 - 2 * (255 - src2) * (255 - src1) / 255)
+BVBLEND_COLOR_DODGE (src2 == 255) ? src2 : min(255, ((src1 &lt;&lt; 8) / (255 - src2))
+BVBLEND_COLOR_BURN (src2 == 0) ? src2 : max(0, (255 - ((255 - src1) &lt;&lt; 8 ) / src2))))
+BVBLEND_LINEAR_DODGE same as BVBLEND_ADD
+BVBLEND_LINEAR_BURN same as BVBLEND_SUBTRACT
+BVBLEND_LINEAR_LIGHT (src2 &lt; 128) ? LINEAR_BURN(src1,(2 * src2)) : LINEAR_DODGE(src1,(2 * (src2 - 128)))
+BVBLEND_VIVID_LIGHT (src2 &lt; 128) ? COLOR_BURN(src1,(2 * src2)) : COLOR_DODGE(src1,(2 * (src2 - 128))))
+BVBLEND_PIN_LIGHT (src2 &lt; 128) ? DARKEN(src1,(2 * src2)) : LIGHTEN(src1,(2 * (src2 - 128)))
+BVBLEND_HARD_MIX (VIVID_LIGHT(src1, src2) &lt; 128) ? 0 : 255
+BVBLEND_REFLECT (src2 == 255) ? src2 : min(255, (src1 * src1 / (255 - src2)))
+BVBLEND_GLOW (src1 == 255) ? src1 : min(255, (src2 * src2 / (255 - src1)))
+BVBLEND_PHOENIX min(src1, src2) - max(src1, src2) + 255)
+BVBLEND_ALPHA alf * src1 + (1 - alf) * src2)</code></pre>
+ </td>
+ </tr>
+</table>
+<a name="filter" class="Code_Header_2">bvbltparams.op.filter</a>
+<p class="code_block">struct bvfilter *filter; /* input */</p>
+<p>When <span class="inline_code"><a href="#BVFLAG_FILTER">BVFLAG_FILTER</a></span> is set in the
+<span class="inline_code"><a href="#flags">bvbltparams.flags</a></span> member, the <span class="inline_code">
+<a href="#op">bvbltparams.op</a></span> union is treated as a <span class="inline_code">filter</span>.</p>
+<p>To specify the filter, the client fills in <span class="inline_code">filter</span> with one of the
+<span class="inline_code">bvfilter</span> values.</p>
+<p>These values will be extended as general filter types are requested.</p>
+<a name="colorkey" class="Code_Header_2">bvbltparams.colorkey</a>
+<p class="code_block">void *colorkey; /* input */</p>
+<p>When either <span class="inline_code"><a href="#BVFLAG_KEY_SRC">BVFLAG_KEY_SRC</a></span> or
+<span class="inline_code"><a href="#BVFLAG_KEY_DST">BVFLAG_KEY_DST</a></span> is set in the <span class="inline_code">
+<a href="#flags">bvbltparams.flags</a></span> member, <span class="inline_code">colorkey</span> points to a single pixel
+used as the color key.</p>
+<p>The format of this pixel matches the surface being keyed.&nbsp; i.e. <span class="inline_code"><a href="#bvsurfgeom">
+src1geom.format</a></span> is the format of the color key if <span class="inline_code">BVFLAG_KEY_SRC</span> is set, or
+<span class="inline_code"><a href="#bvsurfgeom">dst.format</a></span> is the format of the color key if
+<span class="inline_code">BVFLAG_KEY_DST</span> is set.</p>
+<p><em>Subsampled formats do not currently support color keying.</em></p>
+<p class="Code_Header_2"><a name="globalalpha">bvbltparams.globalalpha</a></p>
+<p class="code_block">union bvalpha globalalpha; /* input */</p>
+<p>When <span class="inline_code"><a href="#BVFLAG_BLEND">BVFLAG_BLEND</a></span> is set in the
+<span class="inline_code"><a href="#flags">bvbltparams.flags</a></span>, and when the <span class="inline_code">
+<a href="#blend">blend</a></span> chosen requires it, <span class="inline_code">globalalpha</span> is used to provide an
+alpha blending value for the entire operation.&nbsp; The type is also dependent on the <span class="inline_code">
+<a href="#blend">blend</a></span> chosen.</p>
+<p>For the <span class="inline_code">BVBLENDDEF_FORMAT_CLASSIC</span> blend types, if the <span class="inline_code">BVBLENDDEF_GLOBAL_MASK</span>
+field is not 0, this field is used.&nbsp; Currently <span class="inline_code">BVBLENDDEF_FORMAT_CLASSIC</span> provides
+for an 8-bit (unsigned character / byte) format designated by <span class="inline_code">BVBLENDDEF_GLOBAL_UCHAR</span> as
+well as a 32-bit floating point format designated by <span class="inline_code">BVBLENDDEF_GLOBAL_FLOAT</span>.</p>
+<p class="Code_Header_2"><a name="scalemode">bvbltparams.scalemode</a></p>
+<p class="code_block">enum bvscalemode scalemode; /* input/output */</p>
+<p>This member allows the client to specify the type of scaling to be used.&nbsp; The enumeration begins with 8 bits indicating
+the vendor.&nbsp; The remaining bits are defined by the vendor.&nbsp; <span class="inline_code">BVSCALEDEF_VENDOR_ALL</span>
+and <span class="inline_code">BVSCALEDEF_VENDOR_GENERAL</span> are shared by all implementations.</p>
+<p><span class="inline_code">BVSCALEDEF_VENDOR_ALL</span> can be used to specify an implicit scale type.&nbsp; This type
+is converted to an explicit type by the implementation:</p>
+<table class="indent">
+ <tr>
+ <td class="inline_code">BVSCALE_FASTEST</td>
+ <td>The fastest method of scaling available is used.&nbsp; This may include nearest neighbor.&nbsp; The value of
+ this enumeration is purposely 0, and is the default scale type.&nbsp; No implementation will return an error for
+ this setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_FASTEST_NOT_NEAREST_NEIGHBOR</td>
+ <td>The fastest method of scaling available that is not nearest neighbor is used.&nbsp; This may include an alternative
+ point sample technique.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_FASTEST_POINT_SAMPLE</td>
+ <td>The fastest method of scaling using a point sample technique.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_FASTEST_INTERPOLATED</td>
+ <td>The fastest method of scaling using an interpolation technique.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_FASTEST_PHOTO</td>
+ <td>The fastest method of scaling appropriate for photographs is used.&nbsp; This may include nearest neighbor.&nbsp;
+ No implementation will return an error for this setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_FASTEST_DRAWING</td>
+ <td>The fastest method of scaling appropriate for drawings is used.&nbsp; This may include nearest neighbor.&nbsp;
+ No implementation will return an error for this setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_GOOD</td>
+ <td>A scaling technique is chosen that may be higher quality than the <span class="inline_code">BVSCALE_FASTEST</span>
+ choice.&nbsp; This may include nearest neighbor.&nbsp; No implementation will return an error for this setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_GOOD_POINT_SAMPLE</td>
+ <td>A point sample scaling technique is chosen that may be higher quality than the <span class="inline_code">BVSCALE_FASTEST_POINT_SAMPLE</span>
+ choice.&nbsp; This may include nearest neighbor.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_GOOD_INTERPOLATED</td>
+ <td>An interpolated scaling technique is chosen that may be higher quality than the <span class="inline_code">BVSCALE_FASTEST_INTERPOLATED</span>
+ choice.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_GOOD_PHOTO</td>
+ <td>A scaling technique appropriate for photographs is chosen that may be higher quality than the
+ <span class="inline_code">BVSCALE_FASTEST_PHOTO</span> choice.&nbsp; This may include nearest neighbor.&nbsp; No
+ implementation will return an error for this setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_GOOD_DRAWING</td>
+ <td>A scaling technique appropriate for drawings is chosen that may be higher quality than the
+ <span class="inline_code">BVSCALE_FASTEST_DRAWING</span> choice.&nbsp; This may include nearest neighbor.&nbsp;
+ No implementation will return an error for this setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_BETTER</td>
+ <td>A scaling technique is chosen that may be higher quality than the <span class="inline_code">BVSCALE_GOOD</span>
+ choice.&nbsp; This may include nearest neighbor.&nbsp; No implementation will return an error for this setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_BETTER_POINT_SAMPLE</td>
+ <td>A point sample scaling technique is chosen that may be higher quality than the <span class="inline_code">BVSCALE_GOOD_POINT_SAMPLE</span>
+ choice.&nbsp; This may include nearest neighbor.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_BETTER_INTERPOLATED</td>
+ <td>An interpolated scaling technique is chosen that may be higher quality than the <span class="inline_code">BVSCALE_GOOD_INTERPOLATED</span>
+ choice.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_BETTER_PHOTO</td>
+ <td>A scaling technique appropriate for photographs is chosen that may be higher quality than the
+ <span class="inline_code">BVSCALE_GOOD_PHOTO</span> choice.&nbsp; This may include nearest neighbor.&nbsp; No implementation
+ will return an error for this setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_BETTER_DRAWING</td>
+ <td>A scaling technique appropriate for drawings is chosen that may be higher quality than the
+ <span class="inline_code">BVSCALE_GOOD_DRAWING</span> choice.&nbsp; This may include nearest neighbor.&nbsp; No
+ implementation will return an error for this setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_BEST</td>
+ <td>The highest quality scaling technique is chosen.&nbsp; This may include nearest neighbor.&nbsp; No implementation
+ will return an error for this setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_BEST_POINT_SAMPLE</td>
+ <td>The highest quality point sample technique is chosen.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_BEST_INTERPOLATED</td>
+ <td>The highest quality interpolated scaling technique is chosen.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_BEST_PHOTO</td>
+ <td>The highest quality scaling technique appropriate for photographs is chosen.&nbsp; This may include nearest
+ neighbor.&nbsp; No implementation will return an error for this setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_BEST_DRAWING</td>
+ <td>The highest quality scaling technique appropriate for drawings is chosen.&nbsp; This may include nearest neighbor.&nbsp;
+ No implementation will return an error for this setting.</td>
+ </tr>
+</table>
+<br />
+<span class="inline_code">BVSCALEDEF_VENDOR_GENERAL</span> can be used to specify one of the shared explicit scale types.&nbsp;
+At this point, only a limited number of explicit scale types are defined: <br />
+<br />
+<table class="indent">
+ <tr>
+ <td class="inline_code">BVSCALE_NEAREST_NEIGHBOR</td>
+ <td>This is a point sample scaling technique where the resampled destination pixel is set to the value of the closest
+ source pixel.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_BILINEAR</td>
+ <td>This is an interpolated scaling technique where the resampled destination pixel is set to a value linearly interpolated
+ in two dimensions from the four closest source pixels.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_BICUBIC</td>
+ <td>This is an interpolated scaling technique where the resampled destination pixel is set to a value calculated
+ using cubic interpolation in two dimensions.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_3x3_TAP</td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_5x5_TAP</td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_7x7_TAP</td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVSCALE_9x9_TAP</td>
+ <td>&nbsp;</td>
+ </tr>
+</table>
+<p>If the client wants to know the explicit type chosen by a given implementation, it can set <span class="inline_code">
+BVFLAG_SCALE_RETURN</span> in the <span class="inline_code"><a href="#flags">bvbltparams.flags</a></span> member, and the
+explicit scale type is returned in the <span class="inline_code">scalemode</span> member.</p>
+<p class="note">NOTE:&nbsp; Extending the <span class="inline_code">BVSCALEDEF_VENDOR_GENERAL</span> scale types or obtaining
+a vendor ID can be accomplished by submitting a patch.</p>
+<p class="Code_Header_2"><a name="dithermode">bvbltparams.dithermode</a></p>
+<p class="code_block">enum bvdithermode dithermode; /* input/output */</p>
+<p>This member allows the client to specify the type of dithering to be used, when the output format has fewer bits of depth
+than the internal calculation.&nbsp; The enumeration begins with 8 bits indicating the vendor.&nbsp; The remaining bits
+are defined by the vendor.&nbsp; <span class="inline_code">BVDITHERDEF_VENDOR_ALL</span> and <span class="inline_code">BVDITHERDEF_VENDOR_GENERAL</span>
+are shared by all implementations.</p>
+<p><span class="inline_code">BVDITHERDEF_VENDOR_ALL</span> can be used to specify an implicit dither type.&nbsp; This type
+is converted to an explicit type by the implementation:</p>
+<table class="indent">
+ <tr>
+ <td class="inline_code">BVDITHER_FASTEST</td>
+ <td>The fastest method of dithering available is used.&nbsp; This may include no dithering (truncation).&nbsp; The
+ value of this enumeration is purposely 0, and is the default dither type.&nbsp; No implementation will return an
+ error for this setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_FASTEST_ON</td>
+ <td>The fastest method of dithering available is used.&nbsp; This will not include no dithering.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_FASTEST_RANDOM</td>
+ <td>The fastest method of dithering using a random technique.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_FASTEST_ORDERED</td>
+ <td>The fastest method of dithering using an ordered diffusion technique.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_FASTEST_DIFFUSED</td>
+ <td>The fastest method of dithering using an error diffusion technique.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_FASTEST_PHOTO</td>
+ <td>The fastest method of dithering appropriate for photographs is used.&nbsp; This may include no dithering.&nbsp;
+ No implementation will return an error for this setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_FASTEST_DRAWING</td>
+ <td>The fastest method of dithering appropriate for drawings is used.&nbsp; This may include no dithering.&nbsp;
+ No implementation will return an error for this setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_GOOD</td>
+ <td>A dithering technique is chosen that may be higher quality than the <span class="inline_code">BVDITHER_FASTEST</span>
+ choice.&nbsp; This may include no dithering.&nbsp; No implementation will return an error for this setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_GOOD_ON</td>
+ <td>Any dithering technique available is used.&nbsp; This will not include no dithering.&nbsp; This may be higher
+ quality than <span class="inline_code">BVDITHER_FASTEST_ON</span>.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_GOOD_RANDOM</td>
+ <td>A random dithering technique is chosen that may be higher quality than the <span class="inline_code">BVDITHER_FASTEST_RANDOM</span>
+ choice.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_GOOD_ORDERED</td>
+ <td>An ordered dithering technique is chosen that may be higher quality than the <span class="inline_code">BVDITHER_FASTEST_ORDERED</span>
+ choice.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_GOOD_DIFFUSED</td>
+ <td>A diffused dithering technique is chosen that may be higher quality than the <span class="inline_code">BVDITHER_FASTEST_DIFFUSED</span>
+ choice.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_GOOD_PHOTO</td>
+ <td>A dithering technique appropriate for photographs is chosen that may be higher quality than the
+ <span class="inline_code">BVDITHER_FASTEST_PHOTO</span> choice.&nbsp; This may include no dithering.&nbsp; No implementation
+ will return an error for this setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_GOOD_DRAWING</td>
+ <td>A dithering technique appropriate for drawings is chosen that may be higher quality than the
+ <span class="inline_code">BVDITHER_FASTEST_DRAWING</span> choice.&nbsp; This may include no dithering.&nbsp; No
+ implementation will return an error for this setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_BETTER</td>
+ <td>A dithering technique is chosen that may be higher quality than the <span class="inline_code">BVDITHER_GOOD</span>
+ choice.&nbsp; This may include no dithering.&nbsp; No implementation will return an error for this setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_BETTER_ON</td>
+ <td>Any dithering technique available is used.&nbsp; This will not include no dithering.&nbsp; This may be higher
+ quality than <span class="inline_code">BVDITHER_GOOD_ON</span>.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_BETTER_RANDOM</td>
+ <td>A random dithering technique is chosen that may be higher quality than the <span class="inline_code">BVDITHER_GOOD_RANDOM</span>
+ choice.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_BETTER_ORDERED</td>
+ <td>An ordered dithering technique is chosen that may be higher quality than the <span class="inline_code">BVDITHER_GOOD_ORDERED</span>
+ choice.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_BETTER_DIFFUSED</td>
+ <td>A diffused dithering technique is chosen that may be higher quality than the <span class="inline_code">BVDITHER_GOOD_DIFFUSED</span>
+ choice.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_BETTER_PHOTO</td>
+ <td>A scaling technique appropriate for photographs is chosen that may be higher quality than the
+ <span class="inline_code">BVSCALE_GOOD_PHOTO</span> choice.&nbsp; No implementation will return an error for this
+ setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_BETTER_DRAWING</td>
+ <td>A scaling technique appropriate for drawings is chosen that may be higher quality than the
+ <span class="inline_code">BVSCALE_GOOD_DRAWING</span> choice.&nbsp; No implementation will return an error for this
+ setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_BEST</td>
+ <td>The highest quality dithering technique is chosen.&nbsp; This may include no dithering.&nbsp; No implementation
+ will return an error for this setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_BEST_ON</td>
+ <td>Any dithering technique available is used.&nbsp; This will not include no dithering.&nbsp; This may be higher
+ quality than <span class="inline_code">BVDITHER_BEST_ON</span>.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_BEST_RANDOM</td>
+ <td>The highest quality random dithering technique is chosen.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_BEST_ORDERED</td>
+ <td>The highest quality ordered dithering technique is chosen.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_BEST_DIFFUSED</td>
+ <td>The highest quality diffused dithering technique is chosen.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_BEST_PHOTO</td>
+ <td>The highest quality dithering technique appropriate for photographs is chosen.&nbsp; This may include no dithering.&nbsp;
+ No implementation will return an error for this setting.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_BEST_DRAWING</td>
+ <td>The highest quality dithering technique appropriate for drawings is chosen.&nbsp; This may include no dithering.&nbsp;
+ No implementation will return an error for this setting.</td>
+ </tr>
+</table>
+<br />
+<span class="inline_code">BVDITHERDEF_VENDOR_GENERAL</span> can be used to specify one of the shared explicit dithering
+types.&nbsp; At this point, only a limited number of explicit dither types are defined:<br />
+<br />
+<table class="indent">
+ <tr>
+ <td class="inline_code">BVDITHER_NONE</td>
+ <td>No dithering is performed.&nbsp; Internal pixel component values are truncated to the destination component
+ bit depth.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_ORDERED_2x2</td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_ORDERED_4x4</td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVDITHER_ORDERED_2x2_4x4</td>
+ <td>2x2 ordered dither is used for components with the lowest bit reduction.&nbsp; 4x4 ordered dither is used for
+ the components with the highest bit reduction.&nbsp; (E.g. RGB24 to RGB565 will use 2x2 ordered dither for the green
+ component and 4x4 ordered dither for the red and blue components.)</td>
+ </tr>
+</table>
+<p>If the client wants to know the explicit type chosen by a given implementation, it can set <span class="inline_code">
+BVFLAG_DITHER_RETURN</span> in the <span class="inline_code"><a href="#flags">bvbltparams.flags</a></span> member, and the
+explicit scale type is returned in the <span class="inline_code">dithermode</span> member.</p>
+<p class="note">NOTE:&nbsp; Extending the <span class="inline_code">BVDITHERDEF_VENDOR_GENERAL</span> scale types or obtaining
+a vendor ID can be accomplished by submitting a patch.</p>
+<p class="Code_Header_2"><a name="dstdesc">bvbltparams.dstdesc</a></p>
+<p class="code_block"><a href="#bvbuffdesc">struct bvbuffdesc</a> *dstdesc;</p>
+<p><span class="inline_code">dstdesc</span> is used to specify the destination buffer.&nbsp; If the buffer has not been
+mapped with a call to <span class="inline_code"><a href="#bv_map">bv_map()</a></span>, <span class="inline_code">
+<a href="#bv_blt">bv_blt()</a></span> will map the buffer as necessary to perform the BLT and then unmap afterwards.&nbsp;
+See <span class="inline_code"><a href="#bvbuffdesc">bvbuffdesc</a></span> for details.</p>
+<p class="Code_Header_2"><a name="dstgeom">bvbltparams.dstgeom</a></p>
+<p class="code_block"><a href="#bvsurfgeom">struct bvsurfgeom</a> *dstgeom;</p>
+<p><span class="inline_code">dstgeom</span> is used to specify the geometry of the surface contained in the destination
+buffer.&nbsp; See <span class="inline_code"><a href="#bvsurfgeom">bvsurfgeom</a></span> for details.</p>
+<p class="Code_Header_2"><a name="dstrect">bvbltparams.dstrect</a></p>
+<p class="code_block"><a href="#bvrect">struct bvrect</a> dstrect;</p>
+<p><span class="inline_code">dstrect</span> is used to specify the destination rectangle to receive the BLT.&nbsp; This
+rectangle is clipped by <span class="inline_code"><a href="#cliprect">bvbltparams.cliprect</a></span> when
+<span class="inline_code"><a href="#BVFLAG_CLIP">BVFLAG_CLIP</a></span> is set in the <span class="inline_code">
+<a href="#flags">bvbltparams.flags</a></span> member.</p>
+<p class="Code_Header_2">bvbltparams.<a name="src1.desc">src1</a>/<a name="src2.desc">src2</a>/<a name="mask.desc">mask.desc</a></p>
+<p class="code_block"><a href="#bvbuffdesc">struct bvbuffdesc</a> *src1.desc;<br />
+<a href="#bvbuffdesc">struct bvbuffdesc</a> *src2.desc;<br />
+<a href="#bvbuffdesc">struct bvbuffdesc</a> *mask.desc;</p>
+<p>These members are used to identify the buffer for the source1, source2, and mask surfaces when the associated
+<span class="inline_code">BVFLAG_TILE_*</span> flag is not set.&nbsp; The buffer is the memory in which the surface lies.&nbsp;
+See the <span class="inline_code"><a href="#src1geom">bvbltparams.src1/src2/maskgeom</a></span> for the format and layout/geometry
+of the surface.</p>
+<p class="note">NOTE WELL:&nbsp; Clients should never change the value of a <span class="inline_code">
+<a href="#bvbuffdesc">bvbuffdesc</a></span> structure while a buffer is mapped.</p>
+<p class="Code_Header_2">bvbltparams.<a name="src1.tileparams">src1</a>/<a name="src2.tileparams">src2</a>/<a name="mask.tileparams">mask.tileparams</a></p>
+<p class="code_block"><a href="#bvtileparams">struct bvtileparams</a> *src1.tileparams;<br />
+<a href="#bvtileparams">struct bvtileparams</a> *src2.tileparams;<br />
+<a href="#bvtileparams">struct bvtileparams</a> *mask.tileparams;</p>
+<p>These members are used to identify the buffer for the source1, source2, and mask surfaces when the associated
+<span class="inline_code">BVFLAG_TILE_*</span> flag is set.&nbsp; The buffer is the memory in which the surface lies.&nbsp;
+This differs from the <span class="inline_code"><a href="#src1.desc">src1/src2/mask.desc</a></span> identity by providing
+more information needed for tiling and by not requiring mapping (for hardware implementations that support tiling, the tile
+data is usually moved into an on-chip cache).</p>
+<p class="Code_Header_2">bvbltparams.<a name="src1geom">src1</a>/<a name="src2geom">src2</a>/<a name="maskgeom">maskgeom</a></p>
+<p class="code_block"><a href="#bvsurfgeom">struct bvsurfgeom</a> src1geom;<br />
+<a href="#bvsurfgeom">struct bvsurfgeom</a> src2geom;<br />
+<a href="#bvsurfgeom">struct bvsurfgeom</a> maskgeom;</p>
+<p>These members describe the format and layout/geometry of their respective surfaces.&nbsp; Separating
+<span class="inline_code"><a href="#bvsurfgeom">bvsurfgeom</a></span> from the <span class="inline_code">
+<a href="#bvbuffdesc">bvbuffdesc</a></span> allows easy use of buffers for multiple geometries without remapping.&nbsp;
+See <span class="inline_code"><a href="#bvsurfgeom">bvsurfgeom</a></span> and <span class="inline_code">
+<a href="#bvbuffdesc">bvbuffdesc</a></span> for details.</p>
+<p class="Code_Header_2">bbvbltparams.src1/src2/maskrect</p>
+<p class="code_block"><a href="#bvrect">struct bvrect</a> src1rect;<br />
+<a href="#bvrect">struct bvrect</a> src2rect;<br />
+<a href="#bvrect">struct bvrect</a> maskrect;</p>
+<p>These members specify the rectangle from which data is read for the BLT.&nbsp; These rectangles are clipped by a scaled
+version of the <span class="inline_code"><a href="#cliprect">bvbltparams.cliprect</a></span>&nbsp; (scaling is based on
+the relationship between them and the <span class="inline_code"><a href="#dstrect">bvbltparams.dstrect</a></span>) when
+<span class="inline_code"><a href="#BVFLAG_CLIP">BVFLAG_CLIP</a></span> is set in the <span class="inline_code">
+<a href="#flags">bvbltparams.flags</a></span> member.</p>
+<table class="example">
+ <tr>
+ <td>
+ <p><strong>Example:</strong></p>
+ <a href="#src1rect" class="inline_code">src1rect</a> = (0, 0) - (400 x 200)<br />
+ <a href="#dstrect" class="inline_code">dstrect</a> = (0, 0) - (800 x 600)<br />
+ <a href="#cliprect" class="inline_code">cliprect</a> = (10, 30) - (300 x 300)<p>The scaling ratio of the
+ <a href="#dstrect" class="inline_code">dstrect</a> to the <a href="#src1rect" class="inline_code">src1rect</a> is
+ (800/400,&nbsp; 600/300) or (2, 3).&nbsp; Using this, the effective source 1 clipping rectangle becomes (10/2, 30/3)
+ - (300/2 x 300/3) or (5, 10) - (150 x 100).</p>
+ </td>
+ </tr>
+</table>
+<p>This approach allows fractional clipping at the source using a method which is simpler to implement than fractional coordinates.</p>
+<p class="note">NOTE:&nbsp; In BLTsville, reading outside the source rectangle is forbidden.&nbsp; So scaling algorithms
+which require pixels around a particular source pixel must utilize boundary techniques (mirror, repeat, clamp, etc.) at
+the edges of the source rectangle.&nbsp; However, if the clipping rectangle, when translated back to the source rectangle,
+leaves space between it and the source rectangle, pixels outside the clipped region may be accessed by the implementation.</p>
+<p class="Code_Header_2"><a name="cliprect">bvbltparams.cliprect</a></p>
+<p class="code_block"><a href="#bvrect">struct bvrect</a> cliprect;</p>
+<p><span class="inline_code">cliprect</span> is used to specify a rectangle that limits what region of the destination is
+written.&nbsp; This is most useful for scaling operations, where the necessary scaling factor will not allow translation
+of the destination rectangle back to the source on an integer pixel boundary.</p>
+<p class="note">NOTE:&nbsp; If <span class="inline_code">cliprect</span> exceeds the destination surface, the behavior is
+undefined. </p>
+<p>For example, if the goal is to show a 640 x 480 video on a 1920 x 1080 screen, the video would be stretched to 1440 x
+1080 to maintain the proper aspect ratio.&nbsp; So the relevant rectangles would be:</p>
+<table class="indent">
+ <tr>
+ <td class="thin_bord"><strong>src1rect</strong></td>
+ <td class="thin_bord"><strong>dstrect</strong></td>
+ </tr>
+ <tr>
+ <td class="thin_bord">(0, 0) - 640 x 480</td>
+ <td class="thin_bord">(240, 0) - 1440 x 1080</td>
+ </tr>
+</table>
+<p>However, to handle a 640 x 480 pop-up window that appears centered on the screen, in front of the video, the single BLT
+may be broken into four smaller BLTs pieced around the popup.&nbsp; These rectangles would need to be:</p>
+<table class="indent">
+ <tr>
+ <td class="thin_bord"><strong>src1rect</strong></td>
+ <td class="thin_bord"><strong>dstrect</strong></td>
+ </tr>
+ <tr>
+ <td class="thin_bord">(0, 0) - 640 x 133.333...</td>
+ <td class="thin_bord">(240, 0) - 1440 x 300</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">(0, 133.333...) - 284.444... x 213.333...</td>
+ <td class="thin_bord">(240, 300) - 400 x 480</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">(568.888..., 133.333...) - 284.444... x 213.333...</td>
+ <td class="thin_bord">(1280, 300) - 400 x 480</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">(0, 346.666...) - 640 x 133.333...</td>
+ <td class="thin_bord">(240, 780) - 1440 x 300</td>
+ </tr>
+</table>
+<p>Since this is a scaling factor of 2.25x, translating the required destination rectangles back to the source results in
+non-integer coordinates and dimensions, as illustrated above.&nbsp; And adjusting the source rectangles to the nearest integer
+values will result in visible discontinuities at the boundaries between the rectangles.</p>
+<p>Instead, using the <span class="inline_code">cliprect</span>, this situation can be handled more easily:</p>
+<table class="indent">
+ <tr>
+ <td class="thin_bord"><strong>src1rect</strong></td>
+ <td class="thin_bord"><strong>dstrect</strong></td>
+ <td class="thin_bord"><strong>cliprect</strong></td>
+ </tr>
+ <tr>
+ <td class="thin_bord">(0, 0) - 640 x 480</td>
+ <td class="thin_bord">(240, 0) - 1440 x 1080</td>
+ <td class="thin_bord">(240, 0) - 1440 x 300</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">(0, 0) - 640 x 480</td>
+ <td class="thin_bord">(240, 0) - 1440 x 1080</td>
+ <td class="thin_bord">(240, 300) - 400 x 480</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">(0, 0) - 640 x 480</td>
+ <td class="thin_bord">(240, 0) - 1440 x 1080</td>
+ <td class="thin_bord">(1280, 300) - 400 x 480</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">(0, 0) - 640 x 480</td>
+ <td class="thin_bord">(240, 0) - 1440 x 1080</td>
+ <td class="thin_bord">(240, 780) - 1440 x 300</td>
+ </tr>
+</table>
+<p class="Code_Header_2"><a name="batchflags">bvbltparams.batchflags</a></p>
+<p class="code_block">unsigned long batchflags;</p>
+<p><span class="inline_code">batchflags</span> are used by the client as a hint to indicate to the implementation which
+parameters are changing between successive BLTs of a batch.&nbsp; The flags may be used when the
+<span class="inline_code"><a href="#flags">bvbltparams.flags</a></span> has <span class="inline_code">
+<a href="#BVFLAG_BATCH_CONTINUE">BVFLAG_BATCH_CONTINUE</a></span> or <span class="inline_code">
+<a href="#BVFLAG_BATCH_END">BVFLAG_BATCH_END</a></span> set.</p>
+<table style="" class="indent">
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_OP">BVBATCH_OP</a></span></td>
+ <td>indicates that the operation type (<span class="inline_code"><a href="#BVFLAG_ROP">BVFLAG_ROP</a></span>,
+ <span class="inline_code"><a href="#BVFLAG_BLEND">BVFLAG_BLEND</a></span>, <span class="inline_code">
+ <a href="#BVFLAG_FILTER">BVFLAG_FILTER</a></span>, etc.) has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_KEY">BVBATCH_KEY</a></span></td>
+ <td>indicates that the <span class="inline_code"><a href="#colorkey">bvbltparams.colorkey</a></span> or the color
+ key mode (<span class="inline_code"><a href="#BVFLAG_KEY_SRC">BVFLAG_KEY_SRC</a></span>/<span class="inline_code"><a href="#BVFLAG_KEY_DST">BVFLAG_KEY_DST</a></span>)
+ has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_MISCFLAGS">BVBATCH_MISCFLAGS</a></span></td>
+ <td>indicates that <span class="inline_code"><a href="#flags">bvbltparams.flags</a></span> other than the operation,
+ color key, or clip flag have changes.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_ALPHA">BVBATCH_ALPHA</a></span></td>
+ <td>indicates that <span class="inline_code"><a href="#globalalpha">bvbltparams.globalalpha</a></span> or global
+ alpha type has changed.</td>
+ </tr>
+ <tr>
+ <td><a name="BVBATCH_DITHER" class="inline_code">BVBATCH_DITHER</a></td>
+ <td>indicates that <span class="inline_code"><a href="#dithermode">bvbltparams.dithermode</a></span> has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_SCALE">BVBATCH_SCALE</a></span></td>
+ <td>indicates that <span class="inline_code"><a href="#scalemode">bvbltparams.scalemode</a></span> has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_DST">BVBATCH_DST</a></span></td>
+ <td>indicates that the destination surface (<span class="inline_code"><a href="#dstdesc">bvbltparams.dstdesc</a></span>,
+ <span class="inline_code"><a href="#dstgeom">bvbltparams.dstgeom</a></span> ,or <span class="inline_code">
+ <a href="#dstrect">bvbltparams.dstrect</a></span>) has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_SRC1">BVBATCH_SRC1</a></span> </td>
+ <td>indicates that the source 1 surface (<span class="inline_code"><a href="#src1.desc">bvbltparams.src1.desc</a></span>
+ or <span class="inline_code"><a href="#src1.tileparams">bvbltparams.src1.tileparams</a></span>, or
+ <span class="inline_code"><a href="#src1geom">bvbltparams.src1geom</a></span>) has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_SRC2">BVBATCH_SRC2</a></span> </td>
+ <td>indicates that the source 2 surface (<span class="inline_code"><a href="#src2.desc">bvbltparams.src2.desc</a></span>
+ or <span class="inline_code"><a href="#src2.tileparams">bvbltparams.src2.tileparams</a></span>, or
+ <span class="inline_code"><a href="#src2geom">bvbltparams.src2geom</a></span>) has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_MASK">BVBATCH_MASK</a></span> </td>
+ <td>indicates that the mask surface (<span class="inline_code"><a href="#mask.desc">bvbltparams.mask.desc</a></span>
+ or <span class="inline_code"><a href="#mask.tileparams">bvbltparams.mask.tileparams</a></span>, or
+ <span class="inline_code"><a href="#maskgeom">bvbltparams.maskgeom</a></span>) has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_DSTRECT_ORIGIN">BVBATCH_DSTRECT_ORIGIN</a></span></td>
+ <td>indicates that <span class="inline_code"><a href="#dstrect">bvbltparams.dstrect.left</a></span> or
+ <span class="inline_code"><a href="#dstrect">top</a></span> has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_DSTRECT_SIZE">BVBATCH_DSTRECT_SIZE</a></span></td>
+ <td>indicates that the <span class="inline_code"><a href="#dstrect">bvbltparams.dstrect.width</a></span> or
+ <a href="#dstrect">height</a> has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_SRC1RECT_ORIGIN">BVBATCH_SRC1RECT_ORIGIN</a></span></td>
+ <td>indicates that <span class="inline_code"><a href="#src1rect">bvbltparams.src1rect.left</a></span> or
+ <span class="inline_code"><a href="#dstrect">top</a></span> has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_SRC1RECT_SIZE">BVBATCH_SRC1RECT_SIZE</a></span></td>
+ <td>indicates that the <span class="inline_code"><a href="#src1rect">bvbltparams.src1rect.width</a></span> or
+ <a href="#src1rect">height</a> has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_SRC2RECT_ORIGIN">BVBATCH_SRC2RECT_ORIGIN</a></span></td>
+ <td>indicates that <span class="inline_code"><a href="#src2rect">bvbltparams.src2rect.left</a></span> or
+ <span class="inline_code"><a href="#src2rect">top</a></span> has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_SRC2RECT_SIZE">BVBATCH_SRC2RECT_SIZE</a></span></td>
+ <td>indicates that the <span class="inline_code"><a href="#src2rect">bvbltparams.src2rect.width</a></span> or
+ <a href="#src2rect">height</a> has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_MASKRECT_ORIGIN">BVBATCH_MASKRECT_ORIGIN</a></span></td>
+ <td>indicates that <span class="inline_code"><a href="#maskrect">bvbltparams.maskrect.left</a></span> or
+ <span class="inline_code"><a href="#maskrect">top</a></span> has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_MASKRECT_SIZE">BVBATCH_MASKRECT_SIZE</a></span></td>
+ <td>indicates that the <span class="inline_code"><a href="#maskrect">bvbltparams.maskrect.width</a></span> or
+ <a href="#maskrect">height</a> has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_CLIPRECT_ORIGIN">BVBATCH_CLIPRECT_ORIGIN</a></span></td>
+ <td>indicates that <span class="inline_code"><a href="#cliprect">bvbltparams.cliprect.left</a></span> or
+ <span class="inline_code"><a href="#cliprect">top</a></span> has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_CLIPRECT_SIZE">BVBATCH_CLIPRECT_SIZE</a></span></td>
+ <td>indicates that the <span class="inline_code"><a href="#cliprect">bvbltparams.cliprect.width</a></span> or
+ <a href="#cliprect">height</a> has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_TILE_SRC1">BVBATCH_TILE_SRC1</a></span></td>
+ <td>indicates that the <span class="inline_code"><a href="#src1.tileparams">bvbltparams.src1.tileparams</a></span>
+ has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_TILE_SRC2">BVBATCH_TILE_SRC2</a></span></td>
+ <td>indicates that the <span class="inline_code"><a href="#src2.tileparams">bvbltparams.src2.tileparams</a></span>
+ has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_TILE_MASK">BVBATCH_TILE_MASK</a></span></td>
+ <td>indicates that the <span class="inline_code"><a href="#mask.tileparams">bvbltparams.mask.tileparams</a></span>
+ has changed.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVBATCH_ENDNOP">BVBATCH_ENDNOP</a></span></td>
+ <td>is a special flag used with <span class="inline_code"><a href="#batch_end">BVFLAG_BATCH_END</a></span>, for
+ clients that do not have information that a batch is ending until after the last BLT has been issued.&nbsp; When
+ this flag is set, no BLT is done, but the batch is ended.</td>
+ </tr>
+</table>
+<p class="note">NOTE:&nbsp; These flags are hints, and may be used or not by a BLTsville implementation.&nbsp; So if
+<span class="inline_code"><a href="#bvbltparams">bvbltparams</a></span> members are changed between BLTs in a batch, but
+the <span class="inline_code">bvbltparams.batchflags</span> member is not correctly updated, the resulting behavior on different
+implementations will not be consistent.</p>
+<p class="Code_Header_2"><a name="batch">bvbltparams.batch</a></p>
+<p class="code_block"><a href="#bvbatch">struct bvbatch</a> *batch;</p>
+<p>This member is used as a batch handle, so that multiple batches can be under construction at the same time.</p>
+<p class="Code_Header_2"><a name="callbackfn">bvbltparams.callbackfn</a></p>
+<p class="code_block">void (*callbackfn)(<a href="#bvcallbackerror">struct bvcallbackerror</a> *err, unsigned long
+<a href="#callbackdata">callbackdata</a>);</p>
+<p>This member is a pointer to a client-supplied function which is called by the implementation when
+<span class="inline_code"><a href="#BVFLAG_ASYNC">BVFLAG_ASYNC</a></span> is set and the BLT is complete.&nbsp; If this
+member is NULL, no callback is performed.&nbsp; When there is no error, the <span class="inline_code">err</span>
+parameter will be set to 0;</p>
+<p class="note">NOTE:&nbsp; This function <span class="underline">can be called</span> before the
+<span class="inline_code"><a href="#bv_blt">bv_blt()</a></span> call has returned.</p>
+<p class="Code_Header_2"><a name="callbackdata">bvbltparams.callbackdata</a></p>
+<p class="code_block">unsigned long callbackdata;</p>
+<p>This member is used as the parameter passed back by the <span class="inline_code"><a href="#callbackfn">bvbltparams.callbackfn</a></span>.&nbsp;
+This can be anything from an identifying index to a pointer used by the client.</p>
+<p class="Code_Header_2">bvbltparams.<a name="src2auxdstrect">src2</a>/<a name="maskauxdstrect">maskauxdstrect</a></p>
+<p class="code_block">struct bvrect src2auxdstrect;<br />
+struct bvrect maskauxdstrect;</p>
+<p>These two members are used only when the associated <span class="inline_code"><a href="#BVFLAG_SRC2_AUXDSTRECT">
+BVFLAG_SRC2</a></span>/<span class="inline_code"><a href="#BVFLAG_MASK_AUXDSTRECT">MASK_AUXDSTRECT</a></span> flags are
+set.&nbsp; They are only necessary (and should only be used) in the case where scaling of the inputs differs and the
+entire source images are not being used.&nbsp; <span class="inline_code"><a href="#dstrect">bvbltparams.dstrect</a></span> is always
+used to specify the destination of source 1 image.&nbsp; When the associated flags are set, these two members are used
+to specify the destination of the source 2 and mask images, instead of <span class="inline_code"><a href="#dstrect">
+bvbltparams.dstrect</a></span>.</p>
+<p>These flags must be used with the <span class="inline_code"><a href="#BVFLAG_CLIP">BVFLAG_CLIP</a></span> flag.&nbsp;
+And if the resulting clipped destination does not include all enabled destination rectangles, the results are undefined.</p>
+<div class="example"><strong>Example:</strong>&nbsp; We have two images that we want to merge and view on an 854x480 LCD panel.&nbsp; One
+image is a small background image with 16:9 (64x36) aspect ratio that we want to stretch to fill the screen.&nbsp;
+The other is a standard definition 720x480 (4:3 aspect ratio) image with transparency we want to blend on top of our
+background.<br />
+<table align="center">
+ <tr>
+ <td>
+ <table>
+ <tr>
+ <td class="ctr"><img alt="" src="concrete-64x36.png" width="64" height="36" /></td>
+ </tr>
+ <tr>
+ <td class="ctr">(shown actual size)</td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table class="ctr">
+ <tr>
+ <td><img alt="" src="clock-720x480_4x3-fauxtrans.jpg" width="360" height="240" /></td>
+ </tr>
+ <tr>
+ <td class="ctr">(shown 1/2x; not adjusted for aspect ratio)</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+</table>
+We want to blend the second image onto the center of the first, scaling both, so that it looks like this:<br />
+<table align="center">
+ <tr>
+ <td><img alt="" src="blend-854x480.jpg" width="427" height="240" /></td>
+ </tr>
+ <tr>
+ <td class="ctr">(shown 1/2x)</td>
+ </tr>
+</table>
+The screen is effectively a 16:9 aspect ratio (we can ignore the fraction of a pixel here), which matches our
+background image.&nbsp; So the background image just needs to be scaled from 64x36 to 854x480.<br />
+<br />
+ However, since the second image has a 4:3 aspect ratio, it will not cover the entire background image if we want to
+ maintain its aspect ratio.&nbsp; Our second image is not as wide as our 16:9 image, which means it&#39;s height will match
+ the screen height, but the width will be smaller.&nbsp; Since the screen is 480 lines (pixels) high, to maintain our 4:3
+ aspect ratio, our second image will need to be 640 pixels wide (4 * 480 / 3).&nbsp; So it will need to be scaled from
+ 720x480 to 640x480.<br />
+<br />
+As we mentioned, we would like to center the 640 pixel image on our 854 pixel wide screen.&nbsp; That means the left edge
+of the image will be at pixel 107 ( (854 - 640) / 2 ).&nbsp; So the leftmost 107 columns of pixels will just be a copy
+of the left portion of the background image.&nbsp; Likewise, the rightmost 107 columns will be a copy of the right
+portion of the background image.&nbsp; Only the middle section should be blended.<br />
+<table align="center">
+ <tr>
+ <td><img alt="" src="blend-854x480-threeblts.jpg" width="427" height="240" /></td>
+ </tr>
+ <tr>
+ <td class="ctr">(shown 1/2x)</td>
+ </tr>
+</table>
+ The side two BLTs are quite easy with BLTsville, by using the clipping rectangle:<br />
+<br />
+<table class="indent"><tr><td>
+<span class="inline_code">bvbltparams.flags = BVFLAG_ROP | BVFLAG_CLIP;<br />
+bvbltparams.op.rop = 0xCCCC;<br />
+<br />
+bvbltparams.src1.desc = bkgnddesc;<br />
+bvbltparams.src1geom = bkgndgeom;<br />
+bvbltparams.src1rect.left = 0;<br />
+bvbltparams.src1rect.top = 0;<br />
+bvbltparams.src1width = 64;<br />
+bvbltparams.src1height = 36;<br />
+<br />
+bvbltparams.dstdesc = screendesc;<br />
+bvbltparams.dstgeom = screengeom;<br />
+bvbltparams.dstrect.left = 0;<br />
+bvbltparams.dstrect.top = 0;<br />
+bvbltparams.dstrect.width = 854;<br />
+bvbltparams.dstrect.height = 480;<br />
+<br />
+bvbltparams.cliprect.left = 0;<br />
+bvbltparams.cliprect.top = 0;<br />
+bvbltparams.cliprect.width = 107;<br />
+bvbltparams.cliprect.height = 480;<br />
+bv_blt(&amp;bvbltparams);<br />
+<br />
+bvbltparams.cliprect.left += 640;<br />
+bv_blt(&amp;bvbltparams);</span></td></tr></table>
+<br />
+ However, if we try the same approach with the middle BLT, we run into problems:<br />
+<br />
+<table class="indent"><tr><td>
+<span class="inline_code">bvbltparams.flags = BVFLAG_BLEND | BVFLAG_CLIP;<br />
+bvbltparams.op.blend = BVBLEND_SRC1OVER;<br />
+<br />
+bvbltparams.src1.desc = foregnddesc;<br />
+bvbltparams.src1geom = foregndgeom;<br />
+bvbltparams.src1rect.left = 0;<br />
+bvbltparams.src1rect.top = 0;<br />
+bvbltparams.src1rect.width = 720;<br />
+bvbltparams.src1rect.height = 480;<br />
+<br />
+bvbltparams.src2.desc = bkgnddesc;<br />
+bvbltparams.src2geom = bkgndgeom;<br />
+bvbltparams.src2rect.left = 0;<br />
+bvbltparams.src2rect.top = 0;<br />
+bvbltparams.src2width = 64;<br />
+bvbltparams.src2height = 36;<br />
+<br />
+bvbltparams.cliprect.left = 107;<br />
+bvbltparams.cliprect.top = 0;<br />
+bvbltparams.cliprect.width = 640;<br />
+bvbltparams.cliprect.height = 480;<br />
+bv_blt(&amp;bvbltparams);</span></td></tr></table>
+<table align="center">
+ <tr>
+ <td><img alt="" src="blend-854x480-bad.jpg" width="427" height="240" /></td>
+ </tr>
+ <tr>
+ <td class="ctr">(shown 1/2x)</td>
+ </tr>
+</table>
+ The result is that the foreground image is stretched horizontally.&nbsp; That&#39;s because the scaling factor is
+ derived from the source (1) rectangle and the destination rectangle, which is the full width of the screen.&nbsp;
+ Since we were also scaling the background, we set the destination rectangle to cover the screen, as we did in the
+ previous two BLTs.<br />
+ <br />
+ The edges of our foreground image are also cropped, since we were only modifying the middle of the screen.<br />
+ <br />
+ What if we change the destination rectangle?<br />
+ <br />
+<table class="indent"><tr><td>
+<span class="inline_code">bvbltparams.dstrect.left = 107;<br />
+bvbltparams.dstrect.top = 0;<br />
+bvbltparams.dstrect.width = 640;<br />
+bvbltparams.dstrect.height = 480;<br />
+<br />
+bv_blt(&amp;bvbltparams);</span></td></tr></table>
+<table align="center">
+ <tr>
+ <td><img alt="" src="blend-854x480-bad2.jpg" width="427" height="240" /></td>
+ </tr>
+ <tr>
+ <td class="ctr">(shown 1/2x)</td>
+ </tr>
+</table>
+ Here we get the proper scaling of the foreground image, but the background image is scaled improperly.<br />
+ <br />
+ What if we adjust the source rectangles?&nbsp;
+For our purposes, we want all of the foreground image, but we only need the middle of the background image.&nbsp; So
+ we can manually specify the middle of the background image by modifying the source 2 rectangle:<br />
+ <br />
+<table class="indent"><tr><td>
+<span class="inline_code">bvbltparams.src2rect.left = 107 * 64 / 854;<br />
+bvbltparams.src2rect.width = 640 * 64 / 854;</span></td></tr></table><br />
+Nice, but what are those values?<br />
+<br />
+<table class="indent"><tr><td>
+107 * 1280 / 854 = 8.0187...<br />
+640 * 1280 / 854 = 47.9625...<br />
+</td></tr></table>
+<br />
+ In BLTsville, all rectangle parameters are expressed in integers (this also allows BLTsville to be used in the
+ kernels where floating point variables are not allowed).&nbsp; The clipping rectangle then handles introducing the
+ necessary source pixel subdivision (by translating the clipping rectangle back to the source rectangle in the
+ implementation).&nbsp; So what happens if we actually do use these values as integers?<br />
+<br />
+<table class="indent"><tr><td>
+<span class="inline_code">bvbltparams.src2rect.left = 8;<br />
+bvbltparams.src2rect.top = 0;<br />
+bvbltparams.src2rect.width = 47;<br />
+bvbltparams.src2height = 36;<br />
+<br />
+bv_blt(&amp;bvbltparams);</span></td></tr></table>
+<br />
+ And this is what we get:<br />
+<table align="center">
+ <tr>
+ <td><img alt="" src="blend-854x480-roundingerror.jpg" width="427" height="240" /></td>
+ </tr>
+ <tr>
+ <td class="ctr">(shown 1/2x)</td>
+ </tr>
+</table>
+ Closer, but not quite.&nbsp; Rounding the values above to integers still results in visible errors at the boundaries
+ between the middle and the side BLTs (the one on the right is a bit more visible at this reduced size, but if you
+ view the full image, you&#39;ll see the left one as well), because the left edge and scaling (and right edge as a
+ result) don&#39;t match the alignment and scaling done for the BLTs on the side.&nbsp; <p class="note">NOTE:&nbsp; This artifact is not always obvious in still images.&nbsp;
+ The images here were chosen to make the artifacts obvious in this documentation.&nbsp; But even if the static images
+ appear correct, movement of the images (e.g. moving the foreground image across the background image) or changes in
+ the blending (e.g. fading the foreground image out and finally removing it), will show these less obvious
+ discrepancies.</p>This is actually what the
+ clipping rectangle is for.&nbsp; It&#39;s meant to allow us to always specify the source and destination rectangles the
+ same, but move the clipping window around on the destination to get just the pixels we want.&nbsp; That way the
+ scaling and alignment area always the same.&nbsp; Unfortunately, for this special case, we really need a way to
+ specify different scaling factors for the different inputs.&nbsp; The src2auxdstrect (and maskauxdstrect, when
+ needed) have been added to provide this capability.<br />
+ <br />
+ Here is how this set of BLTs can be done:<br />
+<br />
+<table class="indent"><tr><td>
+<span class="inline_code">bvbltparams.flags = BVFLAG_ROP | BVFLAG_CLIP;<br />
+bvbltparams.op.rop = 0xCCCC;<br />
+<br />
+bvbltparams.src1.desc = bkgnddesc;<br />
+bvbltparams.src1geom = bkgndgeom;<br />
+bvbltparams.src1rect.left = 0;<br />
+bvbltparams.src1rect.top = 0;<br />
+bvbltparams.src1width = 64;<br />
+bvbltparams.src1height = 36;<br />
+<br />
+bvbltparams.dstdesc = screendesc;<br />
+bvbltparams.dstgeom = screengeom;<br />
+bvbltparams.dstrect.left = 0;<br />
+bvbltparams.dstrect.top = 0;<br />
+bvbltparams.dstrect.width = 854;<br />
+bvbltparams.dstrect.height = 480;<br />
+<br />
+bvbltparams.cliprect.left = 0;<br />
+bvbltparams.cliprect.top = 0;<br />
+bvbltparams.cliprect.width = 107;<br />
+bvbltparams.cliprect.height = 480;<br />
+bv_blt(&amp;bvbltparams);<br />
+<br />
+bvbltparams.cliprect.left += 640;<br />
+bv_blt(&amp;bvbltparams);<br />
+<br />
+bvbltparams.flags = BVFLAG_BLEND | BVFLAG_CLIP | BVFLAG_SRC2_AUXDSTRECT;<br />
+bvbltparams.op.blend = BVBLEND_SRC1OVER;<br />
+<br />
+bvbltparams.src1.desc = foregnddesc;<br />
+bvbltparams.src1geom = foregndgeom;<br />
+bvbltparams.src1rect.left = 0;<br />
+bvbltparams.src1rect.top = 0;<br />
+bvbltparams.src1rect.width = 720;<br />
+bvbltparams.src1rect.height = 480;<br />
+<br />
+bvbltparams.dstrect.left = 107;<br />
+bvbltparams.dstrect.top = 0;<br />
+bvbltparams.dstrect.width = 640;<br />
+bvbltparams.dstrect.height = 480;<br />
+<br />
+bvbltparams.src2.desc = bkgnddesc;<br />
+bvbltparams.src2geom = bkgndgeom;<br />
+bvbltparams.src2rect.left = 0;<br />
+bvbltparams.src2rect.top = 0;<br />
+bvbltparams.src2width = 64;<br />
+bvbltparams.src2height = 36;<br />
+<br />
+bvbltparams.src2auxdstrect.left = 0;<br />
+bvbltparams.src2auxdstrect.top = 0;<br />
+bvbltparams.src2auxdstrect.width = 854;<br />
+bvbltparams.src2auxdstrect.height = 480;<br />
+<br />
+bvbltparams.cliprect.left = 107;<br />
+bvbltparams.cliprect.top = 0;<br />
+bvbltparams.cliprect.width = 640;<br />
+bvbltparams.cliprect.height = 480;<br />
+bv_blt(&amp;bvbltparams);</span></td></tr></table>
+<br />
+Using this approach, we get the desired output:<br />
+<table align="center">
+ <tr>
+ <td><img alt="" src="blend-854x480.jpg" width="427" height="240" /></td>
+ </tr>
+ <tr>
+ <td class="ctr">(shown 1/2x)</td>
+ </tr>
+</table>
+ It may also be clear that in that last BLT, the clip rectangle isn&#39;t really necessary.&nbsp; This is good, because
+ it frees up the clipping rectangle to be used to further subdivide the image if necessary (e.g. if partially
+ occluded).<br />
+</div>
+<br />
+<hr />
+<p class="Code_Header"><a name="bvrect">bvrect</a></p>
+<p class="small_code_block">struct bvrect {<br />
+&nbsp;&nbsp;&nbsp; int <a href="#bvrect.left">left</a>;<br />
+&nbsp;&nbsp;&nbsp; int <a href="#bvrect.top">top</a>;<br />
+&nbsp;&nbsp;&nbsp; unsigned int <a href="#bvrect.width">width</a>;<br />
+&nbsp;&nbsp;&nbsp; unsigned int <a href="#bvrect.height">height</a>;<br />
+};</p>
+<p class="Code_Header_2"><a name="bvrect.left">bvrect.left</a></p>
+<p class="code_block">int left;</p>
+<p>This member indicates the left edge of the rectangle, measured in pixels from the left edge of the surface.&nbsp; Note
+that this value <span class="underline">can</span> be negative, indicating that the rectangle begins before the left edge
+of the surface.&nbsp; However, this is only allowed when a rectangle is clipped to the surface.&nbsp; If, after clipping,
+the left edge of the rectangle is still negative, this is an error.</p>
+<p class="Code_Header_2"><a name="bvrect.top">bvrect.top</a></p>
+<p class="code_block">int top;</p>
+<p>This member indicates the top edge of the rectangle, measured in lines of
+<a href="#bfbuffdesc.virtstride" class="inline_code">bvbuffdesc.virtstride</a> bytes from the top edge of the surface.&nbsp;
+Note that this value <span class="underline">can</span> be negative, indicating that the rectangle begins before the top
+edge of the surface.&nbsp; However, this is only allowed when a rectangle is clipped to the surface.&nbsp; If, after clipping,
+the top edge of the rectangle is still negative, this is an error.</p>
+<p class="Code_Header_2"><a name="bvrect.width">bvrect.width</a></p>
+<p class="code_block">unsigned int width;</p>
+<p>This member indicates the width of the rectangle, measured in pixels.&nbsp; Note that this value
+<span class="underline">cannot</span> be negative.&nbsp; (Horizontal flipping is indicated using the
+<span class="inline_code"><a href="#BVFLAG_HORZ_FLIP">BVFLAG_HORZ_FLIP_*</a></span> flags.)&nbsp; The value of this member
+may exceed the width of the associated surface.&nbsp; However, this is only allowed when a rectangle is clipped to the surface.&nbsp;
+If, after clipping, the right edge of the rectangle still exceeds the width of the surface, this is an error.</p>
+<p class="Code_Header_2"><a name="bvrect.height">bvrect.height</a></p>
+<p class="code_block">unsigned int height;</p>
+<p>This member indicates the height of the rectangle, measured in lines of <span class="inline_code">
+<a href="#bvbuffdesc.virtstride">bvbuffdesc.virtstride</a></span> bytes.&nbsp; Note that this value
+<span class="underline">cannot</span> be negative.&nbsp; (Vertical flipping is indicated using the
+<span class="inline_code"><a href="#BVFLAG_VERT_FLIP">BVFLAG_VERT_FLIP_*</a></span> flags.)&nbsp; The value of this member
+may exceed the width of the associated surface.&nbsp; However, this is only allowed when a rectangle is clipped to the surface.&nbsp;
+If, after clipping, the right edge of the rectangle still exceeds the height of the surface, this is an error.</p>
+<hr />
+<a name="bvcopparams" class="Code_Header">bvcopparams</a>
+<p><span class="inline_code">bvcopparams</span> is used to define the cache operation to be performed by
+<span class="inline_code"><a href="#bv_cache">bv_cache()</a></span>.</p>
+<p class="small_code_block">struct bvcopparams {<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int <a href="#bvcopparams.structsize">structsize</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bvbuffdesc">struct bvbuffdesc</a> *<a href="#bvcopparams.desc">desc</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bvsurfgeom">struct bvsurfgeom</a> *<a href="#bvcopparams.geom">geom</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bvrect">struct bvrect</a>&nbsp;&nbsp;&nbsp;&nbsp; *<a href="#bvcopparams.rect">rect</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enum bvcacheop&nbsp; <a href="#bvcopparams.cacheop">cacheop</a>;<br />
+};</p>
+<a name="bvcopparams.structsize" class="Code_Header_2">bvcopparams.structsize</a>
+<p><span class="code_block">unsigned long structsize; /* input */</span></p>
+<p>This member is used for compatibility between BLTsville versions.&nbsp; (See <span class="inline_code">
+<a href="#bvbltparams.structsize">bvbltparams.structsize</a></span> for an explanation.) </p>
+<p class="Code_Header_2"><a name="bvcopparams.desc">bvcopparams.desc</a></p>
+<p class="code_block"><a href="#bvbuffdesc">struct bvbuffdesc</a> *desc;</p>
+<p>This member points to the <span class="inline_code"><a href="#bvbuffdesc">bvbuffdesc</a></span> of the surface for which
+the cache is being manipulated.&nbsp; This buffer should have been mapped with a call to <span class="inline_code">
+<a href="#bv_map">bv_map()</a></span>.</p>
+<p class="note">NOTE:&nbsp; Implementations may choose to dynamically map the surface as with <span class="inline_code">
+<a href="#bv_blt">bv_blt()</a></span>, however in many systems, this will not function properly due to dynamic paging which
+can occur when a surface is not locked.</p>
+<p><span class="Code_Header_2"><a name="bvcopparams.geom">bvcopparams.geom</a></span></p>
+<p class="code_block"><a href="#bvsurfgeom">struct bvsurfgeom</a> *geom;</p>
+<p>This member points to the <span class="inline_code"><a href="#bvsurfgeom">bvsurfgeom</a></span> of the surface for which
+the cache is being manipulated.</p>
+<p><span class="Code_Header_2"><a name="bvcopparams.rect">bvcopparams.rect</a></span></p>
+<p class="code_block"><a href="#bvrect">struct bvrect</a> *rect;</p>
+<p>This member points to the <span class="inline_code"><a href="bvrect">bvrect</a></span> describing the rectangle of the
+surface which is being manipulated.</p>
+<p><span class="Code_Header_2"><a name="bvcopparams.cacheop">bvcopparams.cacheop</a></span></p>
+<p class="code_block">enum bvcacheop cacheop;</p>
+<p>This member specifies the cache operation to be performed.&nbsp; It is an enumeration from the following list:</p>
+<table style="" class="indent">
+ <tr>
+ <td><span class="inline_code"><a name="BVCACHE_BIDIRECTIONAL">BVCACHE_BIDIRECTIONAL</a></span></td>
+ <td>(This usually performs a cache flush operation.)</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVCACHE_CPU_TO_DEVICE">BVCACHE_CPU_TO_DEVICE</a></span></td>
+ <td>Performs the appropriate cache operation to ensure data can be transferred correctly when it was written with
+ the CPU, but will be read by the 2-D device.&nbsp; (This is usually a cache clean operation.)</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVCACHE_CPU_FROM_DEVICE">BVCACHE_CPU_FROM_DEVICE</a></span></td>
+ <td>Performs the appropriate cache operation to ensure data can be transferred correctly when it was written by
+ the 2-D device, but will be read by the CPU.&nbsp; (This is usually a cache invalidate operation.)</td>
+ </tr>
+</table>
+<br />
+<hr />
+<p class="Code_Header"><a name="bvbuffdesc">bvbuffdesc</a></p>
+<p>This structure is used in conjunction with a <span class="inline_code"><a href="#bvsurfgeom">bvsurfgeom</a></span> structure
+to specify the characteristics of a graphic surface.&nbsp; This structure specifies the memory buffer itself.</p>
+<p class="small_code_block">struct bvbuffdesc {<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int <a href="#bvbuffdesc.structsize">structsize</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void *<a href="#bvbuffdesc.virtaddr">virtaddr</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long <a href="#bvbuffdesc.length">length</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bvbuffmap">struct bvbuffmap</a> *<a href="#bvbuffdesc.map">map</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enum bvauxtype <a href="#bvbuffdesc.auxtype">auxtype</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void *<a href="#bvbuffdesc.auxptr">auxptr</a>;<br />
+};</p>
+<p class="Code_Header_2"><a name="bvbuffdesc.structsize">bvbuffdesc.structsize</a></p>
+<p class="code_block">unsigned int structsize;</p>
+<p>This member is used for compatibility between BLTsville versions.&nbsp; (See <span class="inline_code">
+<a href="#bvbltparams.structsize">bvbltparams.structsize</a></span> for an explanation.) </p>
+<p class="Code_Header_2"><a name="bvbuffdesc.virtaddr">bvbuffdesc.virtaddr</a></p>
+<p class="code_block">void *virtaddr;</p>
+<p>This member is used to indicate the CPU virtual address of the start of the buffer.&nbsp; This value must be provided
+unless the <span class="inline_code"><a href="#bvbuffdesc.auxtype">auxtype</a></span>/<span class="inline_code"><a href="#bvbuffdesc.auxptr">auxptr</a></span>
+members below are used.&nbsp; At that time, this member is optional, and the <span class="inline_code">
+<a href="#auxptr">auxptr</a></span> usually has higher priority than this member.</p>
+<p class="imponly"><strong>Implementations Only</strong><br />
+<br />
+Note that this is always the beginning of the buffer.&nbsp; This means that if the <span class="inline_code">
+<a href="#bvsurfgeom.virtaddr">bvsurfgeom.virtstride</a></span> is negative, or the <a href="#bvsurfgeom.orientation">bvsurfgeom.orientation</a>
+does not normalize to 0º&nbsp; (i.e. <span class="inline_code">orientation % 360 != 0</span>), implementations may need
+to use a modified version of <span class="inline_code">virtaddr</span> internally to operate correctly.</p>
+<p class="Code_Header_2"><a name="bvbuffdesc.length">bvbuffdesc.length</a></p>
+<p class="code_block">unsigned long length;</p>
+<p>This member specifies the length of the buffer in bytes.</p>
+<p class="note">NOTE:&nbsp; When used with a <span class="inline_code"><a href="#bvsurfgeom">bvsurfgeom</a></span> structure,
+<span class="inline_code">length</span> should be greater than or equal to <span class="inline_code">
+<a href="#bvsurfgeom.height">bvsurfgeom.height</a> * <a href="#bvsurfgeom.virtstride">bvsurfgeom.virtstride</a></span>.</p>
+<p class="Code_Header_2"><a name="bvbuffdesc.map">bvbuffdesc.map</a></p>
+<p class="code_block">struct bvbuffmap *map;</p>
+<p>This member is used by the implementations and should <span class="underline"><strong>NEVER</strong></span> be manipulated
+by the client.&nbsp; When the <span class="inline_code">bvbuffdesc</span> structure is created, this member should be set
+to 0, indicating that no implementations have mapped the buffer.&nbsp; After a buffer has been mapped using a call to
+<span class="inline_code"><a href="#bv_map">bv_map()</a></span>, this member should be left as-is by clients.&nbsp; (The
+implementation will set this back to 0 before returning from <span class="inline_code"><a href="#bv_unmap">bv_unmap()</a></span>.)</p>
+<p class="imponly"><strong>Implementations Only</strong><br />
+<br />
+This member points to a linked list of <span class="inline_code"><a href="#bvbuffmap">bvbuffmap</a></span> structures associated
+with the buffer.&nbsp; Each <span class="inline_code"><a href="#bvbuffmap">bvbuffmap</a></span> is added to the list as
+the buffer is mapped by a given implementation.&nbsp; This may be done with an explicit call to
+<span class="inline_code"><a href="#bv_map">bv_map()</a></span>, or implicitly with a call to <span class="inline_code">
+<a href="#bv_blt">bv_blt()</a></span>, after a call to <span class="inline_code"><a href="#bv_map">bv_map()</a></span> from
+a different implementation.<br />
+<br />
+Implementations should not assume that the first entry in the list is their <span class="inline_code">
+<a href="#bvbuffmap">bvbuffmap</a></span>.&nbsp; Instead, implementations should compare the <span class="inline_code">
+<a href="#bv_unmap">bv_unmap()</a></span> pointer in the structure to their own function address.</p>
+<p class="Code_Header_2"><a name="bvbuffdesc.auxtype">bvbuffdesc.auxtype</a></p>
+<p class="code_block">enum bvauxtype auxtype;</p>
+<p>This member is used to identify the type of additional information about the buffer provided by
+<span class="inline_code"><a href="#bvbuffdesc.auxptr">auxptr</a></span>.&nbsp; Currently no values are defined for the
+user mode interface, so it should be initialized to 0 or <span class="inline_code">BVAT_NONE</span>.&nbsp; See the
+<a href="#Kernel_Mode_Interface">Kernel Mode Interface</a> for details on the values defined for the kernel mode interface.</p>
+<p class="Code_Header_2"><a name="bvbuffdesc.auxptr">bvbuffdesc.auxptr</a></p>
+<p class="code_block">void *auxptr;</p>
+<p>This member is used to point to additional information about the buffer.&nbsp; The type of this pointer is determined
+by the <span class="inline_code"><a href="#auxtype">auxtype</a></span> value.&nbsp; Currently there are no types defined
+for the user mode interface, so this member is ignored.&nbsp; See the <a href="#Kernel_Mode_Interface">Kernel Mode Interface</a>
+for details on the types defined for the kernel mode interface. </p>
+<hr /><br />
+<table style="" class="imponly">
+ <tr>
+ <td>
+ <p><strong>Implementations Only</strong></p>
+ <p class="Code_Header"><a name="bvbuffmap">bvbuffmap</a></p>
+ <p>This structure is used from the bvbuffdesc.map member to allow implementations to associate their own data with
+ a buffer.</p>
+ <p class="small_code_block"><span class="small_code_block_in_table">struct bvbuffmap {<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int <a href="#bvbuffmap.structsize">structsize</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BVFN_UNMAP <a href="#bvbuffmap.bv_unmap">bv_unmap</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long <a href="#bvbuffmap.handle">handle</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct bvbuffmap *<a href="#bvbuffmap.nextmap">nextmap</a>;<br />
+ };</span></p>
+ <p class="Code_Header_2"><a name="bvbuffmap.structsize">bvbuffmap.structsize</a></p>
+ <p class="code_block">unsigned int structsize;</p>
+ <p>This member is used for compatibility between BLTsville versions.&nbsp; (See <span class="inline_code">
+ <a href="#bvbltparams.structsize">bvbltparams.structsize</a></span> for an explanation.) </p>
+ <p class="Code_Header_2"><a name="bvbuffmap.bv_unmap">bvbuffmap.bv_unmap</a></p>
+ <p class="code_block">BVFN_UNMAP bv_unmap;</p>
+ <p>This member holds the pointer to the <span class="inline_code"><a href="#bv_unmap">bv_unmap()</a></span> function
+ of the implementation associated with the <span class="inline_code">bvbuffmap</span> structure.&nbsp; It serves
+ to allow implementations to identify their <span class="inline_code">bvbuffmap</span> structure in the linked list,
+ as well as to allow implementations to call each other&#39;s <span class="inline_code"><a href="#bv_unmap">bv_unmap()</a></span>
+ calls from their own.</p>
+ <p class="Code_Header_2"><a name="bvbuffmap.handle">bvbuffmap.handle</a></p>
+ <p class="code_block">unsigned long handle;</p>
+ <p>This member is used to hold an implementation-specific piece of data.</p>
+ <p class="Code_Header_2"><a name="bvbuffmap.nextmap">bvbuffmap.nextmap</a></p>
+ <p class="code_block">struct bvbuffmap *nextmap;</p>
+ <p>This member holds a pointer to the next bvbuffmap structure in the linked list.&nbsp; If this member is 0, there
+ are no more entries in the list.<br />
+ <br />
+ <span class="note">NOTE:&nbsp; The Linux/Android Kernel Mode Interface differs slightly from this structure.&nbsp;
+ Refer to the <a href="#Kernel_Mode_Interface">Kernel Mode Interface</a> section for details.</span></p>
+ </td>
+ </tr>
+</table>
+<br />
+<hr />
+<p class="Code_Header"><a name="bvsurfgeom">bvsurfgeom</a></p>
+<p>This structure is used in conjunction with a <span class="inline_code"><a href="#bvbuffdesc">bvbuffdesc</a></span> structure
+to specify the characteristics of a graphic surface.&nbsp; This structure specifies the surface geometric characteristics.</p>
+<p class="note">NOTE:&nbsp; This structure was separated from <span class="inline_code"><a href="#bvbuffdesc">bvbuffdesc</a></span>
+to afford much flexibility to the client.&nbsp; Using the same <span class="inline_code"><a href="#bvbuffdesc">bvbuffdesc</a></span>
+structure with different <span class="inline_code">bvsurfgeom</span> structures or using the same
+<span class="inline_code">bvsurfgeom</span> structure with different <span class="inline_code"><a href="#bvbuffdesc">bvbuffdesc</a></span>
+structures may be of benefit.&nbsp; See the <a href="#bvsurfgeom_examples">examples</a> at the bottom of this section.</p>
+<p class="small_code_block">struct bvcopparams {<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int <a href="#bvsurfgeom.structsize">structsize</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://graphics.github.com/ocd/">enum ocdformat</a> format;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int width;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int height;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int orientation;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long virtstride;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://graphics.github.com/ocd/">enum ocdformat</a> paletteformat;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void *palette;<br />
+};</p>
+<p class="Code_Header_2"><a name="bvsurfgeom.structsize">bvsurfgeom.structsize</a></p>
+<p class="inline_code">unsigned int structsize;</p>
+<p>This member is used for compatibility between BLTsville versions.&nbsp; (See <span class="inline_code">
+<a href="#bvbltparams.structsize">bvbltparams.structsize</a></span> for an explanation.) </p>
+<p class="Code_Header_2"><a name="bvsurfgeom.format">bvsurfgeom.format</a></p>
+<p class="code_block"><a href="http://graphics.github.com/ocd/">enum ocdformat</a> format;</p>
+<p>This member specifies the format of the surface using the <a href="http://graphics.github.com/ocd">Open Color format
+Definitions (OCD)</a>.</p>
+<p class="Code_Header_2"><a name="bvsurfgeom.width">bvsurfgeom.width</a></p>
+<p class="code_block">unsigned int width;</p>
+<p>This member specifies the width of the surface in pixels.&nbsp; This size does not have to be equivalent to the
+<span class="inline_code"><a href="#bvsurfgeom.virtstride">virtstride</a></span> size.</p>
+<p class="imponly"><strong>Implementations Only</strong><br />
+<br />
+Implementations should never assume that <span class="inline_code">width</span> is equivalent to
+<span class="inline_code"><a href="#bvsurfgeom.virtstride">virtstride</a></span>.</p>
+<p class="Code_Header_2"><a name="bvsurfgeom.height">bvsurfgeom.height</a></p>
+<p class="code_block">unsigned int height;</p>
+<p>This member specifies the height of the surface in lines of <span class="inline_code">
+<a href="#bvsurfgeom.virtstride">virtstride</a></span> width.</p>
+<p class="Code_Header_2"><a name="bvsurfgeom.orientation">bvsurfgeom.orientation</a></p>
+<p class="code_block">int orientation;</p>
+<p>This member specifies the orientation or angle of the surface in degrees.&nbsp; Since BLTsville is designed only to specify
+orthogonal rectangles, this value must be a multiple of 90º.&nbsp; This value <span class="underline">may</span> be negative.&nbsp;
+<em>(Extending BLTsville to handle non-orthogonal rectangles may be considered if there is sufficient interest.)</em></p>
+<p class="imponly"><strong>Implementations Only</strong><br />
+<br />
+Implementations should normalize orientation angles.&nbsp; For example, a client that sets the orientation to -450º should
+behave as if the value of 270º were specified. </p>
+<p class="Code_Header_2"><a name="bvsurfgeom.virtstride">bvsurfgeom.virtstride</a></p>
+<p class="code_block">long virtstride;</p>
+<p>This member specifies the horizontal stride of the surface in bytes for an unrotated surface.&nbsp; The stride represents
+the number of bytes needed to move from one pixel to the pixel immediately below it.&nbsp; This value
+<span class="underline">may</span> be negative.</p>
+<p class="note">NOTE:&nbsp; This means the <span class="inline_code">orientation</span> does not affect the
+<span class="inline_code">virtstride</span>.&nbsp; However, rotating a surface usually results in a different configuration
+(i.e. <span class="inline_code">width</span>), which <span class="underline">will</span> affect the
+<span class="inline_code">virtstride</span>.&nbsp; For example, a 320 x 240 x 32 bpp 0º surface might have a
+<span class="inline_code">virtstride</span> of 1280 bytes (320 pixels/line * 32 bits/pixel / 8 bits/byte).&nbsp; When the
+orientation is set to 180º, the <span class="inline_code">virtstride</span> would be the same.&nbsp; But when the orientation
+is set to 90º (or 270º), the <span class="inline_code">virtstride</span> would most likely need to be set to 960 bytes (240
+pixels/line * 32 bits/pixel / 8 bits/byte). </p>
+<p class="imponly"><strong>Implementations Only</strong><br />
+<br />
+Implementations that do not support a negative <span class="inline_code">virtstride</span> must compensate using whatever
+mechanism is appropriate for the implementation.&nbsp; For example, using a vertical flipping/mirroring setting.</p>
+<p class="note">NOTE:&nbsp; The <span class="inline_code">virtstride</span> name must be maintained for backwards compatibility.&nbsp;
+However, no situation should arise where the client would need to provide two different strides for the virtual and physical
+views of a surface (there are situations where a physical stride will need to be available within the implementation, but
+the client will not be the one to supply it), so <em>physstride</em> will most likely never be needed.&nbsp; However, when
+a client provides a physical description of the buffer (see the <a href="#Kernel_Mode_Interface">Kernel Mode Interface</a>
+section below), the <span class="inline_code">virtstride</span> entry should be used to provide the physical stride.</p>
+<p class="Code_Header_2"><a name="bvsurfgeom.paletteformat">bvsurfgeom.paletteformat</a></p>
+<p class="code_block"><a href="http://graphics.github.com/ocd/">enum ocdformat</a> paletteformat;</p>
+<p>This member specifies the format of the palette supplied via the <span class="inline_code">
+<a href="#bvsurfgeom.palette">palette</a></span> member for palettized formats using the
+<a href="http://graphics.github.com/ocd">Open Color format Definitions (OCD)</a>.</p>
+<p class="Code_Header_2"><a name="bvsurfgeom.palette">bvsurfgeom.palette</a></p>
+<p class="code_block">void *palette;</p>
+<p>This member points to a palette used for palettized formats.&nbsp; The format of the palette is specified by the
+<span class="inline_code"><a href="#bvsurfgeom.palette">paletteformat</a></span> member.&nbsp; Palettes are packed based
+on their container size:</p>
+<table class="indent">
+ <tr>
+ <td class="ctr_thin_bord"><strong>Palette Format</strong></td>
+ <td class="ctr_thin_bord"><strong>Palette Layout (byte address)</strong></td>
+ <td class="ctr_thin_bord"><strong>Palette Layout (little endian)</strong></td>
+ </tr>
+ <tr class="small_code_block_in_table">
+ <td class="thin_bord">OCDFMT_xRGB12</td>
+ <td class="ctr_thin_bord">n/a</td>
+ <td class="thin_bord">
+ <table style="width: 100%">
+ <tr>
+ <td class="thin_bord">*(((unsigned short *)palette) + 0)</td>
+ <td class="thin_bord">0xFrgb</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned short *)palette) + 1)</td>
+ <td class="thin_bord">0xFrgb</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">...</td>
+ <td class="thin_bord">...</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned short *)palette) + n - 1)</td>
+ <td class="thin_bord">0xFrgb</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr class="small_code_block_in_table">
+ <td class="thin_bord">OCDFMT_RGB24</td>
+ <td class="thin_bord">
+ <table style="width: 100%">
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + 0)</td>
+ <td class="thin_bord">red0</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + 1)</td>
+ <td class="thin_bord">green0</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + 2)</td>
+ <td class="thin_bord">blue0</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + 3)</td>
+ <td class="thin_bord">red1</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + 4)</td>
+ <td class="thin_bord">green1</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + 5)</td>
+ <td class="thin_bord">blue1</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">...</td>
+ <td class="thin_bord">&nbsp;</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + (3 * n) - 3)</td>
+ <td class="thin_bord">redNm1</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + (3 * n) - 2)</td>
+ <td class="thin_bord">greenNm1</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + (3 * n) - 1)</td>
+ <td class="thin_bord">blueNm1</td>
+ </tr>
+ </table>
+ </td>
+ <td class="ctr_thin_bord">n/a</td>
+ </tr>
+ <tr class="small_code_block_in_table">
+ <td class="thin_bord">OCDFMT_RGBx24</td>
+ <td class="thin_bord">
+ <table style="width: 100%">
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + 0)</td>
+ <td class="thin_bord">red0</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + 1)</td>
+ <td class="thin_bord">green0</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + 2)</td>
+ <td class="thin_bord">blue0</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + 3)</td>
+ <td class="thin_bord">0xFF</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + 4)</td>
+ <td class="thin_bord">red1</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + 5)</td>
+ <td class="thin_bord">green1</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + 6)</td>
+ <td class="thin_bord">blue1</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + 7)</td>
+ <td class="thin_bord">0xFF</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">...</td>
+ <td class="thin_bord">&nbsp;</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + (4 * n) - 4)</td>
+ <td class="thin_bord">redNm1</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + (4 * n) - 3)</td>
+ <td class="thin_bord">greenNm1</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + (4 * n) - 2)</td>
+ <td class="thin_bord">blueNm1</td>
+ </tr>
+ <tr>
+ <td class="thin_bord">*(((unsigned char *)palette) + (4 * n) - 1)</td>
+ <td class="thin_bord">0xFF</td>
+ </tr>
+ </table>
+ </td>
+ <td class="thin_bord">
+ <table style="width: 100%">
+ <tr>
+ <td class="thin_bord">*(((unsigned long *)palette) + 0)</td>
+ <td class="thin_bord">0xFFbbggrr<br />
+ </td>
+ </tr>
+ <tr class="thin_bord">
+ <td class="thin_bord">&nbsp;</td>
+ <td class="thin_bord">&nbsp;</td>
+ </tr>
+ <tr class="thin_bord">
+ <td class="thin_bord">&nbsp;</td>
+ <td class="thin_bord">&nbsp;</td>
+ </tr>
+ <tr class="thin_bord">
+ <td class="thin_bord">&nbsp;</td>
+ <td class="thin_bord">&nbsp;</td>
+ </tr>
+ <tr class="thin_bord">
+ <td class="thin_bord">*(((unsigned long *)palette) + 1)<br />
+ </td>
+ <td class="thin_bord">0xFFbbggrr<br />
+ </td>
+ </tr>
+ <tr class="thin_bord">
+ <td class="thin_bord">&nbsp;</td>
+ <td class="thin_bord">&nbsp;</td>
+ </tr>
+ <tr class="thin_bord">
+ <td class="thin_bord">&nbsp;</td>
+ <td class="thin_bord">&nbsp;</td>
+ </tr>
+ <tr class="thin_bord">
+ <td class="thin_bord">&nbsp;</td>
+ <td class="thin_bord">&nbsp;</td>
+ </tr>
+ <tr class="thin_bord">
+ <td class="thin_bord">...</td>
+ <td class="thin_bord">&nbsp;</td>
+ </tr>
+ <tr class="thin_bord">
+ <td class="thin_bord">*(((unsigned long *)palette) + n - 1)|<br />
+ </td>
+ <td class="thin_bord">0xFFbbggrr<br />
+ </td>
+ </tr>
+ <tr class="thin_bord">
+ <td class="thin_bord">&nbsp;</td>
+ <td class="thin_bord">&nbsp;</td>
+ </tr>
+ <tr class="thin_bord">
+ <td class="thin_bord">&nbsp;</td>
+ <td class="thin_bord">&nbsp;</td>
+ </tr>
+ <tr class="thin_bord">
+ <td class="thin_bord">&nbsp;</td>
+ <td class="thin_bord">&nbsp;</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+</table>
+<p class="note">NOTE:&nbsp; Use of subsampled formats for <span class="inline_code">paletteformat</span> is currently undefined.</p>
+<p class="Header4"><a name="bvsurfgeom_examples">Examples</a></p>
+<p>Mixing and matching <span class="inline_code"><a href="#bvbuffdesc">bvbuffdesc</a></span> and
+<span class="inline_code">bvsurfgeom</span> structures provides maximum flexibility for a client.</p>
+<table style="width: 100%" class="example">
+ <tr>
+ <td><strong>Example:</strong>&nbsp; Using two different <span class="inline_code">bvsurfgeom</span> structures with
+ the same <span class="inline_code"><a href="#bvbuffdesc">bvbuffdesc</a></span> structure allows in-place format
+ conversion:</td>
+ </tr>
+ <tr>
+ <td>
+ <p class="indent"><span class="small_code_block_in_table">...<br />
+ // Convert premultiplied image to non-premultiplied in place<br />
+ struct
+ bvbltparams parms;<br />
+ ...<br />
+ struct
+ bvbuffdesc buff;<br />
+ ...<br />
+ struct
+ bvsurfgeom srcgeom, dstgeom;<br />
+ ...<br />
+ srcgeom.format = OCDFMT_RGBA24;<br />
+ dstgeom.format = OCDFMT_nRGBA24;<br />
+ ...<br />
+ parms.src1.desc = &amp;buff;<br />
+ parms.src1geom = &amp;srcgeom;<br />
+ parms.dstdesc = &amp;buff;<br />
+ parms.dstgeom = &amp;dstgeom;<br />
+ ...<br />
+ bv_blt(&amp;parms);<br />
+ ... </span></p>
+ </td>
+ </tr>
+</table>
+<br />
+<table style="width: 100%" class="example">
+ <tr>
+ <td><strong>Example:</strong>&nbsp; Using three different <span class="inline_code"><a href="#bvbuffdesc">bvbuffdesc</a></span>
+ structures with the same <span class="inline_code">bvsurfgeom</span> structure reduces code and copy errors:</td>
+ </tr>
+ <tr>
+ <td>
+ <p class="indent"><span class="small_code_block_in_table">...<br />
+ // Blend two images of the same size<br />
+ struct
+ bvbltparams parms;<br />
+ ...<br />
+ struct
+ bvbuffdesc src1buff, src2buff, dstbuff;<br />
+ ...<br />
+ struct
+ bvsurfgeom geom;<br />
+ ...<br />
+ parms.src1.desc = &amp;src1buff;<br />
+ parms.src1geom = &amp;geom;<br />
+ parms.src2.desc = &amp;src2buff;<br />
+ parms.src2geom = &amp;geom;<br />
+ parms.dstdesc = &amp;dstbuff;<br />
+ parms.dstgeom = &amp;dstgeom;<br />
+ ...<br />
+ bv_blt(&amp;parms);<br />
+ ... </span></p>
+ </td>
+ </tr>
+</table>
+<br />
+<hr />
+<p class="Code_Header"><a name="bvtileparams">bvtileparams</a></p>
+<p>This structure is used to define the parameters necessary to use a small image as a tile or block that will be repeated
+when used as a source.&nbsp; This structure is used in conjunction with the associated <span class="inline_code">
+<a href="#bvsurfgeom">bvsurfgeom</a></span> and the associated <span class="inline_code"><a href="#bvrect">bvrect</a></span>
+to determine the operation that is performed.</p>
+<p class="small_code_block">struct bvcopparams {<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int <a href="#bvtileparams.structsize">structsize</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long <a href="#bvtileparams.flags">flags</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void *<a href="#bvtileparams.virtaddr">virtaddr</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int <a href="#bvtileparams.dstleft">dstleft</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int <a href="#bvtileparams.dsttop">dsttop</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int <a href="#bvtileparams.srcwidth">srcwidth</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int <a href="#bvtileparams.srcheight">srcheight</a>;<br />
+};</p>
+<p class="Code_Header_2"><a name="bvtileparams.structsize">bvtileparams.structsize</a></p>
+<p class="code_block">unsigned int structsize;</p>
+<p>This member is used for compatibility between BLTsville versions.&nbsp; (See <span class="inline_code">
+<a href="#bvbltparams.structsize">bvbltparams.structsize</a></span> for an explanation.) </p>
+<p class="Code_Header_2"><a name="bvtileparams.flags">bvtileparams.flags</a></p>
+<p class="code_block">unsigned long flags;</p>
+<p>This member specifies some additional information for the tiling operation.&nbsp; It can be composed as the binary OR
+of one selection for each edge (left, top, right, and bottom) from the following flags:</p>
+<table style="" class="indent">
+ <tr>
+ <td><span class="inline_code"><a name="BVTILE_LEFT_REPEAT">BVTILE_LEFT_REPEAT</a></span></td>
+ <td>indicates that the tile is repeated to the left of the destination alignment location.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVTILE_TOP_REPEAT">BVTILE_TOP_REPEAT</a></span></td>
+ <td>indicates that the tile is repeated above the destination alignment location.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVTILE_RIGHT_REPEAT">BVTILE_RIGHT_REPEAT</a></span></td>
+ <td>indicates that the tile is repeated to the right of the destination alignment location.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVTILE_BOTTOM_REPEAT">BVTILE_BOTTOM_REPEAT</a></span></td>
+ <td>indicates that the tile is repeated below the destination alignment location.</td>
+ </tr>
+ <tr>
+ <td><a name="BVTILE_LEFT_MIRROR" class="inline_code">BVTILE_LEFT_MIRROR</a></td>
+ <td>indicates that the tile is mirrored to the left of the destination alignment location.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVTILE_TOP_MIRROR">BVTILE_TOP_MIRROR</a></span></td>
+ <td>indicates that the tile is mirrored above the destination alignment location.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVTILE_RIGHT_MIRROR">BVTILE_RIGHT_MIRROR</a></span></td>
+ <td>indicates that the tile is mirrored to the right of the destination alignment location.</td>
+ </tr>
+ <tr>
+ <td><span class="inline_code"><a name="BVTILE_BOTTOM_MIRROR">BVTILE_BOTTOM_MIRROR</a></span></td>
+ <td>indicates that the tile is mirrored below the destination alignment location.</td>
+ </tr>
+</table>
+<p class="Code_Header_2"><a name="bvtileparams.virtaddr">bvtileparams.virtaddr</a></p>
+<p class="code_block">void *virtaddr;</p>
+<p>This member is used to indicate the CPU virtual address of the start of the buffer.</p>
+<p class="imponly"><strong>Implementations Only</strong><br />
+<br />
+Note that this is always the beginning of the buffer.&nbsp; This means that if the <span class="inline_code">
+<a href="#bvsurfgeom.virtaddr">bvsurfgeom.virtstride</a></span> is negative, or the <a href="#bvsurfgeom.orientation">bvsurfgeom.orientation</a>
+does not normalize to 0º&nbsp; (i.e. <span class="inline_code">orientation % 360 != 0</span>), implementations may need
+to use a modified version of <span class="inline_code">virtaddr</span> internally to operate correctly.</p>
+<p class="Code_Header_2"><a name="bvtileparams.dstleft">bvtileparams.dstleft</a></p>
+<p class="code_block">int dstleft;</p>
+<p>This member is used to designate the left edge of the location of the tile in the destination for alignment purposes
+(alignment location).&nbsp; Note that the <span class="inline_code"><a href="#bvrect">bvrect</a></span> of the destination
+specifies the region which is filled by the tile.</p>
+<p class="Code_Header_2"><a name="bvtileparams.dsttop">bvtileparams.dsttop</a></p>
+<p class="code_block">int dsttop;</p>
+<p>This member is used to designate the top edge of the location of the tile in the destination for alignment purposes (alignment
+location).&nbsp; Note that the <span class="inline_code"><a href="#bvrect">bvrect</a></span> of the destination specifies
+the region which is filled by the tile.</p>
+<p class="Code_Header_2"><a name="bvtileparams.srcwidth">bvtileparams.srcwidth</a></p>
+<p class="code_block">unsigned int srcwidth;</p>
+<p>This member is used to designate the width of the source for purposes of scaling.&nbsp; The relationship between this
+field and the <span class="inline_code"><a href="#bvrect.width">bvrect.width</a></span> of the associated source surface
+determines the horizontal scaling factor.</p>
+<p class="Code_Header_2"><a name="bvtileparams.srcheight">bvtileparams.srcheight</a></p>
+<p class="code_block">unsigned int srcheight;</p>
+<p>This member is used to designate the height of the source for purposes of scaling.&nbsp; The relationship between this
+field and the <span class="inline_code"><a href="#bvrect.height">bvrect.height</a></span> of the associated source surface
+determines the vertical scaling factor.</p>
+<hr />
+<p class="Code_Header"><a name="bvcallbackerror">bvcallbackerror</a></p>
+<p>This structure is used to provide error information to the client of a BLT that failed within an asynchronous operation.&nbsp;
+The errors will be limited to those that occur within the implementation.</p>
+<p class="note">NOTE:&nbsp; Parameter errors should never be returned in this structure.&nbsp; These should have been returned
+to the client before the BLT was ever initiated.</p>
+<p class="small_code_block">struct bvcallbackerror {<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int <a href="#bvcallbackerror.structsize">structsize</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bverror">enum bverror</a> <a href="#bvcallbackerror.error">error</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char *<a href="#bvcallbackerror.errdesc">errdesc</a>;<br />
+};</p>
+<p class="Code_Header_2"><a name="bvcallbackerror.structsize">bvcallbackerror.structsize</a></p>
+<p class="code_block">unsigned int structsize;</p>
+<p>This member is used for compatibility between BLTsville versions.&nbsp; (See <span class="inline_code">
+<a href="#bvbltparams.structsize">bvbltparams.structsize</a></span> for an explanation.) </p>
+<p class="Code_Header_2"><a name="bvcallbackerror.error">bvcallbackerror.error</a></p>
+<p class="code_block"><a href="#bverror">enum bverror</a> error;</p>
+<p>This member is used to indicate the error encountered.&nbsp; In general, these will be error like these:</p>
+<table class="indent">
+ <tr>
+ <td class="inline_code">BVERR_OP_FAILED</td>
+ <td>The operation failed for unspecified reasons.&nbsp; The destination buffer was not modified.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVERR_OP_INCOMPLETE</td>
+ <td>The operation only partially completed.&nbsp; The destination buffer is in an undefined state.</td>
+ </tr>
+ <tr>
+ <td class="inline_code">BVERR_MEMORY_ERROR</td>
+ <td>The operation resulted in a memory error, most likely due to an attempt to access invalid memory.&nbsp; The
+ destination buffer is in an undefined state.</td>
+ </tr>
+</table>
+<p class="Code_Header_2"><a name="bvcallbackerror.errdesc">bvcallbackerror.errdesc</a></p>
+<p class="code_block">char *errdesc;</p>
+<p><span class="inline_code">errdesc</span> is optionally used by implementations to pass a 0-terminated string with additional
+debugging information back to clients for debugging purposes.&nbsp; <span class="inline_code">errdesc</span> is not localized
+or otherwise meant to provide information that is displayed to users.</p>
+<hr />
+<p class="Header1">Batching<a name="batching"></a></p>
+<p>Batching is the single most powerful feature in BLTsville.&nbsp; It is used for two major purposes:</p>
+<ol>
+ <li>To group similar BLTs which use most of the same parameters so that they can be handled more efficiently by the
+ implementation.</li>
+ <li>To group BLTs that should go together so that implementations can use special features that go beyond what seems
+ to be expressed by the BLTsville API.</li>
+</ol>
+<p class="note">NOTE:&nbsp; It is important to realize that BLTs batched together may be done <span class="underline">in
+any order</span>, and in fact may not even be done in the way specified.&nbsp; This includes the BLTs being done as they
+are submitted, or no operations performed until the batch submission is completed with
+<a href="#BVFLAG_BATCH_END" class="inline_code">BVFLAG_BATCH_END</a>.&nbsp; This means the client must not rely on intermediate
+results within a batch.</p>
+<p class="note">NOTE:&nbsp; Because BLTs can be performed in a variety of ways, callbacks for individual BLTs would have
+no consistent meaning.&nbsp; So, when batching is mixed with <span class="inline_code"><a href="#BVFLAG_ASYNC">BVFLAG_ASYNC</a></span>,
+only the callback for the last BLT occurs.</p>
+<p class="note">NOTE:&nbsp; Since implementations can perform batched BLTs in a variety of ways, even synchronous batched
+BLTs can be effectively asynchronous.&nbsp; Therefore, only the last BLT determines the synchronicity of the entire batch.&nbsp;
+i.e. the <span class="inline_code"><a href="#BVFLAG_ASYNC">BVFLAG_ASYNC</a></span> flag is only heeded when combined with
+<span class="inline_code"><a href="#BVFLAG_BATCH_END">BVFLAG_BATCH_END</a>.</span></p>
+<p class="note">NOTE: Failure during the performance of a batch (different from an error on submission--indicated by the
+contents of the <a href="#bvcallbackerror" class="inline_code">bvcallbackerror</a> structure) will result in an unknown
+state for all destination buffers.&nbsp; Do not assume that a given implementation&#39;s state in this case represents the state
+which will be encountered for a different implementation.</p>
+<p class="note">NOTE: Because of the indeterminate nature of the execution of a batch of BLTs, a &quot;batch abort&quot; would not
+result in a known state either.&nbsp; As stated above, a given implementation may have already performed earlier BLTs in
+a batch as the batch is submitted.&nbsp; So errors encountered during the submission of a batch must be handled by the client,
+and then the batch must be terminated normally using <a href="#BVFLAG_BATCH_END" class="inline_code">BVFLAG_BATCH_END</a>.</p>
+<p class="Header2">Batches For Grouping Similar BLTs</p>
+<p>Often, groups of similar BLTs are performed, with changes to only a few parameters.&nbsp; Some implementations have the
+ability to re-use previous settings, coupled with these changes, to perform new BLTs.</p>
+<p>One good example of this in in rendering text, similar to that you are reading now.&nbsp; In most systems, a glyph cache
+is maintained to hold the characters of a given font, rasterized with the specific characteristics desired (e.g. bold, italics,
+etc.).&nbsp; Each font in the glyph cache is normally created using a font rasterization engine from a vector-based font,
+such as FreeType.&nbsp; This technology allows fonts to be described in terms of curves and lines instead of pixels, which
+means they can be created as needed, in any size desirable.</p>
+<table style="" class="glyph_cache">
+ <tr>
+ <td class="glyph_cache">&nbsp; !&quot;#$%&amp;&#39;()*+&#39;-./0123456789:;&lt;=&gt;?<br />
+ @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_<br />
+ `abcdefghijklmnopqrstuvwxyz{|}~</td>
+ </tr>
+</table>
+<p>Then, when a character needs to be rendered, it is copied from the pre-rendered glyph cache.&nbsp; This is much more
+efficient than performing the font rasterization from the vector description each time a character is used.</p>
+<p>With some hardware implementations, the setup to trigger the copy of these characters from the glyph cache to the target
+surface can be quite significant, when compared to the number of pixels actually affected.&nbsp; For example, each character
+might consist of something on the order of&nbsp; 10 x 14, or about 140 pixels.&nbsp; Programming a typical hardware BLTer
+may require tens of commands for each character.</p>
+<p>But note that each of these BLTs differs by only a few parameters.&nbsp; Specifically, once the source and destination
+surfaces have been specified, and the operation described, only the source and destination rectangles change between BLTs.
+To alleviate much of this overhead, most implementations will allow the configuration of a previous BLT to be used again,
+with only those parameters which change provided for the subsequent BLTs.</p>
+<p>BLTsville provides access to this capability via the batch mechanism.</p>
+<p>For rendering a word using a monospaced font like this, the client might construct the batch like this:</p>
+<p class="small_code_block">struct bvbuffdesc screendesc = {sizeof(struct bvbuffdesc}, 0};<br />
+struct bvsurfgeom screengeom = {sizeof(struct bvsurfgeom), 0};<br />
+struct bvbuffdesc glyphcachedesc = {sizeof(struct bvbuffdesc), 0};<br />
+struct bvsurfgeom glyphcachegeom = {sizeof(struct bvsurfgeom), 0};<br />
+struct bvtileparams solidcolortileparams = {sizeof(struct bvtileparams), 0};<br />
+struct bvbuffgeom solidcolorgeom = {sizeof(struct bvsurfgeom), 0};<br />
+<br />
+struct bvbltparams bltparams = {sizeof(struct bvbltparams), 0};<br />
+<br />
+int charsperline = 32;<br />
+int fontwidth = 10;<br />
+int fontheight = 14;<br />
+int i = 0;<br />
+<br />
+screendesc.virtaddr = screenaddr;<br />
+screendesc.length = screenstride * screenheight;<br />
+screengeom.format = OCDFMT_RGB24;<br />
+screengeom.width = screenwidth;<br />
+screengeom.height = screenheight;<br />
+screengeom.virtstride = screenstride;<br />
+<br />
+glyphcachedesc.virtaddr = glyphcacheaddr;<br />
+glyphcachedesc.length = glyphcachestride * glyphcacheheight;<br />
+glyphcachegeom.format = OCDFMT_ALPHA8;<br />
+glyphcachegeom.width = glyphcachewidth;<br />
+glyphcachegeom.height = glyphcacheheight;<br />
+glyphcachegeom.virtstride = glyphstride;<br />
+<br />
+solidcolortileparams.virtaddr = &amp;solidcolor;<br />
+solidcolortileparams.srcwidth = 1;<br />
+solidcolortileparams.srcheight = 1;<br />
+solidcolorgeom.format = OCDFMT_RGB24;<br />
+<br />
+bltparams.flags = BVFLAG_BLEND | BVFLAG_SRC1_TILED | BVFLAG_BATCH_BEGIN;<br />
+bltparams.op.blend = BVBLEND_SRCOVER + BVBLENDDEF_REMOTE;<br />
+bltparams.dstdesc = &amp;screendesc;<br />
+bltparams.dstgeom = &amp;screengeom;<br />
+bltparams.src1.tileparams = &amp;solidcolortileparams;<br />
+bltparams.src1geom = &amp;solidcolorgeom;<br />
+bltparams.src2.desc = &amp;screendesc;<br />
+bltparams.src2geom = &amp;screengeom;<br />
+bltparams.mask.desc = &amp;glyphcachedesc;<br />
+bltparams.maskgeom = &amp;glyphcachegeom;<br />
+<br />
+bltparams.dstrect.left = bltparams.src2rect.left = screenrect.left;<br />
+bltparams.dstrect.top = bltparams.src2rect.top = screenrect.top;<br />
+<br />
+bltparams.maskrect.width = bltparams.dstrect.width = bltparams.src2rect.width = fontwidth;<br />
+bltparams.maskrect.height = bltparams.dstrect.height = bltparams.src2rect.height = fontheight;<br />
+<br />
+bltparams.maskrect.left = ((text[i] - &#39; &#39;) % charsperline) * fontwidth;<br />
+bltparams.maskrect.top = ((text[i] - &#39; &#39;) / charsperline) * fontheight;<br />
+<br />
+bv_blt(&amp;bltparams);<br />
+<br />
+i++;<br />
+if(i &lt; textlen)<br />
+{<br />
+&nbsp; bltparams.flags = (bltparams.flags &amp; ~BVFLAG_BATCH_MASK) | BVFLAG_BATCH_CONTINUE;<br />
+&nbsp; bltparams.batchflags = BVBATCH_DSTRECT_ORIGIN | BVBATCH_SRC2RECT_ORIGIN | BVBATCH_MASKRECT_ORIGIN;<br />
+<br />
+&nbsp; do<br />
+&nbsp; {<br />
+&nbsp;&nbsp;&nbsp; bltparams.dstrect.left += fontwidth;<br />
+&nbsp;&nbsp;&nbsp; bltparams.src2rect.left = bltparams.dstrect.left;<br />
+<br />
+&nbsp;&nbsp;&nbsp; bltparams.maskrect.left = ((text[i] - &#39; &#39;) % charsperline) * fontwidth;<br />
+&nbsp;&nbsp;&nbsp; bltparams.maskrect.top = ((text[i] - &#39; &#39;) / charsperline) * fontheight;<br />
+<br />
+&nbsp;&nbsp;&nbsp; bv_blt(&amp;bltparams);<br />
+<br />
+&nbsp;&nbsp;&nbsp; i++;<br />
+&nbsp; }while(i &lt; textlen);<br />
+}<br />
+<br />
+bltparams.flags = (bltparams.flags &amp; ~BVFLAG_BATCH_MASK) | BVFLAG_BATCH_END;<br />
+bltparams.batchflags = BVBATCH_ENDNOP;<br />
+<br />
+bv_blt(&amp;bltparams);</p>
+<p class="note">NOTE:&nbsp; bvbltparams.batchflags is just a hit.&nbsp; Not all implementations support deltas in
+batching, so clients must not change the values of members of <span class="inline_code"><a href="#bvbltparams">
+bvbltparams</a></span> (or structures it
+references) between BLTs.&nbsp; These values may be used.</p>
+<p class="Header2">Batches For Special Feature BLTs</p>
+<p>Enabling special features of some implementations is a special challenge.&nbsp; But BLTsville is up the task.</p>
+<p>For example, perhaps an implementation is capable of blending four layers at the same time.&nbsp; But BLTsville only allows
+blending to be specified using two layers at a time.&nbsp; How can this be accomplished?</p>
+<p>The most prevalent blending reference used is the <a href="http://dx.doi.org/10.1145/800031.808606">Porter-Duff
+whitepaper</a>, which specifies blending of two sources (A and B).&nbsp; So any N-source blend (N &gt; 2) would require the blends to be
+specified as a grouping of N - 1 two-source blends in order to utilize the
+Porter-Duff equations.&nbsp; That&#39;s how such a blend is specified in BLTsville:</p>
+<p class="small_code_block">bltparams.dstrect.width = bltparams.src1rect.width = bltparams.src2rect.width = dstgeom.width;<br />
+bltparams.dstrect.height = bltparams.src1rect.height = bltparams.src2rect.height = dstgeom.height; <br />
+<br />
+bltparams.flags = BVFLAG_BLEND | BVFLAG_BATCH_BEGIN;<br />
+bltparams.op.blend = BVBLEND_SRCOVER;<br />
+bltparams.dstdesc = &amp;dstdesc;<br />
+bltparams.dstgeom = &amp;dstgeom;<br />
+bltparams.src1.desc = &amp;src1desc;<br />
+bltparams.src1geom = &amp;src1geom;<br />
+bltparams.src2.desc = &amp;src2desc;<br />
+bltparams.src2geom = &amp;src2geom;<br />
+<br />
+bv_blt(&amp;bltparams);<br />
+<br />
+bltparams.src1.desc = &amp;src3desc;<br />
+bltparams.src1geom = &amp;src3geom;<br />
+bltparams.dstdesc = &amp;dstdesc;<br />
+bltparams.dstgeom = &amp;dstgeom;<br />
+<br />
+bltparams.flags = (bltparams.flags &amp; ~BVFLAG_BATCH_MASK) | BVFLAG_BATCH_CONTINUE;<br />
+bltparams.batch = BVBATCH_SRC1 | BVBATCH_SRC2;<br />
+<br />
+bv_blt(&amp;bltparams);<br />
+<br />
+bltparams.src1.desc = &amp;src4desc;<br />
+bltparams.src1geom = &amp;src4geom;<br />
+<br />
+bltparams.flags = (bltparams.flags &amp; ~BVFLAG_BATCH_MASK) | BVFLAG_BATCH_END;<br />
+bltparams.batch = BVBATCH_SRC1;<br />
+<br />
+bv_blt(&amp;bltparams);</p>
+<p>The driver for an implementation that can perform this pair of operations as one BLT would be tasked with recognizing
+that the batch contained BLTs which can be combined.</p>
+<p>The fantastic thing about this approach is that an implementation without the ability to blend N sources in one pass would perform
+the blends separately, but the result would be identical.&nbsp; Moreover, implementations with the ability to combine
+different numbers of operations would likewise produce the same results, even they they used a different number of
+internal steps.&nbsp; Here&#39;s an example:</p>
+<table align="center">
+ <tr>
+ <td>
+<table>
+ <tr>
+ <td class="ctr_thin_bord"><strong>Number of<br />
+ Layers to<br />
+ Blend</strong></td>
+ <td class="ctr_thin_bord"><strong>BLTsville<br />
+ Operations</strong></td>
+ <td class="ctr_thin_bord"><strong>Implementation<br />
+ Capable of<br />
+ Blending One<br />
+ Source with a<br />
+ Destination</strong><br />
+ (2 inputs)</td>
+ <td class="ctr_thin_bord"><strong>Implementation<br />
+ Capable of<br />
+ Blending Two<br />
+ Sources to a<br />
+ Destination</strong><br />
+ (2 inputs)</td>
+ <td class="ctr_thin_bord"><strong>Implementation<br />
+ Capable of<br />
+ Blending Four<br />
+ Sources to a<br />
+ Destination</strong><br />
+ (4 inputs)</td>
+ <td class="ctr_thin_bord"><strong>Implementation<br />
+ Capable of<br />
+ Blending Eight<br />
+ Sources with<br />
+ a Destination</strong><br />
+ (5 inputs)</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">2</td>
+ <td class="nowrap">A over B =&gt; O</td>
+ <td class="nowrap">B =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap">A over B =&gt; O</td>
+ <td class="nowrap">A over B =&gt; O</td>
+ <td class="nowrap">A over B =&gt; O</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">3</td>
+ <td class="nowrap">B over C =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap">C =&gt; O<br />
+ B over O =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap">B over C =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap">A over B over C =&gt; O</td>
+ <td class="nowrap">A over B over C =&gt; O</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">4</td>
+ <td class="nowrap">C over D =&gt; O<br />
+ B over O =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap">D =&gt; O<br />
+ C over O =&gt; O<br />
+ B over O =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap"> C over D =&gt; O<br />
+ B over O =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap"> A over B over C over D =&gt; O</td>
+ <td class="nowrap"> A over B over C over D =&gt; O</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">5</td>
+ <td class="nowrap">D over E =&gt; O<br />
+ C over O =&gt; O<br />
+ B over O =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap">E =&gt; O<br />
+ D over O =&gt; O<br />
+ C over O =&gt; O<br />
+ B over O =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap">D over E =&gt; O<br />
+ C over O =&gt; O<br />
+ B over O =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap">D over E =&gt; O<br />
+ A over B over C over O =&gt; O</td>
+ <td class="nowrap">E =&gt; O<br />
+ A over B over C over D over O =&gt; O</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">6</td>
+ <td class="nowrap">E over F =&gt; O<br />
+ D over O =&gt; O<br />
+ C over O =&gt; O<br />
+ B over O =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap">F =&gt; O<br />
+ E over O =&gt; O<br />
+ D over O =&gt; O<br />
+ C over O =&gt; O<br />
+ B over O =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap">E over F =&gt; O<br />
+ D over O =&gt; O<br />
+ C over O =&gt; O<br />
+ B over O =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap">D over E over F =&gt; O<br />
+ A over B over C over O =&gt; O</td>
+ <td class="nowrap">E over F =&gt; O<br />
+ A over B over C over D over O =&gt; O</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">7</td>
+ <td class="nowrap">F over G =&gt; O<br />
+ E over O =&gt; O<br />
+ D over O =&gt; O<br />
+ C over O =&gt; O<br />
+ B over O =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap">G =&gt; O<br />
+ F over O =&gt; O<br />
+ E over O =&gt; O<br />
+ D over O =&gt; O<br />
+ C over O =&gt; O<br />
+ B over O =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap">F over G =&gt; O<br />
+ E over O =&gt; O<br />
+ D over O =&gt; O<br />
+ C over O =&gt; O<br />
+ B over O =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap">D over E over F over G =&gt; O<br />
+ A over B over C over O =&gt; O</td>
+ <td class="nowrap">E over F over G =&gt; O<br />
+ A over B over C over D over O =&gt; O</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">8</td>
+ <td class="nowrap">G over H =&gt; O<br />
+ F over O =&gt; O<br />
+ E over O =&gt; O<br />
+ D over O =&gt; O<br />
+ C over O =&gt; O<br />
+ B over O =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap">H =&gt; O<br />
+ G over O =&gt; O<br />
+ F over O =&gt; O<br />
+ E over O =&gt; O<br />
+ D over O =&gt; O<br />
+ C over O =&gt; O<br />
+ B over O =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap">G over H =&gt; O<br />
+ F over O =&gt; O<br />
+ E over O =&gt; O<br />
+ D over O =&gt; O<br />
+ C over O =&gt; O<br />
+ B over O =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap">G over H =&gt; O<br />
+ D over E over F over O =&gt; O<br />
+ A over B over C over O =&gt; O</td>
+ <td class="nowrap">E over F over G over H =&gt; O<br />
+ A over B over C over D over O =&gt; O</td>
+ </tr>
+ <tr>
+ <td class="ctr_thin_bord">9</td>
+ <td class="nowrap">H over I =&gt; O<br />
+ G over O =&gt; O<br />
+ F over O =&gt; O<br />
+ E over O =&gt; O<br />
+ D over O =&gt; O<br />
+ C over O =&gt; O<br />
+ B over O =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap">I =&gt; O<br />
+ H over O =&gt; O<br />
+ G over O =&gt; O<br />
+ F over O =&gt; O<br />
+ E over O =&gt; O<br />
+ D over O =&gt; O<br />
+ C over O =&gt; O<br />
+ B over O =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap">H over I =&gt; O<br />
+ G over O =&gt; O<br />
+ F over O =&gt; O<br />
+ E over O =&gt; O<br />
+ D over O =&gt; O<br />
+ C over O =&gt; O<br />
+ B over O =&gt; O<br />
+ A over O =&gt; O</td>
+ <td class="nowrap">G over H over I =&gt; O<br />
+ D over E over F over O =&gt; O<br />
+ A over B over C over O =&gt; O</td>
+ <td class="nowrap">I =&gt; O<br />
+ E over F over G over H over O =&gt; O<br />
+ A over B over C over D over O =&gt; O</td>
+ </tr>
+</table>
+</td>
+ </tr>
+ <tr>
+ <td class="ctr">Comparison of batched BLTsville calls with internal operations, based on implementation capabilities.
+</td>
+ </tr>
+</table>
+<p class="note">NOTE: As mentioned above a batch of BLTs may be serviced in any number of ways.&nbsp; In this example, the
+destination buffer may be used for intermediate results, so it is important that this buffer not be used during the batch--i.e.
+as a displayed buffer.</p>
+<hr />
+<p class="Header1"><a name="start">Where to Start</a></p>
+<p><em>(Note that error checking is omitted in all the examples below for clarity.)</em> </p>
+<p>1.&nbsp; Clients begin by opening one or more BLTsville implementations dynamically.&nbsp; The specific method of doing
+this is dependent on the operating system.&nbsp; For example, Linux might do this like this:</p>
+<p class="small_code_block">struct bltsvillelib<br />
+{<br />
+&nbsp; char* name;<br />
+&nbsp; void* handle;<br />
+&nbsp; BVFN_MAP bv_map;<br />
+&nbsp; BVFN_BLT bv_blt;<br />
+&nbsp; BVFN_UNMAP bv_unmap;<br />
+}; <br />
+<br />
+struct bltsville bvlib[] =<br />
+{<br />
+&nbsp; { &quot;libbltsville_cpu.so&quot;, 0 },<br />
+&nbsp; { &quot;libbltsville_2d.so&quot;, 0 }<br />
+};<br />
+const int NUMBVLIBS = sizeof(bvlib) / sizeof(struct bltsvillelib);<br />
+<br />
+for(int i = 0; i &lt; NUMLIBS; i++)<br />
+{<br />
+&nbsp; bvlib[i].handle = dlopen(bvlib[i].name, RTLD_LOCAL | RTLD_LAZY);<br />
+&nbsp; bvlib[i].bv_map = (BVFN_MAP)dlsym(bvlib[i].handle, &quot;bv_map&quot;);<br />
+&nbsp; bvlib[i].bv_blt = (BVFN_BLT)dlsym(bvlib[i].handle, &quot;bv_blt&quot;);<br />
+&nbsp; bvlib[i].bv_unmap = (BVFN_BLT)dlsym(bvlib[i].handle, &quot;bv_unmap&quot;);<br />
+}<br />
+</p>
+<p>2.&nbsp; Clients then need to create a <span class="inline_code"><a href="#bvbuffdesc">bvbuffdesc</a></span> object for
+each buffer to be accessed in BLTsville:</p>
+<table class="indent">
+ <tr>
+ <td valign="top">
+ <p class="small_code_block_in_table">struct bvbuffdesc buff =<br />
+&nbsp; {sizeof(struct bvbuffdesc), 0};<br />
+ <br />
+ buff.virtaddr = buffptr;<br />
+ buff.length = bufflength;</p>
+ </td>
+ <td class="ctr">&nbsp;or&nbsp</td>
+ <td valign="top">
+ <p class="inline_code"><span class="small_code_block_in_table">struct bvbuffdesc buff;<br />
+ <br />
+ memset(&amp;buff, 0, sizeof(buff));<br />
+ buff.structsize = sizeof(buff);<br />
+ buff.virtaddr = buffptr;<br />
+ buff.length = bufflength;</span></p>
+ </td>
+ </tr>
+</table>
+<p class="strong_emphasis">Note that the client must ensure that the map element and any additional members in
+<span class="inline_code"><a href="#bvbuffdesc">bvbuffdesc</a></span> are initialized to 0.</p>
+<p>3.&nbsp; Next the buffer can be mapped to give the hardware implementations a chance to associate any necessary resources
+with the buffer:</p>
+<table class="indent">
+ <tr>
+ <td valign="top">
+ <p class="small_code_block_in_table">/* do nothing */ </p>
+ </td>
+ <td class="ctr">&nbsp;or&nbsp;</td>
+ <td valign="top">
+ <p class="small_code_block_in_table">bvlib[0].bv_map(&amp;buff); </p>
+ </td>
+ <td class="ctr">&nbsp;or&nbsp;</td>
+ <td valign="top">
+ <p class="small_code_block_in_table">for(int i = 0; i &lt; NUMLIBS; i++)<br />
+ {<br />
+&nbsp; if(bvlib[i].bv_map)<br />
+&nbsp;&nbsp;&nbsp; bvlib[i].bv_map(&amp;buff);<br />
+ }</p>
+ </td>
+ </tr>
+</table>
+<br />
+<table style="width: 100%">
+ <tr>
+ <td valign="top">a. </td>
+ <td>This step is actually optional, as indicated above.&nbsp; However, if the client does not explicitly call
+ <span class="inline_code"><a href="#bv_map">bv_map()</a></span>, the mapping must be done by the implementation
+ to associate the necessary resources with the buffer.&nbsp; So this mapping must be done later, when
+ <span class="inline_code"><a href="#bv_blt">bv_blt()</a></span> is called.&nbsp; Additionally, since the client
+ did not call <span class="inline_code"><a href="#bv_map">bv_map()</a></span>, it is unlikely that the client will
+ call <span class="inline_code"><a href="#bv_unmap">bv_unmap()</a></span> to allow the implementation to free the
+ resources associated with the buffer.&nbsp; So the implementation will internally unmap the resources after completing
+ the BLT.&nbsp; This means that the mapping and unmapping overhead will be encountered on every call to
+ <span class="inline_code"><a href="#bv_blt">bv_blt()</a></span>.<br />
+ <em><br />
+ In general, the CPU implementations have (almost) no overhead associated with mapping and unmapping.&nbsp; So opting
+ not to make the <span class="inline_code"><a href="#bv_map">bv_map()</a></span> call for CPU implementations is
+ likely to have negligible difference in <span class="inline_code"><a href="#bv_blt">bv_blt()</a></span> performance.<br />
+ </em></td>
+ </tr>
+ <tr>
+ <td valign="top">b. </td>
+ <td>Calling <span class="inline_code"><a href="#bv_map">bv_map()</a></span> once for each buffer is enough to tell
+ the implementations that the client can be trusted to call <span class="inline_code"><a href="#bv_unmap">bv_unmap()</a></span>
+ when work with the buffer is complete, as indicated above.&nbsp; It does not matter which implementation&#39;s
+ <span class="inline_code"><a href="#bv_map">bv_map()</a></span> is called.&nbsp; However, that implementation is
+ the only one which will perform the mapping immediately.&nbsp; All other implementations will perform a <em>lazy
+ mapping</em> only when their <span class="inline_code"><a href="#bv_blt">bv_blt()</a></span> call is invoked.<br />
+ <br />
+ This allows the client to avoid the overhead of mapping and unmapping the buffers on each
+ <span class="inline_code"><a href="#bv_blt">bv_blt()</a></span> call.&nbsp; It also avoids the associated mapping
+ and unmapping overhead if a given implementation is never used.<br />
+ <br />
+ <em>As mentioned above, the CPU implementations have (almost) no overhead associated with mapping and unmapping,
+ so they are a good choice to use for the call to <span class="inline_code"><a href="#bv_map">bv_map()</a></span>.<br />
+ </em></td>
+ </tr>
+ <tr>
+ <td valign="top">c. </td>
+ <td>If the client wants direct control over the mapping and unmapping overhead, it can call the
+ <span class="inline_code"><a href="#bv_map">bv_map()</a></span> function of each implementation, as indicated above.&nbsp;
+ Each implementation will perform the mapping at that time, so that the overhead will not appear on subsequent calls
+ to <span class="inline_code"><a href="#bv_blt">bv_blt()</a></span>. </td>
+ </tr>
+</table>
+<p>4.&nbsp; Next the client must create <span class="inline_code"><a href="#bvsurfgeom">bvsurfgeom</a></span> objects for
+each way in which a buffer will be accessed.&nbsp; Often, there is only one way in which a buffer is accessed, so there
+will be the same number of buffers, <span class="inline_code"><a href="#bvbuffdesc">bvbuffdesc</a></span>, and
+<span class="inline_code"><a href="#bvsurfgeom">bvsurfgeom</a></span> objects.&nbsp; If that&#39;s the case, it may be convenient
+for the client to combine them into a parent structure.&nbsp; It may even be possible to share a single bvbuffgeom structure
+among buffers.&nbsp; Or there will be times when it is necessary to treat a buffer in different ways for different BLTs.&nbsp;
+Having these two structures separated allows all of these combinations.</p>
+<table class="indent">
+ <tr>
+ <td valign="top">
+ <p class="small_code_block_in_table">struct bvsurfgeom geom =<br />
+&nbsp; {sizeof(struct bvsurfgeom), 0};<br />
+ <br />
+ geom.format = OCDFMT_RGB24;<br />
+ geom.width = width;<br />
+ geom.height = height;<br />
+ geom.virtstride = stride;</p>
+ </td>
+ <td class="ctr">&nbsp;or&nbsp;</td>
+ <td valign="top">
+ <p class="inline_code"><span class="small_code_block_in_table">struct bvsurfgeom geom;
+ <br />
+ memset(&amp;geom, 0, sizeof(geom));<br />
+ geom.structsize = sizeof(geom);<br />
+ geom.width = width;<br />
+ geom.height = height;<br />
+ geom.virtstride = stride;</span></p>
+ </td>
+ </tr>
+</table>
+<p class="strong_emphasis">Note that the client must ensure that any additional members in <span class="inline_code">
+<a href="#bvsurfgeom">bvsurfgeom</a></span> are initialized to 0 for future compatibility.</p>
+<p>5.&nbsp; Now the client is ready to fill in a bvbltparams structure to specify the type of BLT requested.&nbsp; Here
+is an example of a simple copy from the lower right corner of a surface to the upper left:</p>
+<p class="small_code_block">struct bvbltparams bltparams = {sizeof(struct bvbltparams), 0};<br />
+<br />
+bltparams.flags = BVFLAG_ROP;<br />
+bltparams.op.rop = 0xCCCC; /* SRCCOPY */<br />
+bltparams.dstdesc = &amp;buff;<br />
+bltparams.dstgeom = &amp;geom;<br />
+bltparams.dstrect.left = 0;<br />
+bltparams.dstrect.top = 0;<br />
+bltparams.dstwidth = width / 2;<br />
+bltparams.dstheight = height / 2;<br />
+bltparams.src1.desc = &amp;buff;<br />
+bltparams.src1geom = &amp;geom;<br />
+bltparams.src1rect.left = width / 2;<br />
+bltparams.src1rect.top = height / 2;<br />
+bltparams.src1rect.width = width / 2;<br />
+bltparams.src1rect.height = height / 2;</p>
+<p>6.&nbsp; And next the client can trigger the BLT by calling <span class="inline_code"><a href="#bv_blt">bv_blt()</a></span>:</p>
+<p class="small_code_block">bv_blt(&amp;bltparams); </p>
+<p><em>If the client cannot complete the requested BLT, it returns a </em><span class="inline_code"><a href="#bverror">
+<em>bverror</em></a></span><em> indicating the issue. </em></p>
+<p>7.&nbsp; Finally, the client should clean up:</p>
+<p class="small_code_block">bv_unmap(&amp;buff); </p>
+<hr />
+<p class="Header1"><a name="Kernel_Mode_Interface">Kernel Mode Interface</a></p>
+<p>The kernel mode interface differs only slightly from the user mode interface.&nbsp; Currently there are two differences
+in the general kernel interface, and one in the Linux/Android interface:</p>
+<p class="Code_Header_2">bvbuffdesc.auxtype/auxptr</p>
+<p><span class="inline_code"><a href="#bvbuffdesc.auxtype">bvbuffdesc.auxtype</a></span> is an <span class="inline_code">enum</span>,
+indicating the type of the
+<span class="inline_code"><a href="#bvbuffdesc.auxptr">bvbuffdesc.auxptr</a></span>.&nbsp; The enumeration values and
+the associated types are:</p>
+<table class="indent_thick_bord">
+ <tr>
+ <td class="thin_bord_dbl_botbord"><span class="inline_code"><a href="#bvbuffdesc.auxtype">bvbuffdesc.auxtype</a></span></td>
+ <td class="thin_bord_dbl_botbord">
+<span class="inline_code"><a href="#bvbuffdesc.auxptr">bvbuffdesc.auxptr</a></span> type</td>
+ <td class="thin_bord_dbl_botbord">Notes</td>
+ </tr>
+ <tr>
+ <td class="thin_bord"><span class="inline_code"><a name="BVAT_PHYSDESC">BVAT_PHYSDESC</a></span></td>
+ <td class="thin_bord">
+<a href="#bvphysdesc" class="inline_code">bvphysdesc</a></td>
+ <td class="thin_bord">Used to specify the physical pages of a physically discontiguous buffer constructed using
+ a single page size.&nbsp; This may be used with physically contiguous buffers as well, but
+ <span class="inline_code"><a href="#BVAT_PHYSADDR">BVAT_PHYSADDR</a></span> is preferred.</td>
+ </tr>
+ <tr>
+ <td class="thin_bord"><span class="inline_code"><a name="BVAT_PHYSADDR">BVAT_PHYSADDR</a></span></td>
+ <td class="thin_bord">physical address</td>
+ <td class="thin_bord">Used to specify the starting physical address of a physically contiguous buffer.</td>
+ </tr>
+</table>
+<p>The methods of describing the buffer using physical addresses is not exposed in user mode for security reasons.</p>
+<hr />
+<p class="Code_Header"><a name="bvphysdesc">bvphysdesc</a></p>
+<p class="small_code_block">struct bvphysdesc {<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int <a href="#bvphysdesc.structsize">structsize</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long <a href="#bvphysdesc.pagesize">pagesize</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long *<a href="#bvphysdesc.pagearray">pagearray</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int <a href="#bvphysdesc.pagecount">pagecount</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long <a href="#bvphysdesc.pageoffset">pageoffset</a>;<br />
+};</p>
+<p class="Code_Header_2"><a name="bvphysdesc.structsize">bvphysdesc.structsize</a></p>
+<p class="code_block">unsigned int structsize;</p>
+<p>This member is used for compatibility between BLTsville versions.&nbsp; (See <span class="inline_code">
+<a href="#bvbltparams.structsize">bvbltparams.structsize</a></span> for an explanation.) </p>
+<p class="Code_Header_2"><a name="bvphysdesc.pagesize">bvphysdesc.pagesize</a></p>
+<p class="code_block">unsigned long pagesize;</p>
+<p>This member indicates the size of the physical pages containing the buffer.&nbsp; <span class="inline_code">BVAT_PHYSDESC</span>/<span class="inline_code">bvphysdesc
+</span>does not support buffers which reside in pages that are not all the same size.&nbsp; <span class="inline_code">
+bvphysdesc.pagesize</span> is used to indicate the length of the pages in the <span class="inline_code">
+<a href="#bvphysdesc.pagearray">bvphysdesc.pagearray</a></span> as well as the expected alignment of those pages.&nbsp; If this value is 0, the default
+page size of the system is assumed.</p>
+<p class="note">NOTE:&nbsp; When used with physically contiguous buffers, this member should be set to the length of the
+buffer, which is the same as the value in <span class="inline_code"><a href="#bvbuffdesc.length">bvbuffdesc.length</a></span>.</p>
+<p class="Code_Header_2"><a name="bvphysdesc.pagearray">bvphysdesc.pagearray</a></p>
+<p class="code_block">unsigned long *pagearray;</p>
+<p>This member is an array of <span class="inline_code">unsigned long</span>s holding the physical addresses of the pages
+holding the buffer.&nbsp; The array contains <span class="inline_code"><a href="#bvphysdesc.pagecount">pagecount</a></span>
+entries.&nbsp; The specific format of the physical addresses is O/S dependent.&nbsp; However, <span class="inline_code">
+BVAT_PHYSDESC</span>/<span class="inline_code">bvphysdesc</span> only supports 32-bit physical addresses.</p>
+<p>Addresses in this array must be aligned on <span class="inline_code"><a href="#bvphysdesc.pagesize">
+bvphysdesc.pagesize</a></span> boundaries.&nbsp; Use the <span class="inline_code"><a href="#bvphysdesc.pageoffset">
+bvphysdesc.pageoffset</a></span> member to indicate the offset from the start of the first page to the beginning of the
+buffer.</p>
+<p class="note">NOTE:&nbsp; When used with physically contiguous buffers, the first (only) address in this array should
+be aligned on the system default page boundary, and the <span class="inline_code"><a href="#bvphysdesc.pageoffset">
+bvphysdesc.pageoffset</a></span> member should be used to indicate the offset from that address to the beginning of the
+buffer.</p>
+<p class="Code_Header_2"><a name="bvphysdesc.pagecount">bvphysdesc.pagecount</a></p>
+<p class="code_block">unsigned int pagecount;</p>
+<p>This member indicates the number of pages in the array pointed to by <span class="inline_code">
+<a href="#bvphysdesc.pagearray">bvphysdesc.pagearray</a></span>.</p>
+<p class="note">NOTE:&nbsp; When used with physically contiguous buffers, this member should be set to 1.</p>
+<p class="Code_Header_2"><a name="bvphysdesc.pageoffset">bvphysdesc.pageoffset</a></p>
+<p class="code_block">unsigned long pageoffset;</p>
+<p>This member indicates the number of bytes from the start of the first page (<span class="inline_code">*pagearray</span>)
+to the start of the buffer.&nbsp; The value must be less than <span class="inline_code"><a href="#bvphysdesc.pagesize">
+bvphysdesc.pagesize</a></span>.</p>
+<p class="imponly"><strong>Implementations Only</strong><br />
+<br />
+Implementations should not ignore this member.</p>
+<hr />
+<p class="Header2">bventry</p>
+<p>Kernel mode entry cannot be the same as the user mode.&nbsp; The specific method of accessing the kernel interface is
+O/S specific.&nbsp; However, the following interface is currently defined for the specified O/Ss:</p>
+<table class="example">
+ <tr>
+ <td>
+ <p class="Header4">Linux/Android</p>
+ <p class="Code_Header"><a name="bventry">bventry</a></p>
+ <p>This structure is used to obtain the pointers to the implementation&#39;s BLTsville calls.&nbsp; The client can call
+ the default <span class="inline_code">bv2d_entry()</span> function to obtain the pointers to the implementation
+ chosen by the system integrators, or it can call a specific function to get the pointers for a specific implementation
+ (e.g. <span class="inline_code">gcbv_entry()</span>).</p>
+ <p class="small_code_block">struct bventry {<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int <a href="#bventry.structsize">structsize</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bv_map">BVFN_MAP</a> <a href="#bventry.bv_map">bv_map</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bv_unmap">BVFN_UNMAP</a> <a href="#bventry.bv_unmap">bv_unmap</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bv_blt">BVFN_BLT</a> <a href="#bventry.bv_blt">bv_blt</a>;<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#bv_cache">BVFN_CACHE</a> <a href="#bventry.bv_cache">bv_cache</a>;<br />
+ };</p>
+ <p class="Code_Header_2"><a name="bventry.structsize">bventry.structsize</a></p>
+ <p class="code_block">unsigned int structsize;</p>
+ <p>This member is used for compatibility between BLTsville versions.&nbsp; (See <span class="inline_code">
+ <a href="#bvbltparams.structsize">bvbltparams.structsize</a></span> for an explanation.) </p>
+ <p class="Code_Header_2"><a name="bventry.bv_map">bventry.bv_map</a>/<a name="bventry.bv_unmap">bv_unmap</a>/<a name="bventry.bv_blt">bv_blt</a>/<a name="bventry.bv_cache">bv_cache</a></p>
+ <p class="code_block">BVFN_MAP bv_map;<br />
+ BVFN_UNMAP bv_unmap;<br />
+ BVFN_BLT bv_blt;<br />
+ BVFN_CACHE bv_cache;</p>
+ <p>These members hold pointers to the functions for the specific implementation queried with a call to
+ <span class="inline_code">*_entry()</span>.</p>
+ <p class="note">NOTE:&nbsp; <span class="inline_code"><a href="#bv_cache">bv_cache()</a></span> is optional, so
+ this pointer may be set to 0.</p>
+ </td>
+ </tr>
+</table>
+<br />
+<hr /><br />
+<p class="Header2">Linux/Android Deviation</p>
+<p>Although the linked list used in the <span class="inline_code"><a href="#bvbuffmap">bvbuffmap</a></span> structure is
+not complicated, there may be a requirement to use the standard Linux/Android kernel linked list in that environment.&nbsp;
+To facilitate this, the <span class="inline_code"><a href="#bvbuffmap.map">bvbuffmap.map</a></span> entry is replaced by
+the following entry for Linux/Android <span class="underline">kernel mode only</span>:</p>
+<p class="Code_Header"><a name="bvbuffmap.node" class="Code_Header_2">bvbuffmap.node</a></p>
+<p class="code_block">struct list_head node;</p>
+<p>This member is used to reference the containing linked list for the <span class="inline_code"><a href="#bvbuffmap">bvbuffmap</a></span>
+structures associated with the buffer.</p>
+
+</body>
+
+</html>
diff --git a/bltsville/bltsville/ocdtab.png b/bltsville/bltsville/ocdtab.png
new file mode 100644
index 0000000..239c9bb
--- /dev/null
+++ b/bltsville/bltsville/ocdtab.png
Binary files differ
diff --git a/bltsville/gcbv/Android.mk b/bltsville/gcbv/Android.mk
new file mode 100644
index 0000000..a978401
--- /dev/null
+++ b/bltsville/gcbv/Android.mk
@@ -0,0 +1,86 @@
+#
+# Copyright (c) 2012,
+# Texas Instruments, Inc. and Vivante Corporation.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of Texas Instruments, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL TEXAS INSTRUMENTS, INC. BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := \
+ gcmain.c \
+ mirror/gcbv.c \
+ mirror/gcparser.c \
+ mirror/gcmap.c \
+ mirror/gcbuffer.c \
+ mirror/gcfill.c \
+ mirror/gcblit.c \
+ mirror/gcfilter.c \
+ mirror/gcdbglog.c
+
+LOCAL_CFLAGS :=
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/mirror \
+ $(LOCAL_PATH)/mirror/include \
+ $(COMMON_PATH)/bltsville/bltsville/include \
+ $(COMMON_PATH)/bltsville/ocd/include
+
+VERSION_H := $(COMMON_PATH)/bltsville/gcbv/version.h
+BV_VERSION := $(shell grep "VER_FILEVERSION_STR" $(VERSION_H) | sed "s,.*\"\([0-9.]*\)\\\0.*,\1,")
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libbltsville_gc2d
+LOCAL_MODULE_SUFFIX := .$(BV_VERSION).so
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/../vendor/lib
+
+include $(BUILD_SHARED_LIBRARY)
+
+#Creating SymLinks
+#libbltsville_gc2d.so -> libbltsville_gc2d.VERSION.so
+#libbltsville_hw2d.so -> libbltsville_gc2d.so
+SYMLINKS := $(TARGET_OUT_VENDOR)/lib/libbltsville_gc2d.so
+$(SYMLINKS): GC2D_BINARY := ./$(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX)
+$(SYMLINKS): $(LOCAL_INSTALLED_MODULE) $(LOCAL_PATH)/Android.mk
+ @echo "Symlink: $@ -> $(GC2D_BINARY)"
+ @rm -rf $@
+ $(hide) ln -fs $(GC2D_BINARY) $@
+
+SYMLINKS1 := $(TARGET_OUT_VENDOR)/lib/libbltsville_hw2d.so
+$(SYMLINKS1): LINK_BINARY := ./libbltsville_gc2d.so
+$(SYMLINKS1): $(LOCAL_INSTALLED_MODULE) $(LOCAL_PATH)/Android.mk
+ @echo "Symlink: $@ -> $(LINK_BINARY)"
+ @rm -rf $@
+ $(hide) ln -fs $(LINK_BINARY) $@
+
+ALL_DEFAULT_INSTALLED_MODULES += $(SYMLINKS) $(SYMLINKS1)
+
+# for mm/mmm
+all_modules: $(SYMLINKS) $(SYMLINKS1)
+
diff --git a/bltsville/gcbv/gcmain.c b/bltsville/gcbv/gcmain.c
new file mode 100644
index 0000000..7d8b0bd
--- /dev/null
+++ b/bltsville/gcbv/gcmain.c
@@ -0,0 +1,531 @@
+/*
+ * Copyright (c) 2012,
+ * Texas Instruments, Inc. and Vivante Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Texas Instruments, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL TEXAS INSTRUMENTS, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gcmain.h"
+#include "gcbv.h"
+#include <semaphore.h>
+
+#if ANDROID
+#include <cutils/log.h>
+#include <cutils/process_name.h>
+#endif
+
+#define GCZONE_NONE 0
+#define GCZONE_ALL (~0U)
+#define GCZONE_INIT (1 << 0)
+#define GCZONE_CALLBACK (1 << 1)
+
+GCDBG_FILTERDEF(gcmain, GCZONE_NONE,
+ "init",
+ "callback")
+
+
+static int g_handle;
+
+
+/*******************************************************************************
+ * Callback manager.
+ */
+enum gccallbackinfo_status {
+ UNINIT,
+ SUPPORTED,
+ UNSUPPORTED
+};
+
+static const char * const g_statusNames[] = {
+ "UNINIT",
+ "SUPPORTED",
+ "UNSUPPORTED"
+};
+
+struct gccallbackinfo {
+ /* Callback status */
+ enum gccallbackinfo_status status;
+
+ /* Callback handle. */
+ unsigned long handle;
+
+ /* Termination semaphore. */
+ sem_t stop;
+
+ /* Callback thread handle. */
+ pthread_t thread;
+
+ /* Start/stop mutex */
+ pthread_mutex_t mutex;
+};
+
+struct gccallbackinfo g_callbackinfo = {
+ .status = UNINIT
+};
+
+static void *callbackthread(void *_gccallbackinfo)
+{
+ struct gccallbackinfo *gccallbackinfo;
+ struct gcicallbackwait gccmdcallbackwait;
+ int result;
+
+ /* Get callback info. */
+ gccallbackinfo = (struct gccallbackinfo *) _gccallbackinfo;
+
+ /* Initialize the command. */
+ gccmdcallbackwait.handle = gccallbackinfo->handle;
+ gccmdcallbackwait.timeoutms = 2000;
+
+ /* Enter wait loop. */
+ while (1) {
+ /* Call the kernel to wait for callback event. */
+ result = ioctl(g_handle, GCIOCTL_CALLBACK_WAIT,
+ &gccmdcallbackwait);
+ if (result == 0) {
+ if (gccmdcallbackwait.gcerror == GCERR_NONE) {
+ /* Work completed. */
+ GCDBG(GCZONE_CALLBACK,
+ "callback 0x%08X(0x%08X).\n",
+ (unsigned int)
+ gccmdcallbackwait.callback,
+ (unsigned int)
+ gccmdcallbackwait.callbackparam);
+
+ /* Invoke the callback. */
+ gccmdcallbackwait.callback(
+ gccmdcallbackwait.callbackparam);
+ } else if (gccmdcallbackwait.gcerror == GCERR_TIMEOUT) {
+ /* Timeout. */
+ GCDBG(GCZONE_CALLBACK,
+ "callback wait timeout.\n");
+ } else {
+ /* Error occurred. */
+ GCERR("callback wait failed (0x%08X).\n",
+ gccmdcallbackwait.gcerror);
+ break;
+ }
+ } else if (result != -EINTR) {
+ GCERR("callback wait ioctl failed (%d).\n", result);
+ break;
+ }
+
+ /* Stop requested? */
+ if (sem_trywait(&gccallbackinfo->stop) == 0) {
+ GCDBG(GCZONE_CALLBACK, "terminating.\n");
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static int callback_start(struct gccallbackinfo *gccallbackinfo)
+{
+ int result = 0;
+ struct gcicallback gccmdcallback;
+
+ GCENTER(GCZONE_CALLBACK);
+
+ pthread_mutex_lock(&gccallbackinfo->mutex);
+
+ if (gccallbackinfo->status != UNINIT) {
+ pthread_mutex_unlock(&gccallbackinfo->mutex);
+ return 0;
+ }
+
+ gccmdcallback.handle = 0;
+
+ gccallbackinfo->status =
+#if ANDROID
+ /* The Android zygote process refuses to fork if there is
+ * more than one thread present. */
+ (strcmp(get_process_name(), "zygote") == 0) ? UNSUPPORTED :
+#endif
+ SUPPORTED;
+
+ GCDBG(GCZONE_CALLBACK, "callback status: %s\n",
+ g_statusNames[gccallbackinfo->status]);
+
+ if (gccallbackinfo->status == SUPPORTED) {
+ /* Initialize callback. */
+ result = ioctl(g_handle,
+ GCIOCTL_CALLBACK_ALLOC,
+ &gccmdcallback);
+ if (result != 0) {
+ GCERR("callback ioctl failed (%d).\n", result);
+ goto fail;
+ }
+
+ if (gccmdcallback.gcerror != GCERR_NONE) {
+ GCERR("failed to initialize callback "
+ "mechanism (0x%08X).\n",
+ gccmdcallback.gcerror);
+ goto fail;
+ }
+
+ gccallbackinfo->handle = gccmdcallback.handle;
+
+ /* Initialize the termination semaphore. */
+ result = sem_init(&gccallbackinfo->stop, 0, 0);
+ if (result != 0) {
+ GCERR("callback semaphore init failed (%d).\n", result);
+ goto fail;
+ }
+
+ /* Start the thread. */
+ result = pthread_create(&gccallbackinfo->thread, NULL,
+ callbackthread, gccallbackinfo);
+ if (result != 0) {
+ GCERR("failed to start callback thread.\n");
+ goto fail;
+ }
+
+ gccmdcallback.handle = 0;
+ }
+
+fail:
+ if (gccmdcallback.handle != 0) {
+ ioctl(g_handle, GCIOCTL_CALLBACK_FREE, &gccmdcallback);
+ gccallbackinfo->handle = 0;
+ }
+
+ pthread_mutex_unlock(&gccallbackinfo->mutex);
+
+ GCEXITARG(GCZONE_CALLBACK, "result=%d", result);
+ return result;
+}
+
+static void callback_stop(struct gccallbackinfo *gccallbackinfo)
+{
+ struct gcicallback gccmdcallback;
+
+ GCENTER(GCZONE_CALLBACK);
+
+ pthread_mutex_lock(&gccallbackinfo->mutex);
+
+ if (gccallbackinfo->status == SUPPORTED) {
+ if (gccallbackinfo->thread) {
+ sem_post(&gccallbackinfo->stop);
+ pthread_kill(gccallbackinfo->thread, SIGINT);
+
+ GCDBG(GCZONE_CALLBACK,
+ "waiting to join callback thread...\n");
+
+ pthread_join(gccallbackinfo->thread, NULL);
+ gccallbackinfo->thread = 0;
+ }
+
+ /* Free kernel resources. */
+ gccmdcallback.handle = gccallbackinfo->handle;
+ ioctl(g_handle, GCIOCTL_CALLBACK_FREE, &gccmdcallback);
+ gccallbackinfo->handle = 0;
+ }
+
+ gccallbackinfo->status == UNINIT;
+
+ pthread_mutex_unlock(&gccallbackinfo->mutex);
+
+ GCEXIT(GCZONE_CALLBACK);
+}
+
+
+/*******************************************************************************
+ * IOCTL wrappers.
+ */
+
+#if GCDEBUG_ENABLE && 0
+#define GCPRINTDELAY() sleep(1)
+#else
+#define GCPRINTDELAY()
+#endif
+
+void gc_getcaps_wrapper(struct gcicaps *gcicaps)
+{
+ int result;
+
+ GCPRINTDELAY();
+
+ result = ioctl(g_handle, GCIOCTL_GETCAPS, gcicaps);
+ if (result != 0) {
+ GCERR("ioctl failed (%d).\n", result);
+ gcicaps->gcerror = GCERR_IOCTL;
+ }
+}
+
+void gc_map_wrapper(struct gcimap *gcmap)
+{
+ int result;
+
+ GCPRINTDELAY();
+ result = ioctl(g_handle, GCIOCTL_MAP, gcmap);
+
+ if (result != 0) {
+ GCERR("ioctl failed (%d).\n", result);
+ gcmap->gcerror = GCERR_IOCTL;
+ }
+}
+
+void gc_unmap_wrapper(struct gcimap *gcmap)
+{
+ int result;
+
+ GCPRINTDELAY();
+ result = ioctl(g_handle, GCIOCTL_UNMAP, gcmap);
+
+ if (result != 0) {
+ GCERR("ioctl failed (%d).\n", result);
+ gcmap->gcerror = GCERR_IOCTL;
+ }
+}
+
+void gc_commit_wrapper(struct gcicommit *gccommit)
+{
+ int result;
+
+ GCPRINTDELAY();
+
+ /* Callback start is delayed until needed to handle a case
+ * where it's unsupported on Android. */
+ if (gccommit->callback)
+ callback_start(&g_callbackinfo);
+
+ gccommit->handle = g_callbackinfo.handle;
+ result = ioctl(g_handle, GCIOCTL_COMMIT, gccommit);
+
+ if (result != 0) {
+ GCERR("ioctl failed (%d).\n", result);
+ gccommit->gcerror = GCERR_IOCTL;
+ }
+}
+
+void gc_callback_wrapper(struct gcicallbackarm *gcicallbackarm)
+{
+ int result;
+
+ GCPRINTDELAY();
+
+ callback_start(&g_callbackinfo);
+
+ gcicallbackarm->handle = g_callbackinfo.handle;
+ result = ioctl(g_handle, GCIOCTL_CALLBACK_ARM, gcicallbackarm);
+ if (result != 0) {
+ GCERR("ioctl failed (%d).\n", result);
+ gcicallbackarm->gcerror = GCERR_IOCTL;
+ }
+}
+
+
+/*******************************************************************************
+ * Convert floating point in 0..1 range to an 8-bit value in range 0..255.
+ */
+
+union gcfp {
+ struct {
+ unsigned int mantissa:23;
+ unsigned int exponent:8;
+ unsigned int sign:1;
+ } comp;
+
+ float value;
+};
+
+unsigned char gcfp2norm8(float value)
+{
+ union gcfp gcfp;
+ int exponent;
+ unsigned int mantissa;
+ int shift;
+
+ /* Get access to components. */
+ gcfp.value = value;
+
+ /* Clamp negatives. */
+ if (gcfp.comp.sign)
+ return 0;
+
+ /* Get unbiased exponent. */
+ exponent = (int) gcfp.comp.exponent - 127;
+
+ /* Clamp if too large. */
+ if (exponent >= 0)
+ return 255;
+
+ /* Clamp if too small. */
+ if (exponent < -8)
+ return 0;
+
+ /* Determine the shift value. */
+ shift = (23 - 8) - exponent;
+
+ /* Compute the mantissa. */
+ mantissa = (gcfp.comp.mantissa | 0x00800000) >> shift;
+
+ /* Normalize. */
+ mantissa = (mantissa * 255) >> 8;
+
+ return (unsigned char) mantissa;
+}
+
+
+/*******************************************************************************
+ * Surface allocation.
+ */
+
+enum bverror allocate_surface(struct bvbuffdesc **bvbuffdesc,
+ void **buffer,
+ unsigned int size)
+{
+ enum bverror bverror = BVERR_NONE;
+ struct bvbuffdesc *tempbuffdesc = NULL;
+ void *tempbuff = NULL;
+ unsigned long base;
+
+ /* Allocate surface buffer descriptor. */
+ tempbuffdesc = gcalloc(struct bvbuffdesc, sizeof(struct bvbuffdesc));
+ if (tempbuffdesc == NULL) {
+ BVSETERROR(BVERR_OOM, "failed to allocate surface");
+ goto exit;
+ }
+
+ /* Initialize buffer descriptor. */
+ tempbuffdesc->structsize = sizeof(struct bvbuffdesc);
+ tempbuffdesc->virtaddr = NULL;
+ tempbuffdesc->length = size;
+ tempbuffdesc->map = NULL;
+ tempbuffdesc->auxtype = BVAT_NONE;
+ tempbuffdesc->auxptr = NULL;
+
+ /* Allocate the surface. */
+ tempbuff = gcalloc(void, size + GC_MAX_BASE_ALIGN);
+ if (tempbuff == NULL) {
+ BVSETERROR(BVERR_OOM, "failed to allocate surface");
+ goto exit;
+ }
+
+ /* Align the base address. */
+ tempbuffdesc->virtaddr
+ = (void *) (((unsigned long) tempbuff + GC_MAX_BASE_ALIGN - 1)
+ & ~(GC_MAX_BASE_ALIGN - 1));
+
+ /* Set return pointers. */
+ *bvbuffdesc = tempbuffdesc;
+ *buffer = tempbuff;
+ return BVERR_NONE;
+
+exit:
+ free_surface(tempbuffdesc, tempbuff);
+ return bverror;
+}
+
+void free_surface(struct bvbuffdesc *bvbuffdesc,
+ void *buffer)
+{
+ gcfree(buffer);
+ gcfree(bvbuffdesc);
+}
+
+
+/*******************************************************************************
+ * Cache operation wrapper.
+ */
+
+enum bverror gcbvcacheop(int count, struct c2dmrgn rgn[],
+ enum bvcacheop cacheop)
+{
+ int result;
+ struct gcicache xfer;
+
+ if ((count < 0) || (count > 3))
+ return BVERR_CACHEOP;
+
+ xfer.count = count;
+ xfer.dir = cacheop;
+ memcpy(xfer.rgn, rgn, count * sizeof(struct c2dmrgn));
+
+ GCPRINTDELAY();
+ result = ioctl(g_handle, GCIOCTL_CACHE, &xfer);
+
+ if (result != 0)
+ GCERR("ioctl failed (%d).\n", result);
+
+ return BVERR_NONE;
+}
+
+
+/*******************************************************************************
+ * Device init/cleanup.
+ */
+
+void __attribute__((constructor)) dev_init(void)
+{
+ char *env;
+
+ env = getenv("GCBV_DEBUG");
+ if (env && (atol(env) != 0))
+ GCDBG_ENABLEDUMP();
+
+ GCDBG_INIT();
+ GCDBG_REGISTER(gcmain);
+
+ GCENTER(GCZONE_INIT);
+
+ g_handle = open("/dev/gcioctl", O_RDWR);
+ if (g_handle == -1) {
+ GCERR("failed to open device (%d).\n", errno);
+ goto fail;
+ }
+
+ bv_init();
+
+ pthread_mutex_init(&g_callbackinfo.mutex, 0);
+
+ GCEXIT(GCZONE_INIT);
+ return;
+
+fail:
+ if (g_handle > 0) {
+ close(g_handle);
+ g_handle = 0;
+ }
+
+ GCEXIT(GCZONE_INIT);
+}
+
+void __attribute__((destructor)) dev_exit(void)
+{
+ GCENTER(GCZONE_INIT);
+
+ bv_exit();
+ callback_stop(&g_callbackinfo);
+
+ if (g_handle != 0) {
+ close(g_handle);
+ g_handle = 0;
+ }
+
+ GCEXIT(GCZONE_INIT);
+ GCDBG_EXIT();
+}
+
diff --git a/bltsville/gcbv/gcmain.h b/bltsville/gcbv/gcmain.h
new file mode 100644
index 0000000..6d6489c
--- /dev/null
+++ b/bltsville/gcbv/gcmain.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2012,
+ * Texas Instruments, Inc. and Vivante Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Texas Instruments, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL TEXAS INSTRUMENTS, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCMAIN_H
+#define GCMAIN_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <gcx.h>
+#include <gcioctl.h>
+#include <bltsville.h>
+#include <bvinternal.h>
+#include <bverror.h>
+
+#define GC_DEV_NAME "gc2duser"
+
+
+/*******************************************************************************
+ * Miscellaneous macros.
+ */
+
+/* Not present in userspace bltsville headers */
+#define BVAT_PHYSDESC 0xDEADBEEF
+
+#define gcalloc(type, size) \
+ (type *) malloc(size)
+
+#define gcfree(ptr) \
+ free(ptr)
+
+#define max(x, y) (x > y ? x : y)
+#define min(x, y) (x < y ? x : y)
+
+#define EXPORT_SYMBOL(sym)
+
+#define gc_debug_blt(...)
+
+typedef int64_t s64;
+typedef uint64_t u64;
+
+#define div_u64(x, y) ((x) / (y))
+#define div_s64(x, y) ((x) / (y))
+#define div64_u64(x, y) ((x) / (y))
+#define div64_s64(x, y) ((x) / (y))
+
+#define PAGE_SHIFT 12
+#define PAGE_SIZE (1 << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE-1))
+
+/*******************************************************************************
+ * Not defined in bltsville userspace headers.
+ */
+
+struct bvphysdesc {
+ unsigned int structsize; /* used to identify struct version */
+ unsigned long pagesize; /* page size in bytes */
+ unsigned long *pagearray; /* array of physical pages */
+ unsigned int pagecount; /* number of pages in the pagearray */
+ unsigned long pageoffset; /* page offset in bytes */
+};
+
+
+/*******************************************************************************
+ * IOCTL wrappers.
+ */
+
+void gc_getcaps_wrapper(struct gcicaps *gcicaps);
+void gc_map_wrapper(struct gcimap *gcimap);
+void gc_unmap_wrapper(struct gcimap *gcimap);
+void gc_commit_wrapper(struct gcicommit *gcicommit);
+void gc_callback_wrapper(struct gcicallbackarm *gcicallbackarm);
+
+
+/*******************************************************************************
+ * Surface allocation.
+ */
+enum bverror allocate_surface(struct bvbuffdesc **bvbuffdesc,
+ void **buffer,
+ unsigned int size);
+
+void free_surface(struct bvbuffdesc *bvbuffdesc,
+ void *buffer);
+
+
+/*******************************************************************************
+ * Floating point conversions.
+ */
+
+unsigned char gcfp2norm8(float value);
+
+
+/*******************************************************************************
+ * Cache operation wrapper.
+ */
+
+enum bverror gcbvcacheop(int count, struct c2dmrgn rgn[],
+ enum bvcacheop cacheop);
+
+
+/*******************************************************************************
+ * BLTsville API.
+ */
+
+void bv_init(void);
+void bv_exit(void);
+
+enum bverror bv_map(struct bvbuffdesc *buffdesc);
+enum bverror bv_unmap(struct bvbuffdesc *buffdesc);
+enum bverror bv_blt(struct bvbltparams *bltparams);
+enum bverror bv_cache(struct bvcopparams *copparams);
+
+#endif
diff --git a/bltsville/gcbv/mirror/gcblit.c b/bltsville/gcbv/mirror/gcblit.c
new file mode 100644
index 0000000..5dae273
--- /dev/null
+++ b/bltsville/gcbv/mirror/gcblit.c
@@ -0,0 +1,771 @@
+/*
+ * Copyright(c) 2012,
+ * Texas Instruments, Inc. and Vivante Corporation.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Vivante Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gcbv.h"
+
+#define GCZONE_NONE 0
+#define GCZONE_ALL (~0U)
+#define GCZONE_BLEND (1 << 0)
+#define GCZONE_SURF (1 << 1)
+#define GCZONE_BLIT (1 << 3)
+
+GCDBG_FILTERDEF(blit, GCZONE_NONE,
+ "blend",
+ "surf",
+ "blit")
+
+
+static enum bverror do_blit_end(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch)
+{
+ enum bverror bverror;
+ struct gcblit *gcblit;
+ struct gcmobltconfig *gcmobltconfig;
+ struct gcmostartde *gcmostartde;
+
+ GCENTER(GCZONE_BLIT);
+
+ /* Get a shortcut to the operation specific data. */
+ gcblit = &batch->op.blit;
+
+ GCDBG(GCZONE_BLIT, "finalizing the blit, scrcount = %d\n",
+ gcblit->srccount);
+
+ /***********************************************************************
+ * Configure the operation.
+ */
+
+ /* Allocate command buffer. */
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmobltconfig),
+ (void **) &gcmobltconfig);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Configure multi-source control. */
+ gcmobltconfig->multisource_ldst = gcmobltconfig_multisource_ldst;
+ gcmobltconfig->multisource.raw = 0;
+ gcmobltconfig->multisource.reg.srccount = gcblit->srccount - 1;
+
+ GCDBG(GCZONE_BLIT, "blockenable = %d\n", gcblit->blockenable);
+ if (gcblit->blockenable) {
+ gcmobltconfig->multisource.reg.horblock
+ = GCREG_DE_MULTI_SOURCE_HORIZONTAL_BLOCK_PIXEL16;
+ gcmobltconfig->multisource.reg.verblock
+ = GCREG_DE_MULTI_SOURCE_VERTICAL_BLOCK_LINE64;
+ } else {
+ gcmobltconfig->multisource.reg.horblock
+ = GCREG_DE_MULTI_SOURCE_HORIZONTAL_BLOCK_PIXEL128;
+ gcmobltconfig->multisource.reg.verblock
+ = GCREG_DE_MULTI_SOURCE_VERTICAL_BLOCK_LINE1;
+ }
+
+ /* Set destination configuration. */
+ GCDBG(GCZONE_BLIT, " swizzle code = %d\n", gcblit->swizzle);
+ GCDBG(GCZONE_BLIT, " format code = %d\n", gcblit->format);
+
+ gcmobltconfig->dstconfig_ldst = gcmobltconfig_dstconfig_ldst;
+ gcmobltconfig->dstconfig.raw = 0;
+ gcmobltconfig->dstconfig.reg.swizzle = gcblit->swizzle;
+ gcmobltconfig->dstconfig.reg.format = gcblit->format;
+ gcmobltconfig->dstconfig.reg.command = gcblit->multisrc
+ ? GCREG_DEST_CONFIG_COMMAND_MULTI_SOURCE_BLT
+ : GCREG_DEST_CONFIG_COMMAND_BIT_BLT;
+
+ /***********************************************************************
+ * Start the operation.
+ */
+
+ /* Allocate command buffer. */
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmostartde),
+ (void **) &gcmostartde);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Set START_DE command. */
+ gcmostartde->startde.cmd.fld = gcfldstartde;
+
+ /* Set destination rectangle. */
+ gcmostartde->rect.left = gcblit->dstrect.left;
+ gcmostartde->rect.top = gcblit->dstrect.top;
+ gcmostartde->rect.right = gcblit->dstrect.right;
+ gcmostartde->rect.bottom = gcblit->dstrect.bottom;
+
+ GCDBG(GCZONE_BLIT, "dstrect = (%d,%d)-(%d,%d)\n",
+ gcmostartde->rect.left, gcmostartde->rect.top,
+ gcmostartde->rect.right, gcmostartde->rect.bottom);
+
+ /* Reset the finalizer. */
+ batch->batchend = do_end;
+
+ gc_debug_blt(gcblit->srccount,
+ abs(gcblit->dstrect.right - gcblit->dstrect.left),
+ abs(gcblit->dstrect.bottom - gcblit->dstrect.top));
+
+exit:
+ GCEXITARG(GCZONE_BLIT, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
+
+enum bverror do_blit(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch,
+ struct surfaceinfo *srcinfo)
+{
+ enum bverror bverror = BVERR_NONE;
+ struct gccontext *gccontext = get_context();
+
+ struct gcmosrc0 *gcmosrc0;
+ struct gcmosrc *gcmosrc;
+ struct gcblit *gcblit;
+
+ unsigned int index;
+ struct bvbuffmap *dstmap = NULL;
+ struct bvbuffmap *srcmap = NULL;
+
+ struct surfaceinfo *dstinfo;
+ int dstshiftX, dstshiftY;
+ int dstpixalign, dstbyteshift;
+ int dstoffsetX, dstoffsetY;
+
+ int srcshiftX, srcshiftY, srctopedge;
+ struct gcrect srcclipped;
+ int srcsurfwidth, srcsurfheight;
+ unsigned int physwidth, physheight;
+ int orthogonal;
+ int multisrc;
+
+ GCENTER(GCZONE_BLIT);
+
+ /* 3-plane source not supported. */
+ if ((srcinfo->format.type == BVFMT_YUV) &&
+ (srcinfo->format.cs.yuv.planecount == 3)) {
+ BVSETBLTERROR((srcinfo->index == 0)
+ ? BVERR_SRC1GEOM_FORMAT
+ : BVERR_SRC2GEOM_FORMAT,
+ "unsupported source%d format.",
+ srcinfo->index + 1);
+ goto exit;
+ }
+
+ /* Get a shortcut to the destination surface. */
+ dstinfo = &batch->dstinfo;
+
+ /* Parse destination parameters. */
+ bverror = parse_destination(bvbltparams, batch);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Setup rotation. */
+ process_dest_rotation(bvbltparams, batch);
+
+
+ /***********************************************************************
+ * Determine source surface alignment offset.
+ */
+
+ /* Determine whether the source and the destination are orthogonal
+ * to each other. */
+ orthogonal = (srcinfo->angle % 2) != (dstinfo->angle % 2);
+
+ /* Compute clipped source rectangle. */
+ srcclipped.left = srcinfo->rect.left + batch->clipdelta.left;
+ srcclipped.top = srcinfo->rect.top + batch->clipdelta.top;
+ srcclipped.right = srcinfo->rect.right + batch->clipdelta.right;
+ srcclipped.bottom = srcinfo->rect.bottom + batch->clipdelta.bottom;
+ GCPRINT_RECT(GCZONE_SURF, "clipped source", &srcclipped);
+
+ /* Validate the source rectangle. */
+ if (!valid_rect(srcinfo->geom, &srcclipped)) {
+ BVSETBLTERROR((srcinfo->index == 0)
+ ? BVERR_SRC1RECT
+ : BVERR_SRC2RECT,
+ "invalid source rectangle.");
+ goto exit;
+ }
+
+ /* Compute the source surface shift. */
+ switch (srcinfo->angle) {
+ case ROT_ANGLE_0:
+ srctopedge = srcclipped.top;
+ srcshiftX = srcclipped.left - batch->dstadjusted.left;
+ srcshiftY = srctopedge - batch->dstadjusted.top;
+ break;
+
+ case ROT_ANGLE_90:
+ srctopedge = srcinfo->geom->width - srcclipped.left;
+ srcshiftX = srcclipped.top - batch->dstadjusted.top;
+ srcshiftY = srctopedge
+ - (batch->dstwidth - batch->dstadjusted.left);
+ srctopedge += 1;
+ break;
+
+ case ROT_ANGLE_180:
+ srctopedge = srcinfo->geom->height - srcclipped.top;
+ srcshiftX = (srcinfo->geom->width - srcclipped.left)
+ - (batch->dstwidth - batch->dstadjusted.left);
+ srcshiftY = srctopedge
+ - (batch->dstheight - batch->dstadjusted.top);
+ srctopedge += 1;
+ break;
+
+ case ROT_ANGLE_270:
+ srctopedge = srcclipped.left;
+ srcshiftX = (srcinfo->geom->height - srcclipped.top)
+ - (batch->dstheight - batch->dstadjusted.top);
+ srcshiftY = srctopedge - batch->dstadjusted.left;
+ break;
+
+ default:
+ srctopedge = 0;
+ srcshiftX = 0;
+ srcshiftY = 0;
+ }
+
+ /* We cannot be in the middle of a sample, currently only YUV formats
+ * can have subsamples. Adjust vertical position as necessary.
+ * Horizontal position will be adjusted based on the byte offset and
+ * base address alignment requirement. This assumes that if we are
+ * aligned on the base address, then we are also aligned at the
+ * beginning of a sample. */
+ if (srcinfo->format.type == BVFMT_YUV) {
+ int mody = (srctopedge + srcshiftY)
+ % srcinfo->format.cs.yuv.ysample;
+
+ if (mody < 0)
+ mody = srcinfo->format.cs.yuv.ysample + mody;
+
+ srcshiftY -= mody;
+ srcinfo->ypixalign = -mody;
+ } else {
+ srcinfo->ypixalign = 0;
+ }
+
+ /* Compute the source surface offset in bytes. */
+ srcinfo->bytealign = srcshiftY * (int) srcinfo->geom->virtstride
+ + srcshiftX * (int) srcinfo->format.bitspp / 8;
+
+ /* Compute the source offset in pixels needed to compensate
+ * for the surface base address misalignment if any. */
+ srcinfo->xpixalign = get_pixel_offset(srcinfo, srcinfo->bytealign);
+
+ GCDBG(GCZONE_SURF, "source surface %d:\n", srcinfo->index + 1);
+ GCDBG(GCZONE_SURF, " surface offset (pixels) = %d,%d\n",
+ srcshiftX, srcshiftY);
+ GCDBG(GCZONE_SURF, " surface offset (bytes) = 0x%08X\n",
+ srcinfo->bytealign);
+ GCDBG(GCZONE_SURF, " srcpixalign = %d,%d\n",
+ srcinfo->xpixalign, srcinfo->ypixalign);
+
+ /* Apply the source alignment. */
+ srcinfo->bytealign += srcinfo->xpixalign
+ * (int) srcinfo->format.bitspp / 8;
+ srcshiftX += srcinfo->xpixalign;
+
+ /* NOTE: at this point the source is ready to be presented,
+ * srcinfo->xpixalign and srcinfo->ypixalign represent additional
+ * adjustments for the DESTINATION. */
+
+ GCDBG(GCZONE_SURF, " adjusted surface offset (pixels) = %d,%d\n",
+ srcshiftX, srcshiftY);
+ GCDBG(GCZONE_SURF, " adjusted surface offset (bytes) = 0x%08X\n",
+ srcinfo->bytealign);
+
+ /* Compute U/V plane offsets. */
+ if ((srcinfo->format.type == BVFMT_YUV) &&
+ (srcinfo->format.cs.yuv.planecount > 1))
+ set_computeyuv(srcinfo, srcshiftX, srcshiftY);
+
+ /* Set precomputed destination adjustments based on the destination
+ * base address misalignment only. */
+ dstshiftX = dstinfo->xpixalign;
+ dstshiftY = dstinfo->ypixalign;
+
+ /* Apply source adjustemnts. */
+ if (srcinfo->angle == dstinfo->angle) {
+ dstshiftX += srcinfo->xpixalign;
+ dstshiftY += srcinfo->ypixalign;
+ } else if (((srcinfo->angle + 3) % 4) == dstinfo->angle) {
+ dstshiftY += srcinfo->xpixalign;
+ } else if (((srcinfo->angle + 1) % 4) == dstinfo->angle) {
+ dstshiftX += srcinfo->ypixalign;
+ }
+
+ /* Compute the destination surface offset in bytes. */
+ dstbyteshift = dstshiftY * (int) dstinfo->geom->virtstride
+ + dstshiftX * (int) dstinfo->format.bitspp / 8;
+
+ /* Compute the destination offset in pixels needed to compensate
+ * for the surface base address misalignment if any. If dstpixalign
+ * comes out anything other than zero, multisource blit cannot be
+ * performed. */
+ dstpixalign = get_pixel_offset(dstinfo, dstbyteshift);
+
+ GCDBG(GCZONE_SURF, "destination surface:\n");
+ GCDBG(GCZONE_SURF, " surface offset (pixels) = %d,%d\n",
+ dstshiftX, dstshiftY);
+ GCDBG(GCZONE_SURF, " surface offset (bytes) = 0x%08X\n",
+ dstbyteshift);
+ GCDBG(GCZONE_SURF, " realignment = %d\n",
+ dstpixalign);
+
+ if ((dstpixalign != 0) ||
+ ((srcinfo->xpixalign != 0) && (srcinfo->angle == dstinfo->angle))) {
+ /* Adjust the destination to match the source geometry. */
+ switch (srcinfo->angle) {
+ case ROT_ANGLE_0:
+ /* Adjust coordinates. */
+ srcclipped.left -= srcshiftX;
+ srcclipped.top -= srcshiftY;
+
+ /* Determine source size. */
+ srcsurfwidth = srcinfo->geom->width
+ - srcinfo->xpixalign;
+ srcsurfheight = srcinfo->geom->height;
+ break;
+
+ case ROT_ANGLE_90:
+ /* Adjust top coordinate. */
+ srcclipped.top -= srcshiftX;
+
+ /* Determine source size. */
+ srcsurfwidth = srcinfo->geom->height
+ - srcinfo->xpixalign;
+ srcsurfheight = srcinfo->geom->width;
+ break;
+
+ case ROT_ANGLE_180:
+ /* Determine source size. */
+ srcsurfwidth = srcinfo->geom->width
+ - srcinfo->xpixalign;
+ srcsurfheight = srcinfo->geom->height;
+ break;
+
+ case ROT_ANGLE_270:
+ /* Adjust coordinates. */
+ srcclipped.left -= srcshiftY;
+
+ /* Determine source size. */
+ srcsurfwidth = srcinfo->geom->height
+ - srcinfo->xpixalign;
+ srcsurfheight = srcinfo->geom->width;
+ break;
+
+ default:
+ srcsurfwidth = 0;
+ srcsurfheight = 0;
+ }
+
+ GCDBG(GCZONE_SURF, "srcrect origin = %d,%d\n",
+ srcclipped.left, srcclipped.top);
+ GCDBG(GCZONE_SURF, "source physical size = %dx%d\n",
+ srcsurfwidth, srcsurfheight);
+
+ /* Overwrite destination byte offset. */
+ dstbyteshift = dstinfo->bytealign;
+
+ /* No adjustment necessary for single-source. */
+ dstoffsetX = 0;
+ dstoffsetY = 0;
+
+ /* Set the physical destination size. */
+ physwidth = dstinfo->physwidth;
+ physheight = dstinfo->physheight;
+
+ /* Disable multi source for the cases where the destination
+ * and the source address alignments do not match. */
+ multisrc = 0;
+ GCDBG(GCZONE_SURF, "multi-source disabled.\n");
+ } else {
+ /* Source origin is not used in multi-source setup. */
+ srcclipped.left = 0;
+ srcclipped.top = 0;
+
+ /* Adjust the destination to match the source geometry. */
+ switch (srcinfo->angle) {
+ case ROT_ANGLE_0:
+ /* Adjust the destination horizontally. */
+ dstoffsetX = srcinfo->xpixalign;
+ dstoffsetY = srcinfo->ypixalign;
+
+ /* Apply the source alignment. */
+ if ((dstinfo->angle % 2) == 0) {
+ physwidth = dstinfo->physwidth
+ - srcinfo->xpixalign;
+ physheight = dstinfo->physheight
+ - srcinfo->ypixalign;
+ } else {
+ physwidth = dstinfo->physwidth
+ - srcinfo->ypixalign;
+ physheight = dstinfo->physheight
+ - srcinfo->xpixalign;
+ }
+ break;
+
+ case ROT_ANGLE_90:
+ /* Adjust the destination vertically. */
+ dstoffsetX = srcinfo->ypixalign;
+ dstoffsetY = srcinfo->xpixalign;
+
+ /* Apply the source alignment. */
+ if ((dstinfo->angle % 2) == 0) {
+ physwidth = dstinfo->physwidth
+ - srcinfo->ypixalign;
+ physheight = dstinfo->physheight
+ - srcinfo->xpixalign;
+ } else {
+ physwidth = dstinfo->physwidth
+ - srcinfo->xpixalign;
+ physheight = dstinfo->physheight
+ - srcinfo->ypixalign;
+ }
+ break;
+
+ case ROT_ANGLE_180:
+ /* No adjustment necessary. */
+ dstoffsetX = 0;
+ dstoffsetY = 0;
+
+ /* Apply the source alignment. */
+ if ((dstinfo->angle % 2) == 0) {
+ physwidth = dstinfo->physwidth
+ - srcinfo->xpixalign;
+ physheight = dstinfo->physheight
+ - srcinfo->ypixalign;
+ } else {
+ physwidth = dstinfo->physwidth
+ - srcinfo->ypixalign;
+ physheight = dstinfo->physheight
+ - srcinfo->xpixalign;
+ }
+ break;
+
+ case ROT_ANGLE_270:
+ /* No adjustment necessary. */
+ dstoffsetX = 0;
+ dstoffsetY = 0;
+
+ /* Apply the source alignment. */
+ if ((dstinfo->angle % 2) == 0) {
+ physwidth = dstinfo->physwidth
+ - srcinfo->ypixalign;
+ physheight = dstinfo->physheight
+ - srcinfo->xpixalign;
+ } else {
+ physwidth = dstinfo->physwidth
+ - srcinfo->xpixalign;
+ physheight = dstinfo->physheight
+ - srcinfo->ypixalign;
+ }
+ break;
+
+ default:
+ physwidth = 0;
+ physheight = 0;
+ dstoffsetX = 0;
+ dstoffsetY = 0;
+ }
+
+ /* Source geometry is now the same as the destination. */
+ if (orthogonal) {
+ srcsurfwidth = physheight;
+ srcsurfheight = physwidth;
+ } else {
+ srcsurfwidth = physwidth;
+ srcsurfheight = physheight;
+ }
+
+ /* Enable multi-source. */
+ multisrc = 1;
+ GCDBG(GCZONE_SURF, "multi-source enabled.\n");
+ }
+
+ /* Misaligned source may cause the destination parameters
+ * to change, verify whether this has happened. */
+ if ((batch->dstbyteshift != dstbyteshift) ||
+ (batch->dstphyswidth != physwidth) ||
+ (batch->dstphysheight != physheight) ||
+ (batch->dstoffsetX != dstoffsetX) ||
+ (batch->dstoffsetY != dstoffsetY)) {
+ /* Set new values. */
+ batch->dstbyteshift = dstbyteshift;
+ batch->dstphyswidth = physwidth;
+ batch->dstphysheight = physheight;
+ batch->dstoffsetX = dstoffsetX;
+ batch->dstoffsetY = dstoffsetY;
+
+ /* Now we need to end the current batch and program
+ * the hardware with the new destination. */
+ batch->batchflags |= BVBATCH_DST;
+ }
+
+ /* Check if we need to finalize existing batch. */
+ if ((batch->batchend != do_blit_end) ||
+ (batch->op.blit.srccount == 4) ||
+ (batch->op.blit.multisrc == 0) ||
+ (multisrc == 0) ||
+ ((batch->batchflags & (BVBATCH_DST |
+ BVBATCH_CLIPRECT |
+ BVBATCH_DESTRECT)) != 0)) {
+ /* Finalize existing batch if any. */
+ bverror = batch->batchend(bvbltparams, batch);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Blit batch. */
+ batch->batchend = do_blit_end;
+
+ /* Initialize the new batch. */
+ gcblit = &batch->op.blit;
+ gcblit->blockenable = 0;
+ gcblit->srccount = 0;
+ gcblit->multisrc = multisrc;
+
+ /* Set the destination format. */
+ gcblit->format = dstinfo->format.format;
+ gcblit->swizzle = dstinfo->format.swizzle;
+
+ /* Set the destination coordinates. */
+ gcblit->dstrect.left = batch->dstadjusted.left - dstoffsetX;
+ gcblit->dstrect.top = batch->dstadjusted.top - dstoffsetY;
+ gcblit->dstrect.right = batch->dstadjusted.right - dstoffsetX;
+ gcblit->dstrect.bottom = batch->dstadjusted.bottom - dstoffsetY;
+
+ /* Map the destination. */
+ bverror = do_map(dstinfo->buf.desc, batch, &dstmap);
+ if (bverror != BVERR_NONE) {
+ bvbltparams->errdesc = gccontext->bverrorstr;
+ goto exit;
+ }
+
+ /* Set the new destination. */
+ bverror = set_dst(bvbltparams, batch, dstmap);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Reset the modified flag. */
+ batch->batchflags &= ~(BVBATCH_DST |
+ BVBATCH_CLIPRECT |
+ BVBATCH_DESTRECT);
+ }
+
+ /* Map the source. */
+ bverror = do_map(srcinfo->buf.desc, batch, &srcmap);
+ if (bverror != BVERR_NONE) {
+ bvbltparams->errdesc = gccontext->bverrorstr;
+ goto exit;
+ }
+
+ /***********************************************************************
+ ** Configure source.
+ */
+
+ /* We need to walk in blocks if the source and the destination
+ * surfaces are orthogonal to each other. */
+ batch->op.blit.blockenable |= orthogonal;
+
+ /* Shortcut to the register index. */
+ index = batch->op.blit.srccount;
+
+ /* Set surface parameters. */
+ if (index == 0) {
+ /* Allocate command buffer. */
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmosrc0),
+ (void **) &gcmosrc0);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ add_fixup(bvbltparams, batch, &gcmosrc0->address,
+ srcinfo->bytealign);
+
+ gcmosrc0->config_ldst = gcmosrc0_config_ldst;
+ gcmosrc0->address = GET_MAP_HANDLE(srcmap);
+ gcmosrc0->stride = srcinfo->geom->virtstride;
+ gcmosrc0->rotation.raw = 0;
+ gcmosrc0->rotation.reg.surf_width = srcsurfwidth;
+ gcmosrc0->config.raw = 0;
+ gcmosrc0->config.reg.swizzle = srcinfo->format.swizzle;
+ gcmosrc0->config.reg.format = srcinfo->format.format;
+ gcmosrc0->origin.reg.x = srcclipped.left;
+ gcmosrc0->origin.reg.y = srcclipped.top;
+ gcmosrc0->size.reg = gcregsrcsize_max;
+
+ gcmosrc0->rotation_ldst = gcmosrc0_rotation_ldst;
+ gcmosrc0->rotationheight.reg.height = srcsurfheight;
+ gcmosrc0->rotationangle.raw = 0;
+ gcmosrc0->rotationangle.reg.src = rotencoding[srcinfo->angle];
+ gcmosrc0->rotationangle.reg.dst = rotencoding[dstinfo->angle];
+ gcmosrc0->rotationangle.reg.src_mirror = srcinfo->mirror;
+ gcmosrc0->rotationangle.reg.dst_mirror = GCREG_MIRROR_NONE;
+
+ gcmosrc0->rop_ldst = gcmosrc0_rop_ldst;
+ gcmosrc0->rop.raw = 0;
+ gcmosrc0->rop.reg.type = GCREG_ROP_TYPE_ROP3;
+ gcmosrc0->rop.reg.fg = (unsigned char) srcinfo->rop;
+
+ gcmosrc0->mult_ldst = gcmosrc0_mult_ldst;
+ gcmosrc0->mult.raw = 0;
+ gcmosrc0->mult.reg.srcglobalpremul
+ = GCREG_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_DISABLE;
+
+ if (srcinfo->format.premultiplied)
+ gcmosrc0->mult.reg.srcpremul
+ = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_DISABLE;
+ else
+ gcmosrc0->mult.reg.srcpremul
+ = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_ENABLE;
+
+ if (dstinfo->format.premultiplied) {
+ gcmosrc0->mult.reg.dstpremul
+ = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_DISABLE;
+
+ gcmosrc0->mult.reg.dstdemul
+ = GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_DISABLE;
+ } else {
+ gcmosrc0->mult.reg.dstpremul
+ = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_ENABLE;
+
+ gcmosrc0->mult.reg.dstdemul
+ = GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_ENABLE;
+ }
+
+ /* Program blending. */
+ bverror = set_blending(bvbltparams, batch, srcinfo);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Program YUV source. */
+ if (srcinfo->format.type == BVFMT_YUV) {
+ bverror = set_yuvsrc(bvbltparams, batch,
+ srcinfo, srcmap);
+ if (bverror != BVERR_NONE)
+ goto exit;
+ }
+ } else {
+ /* Allocate command buffer. */
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmosrc),
+ (void **) &gcmosrc);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ add_fixup(bvbltparams, batch, &gcmosrc->address,
+ srcinfo->bytealign);
+
+ gcmosrc->address_ldst = gcmosrc_address_ldst[index];
+ gcmosrc->address = GET_MAP_HANDLE(srcmap);
+ gcmosrc->stride_ldst = gcmosrc_stride_ldst[index];
+ gcmosrc->stride = srcinfo->geom->virtstride;
+
+ gcmosrc->rotation_ldst = gcmosrc_rotation_ldst[index];
+ gcmosrc->rotation.raw = 0;
+ gcmosrc->rotation.reg.surf_width = srcsurfwidth;
+
+ gcmosrc->config_ldst = gcmosrc_config_ldst[index];
+ gcmosrc->config.raw = 0;
+ gcmosrc->config.reg.swizzle = srcinfo->format.swizzle;
+ gcmosrc->config.reg.format = srcinfo->format.format;
+
+ gcmosrc->origin_ldst = gcmosrc_origin_ldst[index];
+ gcmosrc->origin.reg.x = srcclipped.left;
+ gcmosrc->origin.reg.y = srcclipped.top;
+
+ gcmosrc->size_ldst = gcmosrc_size_ldst[index];
+ gcmosrc->size.reg = gcregsrcsize_max;
+
+ gcmosrc->rotationheight_ldst
+ = gcmosrc_rotationheight_ldst[index];
+ gcmosrc->rotationheight.reg.height = srcsurfheight;
+
+ gcmosrc->rotationangle_ldst
+ = gcmosrc_rotationangle_ldst[index];
+ gcmosrc->rotationangle.raw = 0;
+ gcmosrc->rotationangle.reg.src = rotencoding[srcinfo->angle];
+ gcmosrc->rotationangle.reg.dst = rotencoding[dstinfo->angle];
+ gcmosrc->rotationangle.reg.src_mirror = srcinfo->mirror;
+ gcmosrc->rotationangle.reg.dst_mirror = GCREG_MIRROR_NONE;
+
+ gcmosrc->rop_ldst = gcmosrc_rop_ldst[index];
+ gcmosrc->rop.raw = 0;
+ gcmosrc->rop.reg.type = GCREG_ROP_TYPE_ROP3;
+ gcmosrc->rop.reg.fg = (unsigned char) srcinfo->rop;
+
+ gcmosrc->mult_ldst = gcmosrc_mult_ldst[index];
+ gcmosrc->mult.raw = 0;
+ gcmosrc->mult.reg.srcglobalpremul
+ = GCREG_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_DISABLE;
+
+ if (srcinfo->format.premultiplied)
+ gcmosrc->mult.reg.srcpremul
+ = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_DISABLE;
+ else
+ gcmosrc->mult.reg.srcpremul
+ = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_ENABLE;
+
+ if (dstinfo->format.premultiplied) {
+ gcmosrc->mult.reg.dstpremul
+ = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_DISABLE;
+
+ gcmosrc->mult.reg.dstdemul
+ = GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_DISABLE;
+ } else {
+ gcmosrc->mult.reg.dstpremul
+ = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_ENABLE;
+
+ gcmosrc->mult.reg.dstdemul
+ = GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_ENABLE;
+ }
+
+ /* Program blending. */
+ bverror = set_blending_index(bvbltparams, batch,
+ srcinfo, index);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Program YUV source. */
+ if (srcinfo->format.type == BVFMT_YUV) {
+ bverror = set_yuvsrc_index(bvbltparams, batch,
+ srcinfo, srcmap, index);
+ if (bverror != BVERR_NONE)
+ goto exit;
+ }
+ }
+
+ batch->op.blit.srccount += 1;
+
+exit:
+ GCEXITARG(GCZONE_BLIT, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
diff --git a/bltsville/gcbv/mirror/gcbuffer.c b/bltsville/gcbv/mirror/gcbuffer.c
new file mode 100644
index 0000000..7c77d4a
--- /dev/null
+++ b/bltsville/gcbv/mirror/gcbuffer.c
@@ -0,0 +1,383 @@
+/*
+ * Copyright(c) 2012,
+ * Texas Instruments, Inc. and Vivante Corporation.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Vivante Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gcbv.h"
+
+#define GCZONE_NONE 0
+#define GCZONE_ALL (~0U)
+#define GCZONE_BATCH_ALLOC (1 << 0)
+#define GCZONE_BUFFER_ALLOC (1 << 1)
+#define GCZONE_FIXUP_ALLOC (1 << 2)
+#define GCZONE_FIXUP (1 << 3)
+
+GCDBG_FILTERDEF(buffer, GCZONE_NONE,
+ "batchalloc",
+ "bufferalloc"
+ "fixupalloc",
+ "fixup")
+
+
+/*******************************************************************************
+** Miscellaneous defines and macros.
+*/
+
+#define GC_BUFFER_INIT_SIZE \
+( \
+ GC_BUFFER_SIZE - max(sizeof(struct gcbuffer), GC_BUFFER_RESERVE) \
+)
+
+#define GC_BUFFER_RESERVE \
+( \
+ sizeof(struct gcmopipesel) + \
+ sizeof(struct gcmommumaster) + \
+ sizeof(struct gcmommuflush) + \
+ sizeof(struct gcmosignal) + \
+ sizeof(struct gccmdend) \
+)
+
+
+/*******************************************************************************
+ * Batch/command buffer management.
+ */
+
+enum bverror do_end(struct bvbltparams *bvbltparams,
+ struct gcbatch *gcbatch)
+{
+ return BVERR_NONE;
+}
+
+enum bverror allocate_batch(struct bvbltparams *bvbltparams,
+ struct gcbatch **gcbatch)
+{
+ enum bverror bverror;
+ struct gccontext *gccontext = get_context();
+ struct gcbatch *temp;
+ struct gcbuffer *gcbuffer;
+
+ GCENTER(GCZONE_BATCH_ALLOC);
+
+ /* Lock access to batch management. */
+ GCLOCK(&gccontext->batchlock);
+
+ if (list_empty(&gccontext->batchvac)) {
+ temp = gcalloc(struct gcbatch, sizeof(struct gcbatch));
+ if (temp == NULL) {
+ BVSETBLTERROR(BVERR_OOM,
+ "batch header allocation failed");
+ goto exit;
+ }
+
+ GCDBG(GCZONE_BATCH_ALLOC, "allocated new batch = 0x%08X\n",
+ (unsigned int) temp);
+ } else {
+ struct list_head *head;
+ head = gccontext->batchvac.next;
+ temp = list_entry(head, struct gcbatch, link);
+ list_del(head);
+
+ GCDBG(GCZONE_BATCH_ALLOC, "reusing batch = 0x%08X\n",
+ (unsigned int) temp);
+ }
+
+ memset(temp, 0, sizeof(struct gcbatch));
+ temp->structsize = sizeof(struct gcbatch);
+ temp->batchend = do_end;
+ INIT_LIST_HEAD(&temp->buffer);
+ INIT_LIST_HEAD(&temp->unmap);
+ INIT_LIST_HEAD(&temp->link);
+
+ bverror = append_buffer(bvbltparams, temp, &gcbuffer);
+ if (bverror != BVERR_NONE) {
+ free_batch(temp);
+ goto exit;
+ }
+
+ *gcbatch = temp;
+
+ GCDBG(GCZONE_BATCH_ALLOC, "batch allocated = 0x%08X\n",
+ (unsigned int) temp);
+
+exit:
+ /* Unlock access to batch management. */
+ GCUNLOCK(&gccontext->batchlock);
+
+ GCEXITARG(GCZONE_BATCH_ALLOC, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
+
+void free_batch(struct gcbatch *gcbatch)
+{
+ struct list_head *head;
+ struct gccontext *gccontext = get_context();
+ struct gcbuffer *gcbuffer;
+
+ GCENTERARG(GCZONE_BATCH_ALLOC, "batch = 0x%08X\n",
+ (unsigned int) gcbatch);
+
+ /* Lock access. */
+ GCLOCK(&gccontext->batchlock);
+ GCLOCK(&gccontext->bufferlock);
+ GCLOCK(&gccontext->fixuplock);
+ GCLOCK(&gccontext->maplock);
+
+ /* Free implicit unmappings. */
+ list_splice_init(&gcbatch->unmap, &gccontext->unmapvac);
+
+ /* Free command buffers. */
+ while (!list_empty(&gcbatch->buffer)) {
+ head = gcbatch->buffer.next;
+ gcbuffer = list_entry(head, struct gcbuffer, link);
+
+ /* Free fixups. */
+ list_splice_init(&gcbuffer->fixup, &gccontext->fixupvac);
+
+ /* Free the command buffer. */
+ list_move(&gcbuffer->link, &gccontext->buffervac);
+ }
+
+ /* Free the batch. */
+ list_add(&gcbatch->link, &gccontext->batchvac);
+
+ /* Unlock access. */
+ GCUNLOCK(&gccontext->maplock);
+ GCUNLOCK(&gccontext->fixuplock);
+ GCUNLOCK(&gccontext->bufferlock);
+ GCUNLOCK(&gccontext->batchlock);
+
+ GCEXIT(GCZONE_BATCH_ALLOC);
+}
+
+enum bverror append_buffer(struct bvbltparams *bvbltparams,
+ struct gcbatch *gcbatch,
+ struct gcbuffer **gcbuffer)
+{
+ enum bverror bverror;
+ struct gccontext *gccontext = get_context();
+ struct gcbuffer *temp;
+
+ GCENTERARG(GCZONE_BUFFER_ALLOC, "batch = 0x%08X\n",
+ (unsigned int) gcbatch);
+
+ /* Lock access to buffer management. */
+ GCLOCK(&gccontext->bufferlock);
+
+ if (list_empty(&gccontext->buffervac)) {
+ temp = gcalloc(struct gcbuffer, GC_BUFFER_SIZE);
+ if (temp == NULL) {
+ BVSETBLTERROR(BVERR_OOM,
+ "command buffer allocation failed");
+ goto exit;
+ }
+
+ list_add_tail(&temp->link, &gcbatch->buffer);
+
+ GCDBG(GCZONE_BUFFER_ALLOC, "allocated new buffer = 0x%08X\n",
+ (unsigned int) temp);
+ } else {
+ struct list_head *head;
+ head = gccontext->buffervac.next;
+ temp = list_entry(head, struct gcbuffer, link);
+
+ list_move_tail(&temp->link, &gcbatch->buffer);
+
+ GCDBG(GCZONE_BUFFER_ALLOC, "reusing buffer = 0x%08X\n",
+ (unsigned int) temp);
+ }
+
+ INIT_LIST_HEAD(&temp->fixup);
+ temp->pixelcount = 0;
+ temp->head = temp->tail = (unsigned int *) (temp + 1);
+ temp->available = GC_BUFFER_INIT_SIZE;
+
+ GCDBG(GCZONE_BUFFER_ALLOC, "new buffer appended = 0x%08X\n",
+ (unsigned int) temp);
+
+ *gcbuffer = temp;
+ bverror = BVERR_NONE;
+
+exit:
+ /* Unlock access to buffer management. */
+ GCUNLOCK(&gccontext->bufferlock);
+
+ GCEXITARG(GCZONE_BUFFER_ALLOC, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
+
+static enum bverror allocate_fixup(struct bvbltparams *bvbltparams,
+ struct gcbuffer *gcbuffer,
+ struct gcfixup **gcfixup)
+{
+ enum bverror bverror = BVERR_NONE;
+ struct gccontext *gccontext = get_context();
+ struct gcfixup *temp;
+
+ if (list_empty(&gccontext->fixupvac)) {
+ temp = gcalloc(struct gcfixup, sizeof(struct gcfixup));
+ if (temp == NULL) {
+ BVSETBLTERROR(BVERR_OOM, "fixup allocation failed");
+ goto exit;
+ }
+
+ list_add_tail(&temp->link, &gcbuffer->fixup);
+
+ GCDBG(GCZONE_FIXUP_ALLOC,
+ "new fixup struct allocated = 0x%08X\n",
+ (unsigned int) temp);
+ } else {
+ struct list_head *head;
+ head = gccontext->fixupvac.next;
+ temp = list_entry(head, struct gcfixup, link);
+
+ list_move_tail(&temp->link, &gcbuffer->fixup);
+
+ GCDBG(GCZONE_FIXUP_ALLOC, "fixup struct reused = 0x%08X\n",
+ (unsigned int) temp);
+ }
+
+ temp->count = 0;
+ *gcfixup = temp;
+
+exit:
+ return bverror;
+}
+
+enum bverror add_fixup(struct bvbltparams *bvbltparams,
+ struct gcbatch *gcbatch,
+ unsigned int *ptr,
+ unsigned int surfoffset)
+{
+ enum bverror bverror = BVERR_NONE;
+ struct gccontext *gccontext = get_context();
+ struct list_head *head;
+ struct gcbuffer *buffer;
+ struct gcfixup *gcfixup;
+
+ GCENTERARG(GCZONE_FIXUP, "batch = 0x%08X, fixup ptr = 0x%08X\n",
+ (unsigned int) gcbatch, (unsigned int) ptr);
+
+ /* Lock access to fixup management. */
+ GCLOCK(&gccontext->fixuplock);
+
+ /* Get the current command buffer. */
+ if (list_empty(&gcbatch->buffer)) {
+ GCERR("no command buffers are allocated");
+ goto exit;
+ }
+ head = gcbatch->buffer.prev;
+ buffer = list_entry(head, struct gcbuffer, link);
+
+ /* No fixups? Allocate one. */
+ if (list_empty(&buffer->fixup)) {
+ GCDBG(GCZONE_FIXUP_ALLOC, "no fixups allocated.\n");
+ bverror = allocate_fixup(bvbltparams, buffer, &gcfixup);
+ if (bverror != BVERR_NONE)
+ goto exit;
+ } else {
+ /* Get the current fixup. */
+ head = buffer->fixup.prev;
+ gcfixup = list_entry(head, struct gcfixup, link);
+
+ /* No more room? */
+ if (gcfixup->count == GC_FIXUP_MAX) {
+ GCDBG(GCZONE_FIXUP_ALLOC,
+ "out of room, allocating new.\n");
+ bverror = allocate_fixup(bvbltparams, buffer, &gcfixup);
+ if (bverror != BVERR_NONE)
+ goto exit;
+ }
+ }
+
+ GCDBG(GCZONE_FIXUP, "buffer = 0x%08X, fixup struct = 0x%08X\n",
+ (unsigned int) buffer, (unsigned int) gcfixup);
+
+ gcfixup->fixup[gcfixup->count].dataoffset = ptr - buffer->head;
+ gcfixup->fixup[gcfixup->count].surfoffset = surfoffset;
+ gcfixup->count += 1;
+
+ GCDBG(GCZONE_FIXUP, "fixup offset = 0x%08X\n", ptr - buffer->head);
+ GCDBG(GCZONE_FIXUP, "surface offset = 0x%08X\n", surfoffset);
+
+exit:
+ /* Unlock access to fixup management. */
+ GCUNLOCK(&gccontext->fixuplock);
+
+ GCEXITARG(GCZONE_FIXUP, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
+
+enum bverror claim_buffer(struct bvbltparams *bvbltparams,
+ struct gcbatch *gcbatch,
+ unsigned int size,
+ void **buffer)
+{
+ enum bverror bverror;
+ struct list_head *head;
+ struct gcbuffer *gcbuffer;
+
+ GCENTERARG(GCZONE_BUFFER_ALLOC, "batch = 0x%08X, size = %d\n",
+ (unsigned int) gcbatch, size);
+
+ if (size > GC_BUFFER_INIT_SIZE) {
+ GCERR("requested size is too big.\n");
+ BVSETBLTERROR(BVERR_OOM,
+ "command buffer allocation failed");
+ goto exit;
+ }
+
+ /* Get the current command buffer. */
+ head = gcbatch->buffer.prev;
+ gcbuffer = list_entry(head, struct gcbuffer, link);
+
+ GCDBG(GCZONE_BUFFER_ALLOC, "buffer = 0x%08X, available = %d\n",
+ (unsigned int) gcbuffer, gcbuffer->available);
+
+ if (gcbuffer->available < size) {
+ bverror = append_buffer(bvbltparams, gcbatch, &gcbuffer);
+ if (bverror != BVERR_NONE)
+ goto exit;
+ }
+
+ *buffer = gcbuffer->tail;
+ gcbuffer->tail = (unsigned int *)
+ ((unsigned char *) gcbuffer->tail + size);
+ gcbuffer->available -= size;
+ gcbatch->size += size;
+ bverror = BVERR_NONE;
+
+exit:
+ GCEXITARG(GCZONE_BUFFER_ALLOC, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
diff --git a/bltsville/gcbv/mirror/gcbv.c b/bltsville/gcbv/mirror/gcbv.c
new file mode 100644
index 0000000..86d656e
--- /dev/null
+++ b/bltsville/gcbv/mirror/gcbv.c
@@ -0,0 +1,2008 @@
+/*
+ * Copyright(c) 2012,
+ * Texas Instruments, Inc. and Vivante Corporation.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Vivante Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gcbv.h"
+
+#define GCZONE_NONE 0
+#define GCZONE_ALL (~0U)
+#define GCZONE_MAPPING (1 << 0)
+#define GCZONE_BUFFER (1 << 1)
+#define GCZONE_DEST (1 << 2)
+#define GCZONE_SRC (1 << 3)
+#define GCZONE_MASK (1 << 4)
+#define GCZONE_BATCH (1 << 5)
+#define GCZONE_BLIT (1 << 6)
+#define GCZONE_CACHE (1 << 7)
+#define GCZONE_CALLBACK (1 << 8)
+#define GCZONE_TEMP (1 << 9)
+#define GCZONE_BLEND (1 << 10)
+
+GCDBG_FILTERDEF(bv, GCZONE_NONE,
+ "mapping",
+ "buffer",
+ "dest",
+ "source",
+ "mask",
+ "batch",
+ "blit",
+ "cache",
+ "callback",
+ "tempbuffer",
+ "blending")
+
+
+/*******************************************************************************
+** Global driver data access.
+*/
+
+struct gccontext *get_context(void)
+{
+ static struct gccontext gccontext;
+ return &gccontext;
+}
+
+
+/*******************************************************************************
+ * Debugging.
+ */
+
+#if GCDEBUG_ENABLE
+#define GCDUMPBATCH(batch) \
+ dumpbatch(batch)
+
+#define GCVERIFYBATCH(changeflags, prevrect, currrect) \
+ verify_batch(changeflags, prevrect, currrect)
+
+static void dumpbatch(struct gcbatch *gcbatch)
+{
+ struct list_head *gcbufferhead;
+ struct gcbuffer *gcbuffer;
+ struct list_head *gcfixuphead;
+ struct gcfixup *gcfixup;
+ unsigned int i, size;
+
+ if ((GCDBGFILTER.zone & (GCZONE_BUFFER)) == 0)
+ return;
+
+ GCDBG(GCZONE_BUFFER, "BATCH DUMP (0x%08X)\n",
+ (unsigned int) gcbatch);
+
+ list_for_each(gcbufferhead, &gcbatch->buffer) {
+ gcbuffer = list_entry(gcbufferhead, struct gcbuffer, link);
+
+ list_for_each(gcfixuphead, &gcbuffer->fixup) {
+ gcfixup = list_entry(gcfixuphead, struct gcfixup, link);
+
+ GCDBG(GCZONE_BUFFER,
+ " Fixup table @ 0x%08X, count = %d:\n",
+ (unsigned int) gcfixup, gcfixup->count);
+
+ for (i = 0; i < gcfixup->count; i += 1) {
+ GCDBG(GCZONE_BUFFER, " [%02d]"
+ " buffer offset = 0x%08X,"
+ " surface offset = 0x%08X\n",
+ i,
+ gcfixup->fixup[i].dataoffset * 4,
+ gcfixup->fixup[i].surfoffset);
+ }
+ }
+
+ size = (unsigned char *) gcbuffer->tail
+ - (unsigned char *) gcbuffer->head;
+ GCDUMPBUFFER(GCZONE_BUFFER, gcbuffer->head, 0, size);
+ }
+}
+
+static void verify_batch(unsigned int changeflags,
+ struct bvrect *prevrect,
+ struct bvrect *currrect)
+{
+ if ((changeflags & 1) == 0) {
+ /* Origin did not change. */
+ if ((prevrect->left != currrect->left) ||
+ (prevrect->top != currrect->top)) {
+ GCERR("origin changed\n");
+ GCERR(" previous = %d,%d\n",
+ prevrect->left, prevrect->top);
+ GCERR(" current = %d,%d\n",
+ currrect->left, currrect->top);
+ }
+ }
+
+ if ((changeflags & 2) == 0) {
+ /* Size did not change. */
+ if ((prevrect->width != currrect->width) ||
+ (prevrect->height != currrect->height)) {
+ GCERR("size changed\n");
+ GCERR(" previous = %dx%d\n",
+ prevrect->width, prevrect->height);
+ GCERR(" current = %dx%d\n",
+ currrect->width, currrect->height);
+ }
+ }
+
+ prevrect->left = currrect->left;
+ prevrect->top = currrect->top;
+ prevrect->width = currrect->width;
+ prevrect->height = currrect->height;
+}
+#else
+#define GCDUMPBATCH(...)
+#define GCVERIFYBATCH(...)
+#endif
+
+
+/*******************************************************************************
+ * Error handling.
+ */
+
+#define BVSETBLTSURFERROR(errorid, errordesc) \
+do { \
+ struct gccontext *tmpcontext = get_context(); \
+ snprintf(tmpcontext->bverrorstr, sizeof(tmpcontext->bverrorstr), \
+ g_surferr[errorid].message, errordesc.id); \
+ GCDUMPSTRING("%s(%d): [ERROR] %s\n", __func__, __LINE__, \
+ tmpcontext->bverrorstr); \
+ bverror = errordesc.base + g_surferr[errorid].offset; \
+ bvbltparams->errdesc = tmpcontext->bverrorstr; \
+} while (0)
+
+#define GCBVERR_DESC 0
+#define GCBVERR_DESC_VERS 1
+#define GCBVERR_DESC_VIRTADDR 2
+#define GCBVERR_TILE 3
+#define GCBVERR_TILE_VERS 4
+#define GCBVERR_TILE_VIRTADDR 5
+#define GCBVERR_GEOM 6
+#define GCBVERR_GEOM_VERS 7
+#define GCBVERR_GEOM_FORMAT 8
+
+struct bvsurferrorid {
+ char *id;
+ enum bverror base;
+};
+
+struct bvsurferror {
+ unsigned int offset;
+ char *message;
+};
+
+static struct bvsurferror g_surferr[] = {
+ /* GCBVERR_DESC */
+ { 0, "%s desc structure is not set" },
+
+ /* GCBVERR_DESC_VERS */
+ { 100, "%s desc structure has invalid size" },
+
+ /* GCBVERR_DESC_VIRTADDR */
+ { 200, "%s desc virtual pointer is not set" },
+
+ /* GCBVERR_TILE: FIXME/TODO define error code */
+ { 0, "%s tileparams structure is not set" },
+
+ /* GCBVERR_TILE_VERS */
+ { 3000, "%s tileparams structure has invalid size" },
+
+ /* GCBVERR_TILE_VIRTADDR: FIXME/TODO define error code */
+ { 200, "%s tileparams virtual pointer is not set" },
+
+ /* GCBVERR_GEOM */
+ { 1000, "%s geom structure is not set" },
+
+ /* GCBVERR_GEOM_VERS */
+ { 1100, "%s geom structure has invalid size" },
+
+ /* GCBVERR_GEOM_FORMAT */
+ { 1200, "%s invalid format specified" },
+};
+
+static struct bvsurferrorid g_destsurferr = { "dst", BVERR_DSTDESC };
+static struct bvsurferrorid g_src1surferr = { "src1", BVERR_SRC1DESC };
+static struct bvsurferrorid g_src2surferr = { "src2", BVERR_SRC2DESC };
+static struct bvsurferrorid g_masksurferr = { "mask", BVERR_MASKDESC };
+
+
+/*******************************************************************************
+ * Callback info management.
+ */
+
+/* BLTsville callback function. */
+struct gccallbackbltsville {
+ /* Function pointer. */
+ void (*fn) (struct bvcallbackerror *err, unsigned long callbackdata);
+
+ /* Callback data. */
+ unsigned long data;
+};
+
+/* Information for freeing a surface. */
+struct gccallbackfreesurface {
+ /* Pointer to the buffer descriptor. */
+ struct bvbuffdesc *desc;
+
+ /* Pointer to the buffer. */
+ void *ptr;
+};
+
+/* Callback information. */
+struct gccallbackinfo {
+ union {
+ /* BLTsville callback function. */
+ struct gccallbackbltsville callback;
+
+ /* Information for freeing a surface. */
+ struct gccallbackfreesurface freesurface;
+ } info;
+
+ /* Previous/next callback information. */
+ struct list_head link;
+};
+
+static enum bverror get_callbackinfo(struct gccallbackinfo **gccallbackinfo)
+{
+ enum bverror bverror;
+ struct gccontext *gccontext = get_context();
+ struct gccallbackinfo *temp;
+
+ /* Lock access to callback info lists. */
+ GCLOCK(&gccontext->callbacklock);
+
+ if (list_empty(&gccontext->callbackvac)) {
+ temp = gcalloc(struct gccallbackinfo,
+ sizeof(struct gccallbackinfo));
+ if (temp == NULL) {
+ bverror = BVERR_OOM;
+ goto exit;
+ }
+ list_add(&temp->link, &gccontext->callbacklist);
+ } else {
+ struct list_head *head;
+ head = gccontext->callbackvac.next;
+ temp = list_entry(head, struct gccallbackinfo, link);
+ list_move(head, &gccontext->callbacklist);
+ }
+
+ *gccallbackinfo = temp;
+ bverror = BVERR_NONE;
+
+exit:
+ /* Unlock access to callback info lists. */
+ GCUNLOCK(&gccontext->callbacklock);
+
+ return bverror;
+}
+
+static void free_callback(struct gccallbackinfo *gccallbackinfo)
+{
+ struct gccontext *gccontext = get_context();
+
+ /* Lock access to callback info lists. */
+ GCLOCK(&gccontext->callbacklock);
+
+ list_move(&gccallbackinfo->link, &gccontext->callbackvac);
+
+ /* Unlock access to callback info lists. */
+ GCUNLOCK(&gccontext->callbacklock);
+}
+
+void callbackbltsville(void *callbackinfo)
+{
+ struct gccallbackinfo *gccallbackinfo;
+
+ GCENTER(GCZONE_CALLBACK);
+
+ gccallbackinfo = (struct gccallbackinfo *) callbackinfo;
+ GCDBG(GCZONE_CALLBACK, "bltsville_callback = 0x%08X\n",
+ (unsigned int) gccallbackinfo->info.callback.fn);
+ GCDBG(GCZONE_CALLBACK, "bltsville_param = 0x%08X\n",
+ (unsigned int) gccallbackinfo->info.callback.data);
+
+ gccallbackinfo->info.callback.fn(NULL,
+ gccallbackinfo->info.callback.data);
+ free_callback(gccallbackinfo);
+
+ GCEXIT(GCZONE_CALLBACK);
+}
+
+void callbackfreesurface(void *callbackinfo)
+{
+ struct gccallbackinfo *gccallbackinfo;
+
+ GCENTER(GCZONE_CALLBACK);
+
+ gccallbackinfo = (struct gccallbackinfo *) callbackinfo;
+ GCDBG(GCZONE_CALLBACK, "freeing descriptir @ 0x%08X\n",
+ (unsigned int) gccallbackinfo->info.freesurface.desc);
+ GCDBG(GCZONE_CALLBACK, "freeing memory @ 0x%08X\n",
+ (unsigned int) gccallbackinfo->info.freesurface.ptr);
+
+ free_surface(gccallbackinfo->info.freesurface.desc,
+ gccallbackinfo->info.freesurface.ptr);
+ free_callback(gccallbackinfo);
+
+ GCEXIT(GCZONE_CALLBACK);
+}
+
+
+/*******************************************************************************
+ * Temporary buffer management.
+ */
+
+enum bverror allocate_temp(struct bvbltparams *bvbltparams,
+ unsigned int size)
+{
+ enum bverror bverror;
+ struct gccontext *gccontext = get_context();
+
+ GCENTER(GCZONE_TEMP);
+
+ /* Existing buffer too small? */
+ if ((gccontext->tmpbuffdesc != NULL) &&
+ (gccontext->tmpbuffdesc->length < size)) {
+ GCDBG(GCZONE_TEMP, "freeing current buffer.\n");
+ bverror = free_temp(true);
+ if (bverror != BVERR_NONE) {
+ bvbltparams->errdesc = gccontext->bverrorstr;
+ goto exit;
+ }
+ }
+
+ /* Allocate new buffer if necessary. */
+ if ((size > 0) && (gccontext->tmpbuffdesc == NULL)) {
+ /* Allocate temporary surface. */
+ bverror = allocate_surface(&gccontext->tmpbuffdesc,
+ &gccontext->tmpbuff,
+ size);
+ if (bverror != BVERR_NONE) {
+ bvbltparams->errdesc = gccontext->bverrorstr;
+ goto exit;
+ }
+
+ GCDBG(GCZONE_TEMP, "buffdesc @ 0x%08X\n",
+ gccontext->tmpbuffdesc);
+ GCDBG(GCZONE_TEMP, "allocated @ 0x%08X\n",
+ gccontext->tmpbuff);
+ GCDBG(GCZONE_TEMP, "size = %d\n",
+ size);
+
+ /* Map the buffer explicitly. */
+ bverror = bv_map(gccontext->tmpbuffdesc);
+ if (bverror != BVERR_NONE) {
+ bvbltparams->errdesc = gccontext->bverrorstr;
+ goto exit;
+ }
+ }
+
+ /* Success. */
+ bverror = BVERR_NONE;
+
+exit:
+ GCEXIT(GCZONE_TEMP);
+ return bverror;
+}
+
+enum bverror free_temp(bool schedule)
+{
+ enum bverror bverror;
+ struct gccontext *gccontext = get_context();
+ struct gccallbackinfo *gccallbackinfo;
+ struct gcicallbackarm gcicallbackarm;
+
+ /* Is the buffer allocated? */
+ if (gccontext->tmpbuffdesc == NULL) {
+ bverror = BVERR_NONE;
+ goto exit;
+ }
+
+ /* Unmap the buffer. */
+ bverror = bv_unmap(gccontext->tmpbuffdesc);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Cannot be mapped. */
+ if (gccontext->tmpbuffdesc->map != NULL) {
+ BVSETERROR(BVERR_OOM, "temporary buffer is still mapped");
+ goto exit;
+ }
+
+ /* Free the buffer. */
+ if (schedule) {
+ bverror = get_callbackinfo(&gccallbackinfo);
+ if (bverror != BVERR_NONE) {
+ BVSETERROR(BVERR_OOM,
+ "callback allocation failed");
+ goto exit;
+ }
+
+ gccallbackinfo->info.freesurface.desc = gccontext->tmpbuffdesc;
+ gccallbackinfo->info.freesurface.ptr = gccontext->tmpbuff;
+ gcicallbackarm.callback = callbackfreesurface;
+ gcicallbackarm.callbackparam = gccallbackinfo;
+
+ /* Schedule to free the buffer. */
+ gc_callback_wrapper(&gcicallbackarm);
+
+ /* Error? */
+ if (gcicallbackarm.gcerror != GCERR_NONE) {
+ BVSETERROR(BVERR_OOM, "unable to schedule callback");
+ goto exit;
+ }
+ } else {
+ /* Free the buffer immediately. */
+ free_surface(gccontext->tmpbuffdesc, gccontext->tmpbuff);
+ }
+
+ /* Reset the buffer descriptor. */
+ gccontext->tmpbuffdesc = NULL;
+ gccontext->tmpbuff = NULL;
+
+exit:
+ return bverror;
+}
+
+
+/*******************************************************************************
+ * Program the destination.
+ */
+
+enum bverror set_dst(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch,
+ struct bvbuffmap *dstmap)
+{
+ enum bverror bverror = BVERR_NONE;
+ struct gcmodst *gcmodst;
+
+ GCENTER(GCZONE_DEST);
+
+ /* Did destination surface change? */
+ if ((batch->batchflags & BVBATCH_DST) != 0) {
+ /* Allocate command buffer. */
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmodst),
+ (void **) &gcmodst);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Add the address fixup. */
+ add_fixup(bvbltparams, batch, &gcmodst->address,
+ batch->dstbyteshift);
+
+ /* Set surface parameters. */
+ gcmodst->config_ldst = gcmodst_config_ldst;
+ gcmodst->address = GET_MAP_HANDLE(dstmap);
+ gcmodst->stride = bvbltparams->dstgeom->virtstride;
+
+ /* Set surface width and height. */
+ gcmodst->rotation.raw = 0;
+ gcmodst->rotation.reg.surf_width = batch->dstphyswidth;
+ gcmodst->rotationheight_ldst = gcmodst_rotationheight_ldst;
+ gcmodst->rotationheight.raw = 0;
+ gcmodst->rotationheight.reg.height = batch->dstphysheight;
+
+ /* Disable hardware clipping. */
+ gcmodst->clip_ldst = gcmodst_clip_ldst;
+ gcmodst->cliplt.raw = 0;
+ gcmodst->cliprb.raw = 0;
+ gcmodst->cliprb.reg.right = GC_CLIP_RESET_RIGHT;
+ gcmodst->cliprb.reg.bottom = GC_CLIP_RESET_BOTTOM;
+ }
+
+exit:
+ GCEXITARG(GCZONE_DEST, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
+
+/*******************************************************************************
+ * Program blending.
+ */
+
+enum bverror set_blending(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch,
+ struct surfaceinfo *srcinfo)
+{
+ enum bverror bverror = BVERR_NONE;
+ struct gcmoalphaoff *gcmoalphaoff;
+ struct gcmoalpha *gcmoalpha;
+ struct gcmoglobal *gcmoglobal;
+ struct gcalpha *gca;
+
+ GCENTER(GCZONE_BLEND);
+
+ gca = srcinfo->gca;
+ if (gca == NULL) {
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmoalphaoff),
+ (void **) &gcmoalphaoff);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ gcmoalphaoff->control_ldst = gcmoalphaoff_control_ldst[0];
+ gcmoalphaoff->control.reg = gcregalpha_off;
+
+ GCDBG(GCZONE_BLEND, "blending disabled.\n");
+ } else {
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmoalpha),
+ (void **) &gcmoalpha);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ gcmoalpha->config_ldst = gcmoalpha_config_ldst;
+ gcmoalpha->control.reg = gcregalpha_on;
+
+ gcmoalpha->mode.raw = 0;
+ gcmoalpha->mode.reg.src_global_alpha_mode
+ = gca->src_global_alpha_mode;
+ gcmoalpha->mode.reg.dst_global_alpha_mode
+ = gca->dst_global_alpha_mode;
+
+ gcmoalpha->mode.reg.src_blend
+ = gca->srcconfig->factor_mode;
+ gcmoalpha->mode.reg.src_color_reverse
+ = gca->srcconfig->color_reverse;
+
+ gcmoalpha->mode.reg.dst_blend
+ = gca->dstconfig->factor_mode;
+ gcmoalpha->mode.reg.dst_color_reverse
+ = gca->dstconfig->color_reverse;
+
+ GCDBG(GCZONE_BLEND, "dst blend:\n");
+ GCDBG(GCZONE_BLEND, " factor = %d\n",
+ gcmoalpha->mode.reg.dst_blend);
+ GCDBG(GCZONE_BLEND, " inverse = %d\n",
+ gcmoalpha->mode.reg.dst_color_reverse);
+
+ GCDBG(GCZONE_BLEND, "src blend:\n");
+ GCDBG(GCZONE_BLEND, " factor = %d\n",
+ gcmoalpha->mode.reg.src_blend);
+ GCDBG(GCZONE_BLEND, " inverse = %d\n",
+ gcmoalpha->mode.reg.src_color_reverse);
+
+ if ((gca->src_global_alpha_mode
+ != GCREG_GLOBAL_ALPHA_MODE_NORMAL) ||
+ (gca->dst_global_alpha_mode
+ != GCREG_GLOBAL_ALPHA_MODE_NORMAL)) {
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmoglobal),
+ (void **) &gcmoglobal);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ gcmoglobal->color_ldst = gcmoglobal_color_ldst;
+ gcmoglobal->srcglobal.raw = gca->src_global_color;
+ gcmoglobal->dstglobal.raw = gca->dst_global_color;
+ }
+ }
+
+exit:
+ GCEXITARG(GCZONE_BLEND, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
+
+enum bverror set_blending_index(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch,
+ struct surfaceinfo *srcinfo,
+ unsigned int index)
+{
+ enum bverror bverror = BVERR_NONE;
+ struct gcmoalphaoff *gcmoalphaoff;
+ struct gcmoxsrcalpha *gcmoxsrcalpha;
+ struct gcmoxsrcglobal *gcmoxsrcglobal;
+ struct gcalpha *gca;
+
+ GCENTER(GCZONE_BLEND);
+
+ gca = srcinfo->gca;
+ if (gca == NULL) {
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmoalphaoff),
+ (void **) &gcmoalphaoff);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ gcmoalphaoff->control_ldst = gcmoalphaoff_control_ldst[index];
+ gcmoalphaoff->control.reg = gcregalpha_off;
+
+ GCDBG(GCZONE_BLEND, "blending disabled.\n");
+ } else {
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmoxsrcalpha),
+ (void **) &gcmoxsrcalpha);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ gcmoxsrcalpha->control_ldst = gcmoxsrcalpha_control_ldst[index];
+ gcmoxsrcalpha->control.reg = gcregalpha_on;
+
+ gcmoxsrcalpha->mode_ldst = gcmoxsrcalpha_mode_ldst[index];
+ gcmoxsrcalpha->mode.raw = 0;
+ gcmoxsrcalpha->mode.reg.src_global_alpha_mode
+ = gca->src_global_alpha_mode;
+ gcmoxsrcalpha->mode.reg.dst_global_alpha_mode
+ = gca->dst_global_alpha_mode;
+
+ gcmoxsrcalpha->mode.reg.src_blend
+ = gca->srcconfig->factor_mode;
+ gcmoxsrcalpha->mode.reg.src_color_reverse
+ = gca->srcconfig->color_reverse;
+
+ gcmoxsrcalpha->mode.reg.dst_blend
+ = gca->dstconfig->factor_mode;
+ gcmoxsrcalpha->mode.reg.dst_color_reverse
+ = gca->dstconfig->color_reverse;
+
+ GCDBG(GCZONE_BLEND, "dst blend:\n");
+ GCDBG(GCZONE_BLEND, " factor = %d\n",
+ gcmoxsrcalpha->mode.reg.dst_blend);
+ GCDBG(GCZONE_BLEND, " inverse = %d\n",
+ gcmoxsrcalpha->mode.reg.dst_color_reverse);
+
+ GCDBG(GCZONE_BLEND, "src blend:\n");
+ GCDBG(GCZONE_BLEND, " factor = %d\n",
+ gcmoxsrcalpha->mode.reg.src_blend);
+ GCDBG(GCZONE_BLEND, " inverse = %d\n",
+ gcmoxsrcalpha->mode.reg.src_color_reverse);
+
+ if ((gca->src_global_alpha_mode
+ != GCREG_GLOBAL_ALPHA_MODE_NORMAL) ||
+ (gca->dst_global_alpha_mode
+ != GCREG_GLOBAL_ALPHA_MODE_NORMAL)) {
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmoxsrcglobal),
+ (void **) &gcmoxsrcglobal);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ gcmoxsrcglobal->srcglobal_ldst
+ = gcmoxsrcglobal_srcglobal_ldst[index];
+ gcmoxsrcglobal->srcglobal.raw = gca->src_global_color;
+
+ gcmoxsrcglobal->dstglobal_ldst
+ = gcmoxsrcglobal_dstglobal_ldst[index];
+ gcmoxsrcglobal->dstglobal.raw = gca->dst_global_color;
+ }
+ }
+
+exit:
+ GCEXITARG(GCZONE_BLEND, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
+
+/*******************************************************************************
+ * Program YUV source.
+ */
+
+void set_computeyuv(struct surfaceinfo *srcinfo, int x, int y)
+{
+ int pixalign, bytealign;
+ unsigned int height1, size1;
+ unsigned int height2, size2;
+ unsigned int origin;
+ int ssX, ssY;
+
+ GCENTER(GCZONE_SRC);
+
+ /* Compute base address alignment. */
+ pixalign = get_pixel_offset(srcinfo, 0);
+ bytealign = (pixalign * (int) srcinfo->format.bitspp) / 8;
+
+ /* Determine the physical height of the first plane. */
+ height1 = ((srcinfo->angle % 2) == 0)
+ ? srcinfo->geom->height
+ : srcinfo->geom->width;
+
+ /* Determine the size of the first plane. */
+ size1 = srcinfo->geom->virtstride * height1;
+
+ /* Determine the stride of the second plane. */
+ srcinfo->stride2 = srcinfo->geom->virtstride
+ / srcinfo->format.cs.yuv.xsample;
+
+ /* Determine subsample pixel position. */
+ ssX = x / srcinfo->format.cs.yuv.xsample;
+ ssY = y / srcinfo->format.cs.yuv.ysample;
+
+ switch (srcinfo->format.cs.yuv.planecount) {
+ case 2:
+ /* U and V are interleaved in one plane. */
+ ssX *= 2;
+ srcinfo->stride2 *= 2;
+
+ /* Determnine the origin offset. */
+ origin = ssY * srcinfo->stride2 + ssX;
+
+ /* Compute the alignment of the second plane. */
+ srcinfo->bytealign2 = bytealign + size1 + origin;
+
+ GCDBG(GCZONE_SRC, "plane2 offset (bytes) = 0x%08X\n",
+ srcinfo->bytealign2);
+ GCDBG(GCZONE_SRC, "plane2 stride = %d\n",
+ srcinfo->stride2);
+ break;
+
+ case 3:
+ /* Determine the physical height of the U/V planes. */
+ height2 = height1 / srcinfo->format.cs.yuv.ysample;
+
+ /* Determine the size of the U/V planes. */
+ size2 = srcinfo->stride2 * height2;
+
+ /* Determnine the origin offset. */
+ origin = ssY * srcinfo->stride2 + ssX;
+
+ /* Compute the alignment of the U/V planes. */
+ srcinfo->bytealign2 = bytealign + size1 + origin;
+ srcinfo->bytealign3 = bytealign + size1 + size2 + origin;
+
+ /* Determine the stride of the U/V planes. */
+ srcinfo->stride3 = srcinfo->stride2;
+
+ GCDBG(GCZONE_SRC, "plane2 offset (bytes) = 0x%08X\n",
+ srcinfo->bytealign2);
+ GCDBG(GCZONE_SRC, "plane2 stride = %d\n",
+ srcinfo->stride2);
+ GCDBG(GCZONE_SRC, "plane3 offset (bytes) = 0x%08X\n",
+ srcinfo->bytealign3);
+ GCDBG(GCZONE_SRC, "plane3 stride = %d\n",
+ srcinfo->stride3);
+ break;
+ }
+
+ GCEXIT(GCZONE_SRC);
+}
+
+enum bverror set_yuvsrc(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch,
+ struct surfaceinfo *srcinfo,
+ struct bvbuffmap *srcmap)
+{
+ enum bverror bverror = BVERR_NONE;
+ struct gcmoyuv1 *gcmoyuv1;
+ struct gcmoyuv2 *gcmoyuv2;
+ struct gcmoyuv3 *gcmoyuv3;
+
+ GCENTER(GCZONE_SRC);
+
+ GCDBG(GCZONE_SRC, "plane count %d.\n",
+ srcinfo->format.cs.yuv.planecount);
+
+ switch (srcinfo->format.cs.yuv.planecount) {
+ case 1:
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmoyuv1),
+ (void **) &gcmoyuv1);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Set YUV parameters. */
+ gcmoyuv1->pectrl_ldst = gcmoyuv_pectrl_ldst;
+ gcmoyuv1->pectrl.raw = 0;
+ gcmoyuv1->pectrl.reg.standard
+ = srcinfo->format.cs.yuv.std;
+ gcmoyuv1->pectrl.reg.swizzle
+ = srcinfo->format.swizzle;
+ gcmoyuv1->pectrl.reg.convert
+ = GCREG_PE_CONTROL_YUVRGB_DISABLED;
+ break;
+
+ case 2:
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmoyuv2),
+ (void **) &gcmoyuv2);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Set YUV parameters. */
+ gcmoyuv2->pectrl_ldst = gcmoyuv_pectrl_ldst;
+ gcmoyuv2->pectrl.raw = 0;
+ gcmoyuv2->pectrl.reg.standard
+ = srcinfo->format.cs.yuv.std;
+ gcmoyuv2->pectrl.reg.swizzle
+ = srcinfo->format.swizzle;
+ gcmoyuv2->pectrl.reg.convert
+ = GCREG_PE_CONTROL_YUVRGB_DISABLED;
+
+ /* Program U/V plane. */
+ add_fixup(bvbltparams, batch, &gcmoyuv2->uplaneaddress,
+ srcinfo->bytealign2);
+ gcmoyuv2->plane_ldst = gcmoyuv2_plane_ldst;
+ gcmoyuv2->uplaneaddress = GET_MAP_HANDLE(srcmap);
+ gcmoyuv2->uplanestride = srcinfo->stride2;
+ break;
+
+ case 3:
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmoyuv3),
+ (void **) &gcmoyuv3);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Set YUV parameters. */
+ gcmoyuv3->pectrl_ldst = gcmoyuv_pectrl_ldst;
+ gcmoyuv3->pectrl.raw = 0;
+ gcmoyuv3->pectrl.reg.standard
+ = srcinfo->format.cs.yuv.std;
+ gcmoyuv3->pectrl.reg.swizzle
+ = srcinfo->format.swizzle;
+ gcmoyuv3->pectrl.reg.convert
+ = GCREG_PE_CONTROL_YUVRGB_DISABLED;
+
+ /* Program U/V planes. */
+ add_fixup(bvbltparams, batch, &gcmoyuv3->uplaneaddress,
+ srcinfo->bytealign2);
+ add_fixup(bvbltparams, batch, &gcmoyuv3->vplaneaddress,
+ srcinfo->bytealign3);
+ gcmoyuv3->plane_ldst = gcmoyuv3_plane_ldst;
+ gcmoyuv3->uplaneaddress = GET_MAP_HANDLE(srcmap);
+ gcmoyuv3->uplanestride = srcinfo->stride2;
+ gcmoyuv3->vplaneaddress = GET_MAP_HANDLE(srcmap);
+ gcmoyuv3->vplanestride = srcinfo->stride3;
+ break;
+
+ default:
+ GCERR("invlaid plane count %d.\n",
+ srcinfo->format.cs.yuv.planecount);
+ }
+
+exit:
+ GCEXITARG(GCZONE_SRC, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
+
+enum bverror set_yuvsrc_index(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch,
+ struct surfaceinfo *srcinfo,
+ struct bvbuffmap *srcmap,
+ unsigned int index)
+{
+ enum bverror bverror = BVERR_NONE;
+ struct gcmoxsrcyuv1 *gcmoxsrcyuv1;
+ struct gcmoxsrcyuv2 *gcmoxsrcyuv2;
+ struct gcmoxsrcyuv3 *gcmoxsrcyuv3;
+
+ GCENTER(GCZONE_SRC);
+
+ GCDBG(GCZONE_SRC, "plane count %d.\n",
+ srcinfo->format.cs.yuv.planecount);
+
+ switch (srcinfo->format.cs.yuv.planecount) {
+ case 1:
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmoxsrcyuv1),
+ (void **) &gcmoxsrcyuv1);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Set YUV parameters. */
+ gcmoxsrcyuv1->pectrl_ldst
+ = gcmoxsrcyuv_pectrl_ldst[index];
+ gcmoxsrcyuv1->pectrl.raw = 0;
+ gcmoxsrcyuv1->pectrl.reg.standard
+ = srcinfo->format.cs.yuv.std;
+ gcmoxsrcyuv1->pectrl.reg.swizzle
+ = srcinfo->format.swizzle;
+ gcmoxsrcyuv1->pectrl.reg.convert
+ = GCREG_PE_CONTROL_YUVRGB_DISABLED;
+ break;
+
+ case 2:
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmoxsrcyuv2),
+ (void **) &gcmoxsrcyuv2);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Set YUV parameters. */
+ gcmoxsrcyuv2->pectrl_ldst
+ = gcmoxsrcyuv_pectrl_ldst[index];
+ gcmoxsrcyuv2->pectrl.raw = 0;
+ gcmoxsrcyuv2->pectrl.reg.standard
+ = srcinfo->format.cs.yuv.std;
+ gcmoxsrcyuv2->pectrl.reg.swizzle
+ = srcinfo->format.swizzle;
+ gcmoxsrcyuv2->pectrl.reg.convert
+ = GCREG_PE_CONTROL_YUVRGB_DISABLED;
+
+ /* Program U/V plane. */
+ add_fixup(bvbltparams, batch, &gcmoxsrcyuv2->uplaneaddress,
+ srcinfo->bytealign2);
+ gcmoxsrcyuv2->uplaneaddress_ldst
+ = gcmoxsrcyuv_uplaneaddress_ldst[index];
+ gcmoxsrcyuv2->uplaneaddress = GET_MAP_HANDLE(srcmap);
+ gcmoxsrcyuv2->uplanestride_ldst
+ = gcmoxsrcyuv_uplanestride_ldst[index];
+ gcmoxsrcyuv2->uplanestride = srcinfo->stride2;
+ break;
+
+ case 3:
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmoxsrcyuv3),
+ (void **) &gcmoxsrcyuv3);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Set YUV parameters. */
+ gcmoxsrcyuv3->pectrl_ldst
+ = gcmoxsrcyuv_pectrl_ldst[index];
+ gcmoxsrcyuv3->pectrl.raw = 0;
+ gcmoxsrcyuv3->pectrl.reg.standard
+ = srcinfo->format.cs.yuv.std;
+ gcmoxsrcyuv3->pectrl.reg.swizzle
+ = srcinfo->format.swizzle;
+ gcmoxsrcyuv3->pectrl.reg.convert
+ = GCREG_PE_CONTROL_YUVRGB_DISABLED;
+
+ /* Program U/V planes. */
+ add_fixup(bvbltparams, batch, &gcmoxsrcyuv3->uplaneaddress,
+ srcinfo->bytealign2);
+ add_fixup(bvbltparams, batch, &gcmoxsrcyuv3->vplaneaddress,
+ srcinfo->bytealign3);
+ gcmoxsrcyuv3->uplaneaddress_ldst
+ = gcmoxsrcyuv_uplaneaddress_ldst[index];
+ gcmoxsrcyuv3->uplaneaddress = GET_MAP_HANDLE(srcmap);
+ gcmoxsrcyuv3->uplanestride_ldst
+ = gcmoxsrcyuv_uplanestride_ldst[index];
+ gcmoxsrcyuv3->uplanestride = srcinfo->stride2;
+ gcmoxsrcyuv3->vplaneaddress_ldst
+ = gcmoxsrcyuv_vplaneaddress_ldst[index];
+ gcmoxsrcyuv3->vplaneaddress = GET_MAP_HANDLE(srcmap);
+ gcmoxsrcyuv3->vplanestride_ldst
+ = gcmoxsrcyuv_vplanestride_ldst[index];
+ gcmoxsrcyuv3->vplanestride = srcinfo->stride3;
+ break;
+
+ default:
+ GCERR("invlaid plane count %d.\n",
+ srcinfo->format.cs.yuv.planecount);
+ }
+
+exit:
+ GCEXITARG(GCZONE_SRC, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
+
+/*******************************************************************************
+ * Surface compare and validation.
+ */
+
+static inline bool equal_rects(struct bvrect *rect1, struct bvrect *rect2)
+{
+ if (rect1->left != rect2->left)
+ return false;
+
+ if (rect1->top != rect2->top)
+ return false;
+
+ if (rect1->width != rect2->width)
+ return false;
+
+ if (rect1->height != rect2->height)
+ return false;
+
+ return true;
+}
+
+/* The function verifies whether the two buffer descriptors and rectangles
+ define the same physical area. */
+static bool same_phys_area(struct bvbuffdesc *surf1, struct bvrect *rect1,
+ struct bvbuffdesc *surf2, struct bvrect *rect2)
+{
+ struct bvphysdesc *physdesc1;
+ struct bvphysdesc *physdesc2;
+
+ /* If pointers are the same, things are much easier. */
+ if (surf1 == surf2)
+ /* Compare the rectangles. For simplicity we don't consider
+ cases with partially overlapping rectangles at this time. */
+ return equal_rects(rect1, rect2);
+
+ /* Assume diffrent areas if the types are different. */
+ if (surf1->auxtype != surf2->auxtype)
+ return false;
+
+ if (surf1->auxtype == BVAT_PHYSDESC) {
+ physdesc1 = (struct bvphysdesc *) surf1->auxptr;
+ physdesc2 = (struct bvphysdesc *) surf2->auxptr;
+
+ /* Same physical descriptor? */
+ if (physdesc1 == physdesc2)
+ return equal_rects(rect1, rect2);
+
+ /* Same page array? */
+ if (physdesc1->pagearray == physdesc2->pagearray)
+ return equal_rects(rect1, rect2);
+
+ /* Pageoffsets must match since different buffers
+ * can share the same first page (eg nv12).
+ */
+ if (physdesc1->pageoffset != physdesc2->pageoffset)
+ return false;
+
+ /* Assume the same surface if first pages match. */
+ if (physdesc1->pagearray[0] == physdesc2->pagearray[0])
+ return equal_rects(rect1, rect2);
+
+ } else {
+ if (surf1->virtaddr == surf2->virtaddr)
+ return equal_rects(rect1, rect2);
+ }
+
+ return false;
+}
+
+static int verify_surface(unsigned int tile,
+ union bvinbuff *surf,
+ struct bvsurfgeom *geom)
+{
+ if (tile) {
+ if (surf->tileparams == NULL)
+ return GCBVERR_TILE;
+
+ if (surf->tileparams->structsize <
+ STRUCTSIZE(surf->tileparams, srcheight))
+ return GCBVERR_TILE_VERS;
+
+ /* FIXME/TODO */
+ return GCBVERR_TILE;
+ } else {
+ if (surf->desc == NULL)
+ return GCBVERR_DESC;
+
+ if (surf->desc->structsize < STRUCTSIZE(surf->desc, map))
+ return GCBVERR_DESC_VERS;
+ }
+
+ if (geom == NULL)
+ return GCBVERR_GEOM;
+
+ if (geom->structsize < STRUCTSIZE(geom, palette))
+ return GCBVERR_GEOM_VERS;
+
+ /* Validation successful. */
+ return -1;
+}
+
+
+/*******************************************************************************
+ * Library constructor and destructor.
+ */
+
+void bv_init(void)
+{
+ struct gccontext *gccontext = get_context();
+ struct gcicaps gcicaps;
+ unsigned i, j;
+
+ GCDBG_REGISTER(bv);
+ GCDBG_REGISTER(parser);
+ GCDBG_REGISTER(map);
+ GCDBG_REGISTER(buffer);
+ GCDBG_REGISTER(fill);
+ GCDBG_REGISTER(blit);
+ GCDBG_REGISTER(filter);
+
+ GCLOCK_INIT(&gccontext->batchlock);
+ GCLOCK_INIT(&gccontext->bufferlock);
+ GCLOCK_INIT(&gccontext->fixuplock);
+ GCLOCK_INIT(&gccontext->maplock);
+ GCLOCK_INIT(&gccontext->callbacklock);
+
+ INIT_LIST_HEAD(&gccontext->unmapvac);
+ INIT_LIST_HEAD(&gccontext->buffervac);
+ INIT_LIST_HEAD(&gccontext->fixupvac);
+ INIT_LIST_HEAD(&gccontext->batchvac);
+ INIT_LIST_HEAD(&gccontext->callbacklist);
+ INIT_LIST_HEAD(&gccontext->callbackvac);
+
+ /* Initialize the filter cache. */
+ for (i = 0; i < GC_FILTER_COUNT; i += 1)
+ for (j = 0; j < GC_TAP_COUNT; j += 1)
+ INIT_LIST_HEAD(&gccontext->filtercache[i][j].list);
+
+ /* Query hardware caps. */
+ gc_getcaps_wrapper(&gcicaps);
+ if (gcicaps.gcerror == GCERR_NONE) {
+ gccontext->gcmodel = gcicaps.gcmodel;
+ gccontext->gcrevision = gcicaps.gcrevision;
+ gccontext->gcdate = gcicaps.gcdate;
+ gccontext->gctime = gcicaps.gctime;
+ gccontext->gcfeatures = gcicaps.gcfeatures;
+ gccontext->gcfeatures0 = gcicaps.gcfeatures0;
+ gccontext->gcfeatures1 = gcicaps.gcfeatures1;
+ gccontext->gcfeatures2 = gcicaps.gcfeatures2;
+ gccontext->gcfeatures3 = gcicaps.gcfeatures3;
+ }
+}
+
+void bv_exit(void)
+{
+ struct gccontext *gccontext = get_context();
+ struct bvbuffmap *bvbuffmap;
+ struct list_head *head;
+ struct gcschedunmap *gcschedunmap;
+ struct gcbuffer *gcbuffer;
+ struct gcfixup *gcfixup;
+ struct gcbatch *gcbatch;
+ struct gccallbackinfo *gccallbackinfo;
+
+ while (gccontext->buffmapvac != NULL) {
+ bvbuffmap = gccontext->buffmapvac;
+ gccontext->buffmapvac = bvbuffmap->nextmap;
+ gcfree(bvbuffmap);
+ }
+
+ while (!list_empty(&gccontext->unmapvac)) {
+ head = gccontext->unmapvac.next;
+ gcschedunmap = list_entry(head, struct gcschedunmap, link);
+ list_del(head);
+ gcfree(gcschedunmap);
+ }
+
+ while (!list_empty(&gccontext->buffervac)) {
+ head = gccontext->buffervac.next;
+ gcbuffer = list_entry(head, struct gcbuffer, link);
+ list_del(head);
+ gcfree(gcbuffer);
+ }
+
+ while (!list_empty(&gccontext->fixupvac)) {
+ head = gccontext->fixupvac.next;
+ gcfixup = list_entry(head, struct gcfixup, link);
+ list_del(head);
+ gcfree(gcfixup);
+ }
+
+ while (!list_empty(&gccontext->batchvac)) {
+ head = gccontext->batchvac.next;
+ gcbatch = list_entry(head, struct gcbatch, link);
+ list_del(head);
+ gcfree(gcbatch);
+ }
+
+ while (!list_empty(&gccontext->callbacklist)) {
+ head = gccontext->callbacklist.next;
+ list_move(head, &gccontext->callbackvac);
+ }
+
+ while (!list_empty(&gccontext->callbackvac)) {
+ head = gccontext->callbackvac.next;
+ gccallbackinfo = list_entry(head, struct gccallbackinfo, link);
+ list_del(head);
+ gcfree(gccallbackinfo);
+ }
+
+ free_temp(false);
+}
+
+
+/*******************************************************************************
+ * Library API.
+ */
+
+enum bverror bv_map(struct bvbuffdesc *bvbuffdesc)
+{
+ enum bverror bverror;
+ struct bvbuffmap *bvbuffmap;
+
+ GCENTERARG(GCZONE_MAPPING, "bvbuffdesc = 0x%08X\n",
+ (unsigned int) bvbuffdesc);
+
+ if (bvbuffdesc == NULL) {
+ BVSETERROR(BVERR_BUFFERDESC, "bvbuffdesc is NULL");
+ goto exit;
+ }
+
+ if (bvbuffdesc->structsize < STRUCTSIZE(bvbuffdesc, map)) {
+ BVSETERROR(BVERR_BUFFERDESC_VERS, "argument has invalid size");
+ goto exit;
+ }
+
+ bverror = do_map(bvbuffdesc, NULL, &bvbuffmap);
+
+exit:
+ GCEXITARG(GCZONE_MAPPING, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
+
+enum bverror bv_unmap(struct bvbuffdesc *bvbuffdesc)
+{
+ enum bverror bverror = BVERR_NONE;
+ enum bverror otherbverror = BVERR_NONE;
+ struct gccontext *gccontext = get_context();
+ struct bvbuffmap *prev = NULL;
+ struct bvbuffmap *bvbuffmap;
+ struct bvbuffmapinfo *bvbuffmapinfo;
+ struct gcimap gcimap;
+
+ GCENTERARG(GCZONE_MAPPING, "bvbuffdesc = 0x%08X\n",
+ (unsigned int) bvbuffdesc);
+
+ /* Lock access to the mapping list. */
+ GCLOCK(&gccontext->maplock);
+
+ if (bvbuffdesc == NULL) {
+ BVSETERROR(BVERR_BUFFERDESC, "bvbuffdesc is NULL");
+ goto exit;
+ }
+
+ if (bvbuffdesc->structsize < STRUCTSIZE(bvbuffdesc, map)) {
+ BVSETERROR(BVERR_BUFFERDESC_VERS, "argument has invalid size");
+ goto exit;
+ }
+
+ /* Is the buffer mapped? */
+ bvbuffmap = bvbuffdesc->map;
+ if (bvbuffmap == NULL) {
+ GCDBG(GCZONE_MAPPING, "buffer isn't mapped.\n");
+ goto exit;
+ }
+
+ /* Try to find our mapping. */
+ while (bvbuffmap != NULL) {
+ if (bvbuffmap->bv_unmap == bv_unmap)
+ break;
+ prev = bvbuffmap;
+ bvbuffmap = bvbuffmap->nextmap;
+ }
+
+ /* Are there other implementations? */
+ if ((prev != NULL) || (bvbuffmap->nextmap != NULL)) {
+ GCDBG(GCZONE_MAPPING,
+ "have mappings from other implementations.\n");
+
+ /* Was our mapping found? */
+ if (bvbuffmap == NULL) {
+ GCDBG(GCZONE_MAPPING,
+ "no mapping from our implementation.\n");
+
+ /* No, call other implementations. */
+ bverror = bvbuffdesc->map->bv_unmap(bvbuffdesc);
+ goto exit;
+ }
+
+ if (bvbuffmap->structsize
+ < STRUCTSIZE(bvbuffmap, nextmap)) {
+ BVSETERROR(BVERR_BUFFERDESC_VERS,
+ "unsupported bvbuffdesc version");
+ goto exit;
+ }
+
+ /* Remove our mapping. */
+ if (prev == NULL)
+ bvbuffdesc->map = bvbuffmap->nextmap;
+ else
+ prev->nextmap = bvbuffmap->nextmap;
+
+ /* Call other implementation. */
+ otherbverror = bvbuffdesc->map->bv_unmap(bvbuffdesc);
+
+ /* Add our mapping back. */
+ bvbuffmap->nextmap = bvbuffdesc->map;
+ bvbuffdesc->map = bvbuffmap;
+ prev = NULL;
+ } else {
+ GCDBG(GCZONE_MAPPING,
+ "no mappings from other implementations.\n");
+ }
+
+ /* Get the info structure. */
+ bvbuffmapinfo = (struct bvbuffmapinfo *) bvbuffmap->handle;
+
+ GCDBG(GCZONE_MAPPING, "bvbuffmap = 0x%08X\n", (unsigned int) bvbuffmap);
+ GCDBG(GCZONE_MAPPING, "handle = 0x%08X\n", bvbuffmapinfo->handle);
+
+ /* Explicit unmapping. */
+ if (bvbuffmapinfo->usermap == 0)
+ GCERR("explicit count is already zero.\n");
+ bvbuffmapinfo->usermap = 0;
+
+ GCDBG(GCZONE_MAPPING, "explicit count = %d\n",
+ bvbuffmapinfo->usermap);
+ GCDBG(GCZONE_MAPPING, "implicit count = %d\n",
+ bvbuffmapinfo->automap);
+
+ /* Do we have implicit mappings? */
+ if (bvbuffmapinfo->automap > 0) {
+ GCDBG(GCZONE_MAPPING, "have implicit unmappings.\n");
+ goto exit;
+ }
+
+ /* Unmap the buffer. */
+ memset(&gcimap, 0, sizeof(gcimap));
+ gcimap.handle = bvbuffmapinfo->handle;
+ gc_unmap_wrapper(&gcimap);
+ if (gcimap.gcerror != GCERR_NONE) {
+ BVSETERROR(BVERR_OOM, "unable to free gccore memory");
+ goto exit;
+ }
+
+ /* Remove from the buffer descriptor list. */
+ if (prev == NULL)
+ bvbuffdesc->map = bvbuffmap->nextmap;
+ else
+ prev->nextmap = bvbuffmap->nextmap;
+
+ /* Invalidate the record. */
+ bvbuffmap->structsize = 0;
+
+ /* Add to the vacant list. */
+ bvbuffmap->nextmap = gccontext->buffmapvac;
+ gccontext->buffmapvac = bvbuffmap;
+
+exit:
+ /* Unlock access to the mapping list. */
+ GCUNLOCK(&gccontext->maplock);
+
+ GCEXITARG(GCZONE_MAPPING, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
+
+enum bverror bv_blt(struct bvbltparams *bvbltparams)
+{
+ enum bverror bverror = BVERR_NONE;
+ struct gccontext *gccontext = get_context();
+ struct gcalpha *gca = NULL;
+ struct gcalpha _gca;
+ unsigned int op, type, blend, format;
+ unsigned int batchexec = 0;
+ bool nop = false;
+ struct gcbatch *gcbatch;
+ struct bvrect *dstrect;
+ int src1used, src2used, maskused;
+ struct surfaceinfo srcinfo[2];
+ struct bvrect *srcrect[2];
+ unsigned short rop;
+ struct gcicommit gcicommit;
+ int i, srccount, res;
+
+ GCENTERARG(GCZONE_BLIT, "bvbltparams = 0x%08X\n",
+ (unsigned int) bvbltparams);
+
+ /* Verify blt parameters structure. */
+ if (bvbltparams == NULL) {
+ BVSETERROR(BVERR_BLTPARAMS_VERS, "bvbltparams is NULL");
+ goto exit;
+ }
+
+ if (bvbltparams->structsize < STRUCTSIZE(bvbltparams, callbackdata)) {
+ BVSETERROR(BVERR_BLTPARAMS_VERS, "argument has invalid size");
+ goto exit;
+ }
+
+ /* Reset the error message. */
+ bvbltparams->errdesc = NULL;
+
+ /* Verify the destination parameters structure. */
+ res = verify_surface(0, (union bvinbuff *) &bvbltparams->dstdesc,
+ bvbltparams->dstgeom);
+ if (res != -1) {
+ BVSETBLTSURFERROR(res, g_destsurferr);
+ goto exit;
+ }
+
+ /* Extract the operation flags. */
+ op = (bvbltparams->flags & BVFLAG_OP_MASK) >> BVFLAG_OP_SHIFT;
+ type = (bvbltparams->flags & BVFLAG_BATCH_MASK) >> BVFLAG_BATCH_SHIFT;
+ GCDBG(GCZONE_BLIT, "op = %d\n", op);
+ GCDBG(GCZONE_BLIT, "type = %d\n", type);
+
+ switch (type) {
+ case (BVFLAG_BATCH_NONE >> BVFLAG_BATCH_SHIFT):
+ bverror = allocate_batch(bvbltparams, &gcbatch);
+ if (bverror != BVERR_NONE) {
+ bvbltparams->errdesc = gccontext->bverrorstr;
+ goto exit;
+ }
+
+ batchexec = 1;
+ gcbatch->batchflags = 0x7FFFFFFF;
+
+ GCDBG(GCZONE_BATCH, "BVFLAG_BATCH_NONE(0x%08X)\n",
+ (unsigned int) gcbatch);
+ break;
+
+ case (BVFLAG_BATCH_BEGIN >> BVFLAG_BATCH_SHIFT):
+ bverror = allocate_batch(bvbltparams, &gcbatch);
+ if (bverror != BVERR_NONE) {
+ bvbltparams->errdesc = gccontext->bverrorstr;
+ goto exit;
+ }
+
+ bvbltparams->batch = (struct bvbatch *) gcbatch;
+
+ batchexec = 0;
+ bvbltparams->batchflags =
+ gcbatch->batchflags = 0x7FFFFFFF;
+
+ GCDBG(GCZONE_BATCH, "BVFLAG_BATCH_BEGIN(0x%08X)\n",
+ (unsigned int) gcbatch);
+ break;
+
+ case (BVFLAG_BATCH_CONTINUE >> BVFLAG_BATCH_SHIFT):
+ gcbatch = (struct gcbatch *) bvbltparams->batch;
+ if (gcbatch == NULL) {
+ BVSETBLTERROR(BVERR_BATCH, "batch is not initialized");
+ goto exit;
+ }
+
+ if (gcbatch->structsize < STRUCTSIZE(gcbatch, unmap)) {
+ BVSETBLTERROR(BVERR_BATCH, "invalid batch");
+ goto exit;
+ }
+
+ batchexec = 0;
+ gcbatch->batchflags = bvbltparams->batchflags;
+
+ GCDBG(GCZONE_BATCH, "BVFLAG_BATCH_CONTINUE(0x%08X)\n",
+ (unsigned int) gcbatch);
+ break;
+
+ case (BVFLAG_BATCH_END >> BVFLAG_BATCH_SHIFT):
+ gcbatch = (struct gcbatch *) bvbltparams->batch;
+ if (gcbatch == NULL) {
+ BVSETBLTERROR(BVERR_BATCH, "batch is not initialized");
+ goto exit;
+ }
+
+ if (gcbatch->structsize < STRUCTSIZE(gcbatch, unmap)) {
+ BVSETBLTERROR(BVERR_BATCH, "invalid batch");
+ goto exit;
+ }
+
+ batchexec = 1;
+ nop = (bvbltparams->batchflags & BVBATCH_ENDNOP) != 0;
+ gcbatch->batchflags = bvbltparams->batchflags;
+
+ GCDBG(GCZONE_BATCH, "BVFLAG_BATCH_END(0x%08X)\n",
+ (unsigned int) gcbatch);
+ break;
+
+ default:
+ BVSETBLTERROR(BVERR_BATCH, "unrecognized batch type");
+ goto exit;
+ }
+
+ GCDBG(GCZONE_BATCH, "batchflags=0x%08X\n",
+ (unsigned int) gcbatch->batchflags);
+
+ if (!nop) {
+ /* Get a shortcut to the destination rectangle. */
+ dstrect = &bvbltparams->dstrect;
+
+ /* Verify the batch change flags. */
+ GCVERIFYBATCH(gcbatch->batchflags >> 12,
+ &gcbatch->prevdstrect, dstrect);
+
+ switch (op) {
+ case (BVFLAG_ROP >> BVFLAG_OP_SHIFT):
+ GCDBG(GCZONE_BLIT, "BVFLAG_ROP\n");
+
+ rop = bvbltparams->op.rop;
+ src1used = ((rop & 0xCCCC) >> 2)
+ ^ (rop & 0x3333);
+ src2used = ((rop & 0xF0F0) >> 4)
+ ^ (rop & 0x0F0F);
+ maskused = ((rop & 0xFF00) >> 8)
+ ^ (rop & 0x00FF);
+ break;
+
+ case (BVFLAG_BLEND >> BVFLAG_OP_SHIFT):
+ GCDBG(GCZONE_BLIT, "BVFLAG_BLEND\n");
+
+ blend = bvbltparams->op.blend;
+ format = (blend & BVBLENDDEF_FORMAT_MASK)
+ >> BVBLENDDEF_FORMAT_SHIFT;
+
+ bverror = parse_blend(bvbltparams, blend, &_gca);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ gca = &_gca;
+
+ switch (format) {
+ case (BVBLENDDEF_FORMAT_CLASSIC
+ >> BVBLENDDEF_FORMAT_SHIFT):
+ src1used = gca->src1used;
+ src2used = gca->src2used;
+ maskused = blend & BVBLENDDEF_REMOTE;
+ break;
+
+ default:
+ BVSETBLTERROR(BVERR_BLEND,
+ "unrecognized blend format");
+ goto exit;
+ }
+ break;
+
+ case (BVFLAG_FILTER >> BVFLAG_OP_SHIFT):
+ GCDBG(GCZONE_BLIT, "BVFLAG_FILTER\n");
+ BVSETBLTERROR(BVERR_OP,
+ "filter operation not supported");
+ goto exit;
+
+ default:
+ BVSETBLTERROR(BVERR_OP, "unrecognized operation");
+ goto exit;
+ }
+
+ /* Reset the number of sources. */
+ srccount = 0;
+
+ /* Verify the src1 parameters structure. */
+ if (src1used) {
+ GCDBG(GCZONE_SRC, "source #1: used\n");
+ res = verify_surface(
+ bvbltparams->flags & BVBATCH_TILE_SRC1,
+ &bvbltparams->src1, bvbltparams->src1geom);
+ if (res != -1) {
+ BVSETBLTSURFERROR(res, g_src1surferr);
+ goto exit;
+ }
+
+ /* Verify the batch change flags. */
+ GCVERIFYBATCH(gcbatch->batchflags >> 14,
+ &gcbatch->prevsrc1rect,
+ &bvbltparams->src1rect);
+
+ /* Same as the destination? */
+ if (same_phys_area(bvbltparams->src1.desc,
+ &bvbltparams->src1rect,
+ bvbltparams->dstdesc,
+ dstrect)) {
+ GCDBG(GCZONE_BLIT, " same as destination\n");
+ } else {
+ srcinfo[srccount].index = 0;
+ srcinfo[srccount].buf = bvbltparams->src1;
+ srcinfo[srccount].geom = bvbltparams->src1geom;
+ srcinfo[srccount].newgeom
+ = gcbatch->batchflags
+ & BVBATCH_SRC1;
+ srcinfo[srccount].newrect
+ = gcbatch->batchflags
+ & (BVBATCH_SRC1RECT_ORIGIN |
+ BVBATCH_SRC1RECT_SIZE);
+ srcrect[srccount] = &bvbltparams->src1rect;
+
+ bverror = parse_source(bvbltparams, gcbatch,
+ &bvbltparams->src1rect,
+ &srcinfo[srccount]);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ srccount += 1;
+ }
+ }
+
+ /* Verify the src2 parameters structure. */
+ if (src2used) {
+ GCDBG(GCZONE_SRC, "source #2: used\n");
+ res = verify_surface(
+ bvbltparams->flags & BVBATCH_TILE_SRC2,
+ &bvbltparams->src2, bvbltparams->src2geom);
+ if (res != -1) {
+ BVSETBLTSURFERROR(res, g_src2surferr);
+ goto exit;
+ }
+
+ /* Verify the batch change flags. */
+ GCVERIFYBATCH(gcbatch->batchflags >> 16,
+ &gcbatch->prevsrc2rect,
+ &bvbltparams->src2rect);
+
+ /* Same as the destination? */
+ if (same_phys_area(bvbltparams->src2.desc,
+ &bvbltparams->src2rect,
+ bvbltparams->dstdesc,
+ dstrect)) {
+ GCDBG(GCZONE_BLIT, " same as destination\n");
+ } else {
+ srcinfo[srccount].index = 1;
+ srcinfo[srccount].buf = bvbltparams->src2;
+ srcinfo[srccount].geom = bvbltparams->src2geom;
+ srcinfo[srccount].newgeom
+ = gcbatch->batchflags
+ & BVBATCH_SRC2;
+ srcinfo[srccount].newrect
+ = gcbatch->batchflags
+ & (BVBATCH_SRC2RECT_ORIGIN |
+ BVBATCH_SRC2RECT_SIZE);
+ srcrect[srccount] = &bvbltparams->src2rect;
+
+ bverror = parse_source(bvbltparams, gcbatch,
+ &bvbltparams->src2rect,
+ &srcinfo[srccount]);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ srccount += 1;
+ }
+ }
+
+ /* Verify the mask parameters structure. */
+ if (maskused) {
+ GCDBG(GCZONE_MASK, "mask: used\n");
+ res = verify_surface(
+ bvbltparams->flags & BVBATCH_TILE_MASK,
+ &bvbltparams->mask, bvbltparams->maskgeom);
+ if (res != -1) {
+ BVSETBLTSURFERROR(res, g_masksurferr);
+ goto exit;
+ }
+
+ /* Verify the batch change flags. */
+ GCVERIFYBATCH(gcbatch->batchflags >> 18,
+ &gcbatch->prevmaskrect,
+ &bvbltparams->maskrect);
+
+ BVSETBLTERROR(BVERR_OP,
+ "operation with mask not supported");
+ goto exit;
+ }
+
+ GCDBG(GCZONE_BLIT, "srccount = %d\n", srccount);
+
+ if (srccount == 0) {
+ BVSETBLTERROR(BVERR_OP,
+ "operation not supported");
+ goto exit;
+ } else {
+ for (i = 0; i < srccount; i += 1) {
+ int srcw, srch;
+ GCDBG(GCZONE_BLIT,
+ "processing source %d.\n",
+ srcinfo[i].index + 1);
+
+ if (gca == NULL) {
+ GCDBG(GCZONE_BLIT,
+ " blending disabled.\n");
+ srcinfo[i].rop = bvbltparams->op.rop;
+ srcinfo[i].gca = NULL;
+ } else if ((i + 1) != srccount) {
+ GCDBG(GCZONE_BLIT,
+ " disabling blending for "
+ "the first source.\n");
+ srcinfo[i].rop = 0xCC;
+ srcinfo[i].gca = NULL;
+ } else {
+ GCDBG(GCZONE_BLIT,
+ " enabling blending.\n");
+ srcinfo[i].rop = 0xCC;
+ srcinfo[i].gca = gca;
+
+ if (srccount == 1) {
+ gca->srcconfig = gca->k1;
+ gca->dstconfig = gca->k2;
+ } else {
+ gca->srcconfig = gca->k2;
+ gca->dstconfig = gca->k1;
+ }
+ }
+
+ GCDBG(GCZONE_BLIT, " srcsize %dx%d.\n",
+ srcrect[i]->width, srcrect[i]->height);
+ GCDBG(GCZONE_BLIT, " dstsize %dx%d.\n",
+ dstrect->width, dstrect->height);
+
+ srcw = srcrect[i]->width;
+ srch = srcrect[i]->height;
+ if ((srcw == 1) && (srch == 1) &&
+ (bvbltparams->src1.desc->virtaddr)) {
+ GCDBG(GCZONE_BLIT, " op: fill.\n");
+ bverror = do_fill(bvbltparams,
+ gcbatch,
+ &srcinfo[i]);
+ } else if ((srcw == dstrect->width) &&
+ (srch == dstrect->height)) {
+ GCDBG(GCZONE_BLIT, " op: bitblit.\n");
+ bverror = do_blit(bvbltparams,
+ gcbatch,
+ &srcinfo[i]);
+ } else {
+ GCDBG(GCZONE_BLIT, " op: filter.\n");
+ bverror = do_filter(bvbltparams,
+ gcbatch,
+ &srcinfo[i]);
+ }
+
+ if (bverror != BVERR_NONE)
+ goto exit;
+ }
+ }
+ }
+
+ if (batchexec) {
+ struct gcmoflush *flush;
+
+ GCDBG(GCZONE_BLIT, "preparing to submit the batch.\n");
+
+ /* Finalize the current operation. */
+ bverror = gcbatch->batchend(bvbltparams, gcbatch);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Add PE flush. */
+ GCDBG(GCZONE_BLIT, "appending the flush.\n");
+ bverror = claim_buffer(bvbltparams, gcbatch,
+ sizeof(struct gcmoflush),
+ (void **) &flush);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ flush->flush_ldst = gcmoflush_flush_ldst;
+ flush->flush.reg = gcregflush_pe2D;
+
+ /* Process asynchronous operation. */
+ if ((bvbltparams->flags & BVFLAG_ASYNC) == 0) {
+ GCDBG(GCZONE_BLIT, "synchronous batch.\n");
+ gcicommit.callback = NULL;
+ gcicommit.callbackparam = NULL;
+ gcicommit.asynchronous = false;
+ } else {
+ struct gccallbackinfo *gccallbackinfo;
+
+ GCDBG(GCZONE_BLIT, "asynchronous batch (0x%08X):\n",
+ bvbltparams->flags);
+
+ if (bvbltparams->callbackfn == NULL) {
+ GCDBG(GCZONE_BLIT, "no callback given.\n");
+ gcicommit.callback = NULL;
+ gcicommit.callbackparam = NULL;
+ } else {
+ bverror = get_callbackinfo(&gccallbackinfo);
+ if (bverror != BVERR_NONE) {
+ BVSETBLTERROR(BVERR_OOM,
+ "callback allocation "
+ "failed");
+ goto exit;
+ }
+
+ gccallbackinfo->info.callback.fn
+ = bvbltparams->callbackfn;
+ gccallbackinfo->info.callback.data
+ = bvbltparams->callbackdata;
+
+ gcicommit.callback = callbackbltsville;
+ gcicommit.callbackparam = gccallbackinfo;
+
+ GCDBG(GCZONE_BLIT,
+ "gcbv_callback = 0x%08X\n",
+ (unsigned int) gcicommit.callback);
+ GCDBG(GCZONE_BLIT,
+ "gcbv_param = 0x%08X\n",
+ (unsigned int) gcicommit.callbackparam);
+ GCDBG(GCZONE_BLIT,
+ "bltsville_callback = 0x%08X\n",
+ (unsigned int)
+ gccallbackinfo->info.callback.fn);
+ GCDBG(GCZONE_BLIT,
+ "bltsville_param = 0x%08X\n",
+ (unsigned int)
+ gccallbackinfo->info.callback.data);
+ }
+
+ gcicommit.asynchronous = true;
+ }
+
+ /* Process scheduled unmappings. */
+ do_unmap_implicit(gcbatch);
+
+ INIT_LIST_HEAD(&gcicommit.unmap);
+ list_splice_init(&gcbatch->unmap, &gcicommit.unmap);
+
+ /* Pass the batch for execution. */
+ GCDUMPBATCH(gcbatch);
+
+ gcicommit.gcerror = GCERR_NONE;
+ gcicommit.entrypipe = GCPIPE_2D;
+ gcicommit.exitpipe = GCPIPE_2D;
+
+ INIT_LIST_HEAD(&gcicommit.buffer);
+ list_splice_init(&gcbatch->buffer, &gcicommit.buffer);
+
+ GCDBG(GCZONE_BLIT, "submitting the batch.\n");
+ gc_commit_wrapper(&gcicommit);
+
+ /* Move the lists back to the batch. */
+ list_splice_init(&gcicommit.buffer, &gcbatch->buffer);
+ list_splice_init(&gcicommit.unmap, &gcbatch->unmap);
+
+ /* Error? */
+ if (gcicommit.gcerror != GCERR_NONE) {
+ switch (gcicommit.gcerror) {
+ case GCERR_OODM:
+ case GCERR_CTX_ALLOC:
+ BVSETBLTERROR(BVERR_OOM,
+ "unable to allocate gccore "
+ "memory");
+ goto exit;
+ default:
+ BVSETBLTERROR(BVERR_RSRC,
+ "gccore error");
+
+ goto exit;
+ }
+ }
+
+ GCDBG(GCZONE_BLIT, "batch is submitted.\n");
+ }
+
+exit:
+ if ((gcbatch != NULL) && batchexec) {
+ free_batch(gcbatch);
+ bvbltparams->batch = NULL;
+ }
+
+ GCEXITARG(GCZONE_BLIT, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
+
+enum bverror bv_cache(struct bvcopparams *copparams)
+{
+ enum bverror bverror = BVERR_NONE;
+ unsigned int bytespp = 0; /* bytes per pixel */
+ unsigned long vert_offset, horiz_offset;
+ unsigned int true_width, true_height;
+
+ struct c2dmrgn rgn[3];
+ int container_size = 0;
+
+ unsigned long subsample;
+ unsigned long vendor;
+ unsigned long layout;
+ unsigned long size;
+ unsigned long container;
+
+ subsample = copparams->geom->format & OCDFMTDEF_SUBSAMPLE_MASK;
+ vendor = copparams->geom->format & OCDFMTDEF_VENDOR_MASK;
+ layout = copparams->geom->format & OCDFMTDEF_LAYOUT_MASK;
+ size = copparams->geom->format & OCDFMTDEF_COMPONENTSIZEMINUS1_MASK;
+ container = copparams->geom->format & OCDFMTDEF_CONTAINER_MASK;
+
+ if (vendor != OCDFMTDEF_VENDOR_ALL) {
+ bverror = BVERR_FORMAT;
+ goto exit;
+ }
+
+ if (copparams->geom->orientation % 180 != 0) {
+ true_width = copparams->rect->height;
+ true_height = copparams->rect->width;
+ } else {
+ true_width = copparams->rect->width;
+ true_height = copparams->rect->height;
+ }
+
+ switch (container) {
+ case OCDFMTDEF_CONTAINER_8BIT:
+ container_size = 8;
+ break;
+
+ case OCDFMTDEF_CONTAINER_16BIT:
+ container_size = 16;
+ break;
+
+ case OCDFMTDEF_CONTAINER_24BIT:
+ container_size = 24;
+ break;
+
+ case OCDFMTDEF_CONTAINER_32BIT:
+ container_size = 32;
+ break;
+
+ case OCDFMTDEF_CONTAINER_48BIT:
+ container_size = 48;
+ break;
+
+ case OCDFMTDEF_CONTAINER_64BIT:
+ container_size = 64;
+ break;
+ }
+
+ switch (layout) {
+ case OCDFMTDEF_PACKED:
+ switch (subsample) {
+ case OCDFMTDEF_SUBSAMPLE_NONE:
+ if (size >= 8) {
+ bytespp = container_size / 8;
+ } else {
+ GCERR("format not supported.\n");
+ bverror = BVERR_FORMAT;
+ goto exit;
+ }
+ break;
+
+ case OCDFMTDEF_SUBSAMPLE_422_YCbCr:
+ bytespp = (container_size / 2) / 8;
+ break;
+
+ default:
+ bverror = BVERR_FORMAT;
+ goto exit;
+ }
+
+ rgn[0].span = true_width * bytespp;
+ rgn[0].lines = true_height;
+ rgn[0].stride = copparams->geom->virtstride;
+ horiz_offset = copparams->rect->left * bytespp;
+ vert_offset = copparams->rect->top;
+
+ rgn[0].start = (void *) ((unsigned long)
+ copparams->desc->virtaddr +
+ vert_offset * rgn[0].stride +
+ horiz_offset);
+
+ gcbvcacheop(1, rgn, copparams->cacheop);
+ break;
+
+ case OCDFMTDEF_2_PLANE_YCbCr:
+ /* 1 byte per pixel */
+ rgn[0].span = true_width;
+ rgn[0].lines = true_height;
+ rgn[0].stride = copparams->geom->virtstride;
+ rgn[0].start = (void *)
+ ((unsigned long) copparams->desc->virtaddr +
+ copparams->rect->top * rgn[0].stride +
+ copparams->rect->left);
+
+ rgn[1].span = true_width;
+ rgn[1].lines = true_height / 2;
+ rgn[1].stride = copparams->geom->virtstride;
+ rgn[1].start = rgn[0].start +
+ copparams->geom->height * rgn[0].stride;
+
+ GCDBG(GCZONE_CACHE,
+ "virtaddr %p start[0] 0x%08x start[1] 0x%08x\n",
+ copparams->desc->virtaddr, rgn[0].start, rgn[1].start);
+
+ gcbvcacheop(2, rgn, copparams->cacheop);
+ break;
+
+ default:
+ GCERR("format 0x%x (%d) not supported.\n",
+ copparams->geom->format, copparams->geom->format);
+ bverror = BVERR_FORMAT;
+ break;
+ }
+
+exit:
+ if (bverror != BVERR_NONE)
+ GCERR("bverror = %d\n", bverror);
+
+ return bverror;
+}
diff --git a/bltsville/gcbv/mirror/gcbv.h b/bltsville/gcbv/mirror/gcbv.h
new file mode 100644
index 0000000..6392d4f
--- /dev/null
+++ b/bltsville/gcbv/mirror/gcbv.h
@@ -0,0 +1,590 @@
+/*
+ * Copyright(c) 2012,
+ * Texas Instruments, Inc. and Vivante Corporation.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Vivante Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCBV_H
+#define GCBV_H
+
+#include "gcmain.h"
+
+/*******************************************************************************
+ * Miscellaneous defines and macros.
+ */
+
+#define GC_MAX_BASE_ALIGN 64
+
+#if !defined(BVBATCH_DESTRECT)
+#define BVBATCH_DESTRECT (BVBATCH_DSTRECT_ORIGIN | BVBATCH_DSTRECT_SIZE)
+#endif
+
+#if !defined(BVBATCH_SRC1RECT)
+#define BVBATCH_SRC1RECT (BVBATCH_SRC1RECT_ORIGIN | BVBATCH_SRC1RECT_SIZE)
+#endif
+
+#if !defined(BVBATCH_SRC2RECT)
+#define BVBATCH_SRC2RECT (BVBATCH_SRC2RECT_ORIGIN | BVBATCH_SRC2RECT_SIZE)
+#endif
+
+#define STRUCTSIZE(structptr, lastmember) \
+( \
+ (size_t) &structptr->lastmember + \
+ sizeof(structptr->lastmember) - \
+ (size_t) structptr \
+)
+
+#define GET_MAP_HANDLE(map) \
+( \
+ ((struct bvbuffmapinfo *) map->handle)->handle \
+)
+
+#define GC_CLIP_RESET_LEFT ((unsigned short) 0)
+#define GC_CLIP_RESET_TOP ((unsigned short) 0)
+#define GC_CLIP_RESET_RIGHT ((unsigned short) ((1 << 15) - 1))
+#define GC_CLIP_RESET_BOTTOM ((unsigned short) ((1 << 15) - 1))
+
+#define BVSETERROR(error, message, ...) \
+do { \
+ struct gccontext *tmpcontext = get_context(); \
+ snprintf(tmpcontext->bverrorstr, sizeof(tmpcontext->bverrorstr), \
+ message, ##__VA_ARGS__); \
+ GCDUMPSTRING("%s(%d): [ERROR] %s\n", __func__, __LINE__, \
+ tmpcontext->bverrorstr); \
+ bverror = error; \
+} while (0)
+
+#define BVSETBLTERROR(error, message, ...) \
+do { \
+ struct gccontext *tmpcontext = get_context(); \
+ snprintf(tmpcontext->bverrorstr, sizeof(tmpcontext->bverrorstr), \
+ message, ##__VA_ARGS__); \
+ GCDUMPSTRING("%s(%d): [ERROR] %s\n", __func__, __LINE__, \
+ tmpcontext->bverrorstr); \
+ bvbltparams->errdesc = tmpcontext->bverrorstr; \
+ bverror = error; \
+} while (0)
+
+#define GCPRINT_RECT(zone, name, rect) \
+{ \
+ GCDBG(zone, \
+ name " = (%d,%d)-(%d,%d), %dx%d\n", \
+ (rect)->left, (rect)->top, \
+ (rect)->right, (rect)->bottom, \
+ (rect)->right - (rect)->left, \
+ (rect)->bottom - (rect)->top); \
+}
+
+
+/*******************************************************************************
+ * Kernel table definitions.
+ */
+
+#define GC_TAP_COUNT 9
+#define GC_PHASE_BITS 5
+#define GC_PHASE_MAX_COUNT (1 << GC_PHASE_BITS)
+#define GC_PHASE_LOAD_COUNT (GC_PHASE_MAX_COUNT / 2 + 1)
+#define GC_COEFFICIENT_COUNT (GC_PHASE_LOAD_COUNT * GC_TAP_COUNT)
+#define GC_FILTER_CACHE_MAX 10
+
+enum gcfiltertype {
+ GC_FILTER_SYNC,
+ GC_FILTER_BLUR,
+
+ /* Number of supported filter types. */
+ GC_FILTER_COUNT
+};
+
+struct gcfilterkernel {
+ enum gcfiltertype type;
+ unsigned int kernelsize;
+ unsigned int srcsize;
+ unsigned int dstsize;
+ unsigned int scalefactor;
+ short kernelarray[GC_COEFFICIENT_COUNT];
+ struct list_head link;
+};
+
+struct gcfiltercache {
+ unsigned int count;
+ struct list_head list; /* gcfilterkernel */
+};
+
+
+/*******************************************************************************
+ * Global data structure.
+ */
+
+struct gccontext {
+ /* Last generated error message. */
+ char bverrorstr[128];
+
+ /* Capabilities and characteristics. */
+ unsigned int gcmodel;
+ unsigned int gcrevision;
+ unsigned int gcdate;
+ unsigned int gctime;
+ union gcfeatures gcfeatures;
+ union gcfeatures0 gcfeatures0;
+ union gcfeatures1 gcfeatures1;
+ union gcfeatures2 gcfeatures2;
+ union gcfeatures3 gcfeatures3;
+
+ /* Dynamically allocated structure cache. */
+ struct bvbuffmap *buffmapvac; /* bvbuffmap */
+ struct list_head unmapvac; /* gcschedunmap */
+ struct list_head buffervac; /* gcbuffer */
+ struct list_head fixupvac; /* gcfixup */
+ struct list_head batchvac; /* gcbatch */
+
+ /* Callback lists. */
+ struct list_head callbacklist; /* gccallbackinfo */
+ struct list_head callbackvac; /* gccallbackinfo */
+
+ /* Access locks. */
+ GCLOCK_TYPE batchlock;
+ GCLOCK_TYPE bufferlock;
+ GCLOCK_TYPE fixuplock;
+ GCLOCK_TYPE maplock;
+ GCLOCK_TYPE callbacklock;
+
+ /* Kernel table cache. */
+ struct gcfilterkernel *loadedfilter; /* gcfilterkernel */
+ struct gcfiltercache filtercache[GC_FILTER_COUNT][GC_TAP_COUNT];
+
+ /* Temporary buffer descriptor. */
+ struct bvbuffdesc *tmpbuffdesc;
+ void *tmpbuff;
+};
+
+
+/*******************************************************************************
+ * Mapping structures.
+ */
+
+/* bvbuffmap struct attachment. */
+struct bvbuffmapinfo {
+ /* Mapped handle for the buffer. */
+ unsigned long handle;
+
+ /* Number of times the client explicitly mapped this buffer. */
+ int usermap;
+
+ /* Number of times implicit mapping happened. */
+ int automap;
+};
+
+
+/*******************************************************************************
+ * Color format.
+ */
+
+#define BVFMT_RGB 1
+#define BVFMT_YUV 2
+
+struct bvcomponent {
+ unsigned int shift;
+ unsigned int size;
+ unsigned int mask;
+};
+
+struct bvcsrgb {
+ struct bvcomponent r;
+ struct bvcomponent g;
+ struct bvcomponent b;
+ struct bvcomponent a;
+};
+
+struct bvformatxlate {
+ unsigned int type;
+ unsigned int bitspp;
+ unsigned int allocbitspp;
+ unsigned int format;
+ unsigned int swizzle;
+ bool premultiplied;
+
+ union {
+ struct {
+ const struct bvcsrgb *comp;
+ } rgb;
+
+ struct {
+ unsigned int std;
+ unsigned int planecount;
+ unsigned int xsample;
+ unsigned int ysample;
+ } yuv;
+ } cs;
+};
+
+
+/*******************************************************************************
+ * Alpha blending.
+ */
+
+/* Alpha blending hardware configuration. */
+struct gcblendconfig {
+ unsigned char factor_mode;
+ unsigned char color_reverse;
+
+ bool src1used;
+ bool src2used;
+};
+
+/* Alpha blending descriptor. */
+struct gcalpha {
+ unsigned int src_global_color;
+ unsigned int dst_global_color;
+
+ unsigned char src_global_alpha_mode;
+ unsigned char dst_global_alpha_mode;
+
+ struct gcblendconfig *k1;
+ struct gcblendconfig *k2;
+
+ struct gcblendconfig *srcconfig;
+ struct gcblendconfig *dstconfig;
+
+ bool src1used;
+ bool src2used;
+};
+
+
+/*******************************************************************************
+ * Rotation and mirror defines.
+ */
+
+#define GCREG_ROT_ANGLE_ROT0 0x0
+#define GCREG_ROT_ANGLE_ROT90 0x4
+#define GCREG_ROT_ANGLE_ROT180 0x5
+#define GCREG_ROT_ANGLE_ROT270 0x6
+
+#define ROT_ANGLE_INVALID -1
+#define ROT_ANGLE_0 0
+#define ROT_ANGLE_90 1
+#define ROT_ANGLE_180 2
+#define ROT_ANGLE_270 3
+
+#define GCREG_MIRROR_NONE 0x0
+#define GCREG_MIRROR_X 0x1
+#define GCREG_MIRROR_Y 0x2
+#define GCREG_MIRROR_XY 0x3
+
+extern const unsigned int rotencoding[];
+
+
+/*******************************************************************************
+ * Surface descriptor.
+ */
+
+struct surfaceinfo {
+ /* BLTsville source index (-1 for dst, 0 for src1 and 1 for src2). */
+ int index;
+
+ /* Surface buffer descriptor. */
+ union bvinbuff buf;
+
+ /* Surface geometry. */
+ struct bvsurfgeom *geom;
+ bool newgeom;
+
+ /* Rectangle to source from/render to. */
+ struct gcrect rect;
+ bool newrect;
+
+ /* Surface format. */
+ struct bvformatxlate format;
+
+ /* Physical size of the surface (accounted for rotation). */
+ unsigned int physwidth;
+ unsigned int physheight;
+
+ /* Base address alignment. */
+ int xpixalign;
+ int ypixalign;
+ int bytealign;
+ int bytealign2;
+ int bytealign3;
+ int stride2;
+ int stride3;
+
+ /* Rotation angle. */
+ int angle;
+
+ /* Mirror setting. */
+ unsigned int mirror;
+
+ /* ROP. */
+ unsigned short rop;
+
+ /* Blending info. */
+ struct gcalpha *gca;
+};
+
+
+/*******************************************************************************
+ * Batch structures.
+ */
+
+/* Operation finalization call. */
+struct gcbatch;
+typedef enum bverror (*gcbatchend) (struct bvbltparams *bvbltparams,
+ struct gcbatch *gcbatch);
+
+/* Blit states. */
+struct gcblit {
+ /* Number of sources in the operation. */
+ unsigned int srccount;
+
+ /* Multi source enable flag. */
+ unsigned int multisrc;
+
+ /* Computed destination rectangle coordinates; in multi-source
+ * setup can be modified to match new destination and source
+ * geometry. */
+ struct gcrect dstrect;
+
+ /* Block walker enable. */
+ int blockenable;
+
+ /* Destination format and swizzle */
+ unsigned int format;
+ unsigned int swizzle;
+};
+
+/* Filter states. */
+struct gcfilter {
+ /* Kernel size. */
+ unsigned int horkernelsize;
+ unsigned int verkernelsize;
+
+ /* Scale factors. */
+ unsigned int horscalefactor;
+ unsigned int verscalefactor;
+
+ /* Destination angle. */
+ bool angleoverride;
+ int dstangle;
+
+ /* Geometry size that follows angle adjustments. */
+ struct bvsurfgeom dstgeom;
+
+ /* Original source and destination rectangles adjusted
+ * by the source angle. */
+ struct gcrect dstrect;
+ struct gcrect dstrectaux;
+
+ /* Clipped destination rectangle adjusted by the source angle. */
+ struct gcrect dstclipped;
+ struct gcrect dstclippedaux;
+
+ /* Destination rectangles that were clipped, adjusted for
+ * the surface misalignment and the source angle. */
+ struct gcrect dstadjusted;
+ struct gcrect dstadjustedaux;
+};
+
+/* Batch header. */
+struct gcbatch {
+ /* Used to ID structure version. */
+ unsigned int structsize;
+
+ /* Batch change flags. */
+ unsigned long batchflags;
+
+ /* Pointer to the function to finalize the current operation. */
+ gcbatchend batchend;
+
+ /* State of the current operation. */
+ struct {
+ struct gcblit blit;
+ struct gcfilter filter;
+ } op;
+
+ /* Destination surface. */
+ struct surfaceinfo dstinfo;
+
+ /* Aux rectangle present. */
+ bool haveaux;
+ struct gcrect dstrectaux;
+
+ /* Clipped destination rectangle coordinates. */
+ struct gcrect dstclipped;
+ struct gcrect dstclippedaux;
+
+ /* Destination rectangles that were clipped and adjusted for
+ * surface misalignment if any. */
+ struct gcrect dstadjusted;
+ struct gcrect dstadjustedaux;
+
+ /* Clipping deltas; used to correct the source coordinates for
+ * single source blits. */
+ struct gcrect clipdelta;
+
+ /* Adjusted geometry size of the destination surface. */
+ unsigned int dstwidth;
+ unsigned int dstheight;
+
+ /* Physical size of the source and destination surfaces. */
+ unsigned int srcphyswidth;
+ unsigned int srcphysheight;
+ unsigned int dstphyswidth;
+ unsigned int dstphysheight;
+
+ /* Alignment byte offset for the destination surface; in multi-
+ * source setup can be modified to match new destination and source
+ * geometry. */
+ int dstbyteshift;
+
+ /* Destination rectangle adjustment offsets. */
+ int dstoffsetX;
+ int dstoffsetY;
+
+#if GCDEBUG_ENABLE
+ /* Rectangle validation storage. */
+ struct bvrect prevdstrect;
+ struct bvrect prevsrc1rect;
+ struct bvrect prevsrc2rect;
+ struct bvrect prevmaskrect;
+#endif
+
+ /* Total size of the command buffer. */
+ unsigned int size;
+
+ /* Command buffer list (gcbuffer). */
+ struct list_head buffer;
+
+ /* Scheduled implicit unmappings (gcschedunmap). */
+ struct list_head unmap;
+
+ /* Batch linked list (gcbatch). */
+ struct list_head link;
+};
+
+
+/*******************************************************************************
+ * Internal API entries.
+ */
+
+/* Get the pointer to the context. */
+struct gccontext *get_context(void);
+
+/* Validation. */
+bool valid_rect(struct bvsurfgeom *bvsurfgeom, struct gcrect *gcrect);
+
+/* Parsers. */
+enum bverror parse_format(struct bvbltparams *bvbltparams,
+ struct surfaceinfo *surfaceinfo);
+enum bverror parse_blend(struct bvbltparams *bvbltparams,
+ enum bvblend blend,
+ struct gcalpha *gca);
+enum bverror parse_destination(struct bvbltparams *bvbltparams,
+ struct gcbatch *gcbatch);
+enum bverror parse_source(struct bvbltparams *bvbltparams,
+ struct gcbatch *gcbatch,
+ struct bvrect *srcrect,
+ struct surfaceinfo *srcinfo);
+enum bverror parse_scalemode(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch);
+
+/* Setup destination rotation parameters. */
+void process_dest_rotation(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch);
+
+/* Return surface alignment offset. */
+int get_pixel_offset(struct surfaceinfo *surfaceinfo, int offset);
+
+/* Buffer mapping. */
+enum bverror do_map(struct bvbuffdesc *bvbuffdesc,
+ struct gcbatch *gcbatch,
+ struct bvbuffmap **map);
+void do_unmap_implicit(struct gcbatch *gcbatch);
+
+/* Batch/command buffer management. */
+enum bverror do_end(struct bvbltparams *bvbltparams,
+ struct gcbatch *gcbatch);
+enum bverror allocate_batch(struct bvbltparams *bvbltparams,
+ struct gcbatch **gcbatch);
+void free_batch(struct gcbatch *gcbatch);
+enum bverror append_buffer(struct bvbltparams *bvbltparams,
+ struct gcbatch *gcbatch,
+ struct gcbuffer **gcbuffer);
+
+enum bverror add_fixup(struct bvbltparams *bvbltparams,
+ struct gcbatch *gcbatch,
+ unsigned int *fixup,
+ unsigned int surfoffset);
+enum bverror claim_buffer(struct bvbltparams *bvbltparams,
+ struct gcbatch *gcbatch,
+ unsigned int size,
+ void **buffer);
+
+/* Temporary buffer management. */
+enum bverror allocate_temp(struct bvbltparams *bvbltparams,
+ unsigned int size);
+enum bverror free_temp(bool schedule);
+
+/* Program the destination. */
+enum bverror set_dst(struct bvbltparams *bltparams,
+ struct gcbatch *batch,
+ struct bvbuffmap *dstmap);
+
+/* Program blending. */
+enum bverror set_blending(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch,
+ struct surfaceinfo *srcinfo);
+enum bverror set_blending_index(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch,
+ struct surfaceinfo *srcinfo,
+ unsigned int index);
+
+/* Program YUV source. */
+void set_computeyuv(struct surfaceinfo *srcinfo, int x, int y);
+enum bverror set_yuvsrc(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch,
+ struct surfaceinfo *srcinfo,
+ struct bvbuffmap *srcmap);
+enum bverror set_yuvsrc_index(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch,
+ struct surfaceinfo *srcinfo,
+ struct bvbuffmap *srcmap,
+ unsigned int index);
+
+/* Rendering entry points. */
+enum bverror do_fill(struct bvbltparams *bltparams,
+ struct gcbatch *gcbatch,
+ struct surfaceinfo *srcinfo);
+enum bverror do_blit(struct bvbltparams *bltparams,
+ struct gcbatch *gcbatch,
+ struct surfaceinfo *srcinfo);
+enum bverror do_filter(struct bvbltparams *bvbltparams,
+ struct gcbatch *gcbatch,
+ struct surfaceinfo *srcinfo);
+
+#endif
diff --git a/bltsville/gcbv/mirror/gcdbglog.c b/bltsville/gcbv/mirror/gcdbglog.c
new file mode 100644
index 0000000..9743897
--- /dev/null
+++ b/bltsville/gcbv/mirror/gcdbglog.c
@@ -0,0 +1,1684 @@
+/*
+ * Copyright(c) 2012,
+ * Texas Instruments, Inc. and Vivante Corporation.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Vivante Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <gcx.h>
+#include "gcmain.h"
+
+#if ANDROID
+#include <cutils/log.h>
+#endif
+
+#if GCDEBUG_ENABLE
+
+/*******************************************************************************
+ * Debug switches.
+ */
+
+/* Dumping enable default state. */
+#define GC_DUMP_ENABLE 0
+
+/* Ignore all zones as if they were all enabled in all modules. */
+#define GC_IGNORE_ZONES 0
+
+/* When enabled, all output is collected into a buffer with a predefined size.
+ * GC_DUMP_BUFFER_SIZE determines the size of the buffer and GC_ENABLE_OVERFLOW
+ * controls what happens when the buffer gets full. */
+#define GC_BUFFERED_OUTPUT 0
+
+/* Debug output buffer size. */
+#define GC_DUMP_BUFFER_SIZE (200 * 1024)
+
+/* If disabled, the contents of the buffer will be dumped to the console when
+ * the buffer gets full.
+ * If enabled, wrap around mode is enabled where when the buffer gets full,
+ * the oldest entries are overwritten with the new entrie. To dump the buffer
+ * to the console gc_dump_flush must be called explicitly. */
+#define GC_ENABLE_OVERFLOW 1
+
+/* Specifies how many prints are accumulated in the buffer before the buffer is
+ * flushed. Set to zero to disable auto dumping mode. */
+#define GC_FLUSH_COUNT 0
+
+/* Specifies the maximum number of threads that will be tracked in an attempt
+ * to visually separate messages from different threads. To disable thread
+ * tracking, set to 0 or 1. */
+#define GC_THREAD_COUNT 20
+
+/* Specifies spacing for thread messages. */
+#define GC_THREAD_INDENT 0
+
+/* When set to non-zero, specifies how many prints are accumulated in the
+ * buffer before the buffer is flushed. */
+#define GC_SHOW_DUMP_LINE 1
+
+/* If enabled, each print statement will be preceeded with the current
+ * process ID. */
+#define GC_SHOW_PID 1
+
+/* If enabled, internal logging validation code is turned on. */
+#define GC_DEBUG_SELF 0
+
+/* Maximum length of a dump string. */
+#define GC_MAXSTR_LENGTH 256
+
+/* Print buffers like C arrays. */
+#define GC_C_BUFFER 0
+
+
+/*******************************************************************************
+ * Miscellaneous macros.
+ */
+
+#define GC_PTR2INT(p) \
+( \
+ (unsigned int) (p) \
+)
+
+#define GC_ALIGN(n, align) \
+( \
+ ((n) + ((align) - 1)) & ~((align) - 1) \
+)
+
+#define GC_PTRALIGNMENT(p, alignment) \
+( \
+ GC_ALIGN(GC_PTR2INT(p), alignment) - GC_PTR2INT(p) \
+)
+
+#define GC_VARARG_ALIGNMENT sizeof(unsigned long long)
+
+#if defined(GCDBGFILTER)
+#undef GCDBGFILTER
+#endif
+
+#define GCDBGFILTER \
+ (*filter)
+
+#if GC_IGNORE_ZONES
+#define GC_VERIFY_ENABLE(filter, zone) \
+ (g_initdone)
+#else
+#define GC_VERIFY_ENABLE(filter, zone) \
+ (g_initdone && ((filter == NULL) || ((filter->zone & zone) != 0)))
+#endif
+
+#if GC_SHOW_DUMP_LINE
+#define GC_DUMPLINE_FORMAT "[%12d] "
+#endif
+
+#if GC_SHOW_PID
+#define GC_PID_FORMAT "[pid=%04X] "
+#endif
+
+#define GC_EOL_RESERVE 1
+
+
+/*******************************************************************************
+ * Dump item header definition.
+ */
+
+enum itemtype {
+ GC_BUFITEM_NONE,
+ GC_BUFITEM_STRING,
+ GC_BUFITEM_BUFFER
+};
+
+/* Common item head/buffer terminator. */
+struct itemhead {
+ enum itemtype type;
+};
+
+
+/*******************************************************************************
+ * Supported dump items.
+ */
+
+/* GC_BUFITEM_STRING: buffered string. */
+struct itemstring {
+ enum itemtype itemtype;
+ int indent;
+
+#if GC_SHOW_PID
+ pid_t pid;
+#endif
+
+#if GC_SHOW_DUMP_LINE
+ unsigned int dumpline;
+#endif
+
+ const char *message;
+ va_list messagedata;
+ unsigned int datasize;
+};
+
+/* GC_BUFITEM_BUFFER: buffered memory. */
+enum buffertype {
+ GC_BUFTYPE_GENERIC,
+ GC_BUFTYPE_COMMAND,
+ GC_BUFTYPE_SURFACE
+};
+
+#define GC_GENERIC_DATA_COUNT 8
+#define GC_SURFACE_DATA_COUNT 64
+
+struct itembuffer {
+ enum itemtype itemtype;
+ enum buffertype buffertype;
+ int indent;
+
+ unsigned int surfwidth;
+ unsigned int surfheight;
+ unsigned int surfbpp;
+ unsigned int x1, y1;
+ unsigned int x2, y2;
+
+ unsigned int datasize;
+ unsigned int gpuaddr;
+};
+
+
+/*******************************************************************************
+ * Debug output buffer.
+ */
+
+struct threadinfo {
+ pid_t pid;
+ int msgindent;
+ int threadindent;
+};
+
+struct buffout {
+ int enable;
+
+#if GC_THREAD_COUNT > 1
+ unsigned int threadcount;
+ struct threadinfo threadinfo[1 + GC_THREAD_COUNT];
+#else
+ struct threadinfo threadinfo[1];
+#endif
+
+#if GC_SHOW_DUMP_LINE
+ unsigned int dumpline;
+#endif
+
+#if GC_BUFFERED_OUTPUT
+ int start;
+ int index;
+ int count;
+ unsigned char *buffer;
+#endif
+};
+
+static struct buffout g_outputbuffer = {
+ .enable = GC_DUMP_ENABLE
+};
+
+
+/*******************************************************************************
+ * Globals.
+ */
+
+static unsigned int g_initdone;
+static GCDEFINE_LOCK(g_lockmutex);
+static struct list_head gc_filterlist = LIST_HEAD_INIT(gc_filterlist);
+
+
+/*******************************************************************************
+ * Item size functions.
+ */
+
+#if GC_BUFFERED_OUTPUT
+static int get_item_size_terminator(struct itemhead *item)
+{
+ return sizeof(struct itemhead);
+}
+
+static int get_item_size_string(struct itemhead *item)
+{
+ struct itemstring *itemstring = (struct itemstring *) item;
+ unsigned int vlen = *((unsigned char **) &itemstring->messagedata)
+ - ((unsigned char *) itemstring);
+ return vlen + itemstring->datasize;
+}
+
+static int get_item_size_buffer(struct itemhead *item)
+{
+ struct itembuffer *itembuffer = (struct itembuffer *) item;
+ return sizeof(struct itembuffer) + itembuffer->datasize;
+}
+
+#if GC_ENABLE_OVERFLOW
+typedef int (*getitemsize) (struct itemhead *item);
+
+static getitemsize g_itemsize[] = {
+ get_item_size_terminator,
+ get_item_size_string,
+ get_item_size_buffer
+};
+#endif
+#endif
+
+
+/*******************************************************************************
+ * Printing functions.
+ */
+
+#if ANDROID
+#define GC_PRINTK(s, fmt, ...) \
+ LOGI(fmt, ##__VA_ARGS__);
+#else
+#define GC_PRINTK(s, fmt, ...) \
+ printf(fmt, ##__VA_ARGS__);
+#endif
+
+#if GC_DEBUG_SELF
+# define GC_DEBUGMSG(fmt, ...) \
+ GC_PRINTK(NULL, "[%s:%d] " fmt, __func__, __LINE__, \
+ ##__VA_ARGS__)
+#else
+# define GC_DEBUGMSG(...) {}
+#endif
+
+static struct threadinfo *get_threadinfo(struct buffout *buffout)
+{
+#if GC_THREAD_COUNT > 1
+ struct threadinfo *threadinfo;
+ unsigned int i, count;
+ pid_t pid;
+
+ /* Get current pid. */
+ pid = gettid();
+
+ /* Try to locate thread record. */
+ count = buffout->threadcount + 1;
+ for (i = 1; i < count; i += 1)
+ if (buffout->threadinfo[i].pid == pid)
+ return &buffout->threadinfo[i];
+
+ /* Not found, still have room? */
+ if (buffout->threadcount < GC_THREAD_COUNT) {
+ threadinfo = &buffout->threadinfo[count];
+ threadinfo->pid = pid;
+ threadinfo->msgindent = 0;
+ threadinfo->threadindent = buffout->threadcount
+ * GC_THREAD_INDENT;
+ buffout->threadcount += 1;
+ return threadinfo;
+ }
+
+ /* Too many threads, use the common entry. */
+ GC_PRINTK(NULL, "%s(%d) [ERROR] reached the maximum thread number.\n",
+ __func__, __LINE__);
+ threadinfo = buffout->threadinfo;
+ threadinfo->pid = pid;
+ return threadinfo;
+#else
+ struct threadinfo *threadinfo;
+ threadinfo = buffout->threadinfo;
+
+#if GC_SHOW_PID
+ threadinfo->pid = pid;
+#else
+ threadinfo->pid = 0;
+#endif
+
+ return threadinfo;
+#endif
+}
+
+static int gc_get_indent(int indent, char *buffer, int buffersize)
+{
+ static const int MAX_INDENT = 80;
+ int len, _indent;
+
+ _indent = indent % MAX_INDENT;
+ if (_indent > buffersize)
+ _indent = buffersize - 1;
+
+ for (len = 0; len < _indent; len += 1)
+ buffer[len] = ' ';
+
+ buffer[len] = '\0';
+ return len;
+}
+
+static void gc_print_string(struct seq_file *s, struct itemstring *str)
+{
+ int len = 0;
+ char buffer[GC_MAXSTR_LENGTH];
+
+#if GC_SHOW_DUMP_LINE
+ len += snprintf(buffer + len, sizeof(buffer) - len - GC_EOL_RESERVE,
+ GC_DUMPLINE_FORMAT, str->dumpline);
+#endif
+
+#if GC_SHOW_PID
+ len += snprintf(buffer + len, sizeof(buffer) - len - GC_EOL_RESERVE,
+ GC_PID_FORMAT, str->pid);
+#endif
+
+ /* Append the indent string. */
+ len += gc_get_indent(str->indent, buffer + len,
+ sizeof(buffer) - len - GC_EOL_RESERVE);
+
+ /* Format the string. */
+ len += vsnprintf(buffer + len, sizeof(buffer) - len - GC_EOL_RESERVE,
+ str->message, str->messagedata);
+
+ /* Add end-of-line if missing. */
+ if (buffer[len - 1] != '\n')
+ buffer[len++] = '\n';
+ buffer[len] = '\0';
+
+ /* Print the string. */
+ GC_PRINTK(s, "%s", buffer);
+}
+
+static void gc_print_generic(struct seq_file *s, struct itembuffer *item,
+ unsigned char *data)
+{
+ char buffer[GC_MAXSTR_LENGTH];
+ unsigned int i, indent, len;
+
+ /* Append the indent string. */
+ indent = gc_get_indent(item->indent, buffer, sizeof(buffer));
+
+ /* Print the title. */
+ GC_PRINTK(s, "%sBUFFER @ 0x%08X\n",
+ buffer, item->gpuaddr);
+
+ /* Print the buffer. */
+ for (i = 0, len = indent; i < item->datasize; i += 4) {
+ if ((i % GC_GENERIC_DATA_COUNT) == 0) {
+ if (i != 0) {
+ /* Print the string. */
+ GC_PRINTK(s, "%s\n", buffer);
+
+ /* Reset the line. */
+ len = indent;
+ }
+
+ len += snprintf(buffer + len, sizeof(buffer) - len,
+ "0x%08X: ", item->gpuaddr + i);
+ }
+
+ /* Append the data value. */
+ len += snprintf(buffer + len, sizeof(buffer) - len,
+ " 0x%08X", *(unsigned int *) (data + i));
+ }
+
+ /* Print the last partial string. */
+ if ((i % GC_SURFACE_DATA_COUNT) != 0)
+ GC_PRINTK(s, "%s\n", buffer);
+}
+
+static char *gc_module_name(unsigned int index)
+{
+ switch (index) {
+ case GCREG_COMMAND_STALL_STALL_SOURCE_FRONT_END:
+ return "FE";
+
+ case GCREG_COMMAND_STALL_STALL_SOURCE_PIXEL_ENGINE:
+ return "PE";
+
+ case GCREG_COMMAND_STALL_STALL_SOURCE_DRAWING_ENGINE:
+ return "DE";
+
+ default:
+ return "*INVALID*";
+ }
+}
+
+static void gc_print_command(struct seq_file *s, struct itembuffer *item,
+ unsigned char *data)
+{
+ char buffer[GC_MAXSTR_LENGTH];
+ unsigned int *data32;
+ unsigned int i, j, datacount;
+ unsigned int command, count, addr;
+ unsigned int delay, src, dst;
+ unsigned int x1, y1, x2, y2;
+
+ /* Append the indent string. */
+ gc_get_indent(item->indent, buffer, sizeof(buffer));
+
+ /* Print the title. */
+ GC_PRINTK(s, "%sCOMMAND BUFFER @ 0x%08X\n", buffer, item->gpuaddr);
+ GC_PRINTK(s, "%s size = %d\n", buffer, item->datasize);
+
+ datacount = (item->datasize + 3) / 4;
+ data32 = (unsigned int *) data;
+ for (i = 0; i < datacount;) {
+#if GC_C_BUFFER
+ GC_PRINTK(s, "%s\t0x%08X,\n", buffer, data32[i++]);
+#else
+ command = (data32[i] >> 27) & 0x1F;
+
+ switch (command) {
+ case GCREG_COMMAND_OPCODE_LOAD_STATE:
+ count = (data32[i] >> 16) & 0x3F;
+ addr = data32[i] & 0xFFFF;
+ GC_PRINTK(s, "%s 0x%08X: 0x%08X STATE(0x%04X, %d)\n",
+ buffer, item->gpuaddr + (i << 2),
+ data32[i], addr, count);
+ i += 1;
+
+ count |= 1;
+ for (j = 0; j < count; i += 1, j += 1)
+ GC_PRINTK(s, "%s%14c0x%08X\n",
+ buffer, ' ', data32[i]);
+ break;
+
+ case GCREG_COMMAND_OPCODE_END:
+ GC_PRINTK(s, "%s 0x%08X: 0x%08X END()\n",
+ buffer, item->gpuaddr + (i << 2),
+ data32[i]);
+ i += 1;
+
+ GC_PRINTK(s, "%s%14c0x%08X\n",
+ buffer, ' ', data32[i]);
+ i += 1;
+ break;
+
+ case GCREG_COMMAND_OPCODE_NOP:
+ GC_PRINTK(s, "%s 0x%08X: 0x%08X NOP()\n",
+ buffer, item->gpuaddr + (i << 2),
+ data32[i]);
+ i += 1;
+
+ GC_PRINTK(s, "%s" "%14c0x%08X\n",
+ buffer, ' ', data32[i]);
+ i += 1;
+ break;
+
+ case GCREG_COMMAND_OPCODE_STARTDE:
+ count = (data32[i] >> 8) & 0xFF;
+ GC_PRINTK(s, "%s 0x%08X: 0x%08X STARTDE(%d)\n",
+ buffer, item->gpuaddr + (i << 2),
+ data32[i], count);
+ i += 1;
+
+ GC_PRINTK(s, "%s" "%14c0x%08X\n",
+ buffer, ' ', data32[i]);
+ i += 1;
+
+ for (j = 0; j < count; j += 1) {
+ x1 = data32[i] & 0xFFFF;
+ y1 = (data32[i] >> 16) & 0xFFFF;
+ GC_PRINTK(s, "%s%14c0x%08X LT(%d,%d)\n",
+ buffer, ' ', data32[i], x1, y1);
+ i += 1;
+
+ x2 = data32[i] & 0xFFFF;
+ y2 = (data32[i] >> 16) & 0xFFFF;
+ GC_PRINTK(s, "%s%14c0x%08X RB(%d,%d)\n",
+ buffer, ' ', data32[i], x2, y2);
+ i += 1;
+ }
+ break;
+
+ case GCREG_COMMAND_OPCODE_WAIT:
+ delay = data32[i] & 0xFFFF;
+ GC_PRINTK(s, "%s 0x%08X: 0x%08X WAIT(%d)\n",
+ buffer, item->gpuaddr + (i << 2),
+ data32[i], delay);
+ i += 1;
+
+ GC_PRINTK(s, "%s%14c0x%08X\n", buffer, ' ', data32[i]);
+ i += 1;
+ break;
+
+ case GCREG_COMMAND_OPCODE_LINK:
+ count = data32[i] & 0xFFFF;
+ addr = data32[i + 1];
+ GC_PRINTK(s, "%s 0x%08X: 0x%08X "
+ "LINK(0x%08X-0x%08X, %d)\n",
+ buffer, item->gpuaddr + (i << 2),
+ data32[i], addr, addr + count * 8,
+ count);
+ i += 1;
+
+ GC_PRINTK(s, "%s%14c0x%08X\n", buffer, ' ', data32[i]);
+ i += 1;
+ break;
+
+ case GCREG_COMMAND_OPCODE_STALL:
+ src = data32[i + 1] & 0x1F;
+ dst = (data32[i + 1] >> 8) & 0x1F;
+
+ GC_PRINTK(s, "%s 0x%08X: 0x%08X STALL(%s-%s)\n",
+ buffer, item->gpuaddr + (i << 2),
+ data32[i],
+ gc_module_name(src),
+ gc_module_name(dst));
+ i += 1;
+
+ GC_PRINTK(s, "%s" "%14c0x%08X\n",
+ buffer, ' ', data32[i]);
+ i += 1;
+ break;
+
+ default:
+ GC_PRINTK(s, "%s 0x%08X: 0x%08X UNKNOWN COMMAND\n",
+ buffer, item->gpuaddr + (i << 2),
+ data32[i]);
+ i += 2;
+ }
+#endif
+ }
+}
+
+static void gc_flush_line(struct seq_file *s, char *buffer,
+ unsigned int indent, unsigned int *len,
+ unsigned int count, unsigned char checksum)
+{
+ unsigned int _len;
+ char countstr[10];
+
+ /* Correct data count. */
+ count %= GC_SURFACE_DATA_COUNT;
+ if (count == 0)
+ count = GC_SURFACE_DATA_COUNT;
+
+ snprintf(countstr, sizeof(countstr), "%02X", count);
+ buffer[indent + 1] = countstr[0];
+ buffer[indent + 2] = countstr[1];
+
+ /* Append the checksum. */
+ _len = *len;
+ _len += snprintf(buffer + _len, sizeof(buffer) - _len,
+ "%02X", checksum);
+
+ /* Print the string. */
+ GC_PRINTK(s, "%s\n", buffer);
+
+ /* Reset the length. */
+ *len = indent;
+}
+
+static void gc_print_surface(struct seq_file *s, struct itembuffer *itembuffer,
+ unsigned char *data)
+{
+ char buffer[GC_MAXSTR_LENGTH];
+ unsigned int i, indent, len;
+ unsigned int prevupper32 = ~0U;
+ unsigned int currupper32;
+ unsigned int offset, address;
+ unsigned int width, height;
+
+ /* Append the indent string. */
+ indent = gc_get_indent(itembuffer->indent, buffer, sizeof(buffer));
+
+ /* Print the title. */
+ GC_PRINTK(s, "%sIMAGE SURFACE @ 0x%08X\n",
+ buffer, itembuffer->gpuaddr);
+
+ GC_PRINTK(s, "%s surface size = %dx%d\n",
+ buffer, itembuffer->surfwidth, itembuffer->surfheight);
+
+ GC_PRINTK(s, "%s surface colordepth = %d\n",
+ buffer, itembuffer->surfbpp);
+
+ GC_PRINTK(s, "%s dumping rectangle = (%d,%d)-(%d,%d)\n",
+ buffer, itembuffer->x1, itembuffer->y1,
+ itembuffer->x2, itembuffer->y2);
+
+ /* Add TGA header. */
+ width = itembuffer->x2 - itembuffer->x1;
+ height = itembuffer->y2 - itembuffer->y1;
+ GC_PRINTK(s, ":12000000000002000000000000000000"
+ "%02X%02X%02X%02X%02X2000\n",
+ (width & 0xFF), ((width >> 8) & 0xFF),
+ (height & 0xFF), ((height >> 8) & 0xFF),
+ itembuffer->surfbpp * 8);
+
+ /* TGA skip header. */
+ offset = 18;
+
+ /* Print the buffer. */
+ for (i = 0, len = indent; i < itembuffer->datasize; i += 1) {
+ /* Determine the current address. */
+ address = offset + i;
+
+ /* Determine the current higher 16 bits of the address. */
+ currupper32 = address >> 16;
+
+ /* Did it change? */
+ if (currupper32 != prevupper32) {
+ /* Print the previous data if any. */
+ if ((i % GC_SURFACE_DATA_COUNT) != 0)
+ gc_flush_line(s, buffer, indent, &len, i, 0);
+
+ /* Set new upper address. */
+ prevupper32 = currupper32;
+ GC_PRINTK(s, ":02000004%04X00\n", prevupper32);
+
+ /* Add the line prefix. */
+ len += snprintf(buffer + len,
+ sizeof(buffer) - len - 2,
+ ":xx%04X00", address & 0xFFFF);
+ } else if ((i % GC_SURFACE_DATA_COUNT) == 0) {
+ len += snprintf(buffer + len,
+ sizeof(buffer) - len - 2,
+ ":xx%04X00", address & 0xFFFF);
+ }
+
+ /* Append the data value. */
+ len += snprintf(buffer + len,
+ sizeof(buffer) - len - 2,
+ "%02X", data[i]);
+
+ /* End of line? */
+ if (((i + 1) % GC_SURFACE_DATA_COUNT) == 0)
+ gc_flush_line(s, buffer, indent, &len, i + 1, 0);
+ }
+
+ /* Print the last partial string. */
+ if ((i % GC_SURFACE_DATA_COUNT) != 0)
+ gc_flush_line(s, buffer, indent, &len, i, 0);
+
+ /* End of dump. */
+ GC_PRINTK(s, ":00000001FF\n");
+}
+
+typedef void (*printbuffer) (struct seq_file *s, struct itembuffer *itembuffer,
+ unsigned char *data);
+
+static printbuffer g_printbuffer[] = {
+ gc_print_generic,
+ gc_print_command,
+ gc_print_surface
+};
+
+static void gc_print_buffer(struct seq_file *s, struct itembuffer *itembuffer,
+ unsigned char *data)
+{
+ if (((int) itembuffer->buffertype < 0) ||
+ (itembuffer->buffertype >= countof(g_printbuffer))) {
+ GC_PRINTK(s, "BUFFER ENTRY 0x%08X\n",
+ (unsigned int) itembuffer);
+ GC_PRINTK(s, "INVALID BUFFER TYPE %d\n",
+ itembuffer->buffertype);
+ } else {
+ g_printbuffer[itembuffer->buffertype](s, itembuffer, data);
+ }
+}
+
+
+/*******************************************************************************
+ * Print function wrappers.
+ */
+
+#if GC_BUFFERED_OUTPUT
+static unsigned int gc_print_none(struct seq_file *s, struct buffout *buffout,
+ struct itemhead *item)
+{
+ /* Return the size of the node. */
+ return get_item_size_terminator(item);
+}
+
+static unsigned int gc_print_string_wrapper(struct seq_file *s,
+ struct buffout *buffout,
+ struct itemhead *item)
+{
+ /* Print the message. */
+ gc_print_string(s, (struct itemstring *) item);
+
+ /* Return the size of the node. */
+ return get_item_size_string(item);
+}
+
+static unsigned int gc_print_buffer_wrapper(struct seq_file *s,
+ struct buffout *buffout,
+ struct itemhead *item)
+{
+ unsigned char *data;
+ struct itembuffer *itembuffer = (struct itembuffer *) item;
+
+ /* Compute data address. */
+ data = (unsigned char *) (itembuffer + 1);
+
+ /* Print the message. */
+ gc_print_buffer(s, (struct itembuffer *) item, data);
+
+ /* Return the size of the node. */
+ return get_item_size_buffer(item);
+}
+
+typedef unsigned int (*printitem) (struct seq_file *s, struct buffout *buffout,
+ struct itemhead *item);
+
+static printitem g_printarray[] = {
+ gc_print_none,
+ gc_print_string_wrapper,
+ gc_print_buffer_wrapper
+};
+#endif
+
+
+/*******************************************************************************
+ * Private functions.
+ */
+
+unsigned int gc_get_bpp(unsigned int format)
+{
+ unsigned int bpp;
+
+ switch (format) {
+ case GCREG_DE_FORMAT_INDEX8:
+ case GCREG_DE_FORMAT_A8:
+ bpp = 1;
+ break;
+
+ case GCREG_DE_FORMAT_X4R4G4B4:
+ case GCREG_DE_FORMAT_A4R4G4B4:
+ case GCREG_DE_FORMAT_X1R5G5B5:
+ case GCREG_DE_FORMAT_A1R5G5B5:
+ case GCREG_DE_FORMAT_R5G6B5:
+ case GCREG_DE_FORMAT_YUY2:
+ case GCREG_DE_FORMAT_UYVY:
+ case GCREG_DE_FORMAT_RG16:
+ bpp = 2;
+ break;
+
+ case GCREG_DE_FORMAT_X8R8G8B8:
+ case GCREG_DE_FORMAT_A8R8G8B8:
+ bpp = 4;
+ break;
+
+ default:
+ bpp = 0;
+ }
+
+ return bpp;
+}
+
+#if GC_BUFFERED_OUTPUT
+static void gc_buffer_flush(struct seq_file *s, struct buffout *buffout)
+{
+ int i, skip;
+ struct itemhead *item;
+
+ if (buffout->count == 0)
+ return;
+
+ GC_PRINTK(s, "****************************************"
+ "****************************************\n");
+ GC_PRINTK(s, "FLUSHING DEBUG OUTPUT BUFFER (%d elements).\n",
+ buffout->count);
+
+#if !GC_ENABLE_OVERFLOW
+ {
+ int occupied = (100 * (buffout->index - buffout->start))
+ / GC_DUMP_BUFFER_SIZE;
+ if (buffout->start != 0)
+ GC_PRINTK(s, " START = %d\n", buffout->start);
+ GC_PRINTK(s, " INDEX = %d\n", buffout->index);
+ GC_PRINTK(s, " BUFFER USE = %d%%\n", occupied);
+ }
+#endif
+
+ GC_PRINTK(s, "****************************************"
+ "****************************************\n");
+
+ item = (struct itemhead *) &buffout->buffer[buffout->start];
+ GC_DEBUGMSG("start=%d.\n", buffout->start);
+
+ for (i = 0; i < buffout->count; i += 1) {
+ GC_DEBUGMSG("printing item %d of type %d @ 0x%08X.\n",
+ i, item->type, (unsigned int) item);
+ skip = (*g_printarray[item->type]) (s, buffout, item);
+
+ item = (struct itemhead *) ((unsigned char *) item + skip);
+ GC_DEBUGMSG("next item @ 0x%08X.\n", (unsigned int) item);
+
+ if (item->type == GC_BUFITEM_NONE) {
+ GC_DEBUGMSG("reached the end of buffer.\n");
+ item = (struct itemhead *) buffout->buffer;
+ }
+ }
+
+ GC_DEBUGMSG("resetting the buffer.\n");
+ buffout->start = 0;
+ buffout->index = 0;
+ buffout->count = 0;
+}
+
+static struct itemhead *gc_allocate_item(struct buffout *buffout, int size)
+{
+ struct itemhead *item, *next;
+ int endofbuffer = (buffout->index + size
+ >= GC_DUMP_BUFFER_SIZE - sizeof(struct itemhead));
+
+#if GC_ENABLE_OVERFLOW
+ int skip, bufferoverflow;
+
+ bufferoverflow = (buffout->index < buffout->start) &&
+ (buffout->index + size >= buffout->start);
+
+ if (endofbuffer || bufferoverflow) {
+ if (endofbuffer) {
+ if (buffout->index < buffout->start) {
+ item = (struct itemhead *)
+ &buffout->buffer[buffout->start];
+
+ while (item->type != GC_BUFITEM_NONE) {
+ skip = (*g_itemsize[item->type]) (item);
+
+ buffout->start += skip;
+ buffout->count -= 1;
+
+ item->type = GC_BUFITEM_NONE;
+ item = (struct itemhead *)
+ ((unsigned char *) item + skip);
+ }
+
+ buffout->start = 0;
+ }
+
+ buffout->index = 0;
+ }
+
+ item = (struct itemhead *) &buffout->buffer[buffout->start];
+
+ while (buffout->start - buffout->index <= size) {
+ skip = (*g_itemsize[item->type]) (item);
+
+ buffout->start += skip;
+ buffout->count -= 1;
+
+ item->type = GC_BUFITEM_NONE;
+ item = (struct itemhead *)
+ ((unsigned char *) item + skip);
+
+ if (item->type == GC_BUFITEM_NONE) {
+ buffout->start = 0;
+ break;
+ }
+ }
+ }
+#else
+ if (endofbuffer) {
+ GC_PRINTK(NULL, "message buffer full; "
+ "forcing message flush.\n\n");
+ gc_buffer_flush(NULL, buffout);
+ }
+#endif
+
+ item = (struct itemhead *) &buffout->buffer[buffout->index];
+
+ buffout->index += size;
+ buffout->count += 1;
+
+ next = (struct itemhead *) ((unsigned char *) item + size);
+ next->type = GC_BUFITEM_NONE;
+
+ return item;
+}
+
+static void gc_append_string(struct buffout *buffout,
+ struct itemstring *itemstring)
+{
+ unsigned char *messagedata;
+ struct itemstring *item;
+ unsigned int alignment;
+ int size, freesize;
+ int allocsize;
+
+ /* Determine the maximum item size. */
+ allocsize = sizeof(struct itemstring) + itemstring->datasize
+ + GC_VARARG_ALIGNMENT;
+
+ /* Allocate the item. */
+ item = (struct itemstring *) gc_allocate_item(buffout, allocsize);
+ GC_DEBUGMSG("allocated %d bytes @ 0x%08X.\n",
+ allocsize, (unsigned int) item);
+
+ /* Compute the initial message data pointer. */
+ messagedata = (unsigned char *) (item + 1);
+
+ /* Align the data pointer as necessary. */
+ alignment = GC_PTRALIGNMENT(messagedata, GC_VARARG_ALIGNMENT);
+ messagedata += alignment;
+ GC_DEBUGMSG("messagedata @ 0x%08X.\n", (unsigned int) messagedata);
+
+ /* Set item data. */
+ item->itemtype = GC_BUFITEM_STRING;
+ item->indent = itemstring->indent;
+ item->message = itemstring->message;
+ item->messagedata = *(va_list *) &messagedata;
+ item->datasize = itemstring->datasize;
+
+#if GC_SHOW_PID
+ item->pid = itemstring->pid;
+#endif
+
+#if GC_SHOW_DUMP_LINE
+ item->dumpline = itemstring->dumpline;
+#endif
+
+ /* Copy argument value. */
+ if (itemstring->datasize != 0) {
+ GC_DEBUGMSG("copying %d bytes of messagedata.\n",
+ itemstring->datasize);
+ memcpy(messagedata,
+ *(unsigned char **) &itemstring->messagedata,
+ itemstring->datasize);
+ }
+
+ /* Compute the actual node size. */
+ size = sizeof(struct itemstring) + itemstring->datasize + alignment;
+ GC_DEBUGMSG("adjusted item size=%d.\n", size);
+
+ /* Free extra memory if any. */
+ freesize = allocsize - size;
+ GC_DEBUGMSG("freesize=%d.\n", freesize);
+
+ if (freesize != 0) {
+ struct itemhead *next;
+ buffout->index -= freesize;
+ next = (struct itemhead *) ((unsigned char *) item + size);
+ next->type = GC_BUFITEM_NONE;
+ }
+
+#if GC_BUFFERED_OUTPUT && GC_FLUSH_COUNT
+ if (buffout->count >= GC_FLUSH_COUNT) {
+ GC_PRINTK(NULL, "reached %d message count; "
+ "forcing message flush.\n\n", buffout->count);
+ gc_buffer_flush(NULL, buffout);
+ }
+#endif
+}
+
+static void gc_append_buffer(struct buffout *buffout,
+ struct itembuffer *itembuffer,
+ unsigned int *data)
+{
+ struct itembuffer *item;
+ int allocsize;
+
+ /* Determine the item size. */
+ allocsize = sizeof(struct itembuffer) + itembuffer->datasize;
+
+ /* Allocate the item. */
+ item = (struct itembuffer *) gc_allocate_item(buffout, allocsize);
+ GC_DEBUGMSG("allocated %d bytes @ 0x%08X.\n",
+ allocsize, (unsigned int) item);
+
+ /* Set item data. */
+ *item = *itembuffer;
+
+ /* Copy data. */
+ memcpy(item + 1, data, itembuffer->datasize);
+
+#if GC_BUFFERED_OUTPUT && GC_FLUSH_COUNT
+ if (buffout->count >= GC_FLUSH_COUNT) {
+ GC_PRINTK(NULL, "reached %d message count; "
+ "forcing message flush.\n\n", buffout->count);
+ gc_buffer_flush(NULL, buffout);
+ }
+#endif
+}
+#endif
+
+static void gc_print(struct buffout *buffout, unsigned int argsize,
+ const char *message, va_list args)
+{
+ struct itemstring itemstring;
+ struct threadinfo *threadinfo;
+
+ GCLOCK(&g_lockmutex);
+
+ /* Locate thead entry. */
+ threadinfo = get_threadinfo(buffout);
+
+ /* Form the indent string. */
+ if (strncmp(message, "--", 2) == 0)
+ threadinfo->msgindent -= 2;
+
+ /* Fill in the sructure. */
+ itemstring.itemtype = GC_BUFITEM_STRING;
+ itemstring.indent = threadinfo->msgindent
+ + threadinfo->threadindent;
+ itemstring.message = message;
+ itemstring.messagedata = args;
+ itemstring.datasize = argsize;
+
+#if GC_SHOW_PID
+ itemstring.pid = threadinfo->pid;
+#endif
+
+#if GC_SHOW_DUMP_LINE
+ itemstring.dumpline = ++buffout->dumpline;
+#endif
+
+ /* Print the message. */
+#if GC_BUFFERED_OUTPUT
+ gc_append_string(buffout, &itemstring);
+#else
+ gc_print_string(NULL, &itemstring);
+#endif
+
+ /* Check increasing indent. */
+ if (strncmp(message, "++", 2) == 0)
+ threadinfo->msgindent += 2;
+
+ GCUNLOCK(&g_lockmutex);
+}
+
+
+/*******************************************************************************
+ * Dumping functions.
+ */
+
+void gc_dump_string(struct gcdbgfilter *filter, unsigned int zone,
+ const char *message, ...)
+{
+ va_list args;
+ unsigned int i, count, argsize;
+
+ if (!g_outputbuffer.enable)
+ return;
+
+ if (message == NULL)
+ GC_DEBUGMSG("message is NULL.\n");
+
+ if (GC_VERIFY_ENABLE(filter, zone)) {
+ for (i = 0, count = 0; message[i]; i += 1)
+ if (message[i] == '%')
+ count += 1;
+
+ argsize = count * sizeof(unsigned int);
+ GC_DEBUGMSG("argsize=%d.\n", argsize);
+
+ va_start(args, message);
+ gc_print(&g_outputbuffer, argsize, message, args);
+ va_end(args);
+ }
+}
+EXPORT_SYMBOL(gc_dump_string);
+
+void gc_dump_string_sized(struct gcdbgfilter *filter, unsigned int zone,
+ unsigned int argsize, const char *message, ...)
+{
+ va_list args;
+
+ if (!g_outputbuffer.enable)
+ return;
+
+ if (GC_VERIFY_ENABLE(filter, zone)) {
+ va_start(args, message);
+ gc_print(&g_outputbuffer, argsize, message, args);
+ va_end(args);
+ }
+}
+EXPORT_SYMBOL(gc_dump_string_sized);
+
+void gc_dump_cmd_buffer(struct gcdbgfilter *filter, unsigned int zone,
+ void *ptr, unsigned int gpuaddr, unsigned int datasize)
+{
+ struct itembuffer itembuffer;
+ struct threadinfo *threadinfo;
+
+ if (!g_outputbuffer.enable)
+ return;
+
+ if (GC_VERIFY_ENABLE(filter, zone)) {
+ GCLOCK(&g_lockmutex);
+
+ /* Locate thead entry. */
+ threadinfo = get_threadinfo(&g_outputbuffer);
+
+ /* Fill in the sructure. */
+ itembuffer.itemtype = GC_BUFITEM_BUFFER;
+ itembuffer.buffertype = GC_BUFTYPE_COMMAND;
+ itembuffer.indent = threadinfo->msgindent
+ + threadinfo->threadindent;
+ itembuffer.datasize = datasize;
+ itembuffer.gpuaddr = gpuaddr;
+
+ /* Print the message. */
+#if GC_BUFFERED_OUTPUT
+ gc_append_buffer(NULL, &g_outputbuffer, &itembuffer,
+ (unsigned int *) ptr);
+#else
+ gc_print_buffer(NULL, &itembuffer,
+ (unsigned char *) ptr);
+#endif
+
+ GCUNLOCK(&g_lockmutex);
+ }
+}
+EXPORT_SYMBOL(gc_dump_cmd_buffer);
+
+void gc_dump_buffer(struct gcdbgfilter *filter, unsigned int zone,
+ void *ptr, unsigned int gpuaddr,
+ unsigned int datasize)
+{
+ struct itembuffer itembuffer;
+ struct threadinfo *threadinfo;
+
+ if (!g_outputbuffer.enable)
+ return;
+
+ if (GC_VERIFY_ENABLE(filter, zone)) {
+ GCLOCK(&g_lockmutex);
+
+ /* Locate thead entry. */
+ threadinfo = get_threadinfo(&g_outputbuffer);
+
+ /* Fill in the sructure. */
+ itembuffer.itemtype = GC_BUFITEM_BUFFER;
+ itembuffer.buffertype = GC_BUFTYPE_GENERIC;
+ itembuffer.indent = threadinfo->msgindent
+ + threadinfo->threadindent;
+ itembuffer.datasize = datasize;
+ itembuffer.gpuaddr = gpuaddr;
+
+ /* Print the message. */
+#if GC_BUFFERED_OUTPUT
+ gc_append_buffer(NULL, &g_outputbuffer, &itembuffer,
+ (unsigned int *) ptr);
+#else
+ gc_print_buffer(NULL, &itembuffer,
+ (unsigned char *) ptr);
+#endif
+
+ GCUNLOCK(&g_lockmutex);
+ }
+}
+EXPORT_SYMBOL(gc_dump_buffer);
+
+
+/*******************************************************************************
+ * Dumping control functions.
+ */
+
+void gc_dump_enable(void)
+{
+ GCLOCK(&g_lockmutex);
+
+ g_outputbuffer.enable = 1;
+ GC_PRINTK(NULL, "gcx dumping is enabled.\n");
+
+ GCUNLOCK(&g_lockmutex);
+}
+EXPORT_SYMBOL(gc_dump_enable);
+
+void gc_dump_disable(void)
+{
+ GCLOCK(&g_lockmutex);
+
+ g_outputbuffer.enable = 0;
+ GC_PRINTK(NULL, "gcx dumping is disabled.\n");
+
+ GCUNLOCK(&g_lockmutex);
+}
+EXPORT_SYMBOL(gc_dump_disable);
+
+void gc_dump_show_enabled(struct seq_file *s)
+{
+ struct list_head *filterhead;
+ struct gcdbgfilter *filter;
+ unsigned int i, zone;
+
+ GCLOCK(&g_lockmutex);
+
+ GC_PRINTK(s, "gcx logging is %s\n", g_outputbuffer.enable
+ ? "enabled" : "disabled");
+
+ list_for_each(filterhead, &gc_filterlist) {
+ filter = list_entry(filterhead, struct gcdbgfilter,
+ link);
+
+ GC_PRINTK(s, "gcx filter '%s':\n", filter->filtername);
+ GC_PRINTK(s, " zone mask = 0x%08X%s\n", filter->zone,
+ (filter->zone == 0)
+ ? " (all disabled)" : "");
+
+ for (i = 0; filter->zonename[i] != NULL; i++) {
+ zone = 1 << i;
+ GC_PRINTK(s, " 0x%08X: %10s%s\n",
+ zone, filter->zonename[i],
+ ((filter->zone & zone) != 0)
+ ? " (enabled)" : "");
+ }
+ }
+
+ GCUNLOCK(&g_lockmutex);
+}
+EXPORT_SYMBOL(gc_dump_show_enabled);
+
+void gc_dump_filter_enable(const char *filtername, int zone)
+{
+ struct list_head *filterhead;
+ struct gcdbgfilter *filter;
+ unsigned int filterfound = 0;
+ unsigned int havesetzones = 0;
+
+ GCLOCK(&g_lockmutex);
+
+ GC_PRINTK(NULL, "modifying zone mask for filter %s:\n", filtername);
+
+ list_for_each(filterhead, &gc_filterlist) {
+ filter = list_entry(filterhead, struct gcdbgfilter,
+ link);
+
+ if (strcasecmp(filtername, filter->filtername) == 0) {
+ GC_PRINTK(NULL, " 0x%08X --> 0x%08X\n",
+ filter->zone, zone);
+ filter->zone = zone;
+ filterfound = 1;
+ }
+
+ if (filter->zone != 0)
+ havesetzones = 1;
+ }
+
+ GCUNLOCK(&g_lockmutex);
+
+ if (!filterfound)
+ GC_PRINTK(NULL, " couldn't find filter %s.\n", filtername);
+
+ if (havesetzones && !g_outputbuffer.enable)
+ gc_dump_enable();
+ else if (!havesetzones && g_outputbuffer.enable)
+ gc_dump_disable();
+}
+EXPORT_SYMBOL(gc_dump_filter_enable);
+
+void gc_dbg_add_client(struct gcdbgfilter *filter)
+{
+ list_add(&filter->link, &gc_filterlist);
+}
+EXPORT_SYMBOL(gc_dbg_add_client);
+
+void gc_dump_flush(struct seq_file *s)
+{
+#if GC_BUFFERED_OUTPUT
+ GCLOCK(&g_lockmutex);
+
+ /*
+ * Not dumping through debugfs for now because we have
+ * too much data and it'd require us to implement the
+ * seq_file iterator interface.
+ */
+ gc_buffer_flush(NULL, &g_outputbuffer);
+
+ GCUNLOCK(&g_lockmutex);
+#endif
+}
+EXPORT_SYMBOL(gc_dump_flush);
+
+void gc_dump_reset(void)
+{
+#if GC_BUFFERED_OUTPUT
+ GCLOCK(&g_lockmutex);
+
+ g_outputbuffer.start = 0;
+ g_outputbuffer.index = 0;
+ g_outputbuffer.count = 0;
+
+ GC_PRINTK(NULL, "gcx logging buffer is reset.\n");
+
+ GCUNLOCK(&g_lockmutex);
+#endif
+}
+EXPORT_SYMBOL(gc_dump_reset);
+
+
+/*******************************************************************************
+ * Command buffer parser.
+ */
+
+int gc_parse_command_buffer(unsigned int *buffer, unsigned int size,
+ struct gccommandinfo *info)
+{
+ int res;
+ unsigned int i, j, itemcount, index, oldsrc;
+ unsigned int command, count, addr;
+
+ memset(info, 0, sizeof(struct gccommandinfo));
+ info->command = ~0U;
+
+ oldsrc = 0;
+
+ itemcount = (size + 3) / 4;
+ for (i = 0; i < itemcount;) {
+ command = (buffer[i] >> 27) & 0x1F;
+
+ switch (command) {
+ case GCREG_COMMAND_OPCODE_LOAD_STATE:
+ count = (buffer[i] >> 16) & 0x3F;
+ addr = buffer[i] & 0xFFFF;
+ i += 1;
+
+ for (j = 0; j < count; j += 1) {
+ switch (addr) {
+ case gcregDestAddressRegAddrs:
+ info->dst.surf.address = buffer[i];
+ break;
+
+ case gcregDestStrideRegAddrs:
+ info->dst.surf.stride = buffer[i];
+ break;
+
+ case gcregDestRotationConfigRegAddrs:
+ info->dst.surf.width
+ = buffer[i] & 0xFFFF;
+ break;
+
+ case gcregDstRotationHeightRegAddrs:
+ info->dst.surf.height
+ = buffer[i] & 0xFFFF;
+ break;
+
+ case gcregDestConfigRegAddrs:
+ info->command
+ = (buffer[i] >> 12) & 0xF;
+
+ info->dst.surf.swizzle
+ = (buffer[i] >> 16) & 0x3;
+
+ info->dst.surf.format
+ = buffer[i] & 0x1F;
+
+ info->dst.surf.bpp = gc_get_bpp(
+ info->dst.surf.format);
+ break;
+
+ case gcregSrcAddressRegAddrs:
+ info->src[0].surf.address = buffer[i];
+ oldsrc = 1;
+ break;
+
+ case gcregSrcStrideRegAddrs:
+ info->src[0].surf.stride = buffer[i];
+ break;
+
+ case gcregSrcRotationConfigRegAddrs:
+ info->src[0].surf.width
+ = buffer[i] & 0xFFFF;
+ break;
+
+ case gcregSrcRotationHeightRegAddrs:
+ info->src[0].surf.height
+ = buffer[i] & 0xFFFF;
+ break;
+
+ case gcregSrcConfigRegAddrs:
+ info->src[0].surf.swizzle
+ = (buffer[i] >> 20) & 0x3;
+
+ info->src[0].surf.format
+ = (buffer[i] >> 24) & 0x1F;
+
+ info->src[0].surf.bpp = gc_get_bpp(
+ info->src[0].surf.format);
+ break;
+
+ case gcregSrcOriginRegAddrs:
+ info->src[0].rect.left
+ = buffer[i] & 0xFFFF;
+
+ info->src[0].rect.top
+ = (buffer[i] >> 16) & 0xFFFF;
+ break;
+
+ case gcregSrcSizeRegAddrs:
+ info->src[0].rect.right
+ = buffer[i] & 0xFFFF;
+
+ info->src[0].rect.bottom
+ = (buffer[i] >> 16) & 0xFFFF;
+ break;
+
+ case gcregBlock4SrcAddressRegAddrs:
+ case gcregBlock4SrcAddressRegAddrs + 1:
+ case gcregBlock4SrcAddressRegAddrs + 2:
+ case gcregBlock4SrcAddressRegAddrs + 3:
+ index = addr & 3;
+ info->src[index].surf.address
+ = buffer[i];
+ break;
+
+ case gcregBlock4SrcStrideRegAddrs:
+ case gcregBlock4SrcStrideRegAddrs + 1:
+ case gcregBlock4SrcStrideRegAddrs + 2:
+ case gcregBlock4SrcStrideRegAddrs + 3:
+ index = addr & 3;
+ info->src[index].surf.stride
+ = buffer[i];
+ break;
+
+ case gcregBlock4SrcRotationConfigRegAddrs:
+ case gcregBlock4SrcRotationConfigRegAddrs + 1:
+ case gcregBlock4SrcRotationConfigRegAddrs + 2:
+ case gcregBlock4SrcRotationConfigRegAddrs + 3:
+ index = addr & 3;
+ info->src[index].surf.width
+ = buffer[i] & 0xFFFF;
+ break;
+
+ case gcregBlock4SrcRotationHeightRegAddrs:
+ case gcregBlock4SrcRotationHeightRegAddrs + 1:
+ case gcregBlock4SrcRotationHeightRegAddrs + 2:
+ case gcregBlock4SrcRotationHeightRegAddrs + 3:
+ index = addr & 3;
+ info->src[0].surf.height
+ = buffer[i] & 0xFFFF;
+ break;
+
+ case gcregBlock4SrcConfigRegAddrs:
+ case gcregBlock4SrcConfigRegAddrs + 1:
+ case gcregBlock4SrcConfigRegAddrs + 2:
+ case gcregBlock4SrcConfigRegAddrs + 3:
+ index = addr & 3;
+ info->src[index].surf.swizzle
+ = (buffer[i] >> 20) & 0x3;
+
+ info->src[index].surf.format
+ = (buffer[i] >> 24) & 0x1F;
+
+ info->src[index].surf.bpp = gc_get_bpp(
+ info->src[index].surf.format);
+ break;
+
+ case gcregBlock4SrcOriginRegAddrs:
+ case gcregBlock4SrcOriginRegAddrs + 1:
+ case gcregBlock4SrcOriginRegAddrs + 2:
+ case gcregBlock4SrcOriginRegAddrs + 3:
+ index = addr & 3;
+ info->src[index].rect.left
+ = buffer[i] & 0xFFFF;
+
+ info->src[index].rect.top
+ = (buffer[i] >> 16) & 0xFFFF;
+ break;
+
+ case gcregBlock4SrcSizeRegAddrs:
+ case gcregBlock4SrcSizeRegAddrs + 1:
+ case gcregBlock4SrcSizeRegAddrs + 2:
+ case gcregBlock4SrcSizeRegAddrs + 3:
+ index = addr & 3;
+ info->src[index].rect.right
+ = buffer[i] & 0xFFFF;
+
+ info->src[index].rect.bottom
+ = (buffer[i] >> 16) & 0xFFFF;
+ break;
+
+ case gcregDEMultiSourceRegAddrs:
+ info->srccount = (buffer[i] & 0x7) + 1;
+ break;
+ }
+
+ addr += 1;
+ i += 1;
+ }
+
+ i += ((~count) & 1);
+ break;
+
+ case GCREG_COMMAND_OPCODE_END:
+ case GCREG_COMMAND_OPCODE_NOP:
+ case GCREG_COMMAND_OPCODE_WAIT:
+ case GCREG_COMMAND_OPCODE_LINK:
+ case GCREG_COMMAND_OPCODE_STALL:
+ i += 2;
+ break;
+
+ case GCREG_COMMAND_OPCODE_STARTDE:
+ info->dst.rectcount = (buffer[i] >> 8) & 0xFF;
+ i += 2;
+
+ for (j = 0; j < info->dst.rectcount; j += 1) {
+ info->dst.rect[j].left
+ = buffer[i] & 0xFFFF;
+ info->dst.rect[j].top
+ = (buffer[i] >> 16) & 0xFFFF;
+ i += 1;
+
+ info->dst.rect[j].right
+ = buffer[i] & 0xFFFF;
+ info->dst.rect[j].bottom
+ = (buffer[i] >> 16) & 0xFFFF;
+ i += 1;
+ }
+ break;
+
+ default:
+ res = 0;
+ gc_dump_string(NULL, 0,
+ "bad command (%d) "
+ "while parsing the command stream",
+ command);
+ goto exit;
+ }
+
+ }
+
+ /* Enable old source. */
+ if ((info->srccount == 0) && oldsrc)
+ info->srccount = 1;
+
+ /* Success. */
+ res = 1;
+
+exit:
+ return res;
+}
+EXPORT_SYMBOL(gc_parse_command_buffer);
+
+
+/*******************************************************************************
+ * Bltsville debugging.
+ */
+
+char *gc_bvblend_name(enum bvblend blend)
+{
+ switch (blend) {
+ case BVBLEND_CLEAR: return "BVBLEND_CLEAR";
+ case BVBLEND_SRC1: return "BVBLEND_SRC1";
+ case BVBLEND_SRC2: return "BVBLEND_SRC2";
+ case BVBLEND_SRC1OVER: return "BVBLEND_SRC1OVER";
+ case BVBLEND_SRC2OVER: return "BVBLEND_SRC2OVER";
+ case BVBLEND_SRC1IN: return "BVBLEND_SRC1IN";
+ case BVBLEND_SRC2IN: return "BVBLEND_SRC2IN";
+ case BVBLEND_SRC1OUT: return "BVBLEND_SRC1OUT";
+ case BVBLEND_SRC2OUT: return "BVBLEND_SRC2OUT";
+ case BVBLEND_SRC1ATOP: return "BVBLEND_SRC1ATOP";
+ case BVBLEND_SRC2ATOP: return "BVBLEND_SRC2ATOP";
+ case BVBLEND_XOR: return "BVBLEND_XOR";
+ case BVBLEND_PLUS: return "BVBLEND_PLUS";
+ case BVBLEND_NORMAL: return "BVBLEND_NORMAL";
+ case BVBLEND_LIGHTEN: return "BVBLEND_LIGHTEN";
+ case BVBLEND_DARKEN: return "BVBLEND_DARKEN";
+ case BVBLEND_MULTIPLY: return "BVBLEND_MULTIPLY";
+ case BVBLEND_AVERAGE: return "BVBLEND_AVERAGE";
+ case BVBLEND_ADD: return "BVBLEND_ADD";
+ case BVBLEND_SUBTRACT: return "BVBLEND_SUBTRACT";
+ case BVBLEND_DIFFERENCE: return "BVBLEND_DIFFERENCE";
+ case BVBLEND_NEGATE: return "BVBLEND_NEGATE";
+ case BVBLEND_SCREEN: return "BVBLEND_SCREEN";
+ case BVBLEND_EXCLUSION: return "BVBLEND_EXCLUSION";
+ case BVBLEND_OVERLAY: return "BVBLEND_OVERLAY";
+ case BVBLEND_SOFT_LIGHT: return "BVBLEND_SOFT_LIGHT";
+ case BVBLEND_HARD_LIGHT: return "BVBLEND_HARD_LIGHT";
+ case BVBLEND_COLOR_DODGE: return "BVBLEND_COLOR_DODGE";
+ case BVBLEND_COLOR_BURN: return "BVBLEND_COLOR_BURN";
+ case BVBLEND_LINEAR_LIGHT: return "BVBLEND_LINEAR_LIGHT";
+ case BVBLEND_VIVID_LIGHT: return "BVBLEND_VIVID_LIGHT";
+ case BVBLEND_PIN_LIGHT: return "BVBLEND_PIN_LIGHT";
+ case BVBLEND_HARD_MIX: return "BVBLEND_HARD_MIX";
+ case BVBLEND_REFLECT: return "BVBLEND_REFLECT";
+ case BVBLEND_GLOW: return "BVBLEND_GLOW";
+ case BVBLEND_PHOENIX: return "BVBLEND_PHOENIX";
+ default: return "[UNKNOWN]";
+ }
+}
+EXPORT_SYMBOL(gc_bvblend_name);
+
+
+/*******************************************************************************
+ * Initialization/cleanup.
+ */
+
+void gcdbg_init(void)
+{
+#if GC_BUFFERED_OUTPUT
+ /* Allocate the debug buffer. */
+ g_outputbuffer.buffer = kmalloc(GC_DUMP_BUFFER_SIZE, GFP_KERNEL);
+ if (g_outputbuffer.buffer == NULL) {
+ GC_PRINTK(NULL, "failed to allocate dump buffer.\n");
+ return;
+ }
+#endif
+
+ g_initdone = 1;
+}
+
+void gcdbg_exit(void)
+{
+#if GC_BUFFERED_OUTPUT
+ if (g_outputbuffer.buffer != NULL) {
+ kfree(g_outputbuffer.buffer);
+ g_outputbuffer.buffer = NULL;
+ }
+#endif
+
+ g_initdone = 0;
+}
+
+#endif /* GCDEBUG_ENABLE */
diff --git a/bltsville/gcbv/mirror/gcfill.c b/bltsville/gcbv/mirror/gcfill.c
new file mode 100644
index 0000000..458be75
--- /dev/null
+++ b/bltsville/gcbv/mirror/gcfill.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright(c) 2012,
+ * Texas Instruments, Inc. and Vivante Corporation.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Vivante Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gcbv.h"
+
+#define GCZONE_NONE 0
+#define GCZONE_ALL (~0U)
+#define GCZONE_COLOR (1 << 0)
+#define GCZONE_FILL (1 << 1)
+
+GCDBG_FILTERDEF(fill, GCZONE_NONE,
+ "color",
+ "fill")
+
+
+static inline unsigned int extract_component(unsigned int pixel,
+ const struct bvcomponent *desc)
+{
+ unsigned int component;
+ unsigned int component8;
+
+ component = (pixel & desc->mask) >> desc->shift;
+ GCDBG(GCZONE_COLOR, "mask=0x%08X, shift=%d, component=0x%08X\n",
+ desc->mask, desc->shift, component);
+
+ switch (desc->size) {
+ case 0:
+ component8 = 0xFF;
+ GCDBG(GCZONE_COLOR, "component8=0x%08X\n", component8);
+ break;
+
+ case 1:
+ component8 = component ? 0xFF : 0x00;
+ GCDBG(GCZONE_COLOR, "component8=0x%08X\n", component8);
+ break;
+
+ case 4:
+ component8 = component | (component << 4);
+ GCDBG(GCZONE_COLOR, "component8=0x%08X\n", component8);
+ break;
+
+ case 5:
+ component8 = (component << 3) | (component >> 2);
+ GCDBG(GCZONE_COLOR, "component8=0x%08X\n", component8);
+ break;
+
+ case 6:
+ component8 = (component << 2) | (component >> 4);
+ GCDBG(GCZONE_COLOR, "component8=0x%08X\n", component8);
+ break;
+
+ default:
+ component8 = component;
+ GCDBG(GCZONE_COLOR, "component8=0x%08X\n", component8);
+ }
+
+ return component8;
+}
+
+static unsigned int getinternalcolor(void *ptr, struct bvformatxlate *format)
+{
+ unsigned int srcpixel, dstpixel;
+ unsigned int r, g, b, a;
+
+ switch (format->bitspp) {
+ case 16:
+ srcpixel = *(unsigned short *) ptr;
+ GCDBG(GCZONE_COLOR, "srcpixel=0x%08X\n", srcpixel);
+ break;
+
+ case 32:
+ srcpixel = *(unsigned int *) ptr;
+ GCDBG(GCZONE_COLOR, "srcpixel=0x%08X\n", srcpixel);
+ break;
+
+ default:
+ srcpixel = 0;
+ GCDBG(GCZONE_COLOR, "srcpixel=0x%08X\n", srcpixel);
+ }
+
+ r = extract_component(srcpixel, &format->cs.rgb.comp->r);
+ g = extract_component(srcpixel, &format->cs.rgb.comp->g);
+ b = extract_component(srcpixel, &format->cs.rgb.comp->b);
+ a = extract_component(srcpixel, &format->cs.rgb.comp->a);
+
+ GCDBG(GCZONE_COLOR, "(r,g,b,a)=0x%02X,0x%02X,0x%02X,0x%02X\n",
+ r, g, b, a);
+
+ dstpixel = (a << 24) | (r << 16) | (g << 8) | b;
+
+ GCDBG(GCZONE_COLOR, "dstpixel=0x%08X\n", dstpixel);
+
+ return dstpixel;
+}
+
+enum bverror do_fill(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch,
+ struct surfaceinfo *srcinfo)
+{
+ enum bverror bverror;
+ struct gccontext *gccontext = get_context();
+ struct surfaceinfo *dstinfo;
+ struct gcmofill *gcmofill;
+ unsigned char *fillcolorptr;
+ struct bvbuffmap *dstmap = NULL;
+
+ GCENTER(GCZONE_FILL);
+
+ /* Finish previous batch if any. */
+ bverror = batch->batchend(bvbltparams, batch);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Parse destination parameters. */
+ bverror = parse_destination(bvbltparams, batch);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Setup rotation. */
+ process_dest_rotation(bvbltparams, batch);
+
+ /* Get a shortcut to the destination surface. */
+ dstinfo = &batch->dstinfo;
+
+ /* Verify if the destination parameter have been modified. */
+ if ((batch->dstbyteshift != dstinfo->bytealign) ||
+ (batch->dstphyswidth != dstinfo->physwidth) ||
+ (batch->dstphysheight != dstinfo->physheight)) {
+ /* Set new values. */
+ batch->dstbyteshift = dstinfo->bytealign;
+ batch->dstphyswidth = dstinfo->physwidth;
+ batch->dstphysheight = dstinfo->physheight;
+
+ /* Mark as modified. */
+ batch->batchflags |= BVBATCH_DST;
+ }
+
+ /* Map the destination. */
+ bverror = do_map(bvbltparams->dstdesc, batch, &dstmap);
+ if (bverror != BVERR_NONE) {
+ bvbltparams->errdesc = gccontext->bverrorstr;
+ goto exit;
+ }
+
+ /* Set the new destination. */
+ bverror = set_dst(bvbltparams, batch, dstmap);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Reset the modified flag. */
+ batch->batchflags &= ~(BVBATCH_DST |
+ BVBATCH_CLIPRECT |
+ BVBATCH_DESTRECT);
+
+ /***********************************************************************
+ ** Allocate command buffer.
+ */
+
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmofill),
+ (void **) &gcmofill);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /***********************************************************************
+ ** Set dummy source.
+ */
+
+ /* Set surface dummy width and height. */
+ gcmofill->src.rotation_ldst = gcmofillsrc_rotation_ldst;
+ gcmofill->src.rotation.raw = 0;
+ gcmofill->src.rotation.reg.surf_width = 1;
+ gcmofill->src.config.raw = 0;
+
+ gcmofill->src.rotationheight_ldst = gcmofillsrc_rotationheight_ldst;
+ gcmofill->src.rotationheight.reg.height = 1;
+ gcmofill->src.rotationangle.raw = 0;
+ gcmofill->src.rotationangle.reg.dst = GCREG_ROT_ANGLE_ROT0;
+ gcmofill->src.rotationangle.reg.dst_mirror = GCREG_MIRROR_NONE;
+
+ /* Disable alpha blending. */
+ gcmofill->src.alphacontrol_ldst = gcmofillsrc_alphacontrol_ldst;
+ gcmofill->src.alphacontrol.raw = 0;
+ gcmofill->src.alphacontrol.reg.enable = GCREG_ALPHA_CONTROL_ENABLE_OFF;
+
+ /***********************************************************************
+ ** Set fill color.
+ */
+
+ fillcolorptr
+ = (unsigned char *) srcinfo->buf.desc->virtaddr
+ + srcinfo->rect.top * srcinfo->geom->virtstride
+ + srcinfo->rect.left * srcinfo->format.bitspp / 8;
+
+ gcmofill->clearcolor_ldst = gcmofill_clearcolor_ldst;
+ gcmofill->clearcolor.raw = getinternalcolor(fillcolorptr,
+ &srcinfo->format);
+
+ /***********************************************************************
+ ** Configure and start fill.
+ */
+
+ /* Set destination configuration. */
+ gcmofill->dstconfig_ldst = gcmofill_dstconfig_ldst;
+ gcmofill->dstconfig.raw = 0;
+ gcmofill->dstconfig.reg.swizzle = dstinfo->format.swizzle;
+ gcmofill->dstconfig.reg.format = dstinfo->format.format;
+ gcmofill->dstconfig.reg.command = GCREG_DEST_CONFIG_COMMAND_CLEAR;
+
+ /* Set ROP3. */
+ gcmofill->rop_ldst = gcmofill_rop_ldst;
+ gcmofill->rop.raw = 0;
+ gcmofill->rop.reg.type = GCREG_ROP_TYPE_ROP3;
+ gcmofill->rop.reg.fg = (unsigned char) bvbltparams->op.rop;
+
+ /* Set START_DE command. */
+ gcmofill->startde.cmd.fld = gcfldstartde;
+
+ /* Set destination rectangle. */
+ gcmofill->rect.left = batch->dstadjusted.left;
+ gcmofill->rect.top = batch->dstadjusted.top;
+ gcmofill->rect.right = batch->dstadjusted.right;
+ gcmofill->rect.bottom = batch->dstadjusted.bottom;
+
+exit:
+ GCEXITARG(GCZONE_FILL, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
diff --git a/bltsville/gcbv/mirror/gcfilter.c b/bltsville/gcbv/mirror/gcfilter.c
new file mode 100644
index 0000000..525e242
--- /dev/null
+++ b/bltsville/gcbv/mirror/gcfilter.c
@@ -0,0 +1,1788 @@
+/*
+ * Copyright(c) 2012,
+ * Texas Instruments, Inc. and Vivante Corporation.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Vivante Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gcbv.h"
+
+#define GCZONE_NONE 0
+#define GCZONE_ALL (~0U)
+#define GCZONE_KERNEL (1 << 0)
+#define GCZONE_FILTER (1 << 1)
+#define GCZONE_BLEND (1 << 2)
+#define GCZONE_TYPE (1 << 3)
+#define GCZONE_SRC (1 << 4)
+#define GCZONE_DEST (1 << 5)
+#define GCZONE_SURF (1 << 6)
+
+GCDBG_FILTERDEF(filter, GCZONE_NONE,
+ "kernel",
+ "filter",
+ "blend",
+ "type",
+ "src",
+ "dest",
+ "surf")
+
+
+/*******************************************************************************
+ * Miscellaneous defines.
+ */
+
+#define GC_BYTES_PER_CACHELINE (64)
+#define GC_BITS_PER_CACHELINE (GC_BYTES_PER_CACHELINE * 8)
+#define GC_CACHELINE_ALIGN_16 (GC_BITS_PER_CACHELINE / 16 - 1)
+#define GC_CACHELINE_ALIGN_32 (GC_BITS_PER_CACHELINE / 32 - 1)
+
+enum gcscaletype {
+ GC_SCALE_OPF,
+ GC_SCALE_HOR,
+ GC_SCALE_VER,
+ GC_SCALE_HOR_FLIPPED,
+ GC_SCALE_VER_FLIPPED
+};
+
+/*******************************************************************************
+ * Scale factor format: unsigned 1.31 fixed point.
+ */
+
+#define GC_SCALE_TYPE unsigned int
+#define GC_SCALE_FRACTION 31
+#define GC_SCALE_ONE ((GC_SCALE_TYPE) (1 << GC_SCALE_FRACTION))
+
+
+/*******************************************************************************
+ * X coordinate format: signed 4.28 fixed point.
+ */
+
+#define GC_COORD_TYPE int
+#define GC_COORD_FRACTION 28
+#define GC_COORD_PI ((GC_COORD_TYPE) 0x3243F6C0)
+#define GC_COORD_2OVERPI ((GC_COORD_TYPE) 0x0A2F9832)
+#define GC_COORD_PIOVER2 ((GC_COORD_TYPE) 0x1921FB60)
+#define GC_COORD_ZERO ((GC_COORD_TYPE) 0)
+#define GC_COORD_HALF ((GC_COORD_TYPE) (1 << (GC_COORD_FRACTION - 1)))
+#define GC_COORD_ONE ((GC_COORD_TYPE) (1 << GC_COORD_FRACTION))
+#define GC_COORD_NEGONE ((GC_COORD_TYPE) (~GC_COORD_ONE + 1))
+#define GC_COORD_SUBPIX_STEP ((GC_COORD_TYPE) \
+ (1 << (GC_COORD_FRACTION - GC_PHASE_BITS)))
+
+
+/*******************************************************************************
+ * Hardware coefficient format: signed 2.14 fixed point.
+ */
+
+#define GC_COEF_TYPE short
+#define GC_COEF_FRACTION 14
+#define GC_COEF_ZERO ((GC_COEF_TYPE) 0)
+#define GC_COEF_ONE ((GC_COEF_TYPE) (1 << GC_COEF_FRACTION))
+#define GC_COEF_NEGONE ((GC_COEF_TYPE) (~GC_COEF_ONE + 1))
+
+
+/*******************************************************************************
+ * Weight sum format: x.28 fixed point.
+ */
+
+#define GC_SUM_TYPE long long
+#define GC_SUM_FRACTION GC_COORD_FRACTION
+
+
+/*******************************************************************************
+ * Math shortcuts.
+ */
+
+#define computescale(dstsize, srcsize) ((GC_SCALE_TYPE) \
+ div_u64(((u64) (dstsize)) << GC_SCALE_FRACTION, (srcsize)) \
+)
+
+#define normweight(weight, sum) ((GC_COORD_TYPE) \
+ div64_s64(((s64) (weight)) << GC_COORD_FRACTION, (sum)) \
+)
+
+#define convertweight(weight) ((GC_COEF_TYPE) \
+ ((weight) >> (GC_COORD_FRACTION - GC_COEF_FRACTION)) \
+)
+
+
+/*******************************************************************************
+ * Fixed point SINE function. Takes a positive value in range [0..pi/2].
+ */
+
+static GC_COORD_TYPE sine(GC_COORD_TYPE x)
+{
+ static const GC_COORD_TYPE sinetable[] = {
+ 0x00000000, 0x001FFFEB, 0x003FFF55, 0x005FFDC0,
+ 0x007FFAAB, 0x009FF596, 0x00BFEE01, 0x00DFE36C,
+ 0x00FFD557, 0x011FC344, 0x013FACB2, 0x015F9120,
+ 0x017F7010, 0x019F4902, 0x01BF1B78, 0x01DEE6F2,
+ 0x01FEAAEE, 0x021E66F0, 0x023E1A7C, 0x025DC50C,
+ 0x027D6624, 0x029CFD48, 0x02BC89F8, 0x02DC0BB8,
+ 0x02FB8204, 0x031AEC64, 0x033A4A5C, 0x03599B64,
+ 0x0378DF08, 0x039814CC, 0x03B73C2C, 0x03D654B0,
+ 0x03F55DDC, 0x04145730, 0x04334030, 0x04521868,
+ 0x0470DF58, 0x048F9488, 0x04AE3770, 0x04CCC7A8,
+ 0x04EB44A8, 0x0509ADF8, 0x05280328, 0x054643B0,
+ 0x05646F28, 0x05828508, 0x05A084E0, 0x05BE6E38,
+ 0x05DC4098, 0x05F9FB80, 0x06179E88, 0x06352928,
+ 0x06529AF8, 0x066FF380, 0x068D3248, 0x06AA56D8,
+ 0x06C760C0, 0x06E44F90, 0x070122C8, 0x071DD9F8,
+ 0x073A74B8, 0x0756F290, 0x07735308, 0x078F95B0,
+ 0x07ABBA20, 0x07C7BFD8, 0x07E3A678, 0x07FF6D88,
+ 0x081B14A0, 0x08369B40, 0x08520110, 0x086D4590,
+ 0x08886860, 0x08A36910, 0x08BE4730, 0x08D90250,
+ 0x08F39A20, 0x090E0E10, 0x09285DD0, 0x094288E0,
+ 0x095C8EF0, 0x09766F90, 0x09902A60, 0x09A9BEE0,
+ 0x09C32CC0, 0x09DC7390, 0x09F592F0, 0x0A0E8A70,
+ 0x0A2759C0, 0x0A400070, 0x0A587E20, 0x0A70D270,
+ 0x0A88FD00, 0x0AA0FD60, 0x0AB8D350, 0x0AD07E50,
+ 0x0AE7FE10, 0x0AFF5230, 0x0B167A50, 0x0B2D7610,
+ 0x0B444520, 0x0B5AE730, 0x0B715BC0, 0x0B87A290,
+ 0x0B9DBB40, 0x0BB3A580, 0x0BC960F0, 0x0BDEED30,
+ 0x0BF44A00, 0x0C0976F0, 0x0C1E73D0, 0x0C334020,
+ 0x0C47DBB0, 0x0C5C4620, 0x0C707F20, 0x0C848660,
+ 0x0C985B80, 0x0CABFE50, 0x0CBF6E60, 0x0CD2AB80,
+ 0x0CE5B550, 0x0CF88B80, 0x0D0B2DE0, 0x0D1D9C10,
+ 0x0D2FD5C0, 0x0D41DAB0, 0x0D53AAA0, 0x0D654540,
+ 0x0D76AA40, 0x0D87D970, 0x0D98D280, 0x0DA99530,
+ 0x0DBA2140, 0x0DCA7650, 0x0DDA9450, 0x0DEA7AD0,
+ 0x0DFA29B0, 0x0E09A0B0, 0x0E18DF80, 0x0E27E5F0,
+ 0x0E36B3C0, 0x0E4548B0, 0x0E53A490, 0x0E61C720,
+ 0x0E6FB020, 0x0E7D5F70, 0x0E8AD4C0, 0x0E980FF0,
+ 0x0EA510B0, 0x0EB1D6F0, 0x0EBE6260, 0x0ECAB2D0,
+ 0x0ED6C810, 0x0EE2A200, 0x0EEE4070, 0x0EF9A310,
+ 0x0F04C9E0, 0x0F0FB490, 0x0F1A6300, 0x0F24D510,
+ 0x0F2F0A80, 0x0F390340, 0x0F42BF10, 0x0F4C3DE0,
+ 0x0F557F70, 0x0F5E83C0, 0x0F674A80, 0x0F6FD3B0,
+ 0x0F781F20, 0x0F802CB0, 0x0F87FC40, 0x0F8F8DA0,
+ 0x0F96E0D0, 0x0F9DF5B0, 0x0FA4CC00, 0x0FAB63D0,
+ 0x0FB1BCF0, 0x0FB7D740, 0x0FBDB2B0, 0x0FC34F30,
+ 0x0FC8ACA0, 0x0FCDCAF0, 0x0FD2AA10, 0x0FD749E0,
+ 0x0FDBAA50, 0x0FDFCB50, 0x0FE3ACD0, 0x0FE74EC0,
+ 0x0FEAB110, 0x0FEDD3C0, 0x0FF0B6B0, 0x0FF359F0,
+ 0x0FF5BD50, 0x0FF7E0E0, 0x0FF9C490, 0x0FFB6850,
+ 0x0FFCCC30, 0x0FFDF010, 0x0FFED400, 0x0FFF77F0,
+ 0x0FFFDBF0, 0x0FFFFFE0, 0x0FFFE3D0, 0x0FFF87D0,
+ 0x0FFEEBC0, 0x0FFE0FC0, 0x0FFCF3D0, 0x0FFB97E0
+ };
+
+ enum {
+ indexwidth = 8,
+ intwidth = 1,
+ indexshift = intwidth
+ + GC_COORD_FRACTION
+ - indexwidth
+ };
+
+ unsigned int p1, p2;
+ GC_COORD_TYPE p1x, p2x;
+ GC_COORD_TYPE p1y, p2y;
+ GC_COORD_TYPE dx, dy;
+ GC_COORD_TYPE a, b;
+ GC_COORD_TYPE result;
+
+ /* Determine the indices of two closest points in the table. */
+ p1 = ((unsigned int) x) >> indexshift;
+ p2 = p1 + 1;
+
+ if ((p1 >= countof(sinetable)) || (p2 >= countof(sinetable))) {
+ GCERR("invalid table index.\n");
+ return GC_COORD_ZERO;
+ }
+
+ /* Determine the coordinates of the two closest points. */
+ p1x = p1 << indexshift;
+ p2x = p2 << indexshift;
+
+ p1y = sinetable[p1];
+ p2y = sinetable[p2];
+
+ /* Determine the deltas. */
+ dx = p2x - p1x;
+ dy = p2y - p1y;
+
+ /* Find the slope and the y-intercept. */
+ b = (GC_COORD_TYPE) div64_s64(((s64) dy) << GC_COORD_FRACTION, dx);
+ a = p1y - (GC_COORD_TYPE) (((s64) b * p1x) >> GC_COORD_FRACTION);
+
+ /* Compute the result. */
+ result = a + (GC_COORD_TYPE) (((s64) b * x) >> GC_COORD_FRACTION);
+ return result;
+}
+
+
+/*******************************************************************************
+ * SINC function used in filter kernel generation.
+ */
+
+static GC_COORD_TYPE sinc_filter(GC_COORD_TYPE x, int radius)
+{
+ GC_COORD_TYPE result;
+ s64 radius64;
+ s64 pit, pitd;
+ s64 normpit, normpitd;
+ int negpit, negpitd;
+ int quadpit, quadpitd;
+ GC_COORD_TYPE sinpit, sinpitd;
+ GC_COORD_TYPE f1, f2;
+
+ if (x == GC_COORD_ZERO)
+ return GC_COORD_ONE;
+
+ radius64 = abs(radius) << GC_COORD_FRACTION;
+ if (x > radius64)
+ return GC_COORD_ZERO;
+
+ pit = (((s64) GC_COORD_PI) * x) >> GC_COORD_FRACTION;
+ pitd = div_s64(pit, radius);
+
+ /* Sine table only has values for the first positive quadrant,
+ * remove the sign here. */
+ if (pit < 0) {
+ normpit = -pit;
+ negpit = 1;
+ } else {
+ normpit = pit;
+ negpit = 0;
+ }
+
+ if (pitd < 0) {
+ normpitd = -pitd;
+ negpitd = 1;
+ } else {
+ normpitd = pitd;
+ negpitd = 0;
+ }
+
+ /* Determine which quadrant we are in. */
+ quadpit = (int) ((normpit * GC_COORD_2OVERPI)
+ >> (2 * GC_COORD_FRACTION));
+ quadpitd = (int) ((normpitd * GC_COORD_2OVERPI)
+ >> (2 * GC_COORD_FRACTION));
+
+ /* Move coordinates to the first quadrant. */
+ normpit -= (s64) GC_COORD_PIOVER2 * quadpit;
+ normpitd -= (s64) GC_COORD_PIOVER2 * quadpitd;
+
+ /* Normalize the quadrant numbers. */
+ quadpit %= 4;
+ quadpitd %= 4;
+
+ /* Flip the coordinates if necessary. */
+ if ((quadpit == 1) || (quadpit == 3))
+ normpit = GC_COORD_PIOVER2 - normpit;
+
+ if ((quadpitd == 1) || (quadpitd == 3))
+ normpitd = GC_COORD_PIOVER2 - normpitd;
+
+ sinpit = sine((GC_COORD_TYPE) normpit);
+ sinpitd = sine((GC_COORD_TYPE) normpitd);
+
+ /* Negate depending on the quadrant. */
+ if (negpit) {
+ if ((quadpit == 0) || (quadpit == 1))
+ sinpit = -sinpit;
+ } else {
+ if ((quadpit == 2) || (quadpit == 3))
+ sinpit = -sinpit;
+ }
+
+ if (negpitd) {
+ if ((quadpitd == 0) || (quadpitd == 1))
+ sinpitd = -sinpitd;
+ } else {
+ if ((quadpitd == 2) || (quadpitd == 3))
+ sinpitd = -sinpitd;
+ }
+
+ f1 = (GC_COORD_TYPE)
+ div64_s64(((s64) sinpit) << GC_COORD_FRACTION, pit);
+ f2 = (GC_COORD_TYPE)
+ div64_s64(((s64) sinpitd) << GC_COORD_FRACTION, pitd);
+
+ result = (GC_COORD_TYPE) ((((s64) f1) * f2)
+ >> GC_COORD_FRACTION);
+
+ return result;
+}
+
+
+/*******************************************************************************
+ * Filter kernel generator based on SINC function.
+ */
+
+static void calculate_sync_filter(struct gcfilterkernel *gcfilterkernel)
+{
+ GC_SCALE_TYPE scale;
+ GC_COORD_TYPE subpixset[GC_TAP_COUNT];
+ GC_COORD_TYPE subpixeloffset;
+ GC_COORD_TYPE x, weight;
+ GC_SUM_TYPE weightsum;
+ short convweightsum;
+ int kernelhalf, padding;
+ int subpixpos, kernelpos;
+ short *kernelarray;
+ short count, adjustfrom, adjustment;
+ int index;
+
+ /* Compute the scale factor. */
+ scale = (gcfilterkernel->dstsize >= gcfilterkernel->srcsize)
+ ? GC_SCALE_ONE
+ : computescale(gcfilterkernel->dstsize, gcfilterkernel->srcsize);
+
+ /* Calculate the kernel half. */
+ kernelhalf = (int) (gcfilterkernel->kernelsize >> 1);
+
+ /* Init the subpixel offset. */
+ subpixeloffset = GC_COORD_HALF;
+
+ /* Determine kernel padding size. */
+ padding = (GC_TAP_COUNT - gcfilterkernel->kernelsize) / 2;
+
+ /* Set initial kernel array pointer. */
+ kernelarray = gcfilterkernel->kernelarray;
+
+ /* Loop through each subpixel. */
+ for (subpixpos = 0; subpixpos < GC_PHASE_LOAD_COUNT; subpixpos += 1) {
+ /* Compute weights. */
+ weightsum = GC_COORD_ZERO;
+ for (kernelpos = 0; kernelpos < GC_TAP_COUNT; kernelpos += 1) {
+ /* Determine the current index. */
+ index = kernelpos - padding;
+
+ /* Pad with zeros left side. */
+ if (index < 0) {
+ subpixset[kernelpos] = GC_COORD_ZERO;
+ continue;
+ }
+
+ /* Pad with zeros right side. */
+ if (index >= (int) gcfilterkernel->kernelsize) {
+ subpixset[kernelpos] = GC_COORD_ZERO;
+ continue;
+ }
+
+ /* "Filter off" case. */
+ if (gcfilterkernel->kernelsize == 1) {
+ subpixset[kernelpos] = GC_COORD_ONE;
+
+ /* Update the sum of the weights. */
+ weightsum += GC_COORD_ONE;
+ continue;
+ }
+
+ /* Compute X coordinate. */
+ x = ((index - kernelhalf) << GC_COORD_FRACTION)
+ + subpixeloffset;
+
+ /* Scale the coordinate. */
+ x = (GC_COORD_TYPE)
+ ((((s64) x) * scale) >> GC_SCALE_FRACTION);
+
+ /* Compute the weight. */
+ subpixset[kernelpos] = sinc_filter(x, kernelhalf);
+
+ /* Update the sum of the weights. */
+ weightsum += subpixset[kernelpos];
+ }
+
+ /* Convert the weights to the hardware format. */
+ convweightsum = 0;
+ for (kernelpos = 0; kernelpos < GC_TAP_COUNT; kernelpos += 1) {
+ /* Normalize the current weight. */
+ weight = normweight(subpixset[kernelpos], weightsum);
+
+ /* Convert the weight to fixed point. */
+ if (weight == GC_COORD_ZERO)
+ kernelarray[kernelpos] = GC_COEF_ZERO;
+ else if (weight >= GC_COORD_ONE)
+ kernelarray[kernelpos] = GC_COEF_ONE;
+ else if (weight <= GC_COORD_NEGONE)
+ kernelarray[kernelpos] = GC_COEF_NEGONE;
+ else
+ kernelarray[kernelpos] = convertweight(weight);
+
+ /* Compute the sum of all coefficients. */
+ convweightsum += kernelarray[kernelpos];
+ }
+
+ /* Adjust the fixed point coefficients so that the sum is 1. */
+ count = GC_COEF_ONE - convweightsum;
+ if (count < 0) {
+ count = -count;
+ adjustment = -1;
+ } else {
+ adjustment = 1;
+ }
+
+ if (count > GC_TAP_COUNT) {
+ GCERR("adjust count is too high = %d\n", count);
+ } else {
+ adjustfrom = (GC_TAP_COUNT - count) / 2;
+ for (kernelpos = 0; kernelpos < count; kernelpos += 1)
+ kernelarray[adjustfrom + kernelpos]
+ += adjustment;
+ }
+
+ /* Advance the array pointer. */
+ kernelarray += GC_TAP_COUNT;
+
+ /* Advance to the next subpixel. */
+ subpixeloffset -= GC_COORD_SUBPIX_STEP;
+ }
+}
+
+
+/*******************************************************************************
+ * Loads a filter into the GPU.
+ */
+
+static enum bverror load_filter(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch,
+ enum gcfiltertype type,
+ unsigned int kernelsize,
+ unsigned int scalefactor,
+ unsigned int srcsize,
+ unsigned int dstsize,
+ struct gccmdldstate arraystate)
+{
+ enum bverror bverror = BVERR_NONE;
+ struct gccontext *gccontext = get_context();
+ struct gcfiltercache *filtercache;
+ struct list_head *filterlist;
+ struct list_head *filterhead;
+ struct gcfilterkernel *gcfilterkernel;
+ struct gcmofilterkernel *gcmofilterkernel;
+
+ GCDBG(GCZONE_KERNEL, "kernelsize = %d\n", kernelsize);
+ GCDBG(GCZONE_KERNEL, "srcsize = %d\n", srcsize);
+ GCDBG(GCZONE_KERNEL, "dstsize = %d\n", dstsize);
+ GCDBG(GCZONE_KERNEL, "scalefactor = 0x%08X\n", scalefactor);
+
+ /* Is the filter already loaded? */
+ if ((gccontext->loadedfilter != NULL) &&
+ (gccontext->loadedfilter->type == type) &&
+ (gccontext->loadedfilter->kernelsize == kernelsize) &&
+ (gccontext->loadedfilter->scalefactor == scalefactor)) {
+ GCDBG(GCZONE_KERNEL, "filter already computed.\n");
+ gcfilterkernel = gccontext->loadedfilter;
+ goto load;
+ }
+
+ /* Get the proper filter cache. */
+ filtercache = &gccontext->filtercache[type][kernelsize];
+ filterlist = &filtercache->list;
+
+ /* Try to find existing filter. */
+ GCDBG(GCZONE_KERNEL, "scanning for existing filter.\n");
+ list_for_each(filterhead, filterlist) {
+ gcfilterkernel = list_entry(filterhead,
+ struct gcfilterkernel,
+ link);
+ if (gcfilterkernel->scalefactor == scalefactor) {
+ GCDBG(GCZONE_KERNEL, "filter found @ 0x%08X.\n",
+ (unsigned int) gcfilterkernel);
+ break;
+ }
+ }
+
+ /* Found the filter? */
+ if (filterhead != filterlist) {
+ /* Move the filter to the head of the list. */
+ if (filterlist->next != filterhead) {
+ GCDBG(GCZONE_KERNEL, "moving to the head.\n");
+ list_move(filterhead, filterlist);
+ }
+ } else {
+ GCDBG(GCZONE_KERNEL, "filter not found.\n");
+ if (filtercache->count == GC_FILTER_CACHE_MAX) {
+ GCDBG(GCZONE_KERNEL,
+ "reached the maximum number of filters.\n");
+ filterhead = filterlist->prev;
+ list_move(filterhead, filterlist);
+
+ gcfilterkernel = list_entry(filterhead,
+ struct gcfilterkernel,
+ link);
+ } else {
+ GCDBG(GCZONE_KERNEL, "allocating new filter.\n");
+ gcfilterkernel = gcalloc(struct gcfilterkernel,
+ sizeof(struct gcfilterkernel));
+ if (gcfilterkernel == NULL) {
+ BVSETBLTERROR(BVERR_OOM,
+ "filter allocation failed");
+ goto exit;
+ }
+
+ list_add(&gcfilterkernel->link, filterlist);
+ }
+
+ /* Update the number of filters. */
+ filtercache->count += 1;
+
+ /* Initialize the filter. */
+ gcfilterkernel->type = type;
+ gcfilterkernel->kernelsize = kernelsize;
+ gcfilterkernel->srcsize = srcsize;
+ gcfilterkernel->dstsize = dstsize;
+ gcfilterkernel->scalefactor = scalefactor;
+
+ /* Compute the coefficients. */
+ calculate_sync_filter(gcfilterkernel);
+ }
+
+load:
+ GCDBG(GCZONE_KERNEL, "loading filter.\n");
+
+ /* Load the filter. */
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmofilterkernel),
+ (void **) &gcmofilterkernel);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ gcmofilterkernel->kernelarray_ldst = arraystate;
+ memcpy(&gcmofilterkernel->kernelarray,
+ gcfilterkernel->kernelarray,
+ sizeof(gcfilterkernel->kernelarray));
+
+ /* Set the filter. */
+ gccontext->loadedfilter = gcfilterkernel;
+
+exit:
+ return bverror;
+}
+
+
+/*******************************************************************************
+ * Compute the scale factor.
+ */
+
+static inline unsigned int get_scale_factor(unsigned int srcsize,
+ unsigned int dstsize)
+{
+ if ((srcsize <= 1) || (dstsize <= 1))
+ return 0;
+
+ return ((srcsize - 1) << 16) / (dstsize - 1);
+}
+
+
+/*******************************************************************************
+ * Rotates the specified rectangle to the specified angle.
+ */
+
+static void rotate_gcrect(int angle,
+ struct bvsurfgeom *srcgeom, struct gcrect *srcrect,
+ struct bvsurfgeom *dstgeom, struct gcrect *dstrect)
+{
+ unsigned int width, height;
+ struct gcrect rect;
+
+ GCENTER(GCZONE_SURF);
+
+ GCDBG(GCZONE_SURF, "src geom size = %dx%d\n",
+ srcgeom->width, srcgeom->height);
+
+ switch (angle) {
+ case ROT_ANGLE_0:
+ GCDBG(GCZONE_SURF, "ROT_ANGLE_0\n");
+
+ if (dstgeom != srcgeom) {
+ dstgeom->width = srcgeom->width;
+ dstgeom->height = srcgeom->height;
+ }
+
+ if (dstrect != srcrect)
+ *dstrect = *srcrect;
+ break;
+
+ case ROT_ANGLE_90:
+ GCDBG(GCZONE_SURF, "ROT_ANGLE_90\n");
+
+ width = srcgeom->width;
+ height = srcgeom->height;
+
+ dstgeom->width = height;
+ dstgeom->height = width;
+
+ rect.left = height - srcrect->bottom;
+ rect.top = srcrect->left;
+ rect.right = height - srcrect->top;
+ rect.bottom = srcrect->right;
+
+ *dstrect = rect;
+ break;
+
+ case ROT_ANGLE_180:
+ GCDBG(GCZONE_SURF, "ROT_ANGLE_180\n");
+
+ width = srcgeom->width;
+ height = srcgeom->height;
+
+ if (dstgeom != srcgeom) {
+ dstgeom->width = width;
+ dstgeom->height = height;
+ }
+
+ rect.left = width - srcrect->right;
+ rect.top = height - srcrect->bottom;
+ rect.right = width - srcrect->left;
+ rect.bottom = height - srcrect->top;
+
+ *dstrect = rect;
+ break;
+
+ case ROT_ANGLE_270:
+ GCDBG(GCZONE_SURF, "ROT_ANGLE_270\n");
+
+ width = srcgeom->width;
+ height = srcgeom->height;
+
+ dstgeom->width = height;
+ dstgeom->height = width;
+
+ rect.left = srcrect->top;
+ rect.top = width - srcrect->right;
+ rect.right = srcrect->bottom;
+ rect.bottom = width - srcrect->left;
+
+ *dstrect = rect;
+ break;
+ }
+
+ GCEXIT(GCZONE_SURF);
+}
+
+
+/*******************************************************************************
+ * Setup destination rotation parameters.
+ */
+
+void process_rotation(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch,
+ struct surfaceinfo *srcinfo,
+ int adjangle)
+{
+ GCENTER(GCZONE_DEST);
+
+ if (srcinfo->newgeom ||
+ ((batch->batchflags & (BVBATCH_CLIPRECT |
+ BVBATCH_DESTRECT |
+ BVBATCH_DST)) != 0)) {
+ bool orthogonal;
+ struct gcfilter *gcfilter;
+ struct surfaceinfo *dstinfo;
+ int dstoffsetX, dstoffsetY;
+
+ /* Get some shortcuts. */
+ dstinfo = &batch->dstinfo;
+ gcfilter = &batch->op.filter;
+
+ /* Compute the adjusted destination angle. */
+ gcfilter->dstangle
+ = (dstinfo->angle + (4 - srcinfo->angle)) % 4;
+ GCDBG(GCZONE_DEST, "dstangle = %d\n", gcfilter->dstangle);
+
+ /* Determine whether the new and the old destination angles
+ * are orthogonal to each other. */
+ orthogonal = (gcfilter->dstangle % 2) != (dstinfo->angle % 2);
+
+ switch (gcfilter->dstangle) {
+ case ROT_ANGLE_0:
+ /* Determine the origin offset. */
+ dstoffsetX = dstinfo->xpixalign;
+ dstoffsetY = dstinfo->ypixalign;
+
+ /* Determine geometry size. */
+ if (orthogonal) {
+ batch->dstwidth = dstinfo->geom->height
+ - dstinfo->xpixalign;
+ batch->dstheight = dstinfo->geom->width
+ - dstinfo->ypixalign;
+ } else {
+ batch->dstwidth = dstinfo->geom->width
+ - dstinfo->xpixalign;
+ batch->dstheight = dstinfo->geom->height
+ - dstinfo->ypixalign;
+ }
+
+ /* Determine the physical size. */
+ dstinfo->physwidth = batch->dstwidth;
+ dstinfo->physheight = batch->dstheight;
+ break;
+
+ case ROT_ANGLE_90:
+ /* Determine the origin offset. */
+ dstoffsetX = dstinfo->ypixalign;
+ dstoffsetY = dstinfo->xpixalign;
+
+ if (orthogonal) {
+ /* Determine geometry size. */
+ batch->dstwidth = dstinfo->geom->height
+ - dstinfo->ypixalign;
+ batch->dstheight = dstinfo->geom->width
+ - dstinfo->xpixalign;
+
+ /* Determine the physical size. */
+ dstinfo->physwidth = dstinfo->geom->width
+ - dstinfo->xpixalign;
+ dstinfo->physheight = dstinfo->geom->height
+ - dstinfo->ypixalign;
+ } else {
+ /* Determine geometry size. */
+ batch->dstwidth = dstinfo->geom->width
+ - dstinfo->ypixalign;
+ batch->dstheight = dstinfo->geom->height
+ - dstinfo->xpixalign;
+
+ /* Determine the physical size. */
+ dstinfo->physwidth = dstinfo->geom->height
+ - dstinfo->xpixalign;
+ dstinfo->physheight = dstinfo->geom->width
+ - dstinfo->ypixalign;
+ }
+ break;
+
+ case ROT_ANGLE_180:
+ /* Determine the origin offset. */
+ dstoffsetX = 0;
+ dstoffsetY = 0;
+
+ /* Determine geometry size. */
+ if (orthogonal) {
+ batch->dstwidth = dstinfo->geom->height
+ - dstinfo->xpixalign;
+ batch->dstheight = dstinfo->geom->width
+ - dstinfo->ypixalign;
+ } else {
+ batch->dstwidth = dstinfo->geom->width
+ - dstinfo->xpixalign;
+ batch->dstheight = dstinfo->geom->height
+ - dstinfo->ypixalign;
+ }
+
+ /* Determine the physical size. */
+ dstinfo->physwidth = batch->dstwidth;
+ dstinfo->physheight = batch->dstheight;
+ break;
+
+ case ROT_ANGLE_270:
+ /* Determine the origin offset. */
+ dstoffsetX = 0;
+ dstoffsetY = 0;
+
+ if (orthogonal) {
+ /* Determine geometry size. */
+ batch->dstwidth = dstinfo->geom->height
+ = dstinfo->ypixalign;
+ batch->dstheight = dstinfo->geom->width
+ - dstinfo->xpixalign;
+
+ /* Determine the physical size. */
+ dstinfo->physwidth = dstinfo->geom->width
+ - dstinfo->xpixalign;
+ dstinfo->physheight = dstinfo->geom->height
+ - dstinfo->ypixalign;
+ } else {
+ /* Determine geometry size. */
+ batch->dstwidth = dstinfo->geom->width
+ - dstinfo->ypixalign;
+ batch->dstheight = dstinfo->geom->height
+ - dstinfo->xpixalign;
+
+ /* Determine the physical size. */
+ dstinfo->physwidth = dstinfo->geom->height
+ - dstinfo->xpixalign;
+ dstinfo->physheight = dstinfo->geom->width
+ - dstinfo->ypixalign;
+ }
+ break;
+
+ default:
+ dstoffsetX = 0;
+ dstoffsetY = 0;
+ }
+
+ /* Rotate the original destination rectangle
+ * to match the new angle. */
+ rotate_gcrect(adjangle,
+ dstinfo->geom, &dstinfo->rect,
+ &gcfilter->dstgeom, &gcfilter->dstrect);
+
+ /* Rotate the clipped destination rectangle. */
+ rotate_gcrect(adjangle,
+ dstinfo->geom, &batch->dstclipped,
+ &gcfilter->dstgeom, &gcfilter->dstclipped);
+
+ /* Compute the adjusted the destination rectangle. */
+ gcfilter->dstadjusted.left
+ = gcfilter->dstclipped.left - dstoffsetX;
+ gcfilter->dstadjusted.top
+ = gcfilter->dstclipped.top - dstoffsetY;
+ gcfilter->dstadjusted.right
+ = gcfilter->dstclipped.right - dstoffsetX;
+ gcfilter->dstadjusted.bottom
+ = gcfilter->dstclipped.bottom - dstoffsetY;
+
+ GCPRINT_RECT(GCZONE_DEST, "rotated dstrect",
+ &gcfilter->dstrect);
+ GCPRINT_RECT(GCZONE_DEST, "rotated dstclipped",
+ &gcfilter->dstclipped);
+ GCPRINT_RECT(GCZONE_DEST, "rotated dstadjusted",
+ &gcfilter->dstadjusted);
+
+ if (batch->haveaux) {
+ /* Rotate the original aux destination rectangle
+ * to match the new angle. */
+ rotate_gcrect(adjangle, dstinfo->geom,
+ &batch->dstrectaux, &gcfilter->dstgeom,
+ &gcfilter->dstrectaux);
+
+ /* Rotate the aux destination rectangle. */
+ rotate_gcrect(adjangle, dstinfo->geom,
+ &batch->dstclippedaux, &gcfilter->dstgeom,
+ &gcfilter->dstclippedaux);
+
+ /* Compute the adjust the aux destination rectangle. */
+ gcfilter->dstadjustedaux.left
+ = batch->dstclippedaux.left - dstoffsetX;
+ gcfilter->dstadjustedaux.top
+ = batch->dstclippedaux.top - dstoffsetY;
+ gcfilter->dstadjustedaux.right
+ = batch->dstclippedaux.right - dstoffsetX;
+ gcfilter->dstadjustedaux.bottom
+ = batch->dstclippedaux.bottom - dstoffsetY;
+
+ GCPRINT_RECT(GCZONE_DEST, "rotated dstrectaux",
+ &gcfilter->dstrectaux);
+ GCPRINT_RECT(GCZONE_DEST, "rotated dstclippedaux",
+ &gcfilter->dstclippedaux);
+ GCPRINT_RECT(GCZONE_DEST, "rotated dstadjustedaux",
+ &gcfilter->dstadjustedaux);
+ }
+
+ GCDBG(GCZONE_DEST, "aligned geometry size = %dx%d\n",
+ batch->dstwidth, batch->dstheight);
+ GCDBG(GCZONE_DEST, "aligned physical size = %dx%d\n",
+ dstinfo->physwidth, dstinfo->physheight);
+ GCDBG(GCZONE_DEST, "origin offset (pixels) = %d,%d\n",
+ dstoffsetX, dstoffsetY);
+ }
+
+ GCEXIT(GCZONE_DEST);
+}
+
+
+/*******************************************************************************
+ * Rasterizer setup.
+ */
+
+static enum bverror startvr(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch,
+ struct bvbuffmap *srcmap,
+ struct bvbuffmap *dstmap,
+ struct surfaceinfo *srcinfo,
+ struct surfaceinfo *dstinfo,
+ unsigned int srcx,
+ unsigned int srcy,
+ struct gcrect *dstrect,
+ int srcangle,
+ int dstangle,
+ enum gcscaletype scaletype)
+{
+ enum bverror bverror;
+ struct gccontext *gccontext = get_context();
+ struct gcfilter *gcfilter;
+
+ struct gcmovrdst *gcmovrdst;
+ struct gcmovrsrc *gcmovrsrc;
+ struct gcmostartvr *gcmostartvr;
+
+ struct gcrect srcrect;
+
+ GCENTERARG(GCZONE_FILTER, "scaletype = %d\n", scaletype);
+
+ /* Get a shortcut to the filter properties. */
+ gcfilter = &batch->op.filter;
+
+ /***********************************************************************
+ * Program the destination.
+ */
+
+ GCDBG(GCZONE_FILTER, "destination:\n");
+ GCDBG(GCZONE_FILTER, " angle = %d\n", dstangle);
+ GCDBG(GCZONE_FILTER, " pixalign = %d,%d\n",
+ dstinfo->xpixalign, dstinfo->ypixalign);
+ GCDBG(GCZONE_FILTER, " bytealign = %d\n", dstinfo->bytealign);
+ GCDBG(GCZONE_FILTER, " virtstride = %d\n", dstinfo->geom->virtstride);
+ GCDBG(GCZONE_FILTER, " format = %d\n", dstinfo->format.format);
+ GCDBG(GCZONE_FILTER, " swizzle = %d\n", dstinfo->format.swizzle);
+ GCDBG(GCZONE_FILTER, " premul = %d\n", dstinfo->format.premultiplied);
+ GCDBG(GCZONE_FILTER, " physwidth = %d\n", dstinfo->physwidth);
+ GCDBG(GCZONE_FILTER, " physheight = %d\n", dstinfo->physheight);
+ GCPRINT_RECT(GCZONE_FILTER, " rect", dstrect);
+
+ /* Allocate command buffer. */
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmovrdst),
+ (void **) &gcmovrdst);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Add the address fixup. */
+ add_fixup(bvbltparams, batch, &gcmovrdst->address, dstinfo->bytealign);
+
+ /* Set surface parameters. */
+ gcmovrdst->config_ldst = gcmovrdst_config_ldst;
+ gcmovrdst->address = GET_MAP_HANDLE(dstmap);
+ gcmovrdst->stride = dstinfo->geom->virtstride;
+ gcmovrdst->config.raw = 0;
+ gcmovrdst->config.reg.swizzle = dstinfo->format.swizzle;
+ gcmovrdst->config.reg.format = dstinfo->format.format;
+
+ /* Set surface width and height. */
+ gcmovrdst->rotation.raw = 0;
+ gcmovrdst->rotation.reg.surf_width = dstinfo->physwidth;
+ gcmovrdst->rotationheight_ldst = gcmovrdst_rotationheight_ldst;
+ gcmovrdst->rotationheight.raw = 0;
+ gcmovrdst->rotationheight.reg.height = dstinfo->physheight;
+
+ /***********************************************************************
+ * Program the source.
+ */
+
+ /* Determine adjusted source bounding rectangle and origin. */
+ srcrect = srcinfo->rect;
+ srcrect.left -= srcinfo->xpixalign;
+ srcrect.right -= srcinfo->xpixalign;
+ srcx -= (srcinfo->xpixalign << 16);
+
+ GCDBG(GCZONE_FILTER, "source:\n");
+ GCDBG(GCZONE_FILTER, " angle = %d\n", srcangle);
+ GCDBG(GCZONE_FILTER, " pixalign = %d,%d\n",
+ srcinfo->xpixalign, srcinfo->ypixalign);
+ GCDBG(GCZONE_FILTER, " bytealign = %d\n", srcinfo->bytealign);
+ GCDBG(GCZONE_FILTER, " virtstride = %d\n", srcinfo->geom->virtstride);
+ GCDBG(GCZONE_FILTER, " format = %d\n", srcinfo->format.format);
+ GCDBG(GCZONE_FILTER, " swizzle = %d\n", srcinfo->format.swizzle);
+ GCDBG(GCZONE_FILTER, " premul = %d\n", srcinfo->format.premultiplied);
+ GCDBG(GCZONE_FILTER, " physwidth = %d\n", srcinfo->physwidth);
+ GCDBG(GCZONE_FILTER, " physheight = %d\n", srcinfo->physheight);
+ GCPRINT_RECT(GCZONE_FILTER, " rect", &srcrect);
+
+ GCDBG(GCZONE_FILTER, "src origin: 0x%08X,0x%08X\n", srcx, srcy);
+
+ /* Allocate command buffer. */
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmovrsrc),
+ (void **) &gcmovrsrc);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ add_fixup(bvbltparams, batch, &gcmovrsrc->address, srcinfo->bytealign);
+
+ gcmovrsrc->config_ldst = gcmovrsrc_config_ldst;
+
+ gcmovrsrc->address = GET_MAP_HANDLE(srcmap);
+ gcmovrsrc->stride = srcinfo->geom->virtstride;
+
+ gcmovrsrc->rotation.raw = 0;
+ gcmovrsrc->rotation.reg.surf_width = srcinfo->physwidth;
+
+ gcmovrsrc->config.raw = 0;
+ gcmovrsrc->config.reg.swizzle = srcinfo->format.swizzle;
+ gcmovrsrc->config.reg.format = srcinfo->format.format;
+
+ if (gccontext->gcfeatures2.reg.l2cachefor420 &&
+ (srcinfo->format.type == BVFMT_YUV) &&
+ (srcinfo->format.cs.yuv.planecount > 1) &&
+ ((srcinfo->angle & 1) != 0))
+ gcmovrsrc->config.reg.disable420L2cache
+ = GCREG_SRC_CONFIG_DISABLE420_L2_CACHE_DISABLED;
+
+ gcmovrsrc->pos_ldst = gcmovrsrc_pos_ldst;
+
+ /* Source image bounding box. */
+ gcmovrsrc->lt.reg.left = srcrect.left;
+ gcmovrsrc->lt.reg.top = srcrect.top;
+ gcmovrsrc->rb.reg.right = srcrect.right;
+ gcmovrsrc->rb.reg.bottom = srcrect.bottom;
+
+ /* Fractional origin. */
+ gcmovrsrc->x = srcx;
+ gcmovrsrc->y = srcy;
+
+ /* Program rotation. */
+ gcmovrsrc->rotation_ldst = gcmovrsrc_rotation_ldst;
+ gcmovrsrc->rotationheight.reg.height = srcinfo->physheight;
+ gcmovrsrc->rotationangle.raw = 0;
+ gcmovrsrc->rotationangle.reg.src = rotencoding[srcangle];
+ gcmovrsrc->rotationangle.reg.dst = rotencoding[dstangle];
+ gcmovrsrc->rotationangle.reg.src_mirror = srcinfo->mirror;
+ gcmovrsrc->rotationangle.reg.dst_mirror = dstinfo->mirror;
+
+ gcmovrsrc->rop_ldst = gcmovrsrc_rop_ldst;
+ gcmovrsrc->rop.raw = 0;
+ gcmovrsrc->rop.reg.type = GCREG_ROP_TYPE_ROP3;
+ gcmovrsrc->rop.reg.fg = 0xCC;
+
+ /* Program multiply modes. */
+ gcmovrsrc->mult_ldst = gcmovrsrc_mult_ldst;
+ gcmovrsrc->mult.raw = 0;
+ gcmovrsrc->mult.reg.srcglobalpremul
+ = GCREG_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_DISABLE;
+
+ if (srcinfo->format.premultiplied)
+ gcmovrsrc->mult.reg.srcpremul
+ = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_DISABLE;
+ else
+ gcmovrsrc->mult.reg.srcpremul
+ = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_ENABLE;
+
+ if (dstinfo->format.premultiplied) {
+ gcmovrsrc->mult.reg.dstpremul
+ = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_DISABLE;
+
+ gcmovrsrc->mult.reg.dstdemul
+ = GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_DISABLE;
+ } else {
+ gcmovrsrc->mult.reg.dstpremul
+ = GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_ENABLE;
+
+ gcmovrsrc->mult.reg.dstdemul
+ = GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_ENABLE;
+ }
+
+ /* Program YUV source. */
+ if (srcinfo->format.type == BVFMT_YUV) {
+ bverror = set_yuvsrc(bvbltparams, batch, srcinfo, srcmap);
+ if (bverror != BVERR_NONE)
+ goto exit;
+ }
+
+ /***********************************************************************
+ * Program blending.
+ */
+
+ bverror = set_blending(bvbltparams, batch, srcinfo);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /***********************************************************************
+ * Start the operation.
+ */
+
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmostartvr),
+ (void **) &gcmostartvr);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ switch (scaletype) {
+ case GC_SCALE_OPF:
+ gcmostartvr->scalex = gcfilter->horscalefactor;
+ gcmostartvr->scaley = gcfilter->verscalefactor;
+ gcmostartvr->config = gcregvrconfig_onepass;
+ break;
+
+ case GC_SCALE_HOR:
+ gcmostartvr->scalex = gcfilter->horscalefactor;
+ gcmostartvr->scaley = 0;
+ gcmostartvr->config = gcregvrconfig_horizontal;
+ break;
+
+ case GC_SCALE_VER:
+ gcmostartvr->scalex = 0;
+ gcmostartvr->scaley = gcfilter->verscalefactor;
+ gcmostartvr->config = gcregvrconfig_vertical;
+ break;
+
+ case GC_SCALE_HOR_FLIPPED:
+ gcmostartvr->scalex = 0;
+ gcmostartvr->scaley = gcfilter->horscalefactor;
+ gcmostartvr->config = gcregvrconfig_vertical;
+ break;
+
+ case GC_SCALE_VER_FLIPPED:
+ gcmostartvr->scalex = gcfilter->verscalefactor;
+ gcmostartvr->scaley = 0;
+ gcmostartvr->config = gcregvrconfig_horizontal;
+ break;
+ }
+
+ gcmostartvr->scale_ldst = gcmostartvr_scale_ldst;
+ gcmostartvr->rect_ldst = gcmostartvr_rect_ldst;
+ gcmostartvr->config_ldst = gcmostartvr_config_ldst;
+
+ gcmostartvr->lt.left = dstrect->left;
+ gcmostartvr->lt.top = dstrect->top;
+ gcmostartvr->rb.right = dstrect->right;
+ gcmostartvr->rb.bottom = dstrect->bottom;
+
+exit:
+ GCEXITARG(GCZONE_FILTER, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
+
+
+/*******************************************************************************
+ * Main fiter entry.
+ */
+
+enum bverror do_filter(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch,
+ struct surfaceinfo *srcinfo)
+{
+ enum bverror bverror = BVERR_NONE;
+ struct gccontext *gccontext = get_context();
+
+ struct gcfilter *gcfilter;
+ struct surfaceinfo *dstinfo;
+
+ bool scalex, scaley;
+ bool singlepass, twopass;
+
+ struct gcrect *srcrect;
+ struct gcrect *dstrect;
+ struct gcrect *dstclipped;
+ struct gcrect *dstadjusted;
+
+ struct bvsurfgeom dstrotated0geom;
+ struct gcrect dstrotated0;
+
+ struct gcrect dstdelta;
+ struct gcrect srcdelta;
+ struct gcrect srcclipped;
+
+ struct bvbuffmap *srcmap = NULL;
+ struct bvbuffmap *tmpmap = NULL;
+ struct bvbuffmap *dstmap = NULL;
+
+ struct gcmovrconfigex *gcmovrconfigex;
+
+ int adjangle;
+ unsigned int srcx, srcy;
+ unsigned int srcwidth, srcheight;
+ unsigned int dstwidth, dstheight;
+ unsigned int horscalefactor, verscalefactor;
+ unsigned int kernelsize;
+
+ GCENTER(GCZONE_FILTER);
+
+ /* Get some shortcuts. */
+ dstinfo = &batch->dstinfo;
+ gcfilter = &batch->op.filter;
+
+ /* Finish previous batch if any. */
+ bverror = batch->batchend(bvbltparams, batch);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* ROP is not supported by the filters. */
+ if ((srcinfo->rop & 0xFF) != 0xCC) {
+ BVSETBLTERROR(BVERR_ROP,
+ "only copy ROP is supported in scaling mode");
+ goto exit;
+ }
+
+ /* Parse the scale mode. */
+ bverror = parse_scalemode(bvbltparams, batch);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Parse destination parameters. */
+ bverror = parse_destination(bvbltparams, batch);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Compute the source alignments needed to compensate
+ * for the surface base address misalignment if any. */
+ srcinfo->xpixalign = get_pixel_offset(srcinfo, 0);
+ srcinfo->ypixalign = 0;
+ srcinfo->bytealign = (srcinfo->xpixalign
+ * (int) srcinfo->format.bitspp) / 8;
+ GCDBG(GCZONE_SRC, "source surface offset (pixels) = %d,%d\n",
+ srcinfo->xpixalign, srcinfo->ypixalign);
+ GCDBG(GCZONE_SRC, "source surface offset (bytes) = %d\n",
+ srcinfo->bytealign);
+
+ /* Compute U/V plane offsets. */
+ if ((srcinfo->format.type == BVFMT_YUV) &&
+ (srcinfo->format.cs.yuv.planecount > 1))
+ set_computeyuv(srcinfo, 0, 0);
+
+ /* Determine physical size. */
+ if ((srcinfo->angle % 2) == 0) {
+ srcinfo->physwidth = srcinfo->geom->width
+ - srcinfo->xpixalign;
+ srcinfo->physheight = srcinfo->geom->height
+ - srcinfo->ypixalign;
+ } else {
+ srcinfo->physwidth = srcinfo->geom->height
+ - srcinfo->xpixalign;
+ srcinfo->physheight = srcinfo->geom->width
+ - srcinfo->ypixalign;
+ }
+ GCDBG(GCZONE_SRC, "source physical size = %dx%d\n",
+ srcinfo->physwidth, srcinfo->physheight);
+
+ /* OPF does not support source rotation, which can be compensated by
+ * using destination rotation. Compute the adjustment angle.
+ * For simplicity use the same algorythm for both OPF and TPF. */
+ adjangle = (4 - srcinfo->angle) % 4;
+ GCDBG(GCZONE_DEST, "adjangle = %d\n", adjangle);
+
+ /* Compute destination rotation. */
+ process_rotation(bvbltparams, batch, srcinfo, adjangle);
+
+ /* Rotate the source rectangle to 0 degree. */
+ srcrect = &srcinfo->rect;
+ GCPRINT_RECT(GCZONE_FILTER, "full src", srcrect);
+ rotate_gcrect(adjangle,
+ srcinfo->geom, srcrect,
+ srcinfo->geom, srcrect);
+ GCPRINT_RECT(GCZONE_FILTER, "full adjusted src", srcrect);
+
+ /* Get destination rect shortcuts. */
+ if ((srcinfo->index == 1) && batch->haveaux) {
+ dstrect = &gcfilter->dstrectaux;
+ dstclipped = &gcfilter->dstclippedaux;
+ dstadjusted = &gcfilter->dstadjustedaux;
+ } else {
+ dstrect = &gcfilter->dstrect;
+ dstclipped = &gcfilter->dstclipped;
+ dstadjusted = &gcfilter->dstadjusted;
+ }
+
+ GCPRINT_RECT(GCZONE_FILTER, "full adjusted dst", dstrect);
+ GCPRINT_RECT(GCZONE_FILTER, "clipped adjusted dst", dstclipped);
+ GCPRINT_RECT(GCZONE_FILTER, "aligned adjusted dst", dstadjusted);
+
+ /* Determine the source and destination rectangles. */
+ srcwidth = srcrect->right - srcrect->left;
+ srcheight = srcrect->bottom - srcrect->top;
+ dstwidth = dstrect->right - dstrect->left;
+ dstheight = dstrect->bottom - dstrect->top;
+
+ GCDBG(GCZONE_FILTER, "adjusted input src size: %dx%d\n",
+ srcwidth, srcheight);
+ GCDBG(GCZONE_FILTER, "adjusted input dst size: %dx%d\n",
+ dstwidth, dstheight);
+
+ /* Determine the data path. */
+ scalex = (srcwidth != dstwidth);
+ scaley = (srcheight != dstheight);
+
+ twopass = scalex && scaley;
+ if (twopass) {
+ if (((gcfilter->horkernelsize == 3) ||
+ (gcfilter->horkernelsize == 5)) &&
+ ((gcfilter->verkernelsize == 3) ||
+ (gcfilter->verkernelsize == 5))) {
+ singlepass = true;
+ twopass = false;
+ } else {
+ singlepass = false;
+ }
+ } else {
+ /* Two pass filter in one pass mode. */
+ if (!scalex && !scaley)
+ GCERR("no scaling needed.\n");
+
+ GCDBG(GCZONE_FILTER, "only %s scaling needed.\n",
+ scalex ? "horizontal" : "vertical");
+
+ singlepass = false;
+ }
+
+ /* Compute the scale factors. */
+ gcfilter->horscalefactor =
+ horscalefactor = get_scale_factor(srcwidth, dstwidth);
+ GCDBG(GCZONE_FILTER, "horscalefactor = 0x%08X\n", horscalefactor);
+
+ gcfilter->verscalefactor =
+ verscalefactor = get_scale_factor(srcheight, dstheight);
+ GCDBG(GCZONE_FILTER, "verscalefactor = 0x%08X\n", verscalefactor);
+
+ /* Compute the destination offsets. */
+ dstdelta.left = dstclipped->left - dstrect->left;
+ dstdelta.top = dstclipped->top - dstrect->top;
+ dstdelta.right = dstclipped->right - dstrect->left;
+ dstdelta.bottom = dstclipped->bottom - dstrect->top;
+ GCDBG(GCZONE_FILTER, "dst deltas = (%d,%d)-(%d,%d)\n",
+ dstdelta.left, dstdelta.top, dstdelta.right, dstdelta.bottom);
+
+ /* Compute the source offsets. */
+ srcdelta.left = dstdelta.left * horscalefactor;
+ srcdelta.top = dstdelta.top * verscalefactor;
+ srcdelta.right = (dstdelta.right - 1) * horscalefactor + (1 << 16);
+ srcdelta.bottom = (dstdelta.bottom - 1) * verscalefactor + (1 << 16);
+
+ /* Before rendering each destination pixel, the HW will select the
+ * corresponding source center pixel to apply the kernel around.
+ * To make this process precise we need to add 0.5 to source initial
+ * coordinates here; this will make HW pick the next source pixel if
+ * the fraction is equal or greater then 0.5. */
+ srcdelta.left += 0x00008000;
+ srcdelta.top += 0x00008000;
+ srcdelta.right += 0x00008000;
+ srcdelta.bottom += 0x00008000;
+ GCDBG(GCZONE_FILTER, "src deltas = "
+ "(0x%08X,0x%08X)-(0x%08X,0x%08X)\n",
+ srcdelta.left, srcdelta.top, srcdelta.right, srcdelta.bottom);
+ GCDBG(GCZONE_FILTER, "src deltas (int) = (%d,%d)-(%d,%d)\n",
+ srcdelta.left >> 16, srcdelta.top >> 16,
+ srcdelta.right >> 16, srcdelta.bottom >> 16);
+
+ /* Determine clipped source rectangle. */
+ srcclipped.left = srcrect->left + (srcdelta.left >> 16);
+ srcclipped.top = srcrect->top + (srcdelta.top >> 16);
+ srcclipped.right = srcrect->left + (srcdelta.right >> 16);
+ srcclipped.bottom = srcrect->top + (srcdelta.bottom >> 16);
+
+ GCDBG(GCZONE_FILTER, "source:\n");
+ GCDBG(GCZONE_FILTER, " stride = %d, geom = %dx%d\n",
+ srcinfo->geom->virtstride,
+ srcinfo->geom->width, srcinfo->geom->height);
+ GCDBG(GCZONE_FILTER, " rotation = %d\n",
+ srcinfo->angle);
+ GCPRINT_RECT(GCZONE_FILTER, " clipped rect", &srcclipped);
+
+ GCDBG(GCZONE_FILTER, "destination:\n");
+ GCDBG(GCZONE_FILTER, " stride = %d, geom size = %dx%d\n",
+ dstinfo->geom->virtstride,
+ dstinfo->geom->width, dstinfo->geom->height);
+ GCDBG(GCZONE_FILTER, " rotation = %d\n",
+ dstinfo->angle);
+ GCPRINT_RECT(GCZONE_FILTER, " clipped rect", dstclipped);
+
+ /* Validate the source rectangle. */
+ if (!valid_rect(srcinfo->geom, &srcclipped)) {
+ BVSETBLTERROR((srcinfo->index == 0)
+ ? BVERR_SRC1RECT
+ : BVERR_SRC2RECT,
+ "invalid source rectangle.");
+ goto exit;
+ }
+
+ /* Map the source. */
+ bverror = do_map(srcinfo->buf.desc, batch, &srcmap);
+ if (bverror != BVERR_NONE) {
+ bvbltparams->errdesc = gccontext->bverrorstr;
+ goto exit;
+ }
+
+ /* Map the destination. */
+ bverror = do_map(dstinfo->buf.desc, batch, &dstmap);
+ if (bverror != BVERR_NONE) {
+ bvbltparams->errdesc = gccontext->bverrorstr;
+ goto exit;
+ }
+
+ /* Do single pass filter if we can. */
+ if (singlepass) {
+ GCDBG(GCZONE_TYPE, "single pass\n");
+
+ /* Determine the kernel size to use. */
+ kernelsize = max(gcfilter->horkernelsize,
+ gcfilter->verkernelsize);
+
+ /* Set kernel size. */
+ bverror = claim_buffer(bvbltparams, batch,
+ sizeof(struct gcmovrconfigex),
+ (void **) &gcmovrconfigex);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ gcmovrconfigex->config_ldst = gcmovrconfigex_config_ldst;
+ gcmovrconfigex->config.raw = ~0U;
+ gcmovrconfigex->config.reg.kernelsize = kernelsize;
+ gcmovrconfigex->config.reg.mask_kernelsize
+ = GCREG_VR_CONFIG_EX_MASK_FILTER_TAP_ENABLED;
+
+ /* Setup single pass. */
+ srcx = (srcrect->left << 16) + srcdelta.left;
+ srcy = (srcrect->top << 16) + srcdelta.top;
+ GCDBG(GCZONE_SRC, "src origin: 0x%08X,0x%08X\n", srcx, srcy);
+
+ /* Load the horizontal filter. */
+ bverror = load_filter(bvbltparams, batch,
+ GC_FILTER_SYNC,
+ gcfilter->horkernelsize,
+ gcfilter->horscalefactor,
+ srcwidth, dstwidth,
+ gcmofilterkernel_horizontal_ldst);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Load the vertical filter. */
+ bverror = load_filter(bvbltparams, batch,
+ GC_FILTER_SYNC,
+ gcfilter->verkernelsize,
+ gcfilter->verscalefactor,
+ srcheight, dstheight,
+ gcmofilterkernel_vertical_ldst);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Start the operation. */
+ bverror = startvr(bvbltparams, batch,
+ srcmap, dstmap, srcinfo, dstinfo,
+ srcx, srcy, dstadjusted,
+ ROT_ANGLE_0, gcfilter->dstangle,
+ GC_SCALE_OPF);
+ } else if (twopass) {
+ unsigned int horkernelhalf;
+ unsigned int leftextra, rightextra;
+ unsigned int tmprectwidth, tmprectheight;
+ unsigned int tmpalignmask, dstalignmask;
+ unsigned int tmpsize;
+ struct surfaceinfo tmpinfo;
+ struct bvsurfgeom tmpgeom;
+
+ GCDBG(GCZONE_TYPE, "two pass\n");
+
+ /* Initialize the temporaty surface geometry. */
+ tmpgeom.structsize = sizeof(struct bvsurfgeom);
+ tmpgeom.orientation = 0;
+ tmpgeom.paletteformat = 0;
+ tmpgeom.palette = NULL;
+
+ /* Initialize the temporaty surface descriptor. */
+ tmpinfo.index = -1;
+ tmpinfo.geom = &tmpgeom;
+ tmpinfo.angle = gcfilter->dstangle;
+ tmpinfo.mirror = GCREG_MIRROR_NONE;
+ tmpinfo.rop = 0;
+ GCDBG(GCZONE_FILTER, "tmp angle = %d\n", tmpinfo.angle);
+
+ /* Transfer blending parameters from the source to the
+ * temporary buffer so that the blending would happen
+ * on the second pass. */
+ tmpinfo.gca = srcinfo->gca;
+ srcinfo->gca = NULL;
+
+ /* Determine temporary surface format. */
+ if (srcinfo->format.type == BVFMT_YUV) {
+ if (tmpinfo.angle == ROT_ANGLE_0) {
+ GCDBG(GCZONE_FILTER,
+ "tmp format = 4:2:2\n");
+ tmpgeom.format = OCDFMT_YUYV;
+ parse_format(bvbltparams, &tmpinfo);
+ } else {
+ GCDBG(GCZONE_FILTER,
+ "tmp format = dst format\n");
+ tmpgeom.format = dstinfo->geom->format;
+ tmpinfo.format = dstinfo->format;
+ }
+ } else {
+ GCDBG(GCZONE_FILTER,
+ "tmp format = src format\n");
+ tmpgeom.format = srcinfo->geom->format;
+ tmpinfo.format = srcinfo->format;
+ }
+
+ /* Determine pixel alignment masks. */
+ tmpalignmask = GC_BITS_PER_CACHELINE
+ / tmpinfo.format.bitspp - 1;
+ dstalignmask = GC_BITS_PER_CACHELINE
+ / dstinfo->format.bitspp - 1;
+
+ /* In partial filter blit cases, the vertical pass has to render
+ * more pixel information to the left and to the right of the
+ * temporary image so that the next pass has its necessary
+ * kernel information on the edges of the image. */
+ horkernelhalf = gcfilter->horkernelsize >> 1;
+
+ leftextra = srcdelta.left >> 16;
+ rightextra = srcwidth - (srcdelta.right >> 16);
+
+ if (leftextra > horkernelhalf)
+ leftextra = horkernelhalf;
+
+ if (rightextra > horkernelhalf)
+ rightextra = horkernelhalf;
+
+ GCDBG(GCZONE_FILTER, "leftextra = %d, rightextra = %d\n",
+ leftextra, rightextra);
+
+ /* Determine the source origin. */
+ srcx = ((srcrect->left - leftextra) << 16) + srcdelta.left;
+ srcy = (srcrect->top << 16) + srcdelta.top;
+ GCDBG(GCZONE_SRC, "src origin: 0x%08X,0x%08X\n", srcx, srcy);
+ GCDBG(GCZONE_SRC, "src origin (int): %d,%d\n",
+ srcx >> 16, srcy >> 16);
+
+ /* Determine the size of the temporary rectangle. */
+ tmprectwidth = leftextra + rightextra
+ + ((srcdelta.right >> 16) - (srcdelta.left >> 16));
+ tmprectheight = dstadjusted->bottom - dstadjusted->top;
+ GCDBG(GCZONE_FILTER, "tmp rect size: %dx%d\n",
+ tmprectwidth, tmprectheight);
+
+ /* Determine the temporary destination coordinates. */
+ switch (tmpinfo.angle) {
+ case ROT_ANGLE_0:
+ case ROT_ANGLE_180:
+ tmpinfo.rect.left = (srcx >> 16) & tmpalignmask;
+ tmpinfo.rect.top = 0;
+ tmpinfo.rect.right = tmpinfo.rect.left + tmprectwidth;
+ tmpinfo.rect.bottom = tmprectheight;
+
+ tmpgeom.width = (tmpinfo.rect.right + tmpalignmask)
+ & ~tmpalignmask;
+ tmpgeom.height = tmprectheight;
+
+ tmpinfo.physwidth = tmpgeom.width;
+ tmpinfo.physheight = tmpgeom.height;
+ break;
+
+ case ROT_ANGLE_90:
+ tmpinfo.rect.left = 0;
+ tmpinfo.rect.top = dstadjusted->left & dstalignmask;
+ tmpinfo.rect.right = tmprectwidth;
+ tmpinfo.rect.bottom = tmpinfo.rect.top + tmprectheight;
+
+ tmpgeom.width = tmprectwidth;
+ tmpgeom.height = (tmpinfo.rect.bottom + tmpalignmask)
+ & ~tmpalignmask;
+
+ tmpinfo.physwidth = tmpgeom.height;
+ tmpinfo.physheight = tmpgeom.width;
+ break;
+
+ case ROT_ANGLE_270:
+ tmpinfo.rect.left = 0;
+ tmpinfo.rect.right = tmprectwidth;
+ tmpinfo.rect.bottom = dstadjusted->left & dstalignmask;
+
+ tmpgeom.width = tmprectwidth;
+ tmpgeom.height = (tmpinfo.rect.bottom + tmprectheight
+ + tmpalignmask) & ~tmpalignmask;
+
+ tmpinfo.rect.bottom = tmpgeom.height
+ - tmpinfo.rect.bottom;
+ tmpinfo.rect.top = tmpinfo.rect.bottom
+ - tmprectheight;
+
+ tmpinfo.physwidth = tmpgeom.height;
+ tmpinfo.physheight = tmpgeom.width;
+ break;
+ }
+
+ GCPRINT_RECT(GCZONE_DEST, "tmp dest", &tmpinfo.rect);
+ GCDBG(GCZONE_FILTER, "tmp geometry size = %dx%d\n",
+ tmpgeom.width, tmpgeom.height);
+ GCDBG(GCZONE_FILTER, "tmp physical size = %dx%d\n",
+ tmpinfo.physwidth, tmpinfo.physheight);
+
+ /* Determine the size of the temporaty surface. */
+ tmpgeom.virtstride = (tmpinfo.physwidth
+ * tmpinfo.format.bitspp) / 8;
+ tmpsize = tmpgeom.virtstride * tmpinfo.physheight;
+ tmpsize += GC_BYTES_PER_CACHELINE;
+ tmpsize = (tmpsize + ~PAGE_MASK) & PAGE_MASK;
+ GCDBG(GCZONE_FILTER, "tmp stride = %d\n", tmpgeom.virtstride);
+ GCDBG(GCZONE_FILTER, "tmp size (bytes) = %d\n", tmpsize);
+
+ /* Allocate the temporary buffer. */
+ bverror = allocate_temp(bvbltparams, tmpsize);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Map the temporary buffer. */
+ tmpinfo.buf.desc = gccontext->tmpbuffdesc;
+ bverror = do_map(tmpinfo.buf.desc, batch, &tmpmap);
+ if (bverror != BVERR_NONE) {
+ bvbltparams->errdesc = gccontext->bverrorstr;
+ goto exit;
+ }
+
+ /* Compute the temp buffer alignments needed to compensate
+ * for the surface base address misalignment if any. */
+ tmpinfo.xpixalign = 0;
+ tmpinfo.ypixalign = 0;
+ tmpinfo.bytealign = (get_pixel_offset(&tmpinfo, 0)
+ * (int) tmpinfo.format.bitspp) / 8;
+ GCDBG(GCZONE_SRC, "tmp offset (pixels) = %d,%d\n",
+ tmpinfo.xpixalign, tmpinfo.ypixalign);
+ GCDBG(GCZONE_SRC, "tmp offset (bytes) = %d\n",
+ tmpinfo.bytealign);
+
+ /* Load the vertical filter. */
+ bverror = load_filter(bvbltparams, batch,
+ GC_FILTER_SYNC,
+ gcfilter->verkernelsize,
+ gcfilter->verscalefactor,
+ srcheight, dstheight,
+ gcmofilterkernel_shared_ldst);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Start the operation. */
+ GCDBG(GCZONE_TYPE, "vertical pass\n");
+ bverror = startvr(bvbltparams, batch,
+ srcmap, tmpmap, srcinfo, &tmpinfo,
+ srcx, srcy, &tmpinfo.rect,
+ ROT_ANGLE_0, tmpinfo.angle,
+ GC_SCALE_VER);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Fake no rotation. */
+ adjangle = (4 - tmpinfo.angle) % 4;
+ GCDBG(GCZONE_DEST, "adjangle = %d\n", adjangle);
+
+ /* Rotate the source rectangle to 0 degree. */
+ rotate_gcrect(adjangle,
+ tmpinfo.geom, &tmpinfo.rect,
+ tmpinfo.geom, &tmpinfo.rect);
+ GCPRINT_RECT(GCZONE_DEST, "tmp src", &tmpinfo.rect);
+
+ /* Rotate the destination rectangle to 0 degree. */
+ rotate_gcrect(adjangle,
+ &gcfilter->dstgeom, dstclipped,
+ &dstrotated0geom, &dstrotated0);
+ GCPRINT_RECT(GCZONE_DEST, "dest", &dstrotated0);
+
+ /* Apply adjustment. */
+ dstrotated0.left -= dstinfo->xpixalign;
+ dstrotated0.right -= dstinfo->xpixalign;
+
+ /* Determine the source origin. */
+ switch (tmpinfo.angle) {
+ case ROT_ANGLE_0:
+ srcx = ((tmpinfo.rect.left + leftextra) << 16)
+ + (srcdelta.left & 0xFFFF);
+ srcy = (tmpinfo.rect.top << 16)
+ + (srcdelta.top & 0xFFFF);
+ break;
+
+ case ROT_ANGLE_90:
+ srcx = (tmpinfo.rect.left << 16)
+ + (srcdelta.top & 0xFFFF);
+ srcy = ((tmpinfo.rect.top + rightextra) << 16)
+ + (srcdelta.left & 0xFFFF);
+ break;
+
+ case ROT_ANGLE_180:
+ srcx = ((tmpinfo.rect.left + rightextra) << 16)
+ + (srcdelta.left & 0xFFFF);
+ srcy = (tmpinfo.rect.top << 16)
+ + (srcdelta.top & 0xFFFF);
+ break;
+
+ case ROT_ANGLE_270:
+ srcx = (tmpinfo.rect.left << 16)
+ + (srcdelta.top & 0xFFFF);
+ srcy = ((tmpinfo.rect.top + leftextra) << 16)
+ + (srcdelta.left & 0xFFFF);
+ break;
+ }
+
+ GCDBG(GCZONE_SRC, "src origin: 0x%08X,0x%08X\n", srcx, srcy);
+
+ /* Load the horizontal filter. */
+ bverror = load_filter(bvbltparams, batch,
+ GC_FILTER_SYNC,
+ gcfilter->horkernelsize,
+ gcfilter->horscalefactor,
+ srcwidth, dstwidth,
+ gcmofilterkernel_shared_ldst);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Start the operation. */
+ GCDBG(GCZONE_TYPE, "horizontal pass\n");
+ bverror = startvr(bvbltparams, batch,
+ tmpmap, dstmap, &tmpinfo, dstinfo,
+ srcx, srcy, &dstrotated0,
+ ROT_ANGLE_0, ROT_ANGLE_0,
+ ((gcfilter->dstangle % 2) == 0)
+ ? GC_SCALE_HOR
+ : GC_SCALE_HOR_FLIPPED);
+ if (bverror != BVERR_NONE)
+ goto exit;
+ } else {
+ GCDBG(GCZONE_TYPE, "two pass (%s pass config).\n",
+ scalex ? "horizontal" : "vertical");
+
+ /* Setup single pass. */
+ srcx = (srcrect->left << 16) + srcdelta.left;
+ srcy = (srcrect->top << 16) + srcdelta.top;
+ GCDBG(GCZONE_SRC, "src origin: 0x%08X,0x%08X\n", srcx, srcy);
+
+ if (scalex) {
+ /* Load the horizontal filter. */
+ bverror = load_filter(bvbltparams, batch,
+ GC_FILTER_SYNC,
+ gcfilter->horkernelsize,
+ gcfilter->horscalefactor,
+ srcwidth, dstwidth,
+ gcmofilterkernel_shared_ldst);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Start the operation. */
+ bverror = startvr(bvbltparams, batch,
+ srcmap, dstmap, srcinfo, dstinfo,
+ srcx, srcy, dstadjusted,
+ ROT_ANGLE_0, gcfilter->dstangle,
+ GC_SCALE_HOR);
+ if (bverror != BVERR_NONE)
+ goto exit;
+ } else {
+ /* Load the vertical filter. */
+ bverror = load_filter(bvbltparams, batch,
+ GC_FILTER_SYNC,
+ gcfilter->verkernelsize,
+ gcfilter->verscalefactor,
+ srcheight, dstheight,
+ gcmofilterkernel_shared_ldst);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* Start the operation. */
+ bverror = startvr(bvbltparams, batch,
+ srcmap, dstmap, srcinfo, dstinfo,
+ srcx, srcy, dstadjusted,
+ ROT_ANGLE_0, gcfilter->dstangle,
+ GC_SCALE_VER);
+ if (bverror != BVERR_NONE)
+ goto exit;
+ }
+ }
+
+exit:
+ GCEXITARG(GCZONE_FILTER, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
diff --git a/bltsville/gcbv/mirror/gcmap.c b/bltsville/gcbv/mirror/gcmap.c
new file mode 100644
index 0000000..3f2b3f3
--- /dev/null
+++ b/bltsville/gcbv/mirror/gcmap.c
@@ -0,0 +1,342 @@
+/*
+ * Copyright(c) 2012,
+ * Texas Instruments, Inc. and Vivante Corporation.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Vivante Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gcbv.h"
+
+#define GCZONE_NONE 0
+#define GCZONE_ALL (~0U)
+#define GCZONE_MAPPING (1 << 0)
+
+GCDBG_FILTERDEF(map, GCZONE_NONE,
+ "mapping")
+
+
+/*******************************************************************************
+ * Memory management.
+ */
+
+enum bverror do_map(struct bvbuffdesc *bvbuffdesc,
+ struct gcbatch *batch,
+ struct bvbuffmap **map)
+{
+ static const int mapsize
+ = sizeof(struct bvbuffmap)
+ + sizeof(struct bvbuffmapinfo);
+
+ enum bverror bverror;
+ struct gccontext *gccontext = get_context();
+ struct bvbuffmap *bvbuffmap;
+ struct bvbuffmapinfo *bvbuffmapinfo;
+ struct bvphysdesc *bvphysdesc;
+ bool mappedbyothers;
+ struct gcimap gcimap;
+ struct gcschedunmap *gcschedunmap;
+
+ GCENTERARG(GCZONE_MAPPING, "bvbuffdesc = 0x%08X\n",
+ (unsigned int) bvbuffdesc);
+
+ /* Lock access to the mapping list. */
+ GCLOCK(&gccontext->maplock);
+
+ /* Try to find existing mapping. */
+ bvbuffmap = bvbuffdesc->map;
+ while (bvbuffmap != NULL) {
+ if (bvbuffmap->bv_unmap == bv_unmap)
+ break;
+ bvbuffmap = bvbuffmap->nextmap;
+ }
+
+ /* Not mapped yet? */
+ if (bvbuffmap == NULL) {
+ /* New mapping, allocate a record. */
+ if (gccontext->buffmapvac == NULL) {
+ bvbuffmap = gcalloc(struct bvbuffmap, mapsize);
+ if (bvbuffmap == NULL) {
+ BVSETERROR(BVERR_OOM,
+ "failed to allocate mapping record");
+ goto fail;
+ }
+
+ bvbuffmap->structsize = sizeof(struct bvbuffmap);
+ bvbuffmap->bv_unmap = bv_unmap;
+ bvbuffmap->handle = (unsigned long) (bvbuffmap + 1);
+ } else {
+ bvbuffmap = gccontext->buffmapvac;
+ gccontext->buffmapvac = bvbuffmap->nextmap;
+ }
+
+ /* Setup buffer mapping. Here we need to check and make sure
+ * that the buffer starts at a location that is supported by
+ * the hw. If it is not, offset is computed and the buffer is
+ * extended by the value of the offset. */
+ gcimap.gcerror = GCERR_NONE;
+ gcimap.handle = 0;
+
+ if (bvbuffdesc->auxtype == BVAT_PHYSDESC) {
+ bvphysdesc = (struct bvphysdesc *) bvbuffdesc->auxptr;
+
+ if (bvphysdesc->structsize <
+ STRUCTSIZE(bvphysdesc, pageoffset)) {
+ BVSETERROR(BVERR_BUFFERDESC_VERS,
+ "unsupported bvphysdesc version");
+ goto fail;
+ }
+
+ gcimap.buf.offset = bvphysdesc->pageoffset;
+ gcimap.pagesize = bvphysdesc->pagesize;
+ gcimap.pagearray = bvphysdesc->pagearray;
+ gcimap.size = bvbuffdesc->length;
+
+ GCDBG(GCZONE_MAPPING, "new mapping (%s):\n",
+ (batch == NULL) ? "explicit" : "implicit");
+ GCDBG(GCZONE_MAPPING, "pagesize = %lu\n",
+ bvphysdesc->pagesize);
+ GCDBG(GCZONE_MAPPING, "pagearray = 0x%08X\n",
+ (unsigned int) bvphysdesc->pagearray);
+ GCDBG(GCZONE_MAPPING, "pageoffset = %lu\n",
+ bvphysdesc->pageoffset);
+ GCDBG(GCZONE_MAPPING, "mapping size = %d\n",
+ gcimap.size);
+ } else {
+ gcimap.buf.logical = bvbuffdesc->virtaddr;
+ gcimap.pagesize = 0;
+ gcimap.pagearray = NULL;
+ gcimap.size = bvbuffdesc->length;
+
+ GCDBG(GCZONE_MAPPING, "new mapping (%s):\n",
+ (batch == NULL) ? "explicit" : "implicit");
+ GCDBG(GCZONE_MAPPING, "specified virtaddr = 0x%08X\n",
+ (unsigned int) bvbuffdesc->virtaddr);
+ GCDBG(GCZONE_MAPPING, "aligned virtaddr = 0x%08X\n",
+ (unsigned int) gcimap.buf.logical);
+ GCDBG(GCZONE_MAPPING, "mapping size = %d\n",
+ gcimap.size);
+ }
+
+ gc_map_wrapper(&gcimap);
+ if (gcimap.gcerror != GCERR_NONE) {
+ BVSETERROR(BVERR_OOM,
+ "unable to allocate gccore memory");
+ goto fail;
+ }
+
+ /* Set map handle. */
+ bvbuffmapinfo = (struct bvbuffmapinfo *) bvbuffmap->handle;
+ bvbuffmapinfo->handle = gcimap.handle;
+
+ /* Initialize reference counters. */
+ if (batch == NULL) {
+ /* Explicit mapping. */
+ bvbuffmapinfo->usermap = 1;
+ bvbuffmapinfo->automap = 0;
+ } else {
+ /* Implicit mapping; if there are existing mappings
+ * from other implementations, mark this an explicit
+ * mapping as well. */
+ mappedbyothers = (bvbuffdesc->map != NULL);
+ GCDBG(GCZONE_MAPPING, "%smapped by others.\n",
+ mappedbyothers ? "" : "not ");
+
+ bvbuffmapinfo->usermap = mappedbyothers ? 1 : 0;
+ bvbuffmapinfo->automap = 1;
+ }
+
+ /* Add the record to the list of mappings. */
+ bvbuffmap->nextmap = bvbuffdesc->map;
+ bvbuffdesc->map = bvbuffmap;
+ } else {
+ /* Mapping already exists. */
+ bvbuffmapinfo = (struct bvbuffmapinfo *) bvbuffmap->handle;
+
+ /* Advance reference counters. */
+ if (batch == NULL) {
+ /* Explicit mapping. */
+ GCDBG(GCZONE_MAPPING, "explicit map.\n");
+ bvbuffmapinfo->usermap += 1;
+ } else {
+ /* Implicit mapping. */
+ GCDBG(GCZONE_MAPPING, "implicit map.\n");
+ bvbuffmapinfo->automap += 1;
+ }
+
+ GCDBG(GCZONE_MAPPING, "mapping exists.\n");
+ }
+
+ GCDBG(GCZONE_MAPPING, "bvbuffmap = 0x%08X\n",
+ (unsigned int) bvbuffmap);
+ GCDBG(GCZONE_MAPPING, "explicit count = %d\n",
+ bvbuffmapinfo->usermap);
+ GCDBG(GCZONE_MAPPING, "implicit count = %d\n",
+ bvbuffmapinfo->automap);
+
+ /* Schedule for unmapping. */
+ if (batch != NULL) {
+ if (list_empty(&gccontext->unmapvac)) {
+ gcschedunmap = gcalloc(struct gcschedunmap,
+ sizeof(struct gcschedunmap));
+ if (gcschedunmap == NULL) {
+ BVSETERROR(BVERR_OOM,
+ "failed to schedule unmapping");
+ goto fail;
+ }
+ list_add(&gcschedunmap->link, &batch->unmap);
+ } else {
+ struct list_head *head;
+ head = gccontext->unmapvac.next;
+ gcschedunmap = list_entry(head,
+ struct gcschedunmap,
+ link);
+ list_move(&gcschedunmap->link, &batch->unmap);
+ }
+
+ gcschedunmap->handle = (unsigned long) bvbuffdesc;
+
+ GCDBG(GCZONE_MAPPING, "scheduled for unmapping.\n");
+ }
+
+ /* Set the map pointer. */
+ *map = bvbuffmap;
+
+ /* Unlock access to the mapping list. */
+ GCUNLOCK(&gccontext->maplock);
+
+ GCEXITARG(GCZONE_MAPPING, "handle = 0x%08X\n",
+ bvbuffmapinfo->handle);
+ return BVERR_NONE;
+
+fail:
+ if (bvbuffmap != NULL) {
+ bvbuffmap->nextmap = gccontext->buffmapvac;
+ gccontext->buffmapvac = bvbuffmap;
+ }
+
+ /* Unlock access to the mapping list. */
+ GCUNLOCK(&gccontext->maplock);
+
+ GCEXITARG(GCZONE_MAPPING, "bverror = %d\n", bverror);
+ return bverror;
+}
+
+void do_unmap_implicit(struct gcbatch *batch)
+{
+ struct gccontext *gccontext = get_context();
+ struct list_head *head, *temphead;
+ struct gcschedunmap *gcschedunmap;
+ struct bvbuffdesc *bvbuffdesc;
+ struct bvbuffmap *prev, *bvbuffmap;
+ struct bvbuffmapinfo *bvbuffmapinfo;
+
+ GCENTER(GCZONE_MAPPING);
+
+ /* Lock access to the mapping list. */
+ GCLOCK(&gccontext->maplock);
+
+ /* Scan scheduled unmappings and remove the ones that are still
+ * in use. */
+ list_for_each_safe(head, temphead, &batch->unmap) {
+ gcschedunmap = list_entry(head, struct gcschedunmap, link);
+
+ /* Cast the handle. */
+ bvbuffdesc = (struct bvbuffdesc *) gcschedunmap->handle;
+
+ /* Find our mapping. */
+ prev = NULL;
+ bvbuffmap = bvbuffdesc->map;
+ while (bvbuffmap != NULL) {
+ if (bvbuffmap->bv_unmap == bv_unmap)
+ break;
+ prev = bvbuffmap;
+ bvbuffmap = bvbuffmap->nextmap;
+ }
+
+ /* Not found? */
+ if (bvbuffmap == NULL) {
+ GCERR("mapping not found for bvbuffdesc 0x%08X.\n",
+ (unsigned int) bvbuffdesc);
+
+ /* Remove scheduled unmapping. */
+ list_move(head, &gccontext->unmapvac);
+ continue;
+ }
+
+ /* Get the info structure. */
+ bvbuffmapinfo = (struct bvbuffmapinfo *) bvbuffmap->handle;
+
+ GCDBG(GCZONE_MAPPING, "head = 0x%08X\n",
+ (unsigned int) gcschedunmap);
+ GCDBG(GCZONE_MAPPING, " bvbuffmap = 0x%08X\n",
+ (unsigned int) bvbuffmap);
+ GCDBG(GCZONE_MAPPING, " handle = 0x%08X\n",
+ bvbuffmapinfo->handle);
+
+ /* Implicit unmapping. */
+ bvbuffmapinfo->automap -= 1;
+ if (bvbuffmapinfo->automap < 0) {
+ GCERR("implicit count negative.\n");
+ bvbuffmapinfo->automap = 0;
+ }
+
+ GCDBG(GCZONE_MAPPING, " explicit count = %d\n",
+ bvbuffmapinfo->usermap);
+ GCDBG(GCZONE_MAPPING, " implicit count = %d\n",
+ bvbuffmapinfo->automap);
+
+ /* Still referenced? */
+ if (bvbuffmapinfo->usermap || bvbuffmapinfo->automap) {
+ GCDBG(GCZONE_MAPPING, " still referenced.\n");
+
+ /* Remove scheduled unmapping. */
+ list_move(head, &gccontext->unmapvac);
+ continue;
+ }
+
+ GCDBG(GCZONE_MAPPING, " ready for unmapping.\n");
+
+ /* Set the handle. */
+ gcschedunmap->handle = bvbuffmapinfo->handle;
+
+ /* Remove from the buffer descriptor. */
+ if (prev == NULL)
+ bvbuffdesc->map = bvbuffmap->nextmap;
+ else
+ prev->nextmap = bvbuffmap->nextmap;
+
+ /* Add to the vacant list. */
+ bvbuffmap->nextmap = gccontext->buffmapvac;
+ gccontext->buffmapvac = bvbuffmap;
+ }
+
+ /* Unlock access to the mapping list. */
+ GCUNLOCK(&gccontext->maplock);
+
+ GCEXIT(GCZONE_MAPPING);
+}
diff --git a/bltsville/gcbv/mirror/gcparser.c b/bltsville/gcbv/mirror/gcparser.c
new file mode 100644
index 0000000..5bfbdb6
--- /dev/null
+++ b/bltsville/gcbv/mirror/gcparser.c
@@ -0,0 +1,2090 @@
+/*
+ * Copyright(c) 2012,
+ * Texas Instruments, Inc. and Vivante Corporation.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Vivante Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gcbv.h"
+
+#define GCZONE_NONE 0
+#define GCZONE_ALL (~0U)
+#define GCZONE_FORMAT (1 << 0)
+#define GCZONE_FORMAT_VERBOSE (1 << 1)
+#define GCZONE_BLEND (1 << 2)
+#define GCZONE_OFFSET (1 << 3)
+#define GCZONE_DEST (1 << 4)
+#define GCZONE_SRC (1 << 5)
+#define GCZONE_SCALING (1 << 6)
+
+GCDBG_FILTERDEF(parser, GCZONE_NONE,
+ "format",
+ "formatverbose",
+ "blend",
+ "offset",
+ "dest",
+ "src",
+ "scaling")
+
+
+/*******************************************************************************
+ * Internal macros.
+ */
+
+#define GCCONVERT_RECT(zone, name, bvrect, gcrect) \
+{ \
+ (gcrect)->left = (bvrect)->left; \
+ (gcrect)->top = (bvrect)->top; \
+ (gcrect)->right = (bvrect)->left + (bvrect)->width; \
+ (gcrect)->bottom = (bvrect)->top + (bvrect)->height; \
+ \
+ GCPRINT_RECT(zone, name, gcrect); \
+}
+
+
+/*******************************************************************************
+ * Pixel format parser.
+ */
+
+#define OCDFMTDEF_PLACEMENT_SHIFT 9
+#define OCDFMTDEF_PLACEMENT_MASK (3 << OCDFMTDEF_PLACEMENT_SHIFT)
+
+#define BVCOMP(Shift, Size) \
+ { Shift, Size, ((1 << Size) - 1) << Shift }
+
+#define BVRED(Shift, Size) \
+ BVCOMP(Shift, Size)
+
+#define BVGREEN(Shift, Size) \
+ BVCOMP(Shift, Size)
+
+#define BVBLUE(Shift, Size) \
+ BVCOMP(Shift, Size)
+
+#define BVALPHA(Shift, Size) \
+ BVCOMP(Shift, Size)
+
+static const unsigned int rgba16swizzle[] = {
+ GCREG_DE_SWIZZLE_ARGB,
+ GCREG_DE_SWIZZLE_RGBA,
+ GCREG_DE_SWIZZLE_ABGR,
+ GCREG_DE_SWIZZLE_BGRA
+};
+
+static const unsigned int rgb16swizzle[] = {
+ GCREG_DE_SWIZZLE_ARGB,
+ GCREG_DE_SWIZZLE_ARGB,
+ GCREG_DE_SWIZZLE_ABGR,
+ GCREG_DE_SWIZZLE_ABGR
+};
+
+static const unsigned int rgba32swizzle[] = {
+ GCREG_DE_SWIZZLE_BGRA,
+ GCREG_DE_SWIZZLE_ABGR,
+ GCREG_DE_SWIZZLE_RGBA,
+ GCREG_DE_SWIZZLE_ARGB
+};
+
+static const struct bvcsrgb xrgb4444_bits[] = {
+ { BVRED(8, 4), BVGREEN(4, 4), BVBLUE(0, 4), BVALPHA(12, 0) },
+ { BVRED(12, 4), BVGREEN(8, 4), BVBLUE(4, 4), BVALPHA(0, 0) },
+ { BVRED(0, 4), BVGREEN(4, 4), BVBLUE(8, 4), BVALPHA(12, 0) },
+ { BVRED(4, 4), BVGREEN(8, 4), BVBLUE(12, 4), BVALPHA(0, 0) }
+};
+
+static const struct bvcsrgb argb4444_bits[] = {
+ { BVRED(8, 4), BVGREEN(4, 4), BVBLUE(0, 4), BVALPHA(12, 4) },
+ { BVRED(12, 4), BVGREEN(8, 4), BVBLUE(4, 4), BVALPHA(0, 4) },
+ { BVRED(0, 4), BVGREEN(4, 4), BVBLUE(8, 4), BVALPHA(12, 4) },
+ { BVRED(4, 4), BVGREEN(8, 4), BVBLUE(12, 4), BVALPHA(0, 4) }
+};
+
+static const struct bvcsrgb xrgb1555_bits[] = {
+ { BVRED(10, 5), BVGREEN(5, 5), BVBLUE(0, 5), BVALPHA(15, 0) },
+ { BVRED(11, 5), BVGREEN(6, 5), BVBLUE(1, 5), BVALPHA(0, 0) },
+ { BVRED(0, 5), BVGREEN(5, 5), BVBLUE(10, 5), BVALPHA(15, 0) },
+ { BVRED(1, 5), BVGREEN(6, 5), BVBLUE(11, 5), BVALPHA(0, 0) }
+};
+
+static const struct bvcsrgb argb1555_bits[] = {
+ { BVRED(10, 5), BVGREEN(5, 5), BVBLUE(0, 5), BVALPHA(15, 1) },
+ { BVRED(11, 5), BVGREEN(6, 5), BVBLUE(1, 5), BVALPHA(0, 1) },
+ { BVRED(0, 5), BVGREEN(5, 5), BVBLUE(10, 5), BVALPHA(15, 1) },
+ { BVRED(1, 5), BVGREEN(6, 5), BVBLUE(11, 5), BVALPHA(0, 1) }
+};
+
+static const struct bvcsrgb rgb565_bits[] = {
+ { BVRED(11, 5), BVGREEN(5, 6), BVBLUE(0, 5), BVALPHA(0, 0) },
+ { BVRED(11, 5), BVGREEN(5, 6), BVBLUE(0, 5), BVALPHA(0, 0) },
+ { BVRED(0, 5), BVGREEN(5, 6), BVBLUE(11, 5), BVALPHA(0, 0) },
+ { BVRED(0, 5), BVGREEN(5, 6), BVBLUE(11, 5), BVALPHA(0, 0) }
+};
+
+static const struct bvcsrgb xrgb8888_bits[] = {
+ { BVRED(8, 8), BVGREEN(16, 8), BVBLUE(24, 8), BVALPHA(0, 0) },
+ { BVRED(0, 8), BVGREEN(8, 8), BVBLUE(16, 8), BVALPHA(24, 0) },
+ { BVRED(24, 8), BVGREEN(16, 8), BVBLUE(8, 8), BVALPHA(0, 0) },
+ { BVRED(16, 8), BVGREEN(8, 8), BVBLUE(0, 8), BVALPHA(24, 0) }
+};
+
+static const struct bvcsrgb argb8888_bits[] = {
+ { BVRED(8, 8), BVGREEN(16, 8), BVBLUE(24, 8), BVALPHA(0, 8) },
+ { BVRED(0, 8), BVGREEN(8, 8), BVBLUE(16, 8), BVALPHA(24, 8) },
+ { BVRED(24, 8), BVGREEN(16, 8), BVBLUE(8, 8), BVALPHA(0, 8) },
+ { BVRED(16, 8), BVGREEN(8, 8), BVBLUE(0, 8), BVALPHA(24, 8) }
+};
+
+static const unsigned int container[] = {
+ 8, /* OCDFMTDEF_CONTAINER_8BIT */
+ 16, /* OCDFMTDEF_CONTAINER_16BIT */
+ 24, /* OCDFMTDEF_CONTAINER_24BIT */
+ 32, /* OCDFMTDEF_CONTAINER_32BIT */
+ ~0U, /* reserved */
+ 48, /* OCDFMTDEF_CONTAINER_48BIT */
+ ~0U, /* reserved */
+ 64 /* OCDFMTDEF_CONTAINER_64BIT */
+};
+
+enum bverror parse_format(struct bvbltparams *bvbltparams,
+ struct surfaceinfo *surfaceinfo)
+{
+ enum bverror bverror = BVERR_NONE;
+ struct bvformatxlate *format;
+ enum ocdformat ocdformat;
+ unsigned int cs, std, alpha, subsample, layout;
+ unsigned int reversed, leftjust, swizzle, cont, bits;
+
+ format = &surfaceinfo->format;
+ ocdformat = surfaceinfo->geom->format;
+ GCENTERARG(GCZONE_FORMAT, "ocdformat = 0x%08X\n", ocdformat);
+
+ cs = (ocdformat & OCDFMTDEF_CS_MASK)
+ >> OCDFMTDEF_CS_SHIFT;
+ std = (ocdformat & OCDFMTDEF_STD_MASK)
+ >> OCDFMTDEF_STD_SHIFT;
+ alpha = ocdformat & OCDFMTDEF_ALPHA;
+ subsample = (ocdformat & OCDFMTDEF_SUBSAMPLE_MASK)
+ >> OCDFMTDEF_SUBSAMPLE_SHIFT;
+ layout = (ocdformat & OCDFMTDEF_LAYOUT_MASK)
+ >> OCDFMTDEF_LAYOUT_SHIFT;
+ cont = (ocdformat & OCDFMTDEF_CONTAINER_MASK)
+ >> OCDFMTDEF_CONTAINER_SHIFT;
+ bits = ((ocdformat & OCDFMTDEF_COMPONENTSIZEMINUS1_MASK)
+ >> OCDFMTDEF_COMPONENTSIZEMINUS1_SHIFT) + 1;
+
+ GCDBG(GCZONE_FORMAT_VERBOSE, "std = %d\n", std);
+ GCDBG(GCZONE_FORMAT_VERBOSE, "cs = %d\n", cs);
+ GCDBG(GCZONE_FORMAT_VERBOSE, "alpha = %d\n", alpha ? 1 : 0);
+ GCDBG(GCZONE_FORMAT_VERBOSE, "subsample = %d\n", subsample);
+ GCDBG(GCZONE_FORMAT_VERBOSE, "layout = %d\n", layout);
+ GCDBG(GCZONE_FORMAT_VERBOSE, "cont = %d\n", cont);
+ GCDBG(GCZONE_FORMAT_VERBOSE, "bits = %d\n", bits);
+
+ switch (cs) {
+ case (OCDFMTDEF_CS_RGB >> OCDFMTDEF_CS_SHIFT):
+ GCDBG(GCZONE_FORMAT, "OCDFMTDEF_CS_RGB\n");
+
+ /* Determine the swizzle. */
+ swizzle = (ocdformat & OCDFMTDEF_PLACEMENT_MASK)
+ >> OCDFMTDEF_PLACEMENT_SHIFT;
+ GCDBG(GCZONE_FORMAT, "swizzle = %d\n", swizzle);
+
+ /* RGB color space. */
+ format->type = BVFMT_RGB;
+
+ /* Has to be 0 for RGB. */
+ if (std != 0) {
+ BVSETBLTERROR(BVERR_UNK,
+ "unsupported standard");
+ goto exit;
+ }
+
+ /* Determine premultuplied or not. */
+ if (alpha == OCDFMTDEF_ALPHA) {
+ format->premultiplied
+ = ((ocdformat & OCDFMTDEF_NON_PREMULT) == 0);
+ } else {
+ format->premultiplied = true;
+
+ if ((ocdformat & OCDFMTDEF_FILL_EMPTY_0) != 0) {
+ BVSETBLTERROR(BVERR_UNK,
+ "0 filling is not supported");
+ goto exit;
+ }
+ }
+ GCDBG(GCZONE_FORMAT, "premultiplied = %d\n",
+ format->premultiplied);
+
+ /* No subsample support. */
+ if (subsample !=
+ (OCDFMTDEF_SUBSAMPLE_NONE >> OCDFMTDEF_SUBSAMPLE_SHIFT)) {
+ BVSETBLTERROR(BVERR_UNK,
+ "subsampling for RGB is not supported");
+ goto exit;
+ }
+
+ /* Only packed RGB is supported. */
+ if (layout !=
+ (OCDFMTDEF_PACKED >> OCDFMTDEF_LAYOUT_SHIFT)) {
+ BVSETBLTERROR(BVERR_UNK,
+ "only packed RGBA formats are supported");
+ goto exit;
+ }
+
+ /* Determine the format. */
+ switch (bits) {
+ case 12:
+ format->bitspp = 16;
+ format->allocbitspp = 16;
+ format->swizzle = rgba16swizzle[swizzle];
+
+ if (alpha == OCDFMTDEF_ALPHA) {
+ format->format = GCREG_DE_FORMAT_A4R4G4B4;
+ format->cs.rgb.comp = &argb4444_bits[swizzle];
+ } else {
+ format->format = GCREG_DE_FORMAT_X4R4G4B4;
+ format->cs.rgb.comp = &xrgb4444_bits[swizzle];
+ }
+ break;
+
+ case 15:
+ format->bitspp = 16;
+ format->allocbitspp = 16;
+ format->swizzle = rgba16swizzle[swizzle];
+
+ if (alpha == OCDFMTDEF_ALPHA) {
+ format->format = GCREG_DE_FORMAT_A1R5G5B5;
+ format->cs.rgb.comp = &argb1555_bits[swizzle];
+ } else {
+ format->format = GCREG_DE_FORMAT_X1R5G5B5;
+ format->cs.rgb.comp = &xrgb1555_bits[swizzle];
+ }
+ break;
+
+ case 16:
+ if (alpha == OCDFMTDEF_ALPHA) {
+ BVSETBLTERROR(BVERR_UNK,
+ "alpha component is not supported"
+ "for this format.");
+ goto exit;
+ }
+
+ format->bitspp = 16;
+ format->allocbitspp = 16;
+ format->swizzle = rgb16swizzle[swizzle];
+ format->format = GCREG_DE_FORMAT_R5G6B5;
+ format->cs.rgb.comp = &rgb565_bits[swizzle];
+ break;
+
+ case 24:
+ format->bitspp = 32;
+ format->allocbitspp = 32;
+ format->swizzle = rgba32swizzle[swizzle];
+
+ if (alpha == OCDFMTDEF_ALPHA) {
+ format->format = GCREG_DE_FORMAT_A8R8G8B8;
+ format->cs.rgb.comp = &argb8888_bits[swizzle];
+ } else {
+ format->format = GCREG_DE_FORMAT_X8R8G8B8;
+ format->cs.rgb.comp = &xrgb8888_bits[swizzle];
+ }
+ break;
+
+ default:
+ BVSETBLTERROR(BVERR_UNK,
+ "unsupported bit width %d", bits);
+ goto exit;
+ }
+
+ if (format->allocbitspp != container[cont]) {
+ BVSETBLTERROR(BVERR_UNK,
+ "unsupported container");
+ goto exit;
+ }
+ break;
+
+ case (OCDFMTDEF_CS_YCbCr >> OCDFMTDEF_CS_SHIFT):
+ GCDBG(GCZONE_FORMAT, "OCDFMTDEF_CS_YCbCr\n");
+
+ /* YUV color space. */
+ format->type = BVFMT_YUV;
+
+ /* Determine the swizzle. */
+ reversed = ocdformat & OCDFMTDEF_REVERSED;
+ leftjust = ocdformat & OCDFMTDEF_LEFT_JUSTIFIED;
+ GCDBG(GCZONE_FORMAT_VERBOSE, "reversed = %d\n",
+ reversed ? 1 : 0);
+ GCDBG(GCZONE_FORMAT_VERBOSE, "leftjust = %d\n",
+ leftjust ? 1 : 0);
+
+ /* Parse the standard. */
+ switch (std) {
+ case OCDFMTDEF_STD_ITUR_601_YCbCr >> OCDFMTDEF_STD_SHIFT:
+ GCDBG(GCZONE_FORMAT, "OCDFMTDEF_STD_ITUR_601_YCbCr\n");
+ format->cs.yuv.std = GCREG_PE_CONTROL_YUV_601;
+ break;
+
+ case OCDFMTDEF_STD_ITUR_709_YCbCr >> OCDFMTDEF_STD_SHIFT:
+ GCDBG(GCZONE_FORMAT, "OCDFMTDEF_STD_ITUR_709_YCbCr\n");
+ format->cs.yuv.std = GCREG_PE_CONTROL_YUV_709;
+ break;
+
+ default:
+ BVSETBLTERROR(BVERR_UNK,
+ "unsupported color standard");
+ goto exit;
+ }
+
+ /* Alpha is not supported. */
+ if (alpha == OCDFMTDEF_ALPHA) {
+ BVSETBLTERROR(BVERR_UNK,
+ "alpha channel is not supported");
+ goto exit;
+ }
+
+ format->premultiplied = true;
+
+ /* Parse subsampling. */
+ switch (subsample) {
+ case OCDFMTDEF_SUBSAMPLE_422_YCbCr >> OCDFMTDEF_SUBSAMPLE_SHIFT:
+ GCDBG(GCZONE_FORMAT, "OCDFMTDEF_SUBSAMPLE_422_YCbCr\n");
+
+ /* Parse layout. */
+ switch (layout) {
+ case OCDFMTDEF_PACKED >> OCDFMTDEF_LAYOUT_SHIFT:
+ GCDBG(GCZONE_FORMAT, "OCDFMTDEF_PACKED\n");
+
+ if (container[cont] != 32) {
+ BVSETBLTERROR(BVERR_UNK,
+ "unsupported container");
+ goto exit;
+ }
+
+ format->bitspp = 16;
+ format->allocbitspp = 16;
+ format->format = leftjust
+ ? GCREG_DE_FORMAT_YUY2
+ : GCREG_DE_FORMAT_UYVY;
+ format->swizzle = reversed
+ ? GCREG_PE_CONTROL_UV_SWIZZLE_VU
+ : GCREG_PE_CONTROL_UV_SWIZZLE_UV;
+ format->cs.yuv.planecount = 1;
+ format->cs.yuv.xsample = 2;
+ format->cs.yuv.ysample = 1;
+ break;
+
+ default:
+ BVSETBLTERROR(BVERR_UNK,
+ "specified 4:2:2 layout "
+ "is not supported");
+ goto exit;
+ }
+ break;
+
+ case OCDFMTDEF_SUBSAMPLE_420_YCbCr >> OCDFMTDEF_SUBSAMPLE_SHIFT:
+
+ /* Parse layout. */
+ switch (layout) {
+ case OCDFMTDEF_2_PLANE_YCbCr
+ >> OCDFMTDEF_LAYOUT_SHIFT:
+ GCDBG(GCZONE_FORMAT,
+ "OCDFMTDEF_2_PLANE_YCbCr\n");
+
+ if (container[cont] != 48) {
+ BVSETBLTERROR(BVERR_UNK,
+ "unsupported container");
+ goto exit;
+ }
+
+ format->bitspp = 8;
+ format->allocbitspp = 12;
+ format->format = GCREG_DE_FORMAT_NV12;
+ format->swizzle = reversed
+ ? GCREG_PE_CONTROL_UV_SWIZZLE_VU
+ : GCREG_PE_CONTROL_UV_SWIZZLE_UV;
+ format->cs.yuv.planecount = 2;
+ format->cs.yuv.xsample = 2;
+ format->cs.yuv.ysample = 2;
+ break;
+
+ case OCDFMTDEF_3_PLANE_STACKED
+ >> OCDFMTDEF_LAYOUT_SHIFT:
+ GCDBG(GCZONE_FORMAT,
+ "OCDFMTDEF_3_PLANE_STACKED\n");
+
+ if (container[cont] != 48) {
+ BVSETBLTERROR(BVERR_UNK,
+ "unsupported container");
+ goto exit;
+ }
+
+ format->bitspp = 8;
+ format->allocbitspp = 12;
+ format->format = GCREG_DE_FORMAT_YV12;
+ format->swizzle = reversed
+ ? GCREG_PE_CONTROL_UV_SWIZZLE_VU
+ : GCREG_PE_CONTROL_UV_SWIZZLE_UV;
+ format->cs.yuv.planecount = 3;
+ format->cs.yuv.xsample = 2;
+ format->cs.yuv.ysample = 2;
+ break;
+
+ default:
+ BVSETBLTERROR(BVERR_UNK,
+ "specified 4:2:2 layout "
+ "is not supported");
+ goto exit;
+ }
+ break;
+
+ default:
+ BVSETBLTERROR(BVERR_UNK,
+ "specified subsampling is not supported");
+ goto exit;
+ }
+
+ if (format->allocbitspp != bits) {
+ BVSETBLTERROR(BVERR_UNK,
+ "unsupported bit width %d", bits);
+ goto exit;
+ }
+ break;
+
+ default:
+ BVSETBLTERROR(BVERR_UNK,
+ "unsupported color space %d", cs);
+ goto exit;
+ }
+
+ GCDBG(GCZONE_FORMAT, "bpp = %d\n", format->bitspp);
+ GCDBG(GCZONE_FORMAT, "gcformat = %d\n", format->format);
+ GCDBG(GCZONE_FORMAT, "gcswizzle = %d\n", format->swizzle);
+
+ bverror = BVERR_NONE;
+
+exit:
+ GCEXITARG(GCZONE_FORMAT, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
+
+
+/*******************************************************************************
+ * Alpha blending parser.
+ */
+
+#define BVBLENDMATCH(Mode, Inverse, Normal) \
+( \
+ BVBLENDDEF_ ## Mode | \
+ BVBLENDDEF_ ## Inverse | \
+ BVBLENDDEF_ ## Normal \
+)
+
+#define BVSRC1USE(Use) \
+ Use
+
+#define BVSRC2USE(Use) \
+ Use
+
+#define BVBLENDUNDEFINED() \
+ { ~0, ~0, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }
+
+struct bvblendxlate {
+ unsigned char match1;
+ unsigned char match2;
+
+ struct gcblendconfig k1;
+ struct gcblendconfig k2;
+};
+
+static struct bvblendxlate blendxlate[64] = {
+ /**********************************************************************/
+ /* #0: color factor: 00 00 00 A:(1-C1,C1)=zero
+ alpha factor: zero ==> 00 00 00 */
+ {
+ 0x00,
+ 0x00,
+
+ {
+ GCREG_BLENDING_MODE_ZERO,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(false), BVSRC2USE(false)
+ },
+
+ {
+ GCREG_BLENDING_MODE_ZERO,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(false), BVSRC2USE(false)
+ }
+ },
+
+ /* #1: color factor: 00 00 01 A:(1-C1,A1)=A1
+ alpha factor: A1 ==> 00 00 01 or 00 10 01 */
+ {
+ BVBLENDMATCH(ONLY_A, INV_C1, NORM_A1),
+ BVBLENDMATCH(ONLY_A, INV_C2, NORM_A1),
+
+ {
+ GCREG_BLENDING_MODE_NORMAL,
+ GCREG_FACTOR_INVERSE_ENABLE,
+ BVSRC1USE(true), BVSRC2USE(false)
+ },
+
+ {
+ GCREG_BLENDING_MODE_NORMAL,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(true)
+ }
+ },
+
+ /* #2: color factor: 00 00 10 A:(1-C1,C2)=undefined
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #3: color factor: 00 00 11 A:(1-C1,A2)=A2
+ alpha factor: A2 ==> 00 00 11 or 00 10 11 */
+ {
+ BVBLENDMATCH(ONLY_A, INV_C1, NORM_A2),
+ BVBLENDMATCH(ONLY_A, INV_C2, NORM_A2),
+
+ {
+ GCREG_BLENDING_MODE_NORMAL,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(true)
+ },
+
+ {
+ GCREG_BLENDING_MODE_NORMAL,
+ GCREG_FACTOR_INVERSE_ENABLE,
+ BVSRC1USE(false), BVSRC2USE(true)
+ }
+ },
+
+ /* #4: color factor: 00 01 00 A:(1-A1,C1)=1-A1
+ alpha factor: 1-A1 ==> 00 01 00 or 00 01 10 */
+ {
+ BVBLENDMATCH(ONLY_A, INV_A1, NORM_C1),
+ BVBLENDMATCH(ONLY_A, INV_A1, NORM_C2),
+
+ {
+ GCREG_BLENDING_MODE_INVERSED,
+ GCREG_FACTOR_INVERSE_ENABLE,
+ BVSRC1USE(true), BVSRC2USE(false)
+ },
+
+ {
+ GCREG_BLENDING_MODE_INVERSED,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(true)
+ }
+ },
+
+ /* #5: color factor: 00 01 01 A:(1-A1,A1)=undefined
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #6: color factor: 00 01 10 A:(1-A1,C2)=1-A1
+ alpha factor: 1-A1 ==> 00 01 00 or 00 01 10 */
+ {
+ BVBLENDMATCH(ONLY_A, INV_A1, NORM_C1),
+ BVBLENDMATCH(ONLY_A, INV_A1, NORM_C2),
+
+ {
+ GCREG_BLENDING_MODE_INVERSED,
+ GCREG_FACTOR_INVERSE_ENABLE,
+ BVSRC1USE(true), BVSRC2USE(false)
+ },
+
+ {
+ GCREG_BLENDING_MODE_INVERSED,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(true)
+ }
+ },
+
+ /* #7: color factor: 00 01 11 A:(1-A1,A2)=undefined
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #8: color factor: 00 10 00 A:(1-C2,C1)=undefined
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #9: color factor: 00 10 01 A:(1-C2,A1)=A1
+ alpha factor: A1 ==> 00 00 01 or 00 10 01 */
+ {
+ BVBLENDMATCH(ONLY_A, INV_C1, NORM_A1),
+ BVBLENDMATCH(ONLY_A, INV_C2, NORM_A1),
+
+ {
+ GCREG_BLENDING_MODE_NORMAL,
+ GCREG_FACTOR_INVERSE_ENABLE,
+ BVSRC1USE(true), BVSRC2USE(false)
+ },
+
+ {
+ GCREG_BLENDING_MODE_NORMAL,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(true)
+ }
+ },
+
+ /* #10: color factor: 00 10 10 A:(1-C2,C2)=undefined
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #11: color factor: 00 10 11 A:(1-C2,A2)=A2
+ alpha factor: A2 ==> 00 00 11 or 00 10 11 */
+ {
+ BVBLENDMATCH(ONLY_A, INV_C1, NORM_A2),
+ BVBLENDMATCH(ONLY_A, INV_C2, NORM_A2),
+
+ {
+ GCREG_BLENDING_MODE_NORMAL,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(true)
+ },
+
+ {
+ GCREG_BLENDING_MODE_NORMAL,
+ GCREG_FACTOR_INVERSE_ENABLE,
+ BVSRC1USE(false), BVSRC2USE(true)
+ }
+ },
+
+ /* #12: color factor: 00 11 00 A:(1-A2,C1)=1-A2
+ alpha factor: 1-A2 ==> 00 11 00 or 00 11 10 */
+ {
+ BVBLENDMATCH(ONLY_A, INV_A2, NORM_C1),
+ BVBLENDMATCH(ONLY_A, INV_A2, NORM_C2),
+
+ {
+ GCREG_BLENDING_MODE_INVERSED,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(true)
+ },
+
+ {
+ GCREG_BLENDING_MODE_INVERSED,
+ GCREG_FACTOR_INVERSE_ENABLE,
+ BVSRC1USE(false), BVSRC2USE(true)
+ }
+ },
+
+ /* #13: color factor: 00 11 01 A:(1-A2,A1)=undefined
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #14: color factor: 00 11 10 A:(1-A2,C2)=1-A2
+ alpha factor: 1-A2 ==> 00 11 00 or 00 11 10 */
+ {
+ BVBLENDMATCH(ONLY_A, INV_A2, NORM_C1),
+ BVBLENDMATCH(ONLY_A, INV_A2, NORM_C2),
+
+ {
+ GCREG_BLENDING_MODE_INVERSED,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(true)
+ },
+
+ {
+ GCREG_BLENDING_MODE_INVERSED,
+ GCREG_FACTOR_INVERSE_ENABLE,
+ BVSRC1USE(false), BVSRC2USE(true)
+ }
+ },
+
+ /* #15: color factor: 00 11 11 A:(1-A2,A2)=undefined
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /**********************************************************************/
+ /* #16: color factor: 01 00 00 MIN:(1-C1,C1) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #17: color factor: 01 00 01 MIN:(1-C1,A1) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #18: color factor: 01 00 10 MIN:(1-C1,C2) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #19: color factor: 01 00 11 MIN:(1-C1,A2) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #20: color factor: 01 01 00 MIN:(1-A1,C1) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #21: color factor: 01 01 01 MIN:(1-A1,A1) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #22: color factor: 01 01 10 MIN:(1-A1,C2) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #23: color factor: 01 01 11 MIN:(1-A1,A2)
+ alpha factor: one ==> 11 11 11 */
+ {
+ 0x3F,
+ 0x3F,
+
+ {
+ GCREG_BLENDING_MODE_SATURATED_DEST_ALPHA,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(true)
+ },
+
+ {
+ GCREG_BLENDING_MODE_SATURATED_ALPHA,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(true)
+ }
+ },
+
+ /* #24: color factor: 01 10 00 MIN:(1-C2,C1) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #25: color factor: 01 10 01 MIN:(1-C2,A1) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #26: color factor: 01 10 10 MIN:(1-C2,C2) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #27: color factor: 01 10 11 MIN:(1-C2,A2) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #28: color factor: 01 11 00 MIN:(1-A2,C1) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #29: color factor: 01 11 01 MIN:(1-A2,A1)
+ alpha factor: one ==> 11 11 11 */
+ {
+ 0x3F,
+ 0x3F,
+
+ {
+ GCREG_BLENDING_MODE_SATURATED_ALPHA,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(true)
+ },
+
+ {
+ GCREG_BLENDING_MODE_SATURATED_DEST_ALPHA,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(true)
+ }
+ },
+
+ /* #30: color factor: 01 11 10 MIN:(1-A2,C2) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #31: color factor: 01 11 11 MIN:(1-A2,A2) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /**********************************************************************/
+ /* #32: color factor: 10 00 00 MAX:(1-C1,C1) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #33: color factor: 10 00 01 MAX:(1-C1,A1) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #34: color factor: 10 00 10 MAX:(1-C1,C2) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #35: color factor: 10 00 11 MAX:(1-C1,A2) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #36: color factor: 10 01 00 MAX:(1-A1,C1) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #37: color factor: 10 01 01 MAX:(1-A1,A1) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #38: color factor: 10 01 10 MAX:(1-A1,C2) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #39: color factor: 10 01 11 MAX:(1-A1,A2) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #40: color factor: 10 10 00 MAX:(1-C2,C1) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #41: color factor: 10 10 01 MAX:(1-C2,A1) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #42: color factor: 10 10 10 MAX:(1-C2,C2) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #43: color factor: 10 10 11 MAX:(1-C2,A2) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #44: color factor: 10 11 00 MAX:(1-A2,C1) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #45: color factor: 10 11 01 MAX:(1-A2,A1) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #46: color factor: 10 11 10 MAX:(1-A2,C2) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #47: color factor: 10 11 11 MAX:(1-A2,A2) ==> not supported
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /**********************************************************************/
+ /* #48: color factor: 11 00 00 C:(1-C1,C1)=undefined
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #49: color factor: 11 00 01 C:(1-C1,A1)=1-C1
+ alpha factor: 1-A1 ==> 00 01 00 or 00 01 10 */
+ {
+ BVBLENDMATCH(ONLY_A, INV_A1, NORM_C1),
+ BVBLENDMATCH(ONLY_A, INV_A1, NORM_C2),
+
+ {
+ GCREG_BLENDING_MODE_COLOR_INVERSED,
+ GCREG_FACTOR_INVERSE_ENABLE,
+ BVSRC1USE(true), BVSRC2USE(false)
+ },
+
+ {
+ GCREG_BLENDING_MODE_COLOR_INVERSED,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(true)
+ }
+ },
+
+ /* #50: color factor: 11 00 10 C:(1-C1,C2)=undefined
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #51: color factor: 11 00 11 C:(1-C1,A2)=1-C1
+ alpha factor: 1-A1 ==> 00 01 00 or 00 01 10 */
+ {
+ BVBLENDMATCH(ONLY_A, INV_A1, NORM_C1),
+ BVBLENDMATCH(ONLY_A, INV_A1, NORM_C2),
+
+ {
+ GCREG_BLENDING_MODE_COLOR_INVERSED,
+ GCREG_FACTOR_INVERSE_ENABLE,
+ BVSRC1USE(true), BVSRC2USE(false)
+ },
+
+ {
+ GCREG_BLENDING_MODE_COLOR_INVERSED,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(true)
+ }
+ },
+
+ /* #52: color factor: 11 01 00 C:(1-A1,C1)=C1
+ alpha factor: A1 ==> 00 00 01 or 00 10 01 */
+ {
+ BVBLENDMATCH(ONLY_A, INV_C1, NORM_A1),
+ BVBLENDMATCH(ONLY_A, INV_C2, NORM_A1),
+
+ {
+ GCREG_BLENDING_MODE_COLOR,
+ GCREG_FACTOR_INVERSE_ENABLE,
+ BVSRC1USE(true), BVSRC2USE(false)
+ },
+
+ {
+ GCREG_BLENDING_MODE_COLOR,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(true)
+ }
+ },
+
+ /* #53: color factor: 11 01 01 C:(1-A1,A1)=undefined
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #54: color factor: 11 01 10 C:(1-A1,C2)=C2
+ alpha factor: A2 ==> 00 00 11 or 00 10 11 */
+ {
+ BVBLENDMATCH(ONLY_A, INV_C1, NORM_A2),
+ BVBLENDMATCH(ONLY_A, INV_C2, NORM_A2),
+
+ {
+ GCREG_BLENDING_MODE_COLOR,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(true)
+ },
+
+ {
+ GCREG_BLENDING_MODE_COLOR,
+ GCREG_FACTOR_INVERSE_ENABLE,
+ BVSRC1USE(false), BVSRC2USE(true)
+ }
+ },
+
+ /* #55: color factor: 11 01 11 C:(1-A1,A2)=undefined
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #56: color factor: 11 10 00 C:(1-C2,C1)=undefined
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #57: color factor: 11 10 01 C:(1-C2,A1)=1-C2
+ alpha factor: 1-A2 ==> 00 11 00 or 00 11 10 */
+ {
+ BVBLENDMATCH(ONLY_A, INV_A2, NORM_C1),
+ BVBLENDMATCH(ONLY_A, INV_A2, NORM_C2),
+
+ {
+ GCREG_BLENDING_MODE_COLOR_INVERSED,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(true)
+ },
+
+ {
+ GCREG_BLENDING_MODE_COLOR_INVERSED,
+ GCREG_FACTOR_INVERSE_ENABLE,
+ BVSRC1USE(false), BVSRC2USE(true)
+ }
+ },
+
+ /* #58: color factor: 11 10 10 C:(1-C2,C2)=undefined
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #59: color factor: 11 10 11 C:(1-C2,A2)=1-C2
+ alpha factor: 1-A2 ==> 00 11 00 or 00 11 10 */
+ {
+ BVBLENDMATCH(ONLY_A, INV_A2, NORM_C1),
+ BVBLENDMATCH(ONLY_A, INV_A2, NORM_C2),
+
+ {
+ GCREG_BLENDING_MODE_COLOR_INVERSED,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(true)
+ },
+
+ {
+ GCREG_BLENDING_MODE_COLOR_INVERSED,
+ GCREG_FACTOR_INVERSE_ENABLE,
+ BVSRC1USE(false), BVSRC2USE(false)
+ }
+ },
+
+ /* #60: color factor: 11 11 00 C:(1-A2,C1)=C1
+ alpha factor: A1 ==> 00 00 01 or 00 10 01 */
+ {
+ BVBLENDMATCH(ONLY_A, INV_C1, NORM_A1),
+ BVBLENDMATCH(ONLY_A, INV_C2, NORM_A1),
+
+ {
+ GCREG_BLENDING_MODE_COLOR,
+ GCREG_FACTOR_INVERSE_ENABLE,
+ BVSRC1USE(true), BVSRC2USE(false)
+ },
+
+ {
+ GCREG_BLENDING_MODE_COLOR,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(true)
+ }
+ },
+
+ /* #61: color factor: 11 11 01 C:(1-A2,A1)=undefined
+ alpha factor: N/A */
+ BVBLENDUNDEFINED(),
+
+ /* #62: color factor: 11 11 10 C:(1-A2,C2)=C2
+ alpha factor: A2 ==> 00 00 11 or 00 10 11 */
+ {
+ BVBLENDMATCH(ONLY_A, INV_C1, NORM_A2),
+ BVBLENDMATCH(ONLY_A, INV_C2, NORM_A2),
+
+ {
+ GCREG_BLENDING_MODE_COLOR,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(true)
+ },
+
+ {
+ GCREG_BLENDING_MODE_COLOR,
+ GCREG_FACTOR_INVERSE_ENABLE,
+ BVSRC1USE(false), BVSRC2USE(true)
+ }
+ },
+
+ /* #63: color factor: 11 11 11 C:(1-A2,A2)=one
+ alpha factor: one ==> 11 11 11 */
+ {
+ 0x3F,
+ 0x3F,
+
+ {
+ GCREG_BLENDING_MODE_ONE,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(true), BVSRC2USE(false)
+ },
+
+ {
+ GCREG_BLENDING_MODE_ONE,
+ GCREG_FACTOR_INVERSE_DISABLE,
+ BVSRC1USE(false), BVSRC2USE(true)
+ }
+ }
+};
+
+enum bverror parse_blend(struct bvbltparams *bvbltparams,
+ enum bvblend blend,
+ struct gcalpha *gca)
+{
+ enum bverror bverror;
+ unsigned int global;
+ unsigned int k1, k2, k3, k4;
+ struct bvblendxlate *k1_xlate;
+ struct bvblendxlate *k2_xlate;
+ unsigned int alpha;
+
+ GCENTERARG(GCZONE_BLEND, "blend = 0x%08X (%s)\n",
+ blend, gc_bvblend_name(blend));
+
+ if ((blend & BVBLENDDEF_REMOTE) != 0) {
+ BVSETBLTERROR(BVERR_BLEND, "remote alpha not supported");
+ goto exit;
+ }
+
+ global = (blend & BVBLENDDEF_GLOBAL_MASK) >> BVBLENDDEF_GLOBAL_SHIFT;
+
+ switch (global) {
+ case (BVBLENDDEF_GLOBAL_NONE >> BVBLENDDEF_GLOBAL_SHIFT):
+ GCDBG(GCZONE_BLEND, "BVBLENDDEF_GLOBAL_NONE\n");
+
+ gca->src_global_color =
+ gca->dst_global_color = 0;
+
+ gca->src_global_alpha_mode = GCREG_GLOBAL_ALPHA_MODE_NORMAL;
+ gca->dst_global_alpha_mode = GCREG_GLOBAL_ALPHA_MODE_NORMAL;
+ break;
+
+ case (BVBLENDDEF_GLOBAL_UCHAR >> BVBLENDDEF_GLOBAL_SHIFT):
+ GCDBG(GCZONE_BLEND, "BVBLENDDEF_GLOBAL_UCHAR\n");
+
+ gca->src_global_color =
+ gca->dst_global_color =
+ ((unsigned int) bvbltparams->globalalpha.size8) << 24;
+
+ gca->src_global_alpha_mode = GCREG_GLOBAL_ALPHA_MODE_GLOBAL;
+ gca->dst_global_alpha_mode = GCREG_GLOBAL_ALPHA_MODE_GLOBAL;
+ break;
+
+ case (BVBLENDDEF_GLOBAL_FLOAT >> BVBLENDDEF_GLOBAL_SHIFT):
+ GCDBG(GCZONE_BLEND, "BVBLENDDEF_GLOBAL_FLOAT\n");
+
+ alpha = gcfp2norm8(bvbltparams->globalalpha.fp);
+
+ gca->src_global_color =
+ gca->dst_global_color = alpha << 24;
+
+ gca->src_global_alpha_mode = GCREG_GLOBAL_ALPHA_MODE_GLOBAL;
+ gca->dst_global_alpha_mode = GCREG_GLOBAL_ALPHA_MODE_GLOBAL;
+ break;
+
+ default:
+ BVSETBLTERROR(BVERR_BLEND, "invalid global alpha mode");
+ goto exit;
+ }
+
+ /*
+ Co = k1 x C1 + k2 x C2
+ Ao = k3 x A1 + k4 x A2
+ */
+
+ k1 = (blend >> 18) & 0x3F;
+ k2 = (blend >> 12) & 0x3F;
+ k3 = (blend >> 6) & 0x3F;
+ k4 = blend & 0x3F;
+
+ GCDBG(GCZONE_BLEND, "k1 = %d\n", k1);
+ GCDBG(GCZONE_BLEND, "k2 = %d\n", k2);
+ GCDBG(GCZONE_BLEND, "k3 = %d\n", k3);
+ GCDBG(GCZONE_BLEND, "k4 = %d\n", k4);
+
+ k1_xlate = &blendxlate[k1];
+ k2_xlate = &blendxlate[k2];
+
+ if (((k3 != k1_xlate->match1) && (k3 != k1_xlate->match2)) ||
+ ((k4 != k2_xlate->match1) && (k4 != k2_xlate->match2))) {
+ BVSETBLTERROR(BVERR_BLEND,
+ "not supported coefficient combination");
+ goto exit;
+ }
+
+ gca->k1 = &k1_xlate->k1;
+ gca->k2 = &k2_xlate->k2;
+
+ gca->src1used = gca->k1->src1used | gca->k2->src1used;
+ gca->src2used = gca->k1->src2used | gca->k2->src2used;
+
+ bverror = BVERR_NONE;
+
+exit:
+ GCEXITARG(BVERR_BLEND, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
+
+
+/*******************************************************************************
+ * Rotation and mirror.
+ */
+
+#define BVFLAG_FLIP_MASK 0x00000003
+
+#define BVFLAG_FLIP_SRC1_SHIFT 14
+#define BVFLAG_FLIP_SRC2_SHIFT 16
+#define BVFLAG_FLIP_MASK_SHIFT 18
+
+#define GCREG_MIRROR_NONE 0x0
+#define GCREG_MIRROR_X 0x1
+#define GCREG_MIRROR_Y 0x2
+#define GCREG_MIRROR_XY 0x3
+
+#define GCREG_ROT_ANGLE_ROT0 0x0
+#define GCREG_ROT_ANGLE_ROT90 0x4
+#define GCREG_ROT_ANGLE_ROT180 0x5
+#define GCREG_ROT_ANGLE_ROT270 0x6
+
+#define ROT_ANGLE_INVALID -1
+#define ROT_ANGLE_0 0
+#define ROT_ANGLE_90 1
+#define ROT_ANGLE_180 2
+#define ROT_ANGLE_270 3
+
+/* NOTE: BLTsville rotation is defined conunter clock wise. */
+const unsigned int rotencoding[] = {
+ GCREG_ROT_ANGLE_ROT0, /* ROT_ANGLE_0 */
+ GCREG_ROT_ANGLE_ROT270, /* ROT_ANGLE_90 */
+ GCREG_ROT_ANGLE_ROT180, /* ROT_ANGLE_180 */
+ GCREG_ROT_ANGLE_ROT90 /* ROT_ANGLE_270 */
+};
+
+static inline int get_angle(int orientation)
+{
+ int angle;
+
+ /* Normalize the angle. */
+ angle = orientation % 360;
+
+ /* Flip to positive. */
+ if (angle < 0)
+ angle = 360 + angle;
+
+ /* Translate the angle. */
+ switch (angle) {
+ case 0: return ROT_ANGLE_0;
+ case 90: return ROT_ANGLE_90;
+ case 180: return ROT_ANGLE_180;
+ case 270: return ROT_ANGLE_270;
+ }
+
+ /* Not supported angle. */
+ return ROT_ANGLE_INVALID;
+}
+
+
+/*******************************************************************************
+ * Surface compare and validation.
+ */
+
+bool valid_rect(struct bvsurfgeom *bvsurfgeom, struct gcrect *gcrect)
+{
+ int width, height;
+
+ if ((gcrect->left < 0) || (gcrect->top < 0)) {
+ GCERR("invalid rectangle origin: %d,%d.\n",
+ gcrect->left, gcrect->top);
+ return false;
+ }
+
+ width = gcrect->right - gcrect->left;
+ height = gcrect->bottom - gcrect->top;
+ if ((width <= 0) || (height <= 0)) {
+ GCERR("invalid rectangle size: %d,%d.\n",
+ width, height);
+ return false;
+ }
+
+ if (gcrect->right > (int) bvsurfgeom->width) {
+ GCERR("right coordinate (%d) exceeds surface width (%d).\n",
+ gcrect->right, bvsurfgeom->width);
+ return false;
+ }
+
+ if (gcrect->bottom > (int) bvsurfgeom->height) {
+ GCERR("bottom coordinate (%d) exceeds surface height (%d).\n",
+ gcrect->bottom, bvsurfgeom->height);
+ return false;
+ }
+
+ return true;
+}
+
+static bool valid_geom(struct surfaceinfo *surfaceinfo)
+{
+ unsigned int size;
+ unsigned int height;
+
+ /* Compute the size of the surface. */
+ size = (surfaceinfo->geom->width *
+ surfaceinfo->geom->height *
+ surfaceinfo->format.allocbitspp) / 8;
+
+ /* Make sure the size is not greater then the surface. */
+ if (size > surfaceinfo->buf.desc->length) {
+ GCERR("invalid geometry detected:\n");
+ GCERR(" specified dimensions: %dx%d, %d bitspp\n",
+ surfaceinfo->geom->width,
+ surfaceinfo->geom->height,
+ surfaceinfo->format.bitspp);
+ GCERR(" surface size based on the dimensions: %d\n",
+ size);
+ GCERR(" specified surface size: %lu\n",
+ surfaceinfo->buf.desc->length);
+ return false;
+ }
+
+ /* Determine the height of the image. */
+ height = ((surfaceinfo->angle % 2) == 0)
+ ? surfaceinfo->geom->height
+ : surfaceinfo->geom->width;
+
+ /* Compute the size using the stide. */
+ size = surfaceinfo->geom->virtstride * height;
+
+ /* Make sure the size is not greater then the surface. */
+ if (size > surfaceinfo->buf.desc->length) {
+ GCERR("invalid geometry detected:\n");
+ GCERR(" specified dimensions: %dx%d, %d bitspp\n",
+ surfaceinfo->geom->width,
+ surfaceinfo->geom->height,
+ surfaceinfo->format.bitspp);
+ GCERR(" physical image height = %d\n", height);
+ GCERR(" image stride = %d\n", surfaceinfo->geom->virtstride);
+ GCERR(" computed surface size = %d\n", size);
+ GCERR(" specified surface size: %lu\n",
+ surfaceinfo->buf.desc->length);
+ return false;
+ }
+
+ return true;
+}
+
+int get_pixel_offset(struct surfaceinfo *surfaceinfo, int offset)
+{
+ unsigned int alignment;
+ int byteoffset;
+ unsigned int alignedoffset;
+ int pixeloffset;
+
+ GCENTERARG(GCZONE_OFFSET, "surfaceinfo=0x%08X, offset=%d\n",
+ surfaceinfo, offset);
+
+ alignment = (surfaceinfo->format.type == BVFMT_YUV)
+ ? (64 - 1)
+ : (16 - 1);
+
+ GCDBG(GCZONE_OFFSET, "bpp = %d\n", surfaceinfo->format.bitspp);
+ GCDBG(GCZONE_OFFSET, "alignment = %d\n", alignment);
+
+ /* Determine offset in bytes from the base modified by the
+ * given offset. */
+ if (surfaceinfo->buf.desc->auxtype == BVAT_PHYSDESC) {
+ struct bvphysdesc *bvphysdesc;
+ bvphysdesc = (struct bvphysdesc *)
+ surfaceinfo->buf.desc->auxptr;
+ GCDBG(GCZONE_OFFSET, "physical descriptor = 0x%08X\n",
+ bvphysdesc);
+ GCDBG(GCZONE_OFFSET, "first page = 0x%08X\n",
+ bvphysdesc->pagearray[0]);
+ GCDBG(GCZONE_OFFSET, "page offset = 0x%08X\n",
+ bvphysdesc->pageoffset);
+
+ byteoffset = bvphysdesc->pageoffset + offset;
+ } else {
+ GCDBG(GCZONE_OFFSET, "no physical descriptor.\n");
+ byteoffset = (unsigned int)
+ surfaceinfo->buf.desc->virtaddr + offset;
+ }
+
+ GCDBG(GCZONE_OFFSET, "byteoffset = %d\n", byteoffset);
+
+ /* Compute the aligned offset. */
+ alignedoffset = byteoffset & alignment;
+
+ /* Convert to pixels. */
+ pixeloffset = alignedoffset * 8 / surfaceinfo->format.bitspp;
+
+ GCDBG(GCZONE_OFFSET, "alignedoffset = %d\n", alignedoffset);
+ GCDBG(GCZONE_OFFSET, "pixeloffset = %d\n", -pixeloffset);
+
+ GCEXIT(GCZONE_OFFSET);
+ return -pixeloffset;
+}
+
+enum bverror parse_destination(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch)
+{
+ enum bverror bverror = BVERR_NONE;
+
+ GCENTER(GCZONE_DEST);
+
+ GCDBG(GCZONE_DEST, "parsing destination\n");
+
+ /* Did the destination surface change? */
+ if ((batch->batchflags & BVBATCH_DST) != 0) {
+ struct surfaceinfo *dstinfo;
+
+ /* Initialize the destination descriptor. */
+ dstinfo = &batch->dstinfo;
+ dstinfo->index = -1;
+ dstinfo->buf.desc = bvbltparams->dstdesc;
+ dstinfo->geom = bvbltparams->dstgeom;
+
+ /* Initialize members that are not used. */
+ dstinfo->mirror = GCREG_MIRROR_NONE;
+ dstinfo->rop = 0;
+ dstinfo->gca = NULL;
+
+ /* Parse the destination format. */
+ if (parse_format(bvbltparams, dstinfo) != BVERR_NONE) {
+ bverror = BVERR_DSTGEOM_FORMAT;
+ goto exit;
+ }
+
+ /* Parse orientation. */
+ dstinfo->angle = get_angle(dstinfo->geom->orientation);
+ if (dstinfo->angle == ROT_ANGLE_INVALID) {
+ BVSETBLTERROR(BVERR_DSTGEOM,
+ "unsupported destination orientation %d.",
+ dstinfo->geom->orientation);
+ goto exit;
+ }
+
+ /* Compute the destination alignments needed to compensate
+ * for the surface base address misalignment if any. */
+ dstinfo->xpixalign = get_pixel_offset(dstinfo, 0);
+ dstinfo->ypixalign = 0;
+ dstinfo->bytealign = (dstinfo->xpixalign
+ * (int) dstinfo->format.bitspp) / 8;
+
+ GCDBG(GCZONE_DEST, " buffer length = %d\n",
+ dstinfo->buf.desc->length);
+ GCDBG(GCZONE_DEST, " rotation %d degrees.\n",
+ dstinfo->angle * 90);
+
+ if (dstinfo->buf.desc->auxtype == BVAT_PHYSDESC) {
+ struct bvphysdesc *bvphysdesc;
+ bvphysdesc = (struct bvphysdesc *)
+ dstinfo->buf.desc->auxptr;
+ GCDBG(GCZONE_DEST, " physical descriptor = 0x%08X\n",
+ bvphysdesc);
+ GCDBG(GCZONE_DEST, " first page = 0x%08X\n",
+ bvphysdesc->pagearray[0]);
+ GCDBG(GCZONE_DEST, " page offset = 0x%08X\n",
+ bvphysdesc->pageoffset);
+ } else {
+ GCDBG(GCZONE_DEST, " virtual address = 0x%08X\n",
+ (unsigned int) dstinfo->buf.desc->virtaddr);
+ }
+
+ GCDBG(GCZONE_DEST, " stride = %ld\n",
+ dstinfo->geom->virtstride);
+ GCDBG(GCZONE_DEST, " geometry size = %dx%d\n",
+ dstinfo->geom->width, dstinfo->geom->height);
+ GCDBG(GCZONE_DEST, " surface offset (pixels) = %d,%d\n",
+ dstinfo->xpixalign, dstinfo->ypixalign);
+ GCDBG(GCZONE_DEST, " surface offset (bytes) = %d\n",
+ dstinfo->bytealign);
+
+ /* Check for unsupported dest formats. */
+ if ((dstinfo->format.type == BVFMT_YUV) &&
+ (dstinfo->format.cs.yuv.planecount > 1)) {
+ BVSETBLTERROR(BVERR_DSTGEOM_FORMAT,
+ "destination format unsupported");
+ goto exit;
+ }
+
+ /* Destination stride must be 8 pixel aligned. */
+ if ((dstinfo->geom->virtstride
+ & (dstinfo->format.bitspp - 1)) != 0) {
+ BVSETBLTERROR(BVERR_DSTGEOM_STRIDE,
+ "destination stride must be 8 pixel "
+ "aligned.");
+ goto exit;
+ }
+
+ /* Validate geometry. */
+ if (!valid_geom(dstinfo)) {
+ BVSETBLTERROR(BVERR_DSTGEOM,
+ "destination geom exceeds surface size");
+ goto exit;
+ }
+ }
+
+ /* Did clipping/destination rects change? */
+ if ((batch->batchflags & (BVBATCH_CLIPRECT |
+ BVBATCH_DESTRECT |
+ BVBATCH_DST)) != 0) {
+ struct surfaceinfo *dstinfo;
+ struct gcrect cliprect;
+ struct gcrect *dstrect;
+ struct gcrect *dstrectaux;
+
+ /* Get a shortcut to the destination surface. */
+ dstinfo = &batch->dstinfo;
+
+ /* Determine destination rectangle. */
+ dstrect = &dstinfo->rect;
+ GCCONVERT_RECT(GCZONE_DEST,
+ " rect",
+ &bvbltparams->dstrect,
+ dstrect);
+
+ /* Determine whether aux destination is specified. */
+ batch->haveaux
+ = ((bvbltparams->flags & BVFLAG_SRC2_AUXDSTRECT) != 0);
+ GCDBG(GCZONE_DEST, " have aux dest = %d\n", batch->haveaux);
+
+ /* Is clipping rectangle specified? */
+ if ((bvbltparams->flags & BVFLAG_CLIP) == BVFLAG_CLIP) {
+ /* Convert the clipping rectangle. */
+ GCCONVERT_RECT(GCZONE_DEST,
+ " clipping",
+ &bvbltparams->cliprect,
+ &cliprect);
+
+ if ((cliprect.left < GC_CLIP_RESET_LEFT) ||
+ (cliprect.top < GC_CLIP_RESET_TOP) ||
+ (cliprect.right > GC_CLIP_RESET_RIGHT) ||
+ (cliprect.bottom > GC_CLIP_RESET_BOTTOM)) {
+ BVSETERROR(BVERR_CLIP_RECT,
+ "clip rect is invalid");
+ goto exit;
+ }
+
+ /* Compute clipping deltas and the adjusted
+ * destination rect. */
+ if (cliprect.left <= dstrect->left) {
+ batch->clipdelta.left = 0;
+ batch->dstclipped.left = dstrect->left;
+ } else {
+ batch->clipdelta.left = cliprect.left
+ - dstrect->left;
+ batch->dstclipped.left = cliprect.left;
+ }
+
+ if (cliprect.top <= dstrect->top) {
+ batch->clipdelta.top = 0;
+ batch->dstclipped.top = dstrect->top;
+ } else {
+ batch->clipdelta.top = cliprect.top
+ - dstrect->top;
+ batch->dstclipped.top = cliprect.top;
+ }
+
+ if (cliprect.right >= dstrect->right) {
+ batch->clipdelta.right = 0;
+ batch->dstclipped.right = dstrect->right;
+ } else {
+ batch->clipdelta.right = cliprect.right
+ - dstrect->right;
+ batch->dstclipped.right = cliprect.right;
+ }
+
+ if (cliprect.bottom >= dstrect->bottom) {
+ batch->clipdelta.bottom = 0;
+ batch->dstclipped.bottom = dstrect->bottom;
+ } else {
+ batch->clipdelta.bottom = cliprect.bottom
+ - dstrect->bottom;
+ batch->dstclipped.bottom = cliprect.bottom;
+ }
+
+ /* Clip the aux destination. */
+ if (batch->haveaux) {
+ /* Convert the aux rectangle. */
+ dstrectaux = &batch->dstrectaux;
+ GCCONVERT_RECT(GCZONE_DEST,
+ " aux rect",
+ &bvbltparams->src2auxdstrect,
+ dstrectaux);
+
+ if (cliprect.left <= dstrectaux->left)
+ batch->dstclippedaux.left
+ = dstrectaux->left;
+ else
+ batch->dstclippedaux.left
+ = cliprect.left;
+
+ if (cliprect.top <= dstrectaux->top)
+ batch->dstclippedaux.top
+ = dstrectaux->top;
+ else
+ batch->dstclippedaux.top
+ = cliprect.top;
+
+ if (cliprect.right >= dstrectaux->right)
+ batch->dstclippedaux.right
+ = dstrectaux->right;
+ else
+ batch->dstclippedaux.right
+ = cliprect.right;
+
+ if (cliprect.bottom >= dstrectaux->bottom)
+ batch->dstclippedaux.bottom
+ = dstrectaux->bottom;
+ else
+ batch->dstclippedaux.bottom
+ = cliprect.bottom;
+ }
+ } else {
+ batch->clipdelta.left =
+ batch->clipdelta.top =
+ batch->clipdelta.right =
+ batch->clipdelta.bottom = 0;
+
+ batch->dstclipped = *dstrect;
+ if (batch->haveaux)
+ /* Convert the aux rectangle. */
+ GCCONVERT_RECT(GCZONE_DEST,
+ " aux rect",
+ &bvbltparams->src2auxdstrect,
+ &batch->dstclippedaux);
+ }
+
+ GCPRINT_RECT(GCZONE_DEST, " clipped dest",
+ &batch->dstclipped);
+
+ /* Validate the destination rectangle. */
+ if (!valid_rect(dstinfo->geom, &batch->dstclipped)) {
+ BVSETBLTERROR(BVERR_DSTRECT,
+ "invalid destination rectangle.");
+ goto exit;
+ }
+
+ if (batch->haveaux) {
+ GCPRINT_RECT(GCZONE_DEST, " clipped aux dest",
+ &batch->dstclippedaux);
+
+ /* Validate the aux destination rectangle. */
+ if (!valid_rect(dstinfo->geom, &batch->dstclippedaux)) {
+ BVSETBLTERROR(BVERR_DSTRECT,
+ "invalid aux destination "
+ "rectangle.");
+ goto exit;
+ }
+ }
+
+ GCDBG(GCZONE_DEST,
+ " clipping delta = (%d,%d)-(%d,%d)\n",
+ batch->clipdelta.left,
+ batch->clipdelta.top,
+ batch->clipdelta.right,
+ batch->clipdelta.bottom);
+ }
+
+exit:
+ GCEXITARG(GCZONE_DEST, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
+
+void process_dest_rotation(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch)
+{
+ GCENTER(GCZONE_DEST);
+
+ /* Did clipping/destination rects change? */
+ if ((batch->batchflags & (BVBATCH_CLIPRECT |
+ BVBATCH_DESTRECT |
+ BVBATCH_DST)) != 0) {
+ struct surfaceinfo *dstinfo;
+ int dstoffsetX, dstoffsetY;
+
+ /* Initialize the destination descriptor. */
+ dstinfo = &batch->dstinfo;
+
+ switch (dstinfo->angle) {
+ case ROT_ANGLE_0:
+ /* Determine the origin offset. */
+ dstoffsetX = dstinfo->xpixalign;
+ dstoffsetY = dstinfo->ypixalign;
+
+ /* Determine geometry size. */
+ batch->dstwidth = dstinfo->geom->width
+ - dstinfo->xpixalign;
+ batch->dstheight = dstinfo->geom->height
+ - dstinfo->ypixalign;
+
+ /* Determine the physical size. */
+ dstinfo->physwidth = batch->dstwidth;
+ dstinfo->physheight = batch->dstheight;
+ break;
+
+ case ROT_ANGLE_90:
+ /* Determine the origin offset. */
+ dstoffsetX = dstinfo->ypixalign;
+ dstoffsetY = dstinfo->xpixalign;
+
+ /* Determine geometry size. */
+ batch->dstwidth = dstinfo->geom->width
+ - dstinfo->ypixalign;
+ batch->dstheight = dstinfo->geom->height
+ - dstinfo->xpixalign;
+
+ /* Determine the physical size. */
+ dstinfo->physwidth = dstinfo->geom->height
+ - dstinfo->xpixalign;
+ dstinfo->physheight = dstinfo->geom->width
+ - dstinfo->ypixalign;
+ break;
+
+ case ROT_ANGLE_180:
+ /* Determine the origin offset. */
+ dstoffsetX = 0;
+ dstoffsetY = 0;
+
+ /* Determine geometry size. */
+ batch->dstwidth = dstinfo->geom->width
+ - dstinfo->xpixalign;
+ batch->dstheight = dstinfo->geom->height
+ - dstinfo->ypixalign;
+
+ /* Determine the physical size. */
+ dstinfo->physwidth = batch->dstwidth;
+ dstinfo->physheight = batch->dstheight;
+ break;
+
+ case ROT_ANGLE_270:
+ /* Determine the origin offset. */
+ dstoffsetX = 0;
+ dstoffsetY = 0;
+
+ /* Determine geometry size. */
+ batch->dstwidth = dstinfo->geom->width
+ - dstinfo->ypixalign;
+ batch->dstheight = dstinfo->geom->height
+ - dstinfo->xpixalign;
+
+ /* Determine the physical size. */
+ dstinfo->physwidth = dstinfo->geom->height
+ - dstinfo->xpixalign;
+ dstinfo->physheight = dstinfo->geom->width
+ - dstinfo->ypixalign;
+ break;
+
+ default:
+ dstoffsetX = 0;
+ dstoffsetY = 0;
+ }
+
+ /* Compute adjusted destination rectangles. */
+ batch->dstadjusted.left
+ = batch->dstclipped.left
+ - dstoffsetX;
+ batch->dstadjusted.top
+ = batch->dstclipped.top
+ - dstoffsetY;
+ batch->dstadjusted.right
+ = batch->dstclipped.right
+ - dstoffsetX;
+ batch->dstadjusted.bottom
+ = batch->dstclipped.bottom
+ - dstoffsetY;
+
+ GCPRINT_RECT(GCZONE_DEST, "adjusted dest",
+ &batch->dstadjusted);
+
+ GCDBG(GCZONE_DEST, "aligned geometry size = %dx%d\n",
+ batch->dstwidth, batch->dstheight);
+ GCDBG(GCZONE_DEST, "aligned physical size = %dx%d\n",
+ dstinfo->physwidth, dstinfo->physheight);
+ GCDBG(GCZONE_DEST, "origin offset (pixels) = %d,%d\n",
+ dstoffsetX, dstoffsetY);
+ }
+
+ GCEXIT(GCZONE_DEST);
+}
+
+enum bverror parse_source(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch,
+ struct bvrect *srcrect,
+ struct surfaceinfo *srcinfo)
+{
+ enum bverror bverror = BVERR_NONE;
+
+ GCENTER(GCZONE_SRC);
+ GCDBG(GCZONE_SRC, "parsing source #%d\n",
+ srcinfo->index + 1);
+
+ /* Parse the source format. */
+ if (parse_format(bvbltparams, srcinfo) != BVERR_NONE) {
+ bverror = (srcinfo->index == 0)
+ ? BVERR_SRC1GEOM_FORMAT
+ : BVERR_SRC2GEOM_FORMAT;
+ goto exit;
+ }
+
+ /* Parse orientation. */
+ srcinfo->angle = get_angle(srcinfo->geom->orientation);
+ if (srcinfo->angle == ROT_ANGLE_INVALID) {
+ BVSETBLTERROR((srcinfo->index == 0)
+ ? BVERR_SRC1GEOM
+ : BVERR_SRC2GEOM,
+ "unsupported source%d orientation %d.",
+ srcinfo->index + 1,
+ srcinfo->geom->orientation);
+ goto exit;
+ }
+
+ /* Determine source mirror. */
+ srcinfo->mirror = (srcinfo->index == 0)
+ ? (bvbltparams->flags >> BVFLAG_FLIP_SRC1_SHIFT)
+ & BVFLAG_FLIP_MASK
+ : (bvbltparams->flags >> BVFLAG_FLIP_SRC2_SHIFT)
+ & BVFLAG_FLIP_MASK;
+
+ GCDBG(GCZONE_SRC, " buffer length = %d\n", srcinfo->buf.desc->length);
+ GCDBG(GCZONE_SRC, " rotation %d degrees.\n", srcinfo->angle * 90);
+
+ if (srcinfo->buf.desc->auxtype == BVAT_PHYSDESC) {
+ struct bvphysdesc *bvphysdesc;
+ bvphysdesc = (struct bvphysdesc *) srcinfo->buf.desc->auxptr;
+ GCDBG(GCZONE_SRC, " physical descriptor = 0x%08X\n",
+ bvphysdesc);
+ GCDBG(GCZONE_SRC, " first page = 0x%08X\n",
+ bvphysdesc->pagearray[0]);
+ GCDBG(GCZONE_SRC, " page offset = 0x%08X\n",
+ bvphysdesc->pageoffset);
+ } else {
+ GCDBG(GCZONE_SRC, " virtual address = 0x%08X\n",
+ (unsigned int) srcinfo->buf.desc->virtaddr);
+ }
+
+ GCDBG(GCZONE_SRC, " stride = %ld\n",
+ srcinfo->geom->virtstride);
+ GCDBG(GCZONE_SRC, " geometry size = %dx%d\n",
+ srcinfo->geom->width, srcinfo->geom->height);
+ GCDBG(GCZONE_SRC, " mirror = %d\n", srcinfo->mirror);
+
+ /* Convert the rectangle. */
+ GCCONVERT_RECT(GCZONE_SRC,
+ " rect", srcrect, &srcinfo->rect);
+
+ /* Source must be 8 pixel aligned. */
+ if ((srcinfo->geom->virtstride
+ & (srcinfo->format.bitspp - 1)) != 0) {
+ BVSETBLTERROR((srcinfo->index == 0)
+ ? BVERR_SRC1GEOM_STRIDE
+ : BVERR_SRC2GEOM_STRIDE,
+ "source stride must be 8 pixel aligned.");
+ goto exit;
+ }
+
+ /* Planar YUV? */
+ if ((srcinfo->format.type == BVFMT_YUV) &&
+ (srcinfo->format.cs.yuv.planecount > 1)) {
+ int xpixalign;
+
+ /* Source rotation is not supported. */
+ if (srcinfo->angle != ROT_ANGLE_0) {
+ BVSETBLTERROR((srcinfo->index == 0)
+ ? BVERR_SRC1_ROT
+ : BVERR_SRC2_ROT,
+ "rotation of planar YUV is "
+ "not supported");
+ goto exit;
+ }
+
+ /* Check base address alignment. */
+ xpixalign = get_pixel_offset(srcinfo, 0);
+ if (xpixalign != 0) {
+ BVSETBLTERROR((srcinfo->index == 0)
+ ? BVERR_SRC1DESC_ALIGNMENT
+ : BVERR_SRC2DESC_ALIGNMENT,
+ "planar YUV base address must be "
+ "64 byte aligned.");
+ goto exit;
+ }
+ }
+
+ /* Validate source geometry. */
+ if (!valid_geom(srcinfo)) {
+ BVSETBLTERROR((srcinfo->index == 0)
+ ? BVERR_SRC1GEOM
+ : BVERR_SRC2GEOM,
+ "source%d geom exceeds surface size.",
+ srcinfo->index + 1);
+ goto exit;
+ }
+
+exit:
+ GCEXITARG(GCZONE_SRC, "bv%s = %d\n",
+ (bverror == BVERR_NONE) ? "result" : "error", bverror);
+ return bverror;
+}
+
+static enum bverror parse_implicitscale(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch)
+{
+ enum bverror bverror = BVERR_NONE;
+ unsigned int quality;
+ unsigned int technique;
+ unsigned int imagetype;
+
+ GCENTER(GCZONE_SCALING);
+
+ quality = (bvbltparams->scalemode & BVSCALEDEF_QUALITY_MASK)
+ >> BVSCALEDEF_QUALITY_SHIFT;
+ technique = (bvbltparams->scalemode & BVSCALEDEF_TECHNIQUE_MASK)
+ >> BVSCALEDEF_TECHNIQUE_SHIFT;
+ imagetype = (bvbltparams->scalemode & BVSCALEDEF_TYPE_MASK)
+ >> BVSCALEDEF_TYPE_SHIFT;
+
+ GCDBG(GCZONE_SCALING, "quality = %d\n", quality);
+ GCDBG(GCZONE_SCALING, "technique = %d\n", technique);
+ GCDBG(GCZONE_SCALING, "imagetype = %d\n", imagetype);
+
+ switch (quality) {
+ case BVSCALEDEF_FASTEST >> BVSCALEDEF_QUALITY_SHIFT:
+ batch->op.filter.horkernelsize = 3;
+ batch->op.filter.verkernelsize = 3;
+ break;
+
+ case BVSCALEDEF_GOOD >> BVSCALEDEF_QUALITY_SHIFT:
+ batch->op.filter.horkernelsize = 5;
+ batch->op.filter.verkernelsize = 5;
+ break;
+
+ case BVSCALEDEF_BETTER >> BVSCALEDEF_QUALITY_SHIFT:
+ batch->op.filter.horkernelsize = 7;
+ batch->op.filter.verkernelsize = 7;
+ break;
+
+ case BVSCALEDEF_BEST >> BVSCALEDEF_QUALITY_SHIFT:
+ batch->op.filter.horkernelsize = 9;
+ batch->op.filter.verkernelsize = 9;
+ break;
+
+ default:
+ BVSETBLTERROR(BVERR_SCALE_MODE,
+ "unsupported scale quality 0x%02X", quality);
+ goto exit;
+ }
+
+ switch (technique) {
+ case BVSCALEDEF_DONT_CARE >> BVSCALEDEF_TECHNIQUE_SHIFT:
+ case BVSCALEDEF_NOT_NEAREST_NEIGHBOR >> BVSCALEDEF_TECHNIQUE_SHIFT:
+ break;
+
+ case BVSCALEDEF_POINT_SAMPLE >> BVSCALEDEF_TECHNIQUE_SHIFT:
+ batch->op.filter.horkernelsize = 1;
+ batch->op.filter.verkernelsize = 1;
+ break;
+
+ case BVSCALEDEF_INTERPOLATED >> BVSCALEDEF_TECHNIQUE_SHIFT:
+ break;
+
+ default:
+ BVSETBLTERROR(BVERR_SCALE_MODE,
+ "unsupported scale technique %d", technique);
+ goto exit;
+ }
+
+ switch (imagetype) {
+ case 0:
+ case BVSCALEDEF_PHOTO >> BVSCALEDEF_TYPE_SHIFT:
+ case BVSCALEDEF_DRAWING >> BVSCALEDEF_TYPE_SHIFT:
+ break;
+
+ default:
+ BVSETBLTERROR(BVERR_SCALE_MODE,
+ "unsupported image type %d", imagetype);
+ goto exit;
+ }
+
+ GCDBG(GCZONE_SCALING, "kernel size = %dx%d\n",
+ batch->op.filter.horkernelsize,
+ batch->op.filter.verkernelsize);
+
+exit:
+ GCEXIT(GCZONE_SCALING);
+ return bverror;
+}
+
+static enum bverror parse_explicitscale(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch)
+{
+ enum bverror bverror = BVERR_NONE;
+ unsigned int horsize;
+ unsigned int versize;
+
+ GCENTER(GCZONE_SCALING);
+
+ horsize = (bvbltparams->scalemode & BVSCALEDEF_HORZ_MASK)
+ >> BVSCALEDEF_HORZ_SHIFT;
+ versize = (bvbltparams->scalemode & BVSCALEDEF_VERT_MASK)
+ >> BVSCALEDEF_VERT_SHIFT;
+
+ GCDBG(GCZONE_SCALING, "horsize = %d\n", horsize);
+ GCDBG(GCZONE_SCALING, "versize = %d\n", versize);
+
+ switch (horsize) {
+ case BVSCALEDEF_NEAREST_NEIGHBOR:
+ batch->op.filter.horkernelsize = 1;
+ break;
+
+ case BVSCALEDEF_LINEAR:
+ case BVSCALEDEF_CUBIC:
+ case BVSCALEDEF_3_TAP:
+ batch->op.filter.horkernelsize = 3;
+ break;
+
+ case BVSCALEDEF_5_TAP:
+ batch->op.filter.horkernelsize = 5;
+ break;
+
+ case BVSCALEDEF_7_TAP:
+ batch->op.filter.horkernelsize = 7;
+ break;
+
+ case BVSCALEDEF_9_TAP:
+ batch->op.filter.horkernelsize = 9;
+ break;
+
+ default:
+ BVSETBLTERROR(BVERR_SCALE_MODE,
+ "unsupported horizontal kernel size %d", horsize);
+ goto exit;
+ }
+
+ switch (versize) {
+ case BVSCALEDEF_NEAREST_NEIGHBOR:
+ batch->op.filter.verkernelsize = 1;
+ break;
+
+ case BVSCALEDEF_LINEAR:
+ case BVSCALEDEF_CUBIC:
+ case BVSCALEDEF_3_TAP:
+ batch->op.filter.verkernelsize = 3;
+ break;
+
+ case BVSCALEDEF_5_TAP:
+ batch->op.filter.verkernelsize = 5;
+ break;
+
+ case BVSCALEDEF_7_TAP:
+ batch->op.filter.verkernelsize = 7;
+ break;
+
+ case BVSCALEDEF_9_TAP:
+ batch->op.filter.verkernelsize = 9;
+ break;
+
+ default:
+ BVSETBLTERROR(BVERR_SCALE_MODE,
+ "unsupported vertical kernel size %d", versize);
+ goto exit;
+ }
+
+ GCDBG(GCZONE_SCALING, "kernel size = %dx%d\n",
+ batch->op.filter.horkernelsize,
+ batch->op.filter.verkernelsize);
+
+exit:
+ GCEXIT(GCZONE_SCALING);
+ return bverror;
+}
+
+enum bverror parse_scalemode(struct bvbltparams *bvbltparams,
+ struct gcbatch *batch)
+{
+ enum bverror bverror;
+ unsigned int scaleclass;
+
+ GCENTER(GCZONE_SCALING);
+
+ scaleclass = (bvbltparams->scalemode & BVSCALEDEF_CLASS_MASK)
+ >> BVSCALEDEF_CLASS_SHIFT;
+
+ GCDBG(GCZONE_SCALING, "scaleclass = %d\n", scaleclass);
+
+ switch (scaleclass) {
+ case BVSCALEDEF_IMPLICIT >> BVSCALEDEF_CLASS_SHIFT:
+ bverror = parse_implicitscale(bvbltparams, batch);
+ break;
+
+ case BVSCALEDEF_EXPLICIT >> BVSCALEDEF_CLASS_SHIFT:
+ bverror = parse_explicitscale(bvbltparams, batch);
+ break;
+
+ default:
+ BVSETBLTERROR(BVERR_SCALE_MODE,
+ "unsupported scale class %d", scaleclass);
+ goto exit;
+ }
+
+exit:
+ GCEXIT(GCZONE_SCALING);
+ return bverror;
+}
diff --git a/bltsville/gcbv/mirror/include/cache-2dmanager.h b/bltsville/gcbv/mirror/include/cache-2dmanager.h
new file mode 100644
index 0000000..9740314
--- /dev/null
+++ b/bltsville/gcbv/mirror/include/cache-2dmanager.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright(c) 2012,
+ * Texas Instruments, Inc. and Vivante Corporation.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Vivante Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CACHE_2DMANAGER_H_
+#define CACHE_2DMANAGER_H_
+
+/* The value below only applies to OMAP4 */
+#define L1CACHE_SIZE 32768
+#define L2CACHE_SIZE 1048576
+
+#define L1THRESHOLD L1CACHE_SIZE
+#define L2THRESHOLD L2CACHE_SIZE
+
+struct c2dmrgn {
+ char *start; /* addr of upper left of rect */
+ size_t span; /* bytes to be operated on per line */
+ size_t lines; /* lines to be operated on */
+ long stride; /* bytes per line */
+};
+
+/*
+ * c2dm_l1cache(count, rgns, dir)
+ *
+ * L1 Cache operations in 2D
+ *
+ * - count - number of regions
+ * - rgns - array of regions
+ * - dir - cache operation direction
+ *
+ */
+void c2dm_l1cache(int count, struct c2dmrgn rgns[], int dir);
+
+/*
+ * c2dm_l2cache(count, rgns, dir)
+ *
+ * L2 Cache operations in 2D
+ *
+ * - count - number of regions
+ * - rgns - array of regions
+ * - dir - cache operation direction
+ *
+ */
+void c2dm_l2cache(int count, struct c2dmrgn rgns[], int dir);
+
+
+#endif /* CACHE_2DMANAGER_H_ */
diff --git a/bltsville/gcbv/mirror/include/gcdbglog.h b/bltsville/gcbv/mirror/include/gcdbglog.h
new file mode 100644
index 0000000..a4e759a
--- /dev/null
+++ b/bltsville/gcbv/mirror/include/gcdbglog.h
@@ -0,0 +1,384 @@
+/*
+ * Copyright(c) 2012,
+ * Texas Instruments, Inc. and Vivante Corporation.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Vivante Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCDBGLOG_H
+#define GCDBGLOG_H
+
+#include "gclist.h"
+#include <bltsville.h>
+struct gcmmucontext;
+
+
+/*******************************************************************************
+ * Debug logging switches.
+ */
+
+/* Enables internal gccore logging backend. */
+#if !defined(GCDEBUG_ENABLE)
+#define GCDEBUG_ENABLE 0 /* Enabled for development branch only. */
+#endif
+
+/* Enables linux builtin logging backend. */
+#if !defined(GCDEBUG_LINUXLOGS)
+#define GCDEBUG_LINUXLOGS 0
+#endif
+
+#if GCDEBUG_ENABLE && GCDEBUG_LINUXLOGS
+#error GCDEBUG_ENABLE and GCDEBUG_LINUXLOGS cannot be enabled simultaneously.
+#endif
+
+
+/*******************************************************************************
+ * Dumping interface macro for release mode.
+ */
+
+#if !GCDEBUG_ENABLE && !GCDEBUG_LINUXLOGS
+#define GCDBG_INIT(...)
+#define GCDBG_EXIT(...)
+#define GCDBG_FILTERDEF(...)
+#define GCDBG_REGISTER(...)
+#define GCENTER(...)
+#define GCEXIT(...)
+#define GCENTERARG(...)
+#define GCEXITARG(...)
+#define GCDBG(...) {}
+#define GCERR(...) {}
+#define GCDUMPSTRING(...) {}
+#define GCDUMPBUFFER(...) {}
+#define GCDUMPARENA(...) {}
+#define GCDUMPARENAS(...) {}
+#define GCGPUSTATUS(...) {}
+#endif
+
+#if !GCDEBUG_ENABLE
+#define GCDBG_REPORT_MISSING() \
+ printf("gcx logging is not integrated.\n")
+
+#define GCDBG_SHOWENABLED(s) \
+ GCDBG_REPORT_MISSING()
+
+#define GCDBG_ENABLEDUMP() \
+ GCDBG_REPORT_MISSING()
+
+#define GCDBG_DISABLEDUMP() \
+ GCDBG_REPORT_MISSING()
+
+#define GCDBG_SETFILTER(filtername, zone) \
+ GCDBG_REPORT_MISSING()
+
+#define GCDBG_FLUSHDUMP(s) \
+ GCDBG_REPORT_MISSING()
+
+#define GCDBG_RESETDUMP() \
+ GCDBG_REPORT_MISSING()
+
+#endif
+
+
+/*******************************************************************************
+ * Dumping macros not specific to a particular logging backend.
+ */
+
+#if GCDEBUG_ENABLE || GCDEBUG_LINUXLOGS
+
+#define GC_MOD_PREFIX \
+ GC_DEV_NAME ": %s(%d) "
+
+#define GCDUMPARENA(zone, text, arena) \
+do { \
+ GCDBG(zone, text " @ 0x%08X:\n", (unsigned int) arena); \
+ GCDBG(zone, " number of pages = %u\n", \
+ (arena)->count); \
+ GCDBG(zone, " from (absolute/mtlb/stlb) = 0x%08X / %u / %u\n", \
+ (arena)->start.absolute, \
+ (arena)->start.loc.mtlb, \
+ (arena)->start.loc.stlb); \
+ GCDBG(zone, " to (absolute/mtlb/stlb) = 0x%08X / %u / %u\n", \
+ (arena)->end.absolute, \
+ (arena)->end.loc.mtlb, \
+ (arena)->end.loc.stlb); \
+} while (false)
+
+#define GCDUMPARENAS(zone, text, arenahead) \
+do { \
+ GCDBG(zone, "%s:\n", text); \
+ \
+ if (list_empty(arenahead)) { \
+ GCDBG(zone, " no arenas defined in the list.\n"); \
+ } else { \
+ struct list_head *entry; \
+ struct gcmmuarena *arena; \
+ \
+ list_for_each(entry, arenahead) { \
+ arena = list_entry(entry, struct gcmmuarena, link); \
+ GCDUMPARENA(zone, "arena", arena); \
+ } \
+ } \
+} while (false)
+
+#endif
+
+#define GC_FUNC_ENTER "++"
+#define GC_FUNC_EXIT "--"
+
+
+/*******************************************************************************
+ * Dumping macros for internal gccore logging backend.
+ */
+
+#if GCDEBUG_ENABLE
+
+#define GCDBGFILTER \
+ g_gcdbgfilter
+
+#define GCDBG_INIT() \
+ gcdbg_init()
+
+#define GCDBG_EXIT() \
+ gcdbg_exit()
+
+#define GCDBG_FILTERDEF(name, initzone, ...) \
+ static struct gcdbgfilter GCDBGFILTER = { \
+ .link = LIST_HEAD_INIT(GCDBGFILTER.link), \
+ .filtername = #name, \
+ .zone = initzone, \
+ .zonename = { __VA_ARGS__, NULL } \
+ }; \
+ \
+ struct gcdbgfilter *name ## _dbgfilter(void) \
+ { \
+ return &GCDBGFILTER; \
+ }
+
+#define GCDBG_REGISTER(name) \
+do { \
+ struct gcdbgfilter *name ## _dbgfilter(void); \
+ gc_dbg_add_client(name ## _dbgfilter()); \
+} while (0)
+
+#define GCDBG_SHOWENABLED(s) \
+ gc_dump_show_enabled(s)
+
+#define GCDBG_ENABLEDUMP() \
+ gc_dump_enable()
+
+#define GCDBG_DISABLEDUMP() \
+ gc_dump_disable()
+
+#define GCDBG_SETFILTER(filtername, zone) \
+ gc_dump_filter_enable(filtername, zone)
+
+#define GCDBG_FLUSHDUMP(s) \
+ gc_dump_flush(s)
+
+#define GCDBG_RESETDUMP() \
+ gc_dump_reset()
+
+#define GCENTER(zone) \
+ gc_dump_string(&GCDBGFILTER, zone, GC_FUNC_ENTER GC_MOD_PREFIX "\n", \
+ __func__, __LINE__)
+
+#define GCEXIT(zone) \
+ gc_dump_string(&GCDBGFILTER, zone, GC_FUNC_EXIT GC_MOD_PREFIX "\n", \
+ __func__, __LINE__)
+
+#define GCENTERARG(zone, msg, ...) \
+ gc_dump_string(&GCDBGFILTER, zone, GC_FUNC_ENTER GC_MOD_PREFIX msg, \
+ __func__, __LINE__, ##__VA_ARGS__)
+
+#define GCEXITARG(zone, msg, ...) \
+ gc_dump_string(&GCDBGFILTER, zone, GC_FUNC_EXIT GC_MOD_PREFIX msg, \
+ __func__, __LINE__, ##__VA_ARGS__)
+
+#define GCDBG(zone, msg, ...) \
+ gc_dump_string(&GCDBGFILTER, zone, GC_MOD_PREFIX msg, \
+ __func__, __LINE__, ##__VA_ARGS__)
+
+#define GCERR(msg, ...) \
+ gc_dump_string(NULL, 0, GC_MOD_PREFIX "[ERROR] " msg, \
+ __func__, __LINE__, ##__VA_ARGS__)
+
+#define GCDUMPSTRING(msg, ...) \
+ gc_dump_string(NULL, 0, msg, ##__VA_ARGS__)
+
+#define GCDUMPBUFFER(zone, ptr, gpuaddr, datasize) \
+ gc_dump_cmd_buffer(&GCDBGFILTER, zone, ptr, gpuaddr, datasize)
+
+#endif
+
+
+/*******************************************************************************
+ * Dumping macros for linux builtin logging backend.
+ */
+
+#if GCDEBUG_LINUXLOGS
+
+#define GCDBG_INIT()
+#define GCDBG_EXIT()
+#define GCDBG_FILTERDEF(...)
+#define GCDBG_REGISTER(...)
+
+#define GCENTER(zone) \
+ GCDBG(zone, GC_FUNC_ENTER " %s(%d)\n", __func__, __LINE__)
+
+#define GCEXIT(zone) \
+ GCDBG(zone, GC_FUNC_EXIT " %s(%d)\n", __func__, __LINE__)
+
+#define GCENTERARG(zone, msg, ...) \
+ GCDBG(zone, GC_FUNC_ENTER " %s(%d) " msg "\n", \
+ __func__, __LINE__, ##__VA_ARGS__)
+
+#define GCEXITARG(zone, msg, ...) \
+ GCDBG(zone, GC_FUNC_EXIT " %s(%d) " msg "\n", \
+ __func__, __LINE__, ##__VA_ARGS__)
+
+#define GCDBG(zone, msg, ...) \
+ dev_dbg(gc_get_dev(), msg, ##__VA_ARGS__)
+
+#define GCERR(msg, ...) \
+ GCDBG(0, msg, ##__VA_ARGS__)
+
+#define GCDUMPSTRING(msg, ...) \
+ GCDBG(0, msg, ##__VA_ARGS__)
+
+#define GCDUMPBUFFER(...) {}
+#define GCGPUSTATUS(...) {}
+
+#endif
+
+
+/*******************************************************************************
+ * Command buffer parser.
+ */
+
+struct gcsurfaceinfo {
+ unsigned int width;
+ unsigned int height;
+ unsigned int address;
+ unsigned int stride;
+ unsigned int swizzle;
+ unsigned int format;
+ unsigned int bpp;
+};
+
+struct gcrect {
+ int left;
+ int top;
+ int right;
+ int bottom;
+};
+
+struct gcsourceinfo {
+ struct gcsurfaceinfo surf;
+ struct gcrect rect;
+};
+
+struct gcdestinfo {
+ struct gcsurfaceinfo surf;
+ unsigned int rectcount;
+ struct gcrect rect[256];
+};
+
+struct gccommandinfo {
+ unsigned int command;
+ unsigned int srccount;
+ struct gcsourceinfo src[4];
+ struct gcdestinfo dst;
+};
+
+/* Parse the specified command buffer and fill in the structure. */
+int gc_parse_command_buffer(unsigned int *buffer, unsigned int size,
+ struct gccommandinfo *info);
+
+
+/*******************************************************************************
+ * Filter structure.
+ */
+
+struct gcdbgfilter {
+ struct list_head link;
+ char *filtername;
+ unsigned int zone;
+ const char *zonename[];
+};
+
+
+/*******************************************************************************
+ * Debug init/exit functions.
+ */
+
+void gcdbg_init(void);
+void gcdbg_exit(void);
+
+
+/*******************************************************************************
+ * Dumping functions.
+ */
+
+/* String dumping. */
+void gc_dump_string(struct gcdbgfilter *filter, unsigned int zone,
+ const char *message, ...);
+void gc_dump_string_sized(struct gcdbgfilter *filter, unsigned int zone,
+ unsigned int argsize, const char *message, ...);
+
+/* Dump command buffer. */
+void gc_dump_cmd_buffer(struct gcdbgfilter *filter, unsigned int zone,
+ void *ptr, unsigned int gpuaddr, unsigned int datasize);
+
+/* Dump generic buffer. */
+void gc_dump_buffer(struct gcdbgfilter *filter, unsigned int zone,
+ void *ptr, unsigned int gpuaddr, unsigned int datasize);
+
+
+/*******************************************************************************
+ * Bltsville debugging.
+ */
+
+char *gc_bvblend_name(enum bvblend blend);
+
+
+/*******************************************************************************
+ * Dumping control.
+ */
+
+struct seq_file;
+
+struct device *gc_get_dev(void);
+void gc_dump_show_enabled(struct seq_file *s);
+void gc_dump_enable(void);
+void gc_dump_disable(void);
+void gc_dump_filter_enable(const char *filtername, int zone);
+void gc_dump_flush(struct seq_file *s);
+void gc_dump_reset(void);
+void gc_dbg_add_client(struct gcdbgfilter *filter);
+
+#endif
diff --git a/bltsville/gcbv/mirror/include/gcerror.h b/bltsville/gcbv/mirror/include/gcerror.h
new file mode 100644
index 0000000..2efcf39
--- /dev/null
+++ b/bltsville/gcbv/mirror/include/gcerror.h
@@ -0,0 +1,226 @@
+/*
+ * Copyright(c) 2012,
+ * Texas Instruments, Inc. and Vivante Corporation.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Vivante Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCERROR_H
+#define GCERROR_H
+
+#define GCERR_SETGRP(error, group) \
+( \
+ (enum gcerror) \
+ ((error & GCERR_GENERIC_MASK) | group) \
+)
+
+#define GCERR_GENERIC(error) \
+( \
+ (error & GCERR_GENERIC_MASK) << GCERR_GENERIC_SHIFT \
+)
+
+#define GCERR_GROUP(error) \
+( \
+ (error & GCERR_GROUP_MASK) << GCERR_GROUP_SHIFT \
+)
+
+enum gcerror {
+ /***********************************************************************
+ ** No error / success.
+ */
+ GCERR_NONE = 0,
+
+ /***********************************************************************
+ ** Error code zones.
+ */
+
+ /* Generic error code zone. These errors inform of the low level
+ reason of the faulure, but don't carry information about which
+ logical part of the code generated the error. */
+ GCERR_GENERIC_SIZE = 12,
+ GCERR_GENERIC_SHIFT = 0,
+ GCERR_GENERIC_MASK
+ = ((1 << GCERR_GENERIC_SIZE) - 1) << GCERR_GENERIC_SHIFT,
+
+ /* Group error code zone. These errors inform about the logical part
+ of the code where the error occurred. */
+ GCERR_GROUP_SIZE = (32 - GCERR_GENERIC_SIZE),
+ GCERR_GROUP_SHIFT = GCERR_GENERIC_SIZE,
+ GCERR_GROUP_MASK
+ = ((1 << GCERR_GROUP_SIZE) - 1) << GCERR_GROUP_SHIFT,
+
+ /***********************************************************************
+ ** Generic zone errors.
+ */
+
+ GCERR_OODM /* Out of dynamic memory. */
+ = GCERR_GENERIC(1),
+
+ GCERR_OOPM /* Out of paged memory. */
+ = GCERR_GENERIC(2),
+
+ GCERR_PMMAP /* Paged memory mapping. */
+ = GCERR_GENERIC(3),
+
+ GCERR_USER_READ /* Reading user input. */
+ = GCERR_GENERIC(4),
+
+ GCERR_USER_WRITE /* Writing user output. */
+ = GCERR_GENERIC(5),
+
+ GCERR_INTERRUPTED /* Interrupted by a signal. */
+ = GCERR_GENERIC(6),
+
+ GCERR_TIMEOUT /* Timeout. */
+ = GCERR_GENERIC(7),
+
+ GCERR_NOT_FOUND /* Data/entry not found. */
+ = GCERR_GENERIC(8),
+
+ GCERR_IOCTL /* IOCTL failed. */
+ = GCERR_GENERIC(9),
+
+ /***********************************************************************
+ ** Group zone errors.
+ */
+
+ /**** Context errors. */
+ GCERR_CTX_ALLOC /* Context allocation. */
+ = GCERR_GROUP(0x01000),
+
+ GCERR_CTX_CHANGE /* Lock/unlock error. */
+ = GCERR_GROUP(0x01010),
+
+ GCERR_CTX_NULL /* Context not set. */
+ = GCERR_GROUP(0x01020),
+
+ /**** Command queue errors. */
+ GCERR_CMD_ENTRY_PIPE /* Entry pipe is invalid. */
+ = GCERR_GROUP(0x02000),
+
+ GCERR_CMD_EXIT_PIPE /* Exit pipe is invalid. */
+ = GCERR_GROUP(0x02010),
+
+ GCERR_CMD_MAPPED /* Command buffer mapping error. */
+ = GCERR_GROUP(0x02020),
+
+ GCERR_CMD_CONSISTENCY /* Inconsistent mapping. */
+ = GCERR_GROUP(0x02030),
+
+ GCERR_CMD_ALLOC /* Buffer allocation. */
+ = GCERR_GROUP(0x02040),
+
+ GCERR_CMD_QUEUE_ALLOC /* Buffer queue allocation. */
+ = GCERR_GROUP(0x02050),
+
+ GCERR_CMD_EVENT_ALLOC /* Event allocation. */
+ = GCERR_GROUP(0x02060),
+
+ GCERR_CMD_INT_ALLOC /* Interrupt allocation. */
+ = GCERR_GROUP(0x02070),
+
+ GCERR_CMD_ISR /* ISR initialization. */
+ = GCERR_GROUP(0x02080),
+
+ GCERR_CMD_THREAD /* Thread initialization. */
+ = GCERR_GROUP(0x02090),
+
+ /**** MMU errors. */
+ GCERR_MMU_CTXT_BAD /* Invalid context. */
+ = GCERR_GROUP(0x03000),
+
+ GCERR_MMU_MTLB_ALLOC /* MTLB allocation. */
+ = GCERR_GROUP(0x03010),
+
+ GCERR_MMU_MTLB_SET /* MTLB setting. */
+ = GCERR_GROUP(0x03020),
+
+ GCERR_MMU_STLB_ALLOC /* STLB allocation. */
+ = GCERR_GROUP(0x03030),
+
+ GCERR_MMU_STLBIDX_ALLOC /* STLB index allocation. */
+ = GCERR_GROUP(0x03040),
+
+ GCERR_MMU_ARENA_ALLOC /* Vacant arena allocation. */
+ = GCERR_GROUP(0x03050),
+
+ GCERR_MMU_OOM /* No available arenas to allocate. */
+ = GCERR_GROUP(0x03060),
+
+ GCERR_MMU_SAFE_ALLOC /* Safe zone allocation. */
+ = GCERR_GROUP(0x03070),
+
+ GCERR_MMU_INIT /* MMU initialization. */
+ = GCERR_GROUP(0x03080),
+
+ GCERR_MMU_ARG /* Invalid argument. */
+ = GCERR_GROUP(0x03090),
+
+ GCERR_MMU_CLIENT /* Client initialization. */
+ = GCERR_GROUP(0x030A0),
+
+ GCERR_MMU_BUFFER_BAD /* Invalid buffer to map. */
+ = GCERR_GROUP(0x030B0),
+
+ GCERR_MMU_PAGE_BAD /* Bad page within the buffer. */
+ = GCERR_GROUP(0x030C0),
+
+ GCERR_MMU_DESC_ALLOC /* Bad page within the buffer. */
+ = GCERR_GROUP(0x030D0),
+
+ GCERR_MMU_PHYS_ALLOC /* Bad page within the buffer. */
+ = GCERR_GROUP(0x030E0),
+
+ GCERR_MMU_OFFSET /* Bad buffer offset. */
+ = GCERR_GROUP(0x030F0),
+
+ /**** Power management. */
+ GCERR_POWER_MODE /* Invlalid power mode requested. */
+ = GCERR_GROUP(0x04000),
+
+ GCERR_POWER_CLOCK_ON /* Failed to enable clock. */
+ = GCERR_GROUP(0x04010),
+
+ GCERR_POWER_IRQ_ON /* Failed to install IRQ handler. */
+ = GCERR_GROUP(0x04020),
+
+ GCERR_POWER_PULSE /* Pulse skipping error. */
+ = GCERR_GROUP(0x04030),
+
+ /**** GCIOCTL module errors. */
+ GCERR_IOCTL_CTX_ALLOC /* Context wrapper allocation. */
+ = GCERR_GROUP(0x11000),
+
+ GCERR_IOCTL_BUF_ALLOC /* Command buffer allocation. */
+ = GCERR_GROUP(0x11010),
+
+ GCERR_IOCTL_FIXUP_ALLOC /* Fixup buffer allocation. */
+ = GCERR_GROUP(0x11020),
+};
+
+#endif
diff --git a/bltsville/gcbv/mirror/include/gcioctl.h b/bltsville/gcbv/mirror/include/gcioctl.h
new file mode 100644
index 0000000..4f31b5a
--- /dev/null
+++ b/bltsville/gcbv/mirror/include/gcioctl.h
@@ -0,0 +1,293 @@
+/*
+ * Copyright(c) 2012,
+ * Texas Instruments, Inc. and Vivante Corporation.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Vivante Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCIOCTL_H
+#define GCIOCTL_H
+
+#include "gclist.h"
+#include "gcerror.h"
+#include "gcreg.h"
+#include "cache-2dmanager.h"
+#include <bverror.h>
+
+/* IOCTL parameters. */
+#define GCIOCTL_TYPE 0x5D
+#define GCIOCTL_BASE 0x5D
+
+
+/*******************************************************************************
+ * Capability query API entry.
+ */
+
+#define GCIOCTL_GETCAPS _IOWR(GCIOCTL_TYPE, GCIOCTL_BASE + 0x00, \
+ struct gcicaps)
+
+/* GCIOCTL_CALLBACK_ALLOC / GCIOCTL_CALLBACK_FREE:
+ * To be able to use the callback mechanism each user space client must
+ * use the ALLOC/FREE APIs to manage a kernel side callback object
+ * represented by the handle member of struct gcicallback.
+ * ALLOC API allocates the object and returns the handle to it. */
+struct gcicaps {
+ /* Error code. */
+ enum gcerror gcerror;
+
+ /* Capabilities and characteristics. */
+ unsigned int gcmodel;
+ unsigned int gcrevision;
+ unsigned int gcdate;
+ unsigned int gctime;
+ union gcfeatures gcfeatures;
+ union gcfeatures0 gcfeatures0;
+ union gcfeatures1 gcfeatures1;
+ union gcfeatures2 gcfeatures2;
+ union gcfeatures3 gcfeatures3;
+};
+
+/*******************************************************************************
+ * Commit API entry.
+ */
+
+#define GCIOCTL_COMMIT _IOWR(GCIOCTL_TYPE, GCIOCTL_BASE + 0x10, \
+ struct gcicommit)
+
+/* GPU graphics pipe definition. */
+enum gcpipe {
+ GCPIPE_UNKNOWN,
+ GCPIPE_2D,
+ GCPIPE_3D
+};
+
+/* Commit header; contains pointers to the head and the tail of a linked list
+ of command buffers to execute. */
+struct gcicommit {
+ /* Return status code. */
+ enum gcerror gcerror;
+
+ /* Entry graphics pipe specifies the pipe the GPU is expected to be in
+ * for successfull execution of the specified command buffers in this
+ * call. Exit graphics pipe specifies the state of the GPU after the
+ * buffers are executed. */
+ enum gcpipe entrypipe;
+ enum gcpipe exitpipe;
+
+ /* List of command buffers to be executed (gcbuffer). */
+ struct list_head buffer;
+
+ /* Pointer to the callback function to be called when the GPU completes
+ * execution of all buffers specified in this call. This member can be
+ * NULL if no callback is desired. callbackparam specifies data to be
+ * passed to the callback. */
+ void (*callback) (void *callbackparam);
+ void *callbackparam;
+
+ /* Callback object handle allocated with GCIOCTL_CALLBACK_ALLOC API. */
+ unsigned long handle;
+
+ /* If asynchronous is set to true, the call returns immediately without
+ * waiting until all specified buffers have been executed. If set to
+ * false, the call does not return until execution is finished. */
+ bool asynchronous;
+
+ /* Scheduled unmappings (gcschedunmap). */
+ struct list_head unmap;
+};
+
+/* Command buffer header. */
+#define GC_BUFFER_SIZE (32 * 1024)
+struct gcbuffer {
+ /* Fixup list (gcfixup). */
+ struct list_head fixup;
+
+ /* Number of pixels to be rendered. */
+ unsigned int pixelcount;
+
+ /* Pointers to the head and tail of the command buffer list. */
+ unsigned int *head;
+ unsigned int *tail;
+
+ /* Number of bytes available in the buffer for allocation. */
+ unsigned int available;
+
+ /* Commmand buffer list (gcbuffer). */
+ struct list_head link;
+};
+
+/* Fixup entry. */
+struct gcfixupentry {
+ /* Offset into the commmand buffer where fixup is to be performed. */
+ unsigned int dataoffset;
+
+ /* Offset to be added to the translated address. */
+ unsigned int surfoffset;
+};
+
+/* Address fixup array. */
+#define GC_FIXUP_MAX 1024
+struct gcfixup {
+ /* Fixup list (gcfixup). */
+ struct list_head link;
+
+ /* Fixup array. */
+ unsigned int count;
+ struct gcfixupentry fixup[GC_FIXUP_MAX];
+};
+
+/* Defines a link list of scheduled unmappings. */
+struct gcschedunmap {
+ /* Map handle. */
+ unsigned long handle;
+
+ /* Previous/next unmapping info (gcschedunmap). */
+ struct list_head link;
+};
+
+
+/*******************************************************************************
+ * Map/unmap API entries.
+ */
+
+#define GCIOCTL_MAP _IOWR(GCIOCTL_TYPE, GCIOCTL_BASE + 0x20, \
+ struct gcimap)
+#define GCIOCTL_UNMAP _IOWR(GCIOCTL_TYPE, GCIOCTL_BASE + 0x21, \
+ struct gcimap)
+
+struct gcimap {
+ /* Return status code. */
+ enum gcerror gcerror;
+
+ /* Mapped handle of the buffer. */
+ unsigned long handle;
+
+ union {
+ /* Pointer to the buffer to be mapped;
+ * used when pagearray is not provided (set to NULL). */
+ void *logical;
+
+ /* Page offset of the buffer to be mapped;
+ * used when pagearray is provided. */
+ unsigned int offset;
+ } buf;
+
+ /* Size of a physical page, 0 for default. */
+ unsigned int pagesize;
+
+ /* Pointer to array of physical pages. */
+ unsigned long *pagearray;
+
+ /* Size of the buffer to be mappped. */
+ unsigned int size;
+};
+
+
+/*******************************************************************************
+ * Cache manipulation API entries.
+ */
+
+#define GCIOCTL_CACHE _IOW(GCIOCTL_TYPE, GCIOCTL_BASE + 0x30, \
+ struct gcicache)
+
+struct gcicache {
+ /* Number of regions. */
+ int count;
+
+ /* The most regions that we deal with is 3. */
+ struct c2dmrgn rgn[3];
+
+ /* Direction of data. */
+ int dir;
+};
+
+
+/*******************************************************************************
+ * Callback API entry.
+ */
+
+#define GCIOCTL_CALLBACK_ALLOC _IOWR(GCIOCTL_TYPE, GCIOCTL_BASE + 0x40, \
+ struct gcicallback)
+#define GCIOCTL_CALLBACK_FREE _IOWR(GCIOCTL_TYPE, GCIOCTL_BASE + 0x41, \
+ struct gcicallback)
+#define GCIOCTL_CALLBACK_WAIT _IOWR(GCIOCTL_TYPE, GCIOCTL_BASE + 0x42, \
+ struct gcicallbackwait)
+#define GCIOCTL_CALLBACK_ARM _IOWR(GCIOCTL_TYPE, GCIOCTL_BASE + 0x43, \
+ struct gcicallbackarm)
+
+/* GCIOCTL_CALLBACK_ALLOC / GCIOCTL_CALLBACK_FREE:
+ * To be able to use the callback mechanism each user space client must
+ * use the ALLOC/FREE APIs to manage a kernel side callback object
+ * represented by the handle member of struct gcicallback.
+ * ALLOC API allocates the object and returns the handle to it. */
+struct gcicallback {
+ /* Error code. */
+ enum gcerror gcerror;
+
+ /* Callback object handle. */
+ unsigned long handle;
+};
+
+/* GCIOCTL_CALLBACK_WAIT:
+ * Called by the user level client to block and wait until the hardware
+ * has executed a callback that was previosuly scheduled for the handle. */
+struct gcicallbackwait {
+ /* Error code. */
+ enum gcerror gcerror;
+
+ /* Callback object handle. */
+ unsigned long handle;
+
+ /* Timeout in milliseconds. */
+ unsigned long timeoutms;
+
+ /* OUT: if the call succeeds, callback and callbackparam are
+ * initialized with the callback to call. */
+ void (*callback) (void *callbackparam);
+ void *callbackparam;
+};
+
+/* GCIOCTL_CALLBACK_ARM:
+ * Called by the client to arm a callback. This is similar to what
+ * COMMIT API does, but in a separate API. */
+struct gcicallbackarm {
+ /* Return status code. */
+ enum gcerror gcerror;
+
+ /* Pointer to the callback function to be called when the GPU completes
+ * execution of all buffers specified in this call. This member can be
+ * NULL if no callback is desired. callbackparam specifies data to be
+ * passed to the callback. */
+ void (*callback) (void *callbackparam);
+ void *callbackparam;
+
+ /* Callback object handle allocated with GCIOCTL_CALLBACK_ALLOC API. */
+ unsigned long handle;
+};
+
+#endif
diff --git a/bltsville/gcbv/mirror/include/gclist.h b/bltsville/gcbv/mirror/include/gclist.h
new file mode 100644
index 0000000..614f76e
--- /dev/null
+++ b/bltsville/gcbv/mirror/include/gclist.h
@@ -0,0 +1,594 @@
+/*
+ * Copyright(c) 2012,
+ * Texas Instruments, Inc. and Vivante Corporation.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef _GCLIST_H
+#define _GCLIST_H
+
+/* Adaptation of Linux kernel double linked list. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LIST_POISON1 ((void *) 0x00100100)
+#define LIST_POISON2 ((void *) 0x00200200)
+
+#if !defined(countof)
+#define countof(a) \
+ (sizeof(a) / sizeof(a[0]))
+#endif
+
+#if !defined(offsetof)
+#define offsetof(type, member) \
+ ((size_t) &((type *) 0)->member)
+#endif
+
+#if !defined(containerof)
+#define containerof(ptr, type, member) \
+ ((type *) ((char *) ptr - offsetof(type, member)))
+#endif
+
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+ struct list_head name = LIST_HEAD_INIT(name)
+
+static void INIT_LIST_HEAD(struct list_head *list)
+{
+ list->next = list;
+ list->prev = list;
+}
+
+/* Insert a new entry between two known consecutive entries.
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already! */
+static void __list_add(struct list_head *entry,
+ struct list_head *prev,
+ struct list_head *next)
+{
+ next->prev = entry;
+ entry->next = next;
+ entry->prev = prev;
+ prev->next = entry;
+}
+
+/**
+ * list_add - add a new entry
+ * @newentry: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static void list_add(struct list_head *newentry,
+ struct list_head *head)
+{
+ __list_add(newentry, head, head->next);
+}
+
+
+/**
+ * list_add_tail - add a new entry
+ * @newentry: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static void list_add_tail(struct list_head *newentry,
+ struct list_head *head)
+{
+ __list_add(newentry, head->prev, head);
+}
+
+/* Delete a list entry by making the prev/next entries point to each other.
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already! */
+static void __list_del(struct list_head *prev,
+ struct list_head *next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty() on entry does not return true after this,
+ * the entry is in an undefined state.
+ */
+static void __list_del_entry(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+}
+
+static void list_del(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ entry->next = LIST_POISON1;
+ entry->prev = LIST_POISON2;
+}
+
+/**
+ * list_replace - replace old entry by new one
+ * @oldentry : the element to be replaced
+ * @newentry : the new element to insert
+ *
+ * If @old was empty, it will be overwritten.
+ */
+static void list_replace(struct list_head *oldentry,
+ struct list_head *newentry)
+{
+ newentry->next = oldentry->next;
+ newentry->next->prev = newentry;
+ newentry->prev = oldentry->prev;
+ newentry->prev->next = newentry;
+}
+
+static void list_replace_init(struct list_head *oldentry,
+ struct list_head *newentry)
+{
+ list_replace(oldentry, newentry);
+ INIT_LIST_HEAD(oldentry);
+}
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static void list_del_init(struct list_head *entry)
+{
+ __list_del_entry(entry);
+ INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_move - delete from one list and add as another's head
+ * @list: the entry to move
+ * @head: the head that will precede our entry
+ */
+static void list_move(struct list_head *list,
+ struct list_head *head)
+{
+ __list_del_entry(list);
+ list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @list: the entry to move
+ * @head: the head that will follow our entry
+ */
+static void list_move_tail(struct list_head *list,
+ struct list_head *head)
+{
+ __list_del_entry(list);
+ list_add_tail(list, head);
+}
+
+/**
+ * list_is_last - tests whether @list is the last entry in list @head
+ * @list: the entry to test
+ * @head: the head of the list
+ */
+static int list_is_last(const struct list_head *list,
+ const struct list_head *head)
+{
+ return list->next == head;
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static int list_empty(const struct list_head *head)
+{
+ return (head->next == NULL) || (head->next == head);
+}
+
+/**
+ * list_empty_careful - tests whether a list is empty and not being modified
+ * @head: the list to test
+ *
+ * Description:
+ * tests whether a list is empty _and_ checks that no other CPU might be
+ * in the process of modifying either member (next or prev)
+ *
+ * NOTE: using list_empty_careful() without synchronization
+ * can only be safe if the only activity that can happen
+ * to the list entry is list_del_init(). Eg. it cannot be used
+ * if another CPU could re-list_add() it.
+ */
+static int list_empty_careful(const struct list_head *head)
+{
+ struct list_head *next = head->next;
+ return (next == head) && (next == head->prev);
+}
+
+/**
+ * list_rotate_left - rotate the list to the left
+ * @head: the head of the list
+ */
+static void list_rotate_left(struct list_head *head)
+{
+ struct list_head *first;
+
+ if (!list_empty(head)) {
+ first = head->next;
+ list_move_tail(first, head);
+ }
+}
+
+/**
+ * list_is_singular - tests whether a list has just one entry.
+ * @head: the list to test.
+ */
+static int list_is_singular(const struct list_head *head)
+{
+ return !list_empty(head) && (head->next == head->prev);
+}
+
+static void __list_cut_position(struct list_head *list,
+ struct list_head *head,
+ struct list_head *entry)
+{
+ struct list_head *new_first = entry->next;
+ list->next = head->next;
+ list->next->prev = list;
+ list->prev = entry;
+ entry->next = list;
+ head->next = new_first;
+ new_first->prev = head;
+}
+
+/**
+ * list_cut_position - cut a list into two
+ * @list: a new list to add all removed entries
+ * @head: a list with entries
+ * @entry: an entry within head, could be the head itself
+ * and if so we won't cut the list
+ *
+ * This helper moves the initial part of @head, up to and
+ * including @entry, from @head to @list. You should
+ * pass on @entry an element you know is on @head. @list
+ * should be an empty list or a list you do not care about
+ * losing its data.
+ */
+static void list_cut_position(struct list_head *list,
+ struct list_head *head,
+ struct list_head *entry)
+{
+ if (list_empty(head))
+ return;
+ if (list_is_singular(head) &&
+ (head->next != entry && head != entry))
+ return;
+ if (entry == head)
+ INIT_LIST_HEAD(list);
+ else
+ __list_cut_position(list, head, entry);
+}
+
+static void __list_splice(const struct list_head *list,
+ struct list_head *prev,
+ struct list_head *next)
+{
+ struct list_head *first = list->next;
+ struct list_head *last = list->prev;
+
+ first->prev = prev;
+ prev->next = first;
+
+ last->next = next;
+ next->prev = last;
+}
+
+/**
+ * list_splice - join two lists, this is designed for stacks
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static void list_splice(const struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list))
+ __list_splice(list, head, head->next);
+}
+
+/**
+ * list_splice_tail - join two lists, each list being a queue
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static void list_splice_tail(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list))
+ __list_splice(list, head->prev, head);
+}
+
+/**
+ * list_splice_init - join two lists and reinitialise the emptied list.
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * The list at @list is reinitialised
+ */
+static void list_splice_init(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list)) {
+ __list_splice(list, head, head->next);
+ INIT_LIST_HEAD(list);
+ }
+}
+
+/**
+ * list_splice_tail_init - join two lists and reinitialise the emptied list
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * Each of the lists is a queue.
+ * The list at @list is reinitialised
+ */
+static void list_splice_tail_init(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list)) {
+ __list_splice(list, head->prev, head);
+ INIT_LIST_HEAD(list);
+ }
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr: the &struct list_head pointer.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+ containerof(ptr, type, member)
+
+/**
+ * list_first_entry - get the first element from a list
+ * @ptr: the list head to take the element from.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_first_entry(ptr, type, member) \
+ list_entry((ptr)->next, type, member)
+
+/**
+ * list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @head: the head for your list.
+ */
+#define list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * __list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @head: the head for your list.
+ *
+ * This variant doesn't differ from list_for_each() any more.
+ * We don't do prefetching in either case.
+ */
+#define __list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_prev - iterate over a list backwards
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @head: the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+ for (pos = (head)->prev; pos != (head); pos = pos->prev)
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+ for (pos = (head)->next, n = pos->next; pos != (head); \
+ pos = n, n = pos->next)
+
+/**
+ * list_for_each_prev_safe - iterate over a list backwards safe against removal
+ * of list entry
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_prev_safe(pos, n, head) \
+ for (pos = (head)->prev, n = pos->prev; \
+ pos != (head); \
+ pos = n, n = pos->prev)
+
+/**
+ * list_for_each_entry - iterate over list of given type
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_reverse - iterate backwards over list of given type.
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_reverse(pos, head, member) \
+ for (pos = list_entry((head)->prev, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_prepare_entry - prepare a pos entry for use in
+ * list_for_each_entry_continue()
+ * @pos: the type * to use as a start point
+ * @head: the head of the list
+ * @member: the name of the list_struct within the struct.
+ *
+ * Prepares a pos entry for use as a start point in
+ * list_for_each_entry_continue().
+ */
+#define list_prepare_entry(pos, head, member) \
+ ((pos) ? : list_entry(head, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue - continue iteration over list of given type
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Continue to iterate over list of given type, continuing after
+ * the current position.
+ */
+ #define list_for_each_entry_continue(pos, head, member) \
+ for (pos = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue_reverse - iterate backwards from the given point
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Start to iterate over list of given type backwards, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue_reverse(pos, head, member) \
+ for (pos = list_entry(pos->member.prev, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_from - iterate over list of given type from the current
+ * point
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing from current position.
+ */
+#define list_for_each_entry_from(pos, head, member) \
+ for (; &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against
+ * removal of list entry
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_continue - continue list iteration safe against
+ * removal
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing after current point,
+ * safe against removal of list entry.
+ */
+#define list_for_each_entry_safe_continue(pos, n, head, member) \
+ for (pos = list_entry(pos->member.next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_from - iterate over list from current point
+ * safe against removal
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type from current point, safe against
+ * removal of list entry.
+ */
+#define list_for_each_entry_safe_from(pos, n, head, member) \
+ for (n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_reverse - iterate backwards over list safe
+ * against removal
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Iterate backwards over list of given type, safe against removal
+ * of list entry.
+ */
+#define list_for_each_entry_safe_reverse(pos, n, head, member) \
+ for (pos = list_entry((head)->prev, typeof(*pos), member), \
+ n = list_entry(pos->member.prev, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+
+/**
+ * list_safe_reset_next - reset a stale list_for_each_entry_safe loop
+ * @pos: the loop cursor used in the list_for_each_entry_safe loop
+ * @n: temporary storage used in list_for_each_entry_safe
+ * @member: the name of the list_struct within the struct.
+ *
+ * list_safe_reset_next is not safe to use in general if the list may be
+ * modified concurrently (eg. the lock is dropped in the loop body). An
+ * exception to this is if the cursor element (pos) is pinned in the list,
+ * and list_safe_reset_next is called after re-taking the lock and before
+ * completing the current iteration of the loop body.
+ */
+#define list_safe_reset_next(pos, n, member) \
+ n = list_entry(pos->member.next, typeof(*pos), member)
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/bltsville/gcbv/mirror/include/gcreg.h b/bltsville/gcbv/mirror/include/gcreg.h
new file mode 100644
index 0000000..0328c25
--- /dev/null
+++ b/bltsville/gcbv/mirror/include/gcreg.h
@@ -0,0 +1,10269 @@
+/*
+ * Copyright(c) 2012,
+ * Texas Instruments, Inc. and Vivante Corporation.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Vivante Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __gcreg_h
+#define __gcreg_h
+
+/*******************************************************************************
+** Register access macros.
+*/
+
+#define GCREGSTART(reg_field) \
+( \
+ 0 ? reg_field \
+)
+
+#define GCREGEND(reg_field) \
+( \
+ 1 ? reg_field \
+)
+
+#define GCREGSIZE(reg_field) \
+( \
+ GCREGEND(reg_field) - GCREGSTART(reg_field) + 1 \
+)
+
+#define GCREGALIGN(data, reg_field) \
+( \
+ ((unsigned int) (data)) << GCREGSTART(reg_field) \
+)
+
+#define GCREGMASK(reg_field) \
+( \
+ GCREGALIGN(~0UL >> (32 - GCREGSIZE(reg_field)), reg_field) \
+)
+
+#define GCSETFIELDVAL(data, reg, field, value) \
+( \
+ (((unsigned int) (data)) & ~GCREGMASK(reg##_##field)) \
+ | (GCREGALIGN(reg##_##field##_##value, reg##_##field) \
+ & GCREGMASK(reg##_##field)) \
+)
+
+#define GCSETFIELD(data, reg, field, value) \
+( \
+ (((unsigned int) (data)) & ~GCREGMASK(reg##_##field)) \
+ | (GCREGALIGN((unsigned int) (value), reg##_##field) \
+ & GCREGMASK(reg##_##field)) \
+)
+
+#define GCGETFIELD(data, reg, field) \
+( \
+ (((unsigned int) (data)) & GCREGMASK(reg##_##field)) \
+ >> GCREGSTART(reg##_##field) \
+)
+
+#define GCREGVALUE(reg, field, val) \
+( \
+ reg##_##field##_##val \
+)
+
+/*******************************************************************************
+** Register gcregHiClockControl
+*/
+
+#define GCREG_HI_CLOCK_CONTROL_Address 0x00000
+#define GCREG_HI_CLOCK_CONTROL_MSB 15
+#define GCREG_HI_CLOCK_CONTROL_LSB 0
+#define GCREG_HI_CLOCK_CONTROL_BLK 0
+#define GCREG_HI_CLOCK_CONTROL_Count 1
+#define GCREG_HI_CLOCK_CONTROL_FieldMask 0x000A17FE
+#define GCREG_HI_CLOCK_CONTROL_ReadMask 0x000A17FE
+#define GCREG_HI_CLOCK_CONTROL_WriteMask 0x000817FE
+#define GCREG_HI_CLOCK_CONTROL_ResetValue 0x00000100
+
+/* Disable 3D clock. */
+#define GCREG_HI_CLOCK_CONTROL_CLK3D_DIS 0 : 0
+#define GCREG_HI_CLOCK_CONTROL_CLK3D_DIS_End 0
+#define GCREG_HI_CLOCK_CONTROL_CLK3D_DIS_Start 0
+#define GCREG_HI_CLOCK_CONTROL_CLK3D_DIS_Type U01
+
+/* Disable 2D clock. */
+#define GCREG_HI_CLOCK_CONTROL_CLK2D_DIS 1 : 1
+#define GCREG_HI_CLOCK_CONTROL_CLK2D_DIS_End 1
+#define GCREG_HI_CLOCK_CONTROL_CLK2D_DIS_Start 1
+#define GCREG_HI_CLOCK_CONTROL_CLK2D_DIS_Type U01
+
+#define GCREG_HI_CLOCK_CONTROL_FSCALE_VAL 8 : 2
+#define GCREG_HI_CLOCK_CONTROL_FSCALE_VAL_End 8
+#define GCREG_HI_CLOCK_CONTROL_FSCALE_VAL_Start 2
+#define GCREG_HI_CLOCK_CONTROL_FSCALE_VAL_Type U07
+
+#define GCREG_HI_CLOCK_CONTROL_FSCALE_CMD_LOAD 9 : 9
+#define GCREG_HI_CLOCK_CONTROL_FSCALE_CMD_LOAD_End 9
+#define GCREG_HI_CLOCK_CONTROL_FSCALE_CMD_LOAD_Start 9
+#define GCREG_HI_CLOCK_CONTROL_FSCALE_CMD_LOAD_Type U01
+
+/* Disables clock gating for rams. */
+#define GCREG_HI_CLOCK_CONTROL_DISABLE_RAM_CLK_GATING 10 : 10
+#define GCREG_HI_CLOCK_CONTROL_DISABLE_RAM_CLK_GATING_End 10
+#define GCREG_HI_CLOCK_CONTROL_DISABLE_RAM_CLK_GATING_Start 10
+#define GCREG_HI_CLOCK_CONTROL_DISABLE_RAM_CLK_GATING_Type U01
+
+/* Disable debug registers. If this bit is 1, debug regs are clock gated. */
+#define GCREG_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS 11 : 11
+#define GCREG_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS_End 11
+#define GCREG_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS_Start 11
+#define GCREG_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS_Type U01
+
+/* Soft resets the IP. */
+#define GCREG_HI_CLOCK_CONTROL_SOFT_RESET 12 : 12
+#define GCREG_HI_CLOCK_CONTROL_SOFT_RESET_End 12
+#define GCREG_HI_CLOCK_CONTROL_SOFT_RESET_Start 12
+#define GCREG_HI_CLOCK_CONTROL_SOFT_RESET_Type U01
+
+/* 3D pipe is idle. */
+#define GCREG_HI_CLOCK_CONTROL_IDLE_3D 16 : 16
+#define GCREG_HI_CLOCK_CONTROL_IDLE_3D_End 16
+#define GCREG_HI_CLOCK_CONTROL_IDLE_3D_Start 16
+#define GCREG_HI_CLOCK_CONTROL_IDLE_3D_Type U01
+
+/* 2D pipe is idle. */
+#define GCREG_HI_CLOCK_CONTROL_IDLE_2D 17 : 17
+#define GCREG_HI_CLOCK_CONTROL_IDLE_2D_End 17
+#define GCREG_HI_CLOCK_CONTROL_IDLE_2D_Start 17
+#define GCREG_HI_CLOCK_CONTROL_IDLE_2D_Type U01
+
+/* VG pipe is idle. */
+#define GCREG_HI_CLOCK_CONTROL_IDLE_VG 18 : 18
+#define GCREG_HI_CLOCK_CONTROL_IDLE_VG_End 18
+#define GCREG_HI_CLOCK_CONTROL_IDLE_VG_Start 18
+#define GCREG_HI_CLOCK_CONTROL_IDLE_VG_Type U01
+
+/* Isolate GPU bit */
+#define GCREG_HI_CLOCK_CONTROL_ISOLATE_GPU 19 : 19
+#define GCREG_HI_CLOCK_CONTROL_ISOLATE_GPU_End 19
+#define GCREG_HI_CLOCK_CONTROL_ISOLATE_GPU_Start 19
+#define GCREG_HI_CLOCK_CONTROL_ISOLATE_GPU_Type U01
+
+union gcclockcontrol {
+ struct {
+ /* gcregHiClockControl:
+ GCREG_HI_CLOCK_CONTROL_CLK3D_DIS */
+ unsigned int disable3d:1;
+
+ /* gcregHiClockControl:
+ GCREG_HI_CLOCK_CONTROL_CLK2D_DIS */
+ unsigned int disable2d:1;
+
+ /* gcregHiClockControl:
+ GCREG_HI_CLOCK_CONTROL_FSCALE_VAL */
+ unsigned int pulsecount:7;
+
+ /* gcregHiClockControl:
+ GCREG_HI_CLOCK_CONTROL_FSCALE_CMD_LOAD */
+ unsigned int pulseset:1;
+
+ /* gcregHiClockControl:
+ GCREG_HI_CLOCK_CONTROL_DISABLE_RAM_CLK_GATING */
+ unsigned int ramgate:1;
+
+ /* gcregHiClockControl:
+ GCREG_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS */
+ unsigned int disabledbg:1;
+
+ /* gcregHiClockControl:
+ GCREG_HI_CLOCK_CONTROL_SOFT_RESET */
+ unsigned int reset:1;
+
+ /* gcregHiClockControl:
+ reserved */
+ unsigned int _reserved_13_15:3;
+
+ /* gcregHiClockControl:
+ GCREG_HI_CLOCK_CONTROL_IDLE_3D */
+ unsigned int idle3d:1;
+
+ /* gcregHiClockControl:
+ GCREG_HI_CLOCK_CONTROL_IDLE_2D */
+ unsigned int idle2d:1;
+
+ /* gcregHiClockControl:
+ GCREG_HI_CLOCK_CONTROL_IDLE_VG */
+ unsigned int idlevg:1;
+
+ /* gcregHiClockControl:
+ GCREG_HI_CLOCK_CONTROL_ISOLATE_GPU */
+ unsigned int isolate:1;
+
+ /* gcregHiClockControl:
+ reserved */
+ unsigned int _reserved_20_31:12;
+ } reg;
+
+ unsigned int raw;
+};
+
+/*******************************************************************************
+** Register gcregHiIdle
+*/
+
+#define GCREG_HI_IDLE_Address 0x00004
+#define GCREG_HI_IDLE_MSB 15
+#define GCREG_HI_IDLE_LSB 0
+#define GCREG_HI_IDLE_BLK 0
+#define GCREG_HI_IDLE_Count 1
+#define GCREG_HI_IDLE_FieldMask 0x80000007
+#define GCREG_HI_IDLE_ReadMask 0x80000007
+#define GCREG_HI_IDLE_WriteMask 0x00000000
+#define GCREG_HI_IDLE_ResetValue 0x00000007
+
+/* FE is idle. */
+#define GCREG_HI_IDLE_IDLE_FE 0 : 0
+#define GCREG_HI_IDLE_IDLE_FE_End 0
+#define GCREG_HI_IDLE_IDLE_FE_Start 0
+#define GCREG_HI_IDLE_IDLE_FE_Type U01
+
+/* DE is idle. */
+#define GCREG_HI_IDLE_IDLE_DE 1 : 1
+#define GCREG_HI_IDLE_IDLE_DE_End 1
+#define GCREG_HI_IDLE_IDLE_DE_Start 1
+#define GCREG_HI_IDLE_IDLE_DE_Type U01
+
+/* PE is idle. */
+#define GCREG_HI_IDLE_IDLE_PE 2 : 2
+#define GCREG_HI_IDLE_IDLE_PE_End 2
+#define GCREG_HI_IDLE_IDLE_PE_Start 2
+#define GCREG_HI_IDLE_IDLE_PE_Type U01
+
+/* AXI is in low power mode. */
+#define GCREG_HI_IDLE_AXI_LP 31 : 31
+#define GCREG_HI_IDLE_AXI_LP_End 31
+#define GCREG_HI_IDLE_AXI_LP_Start 31
+#define GCREG_HI_IDLE_AXI_LP_Type U01
+
+union gcidle {
+ struct {
+ /* gcregHiIdle: GCREG_HI_IDLE_IDLE_FE */
+ unsigned int fe:1;
+
+ /* gcregHiIdle: GCREG_HI_IDLE_IDLE_DE */
+ unsigned int de:1;
+
+ /* gcregHiIdle: GCREG_HI_IDLE_IDLE_PE */
+ unsigned int pe:1;
+
+ /* gcregHiIdle: reserved */
+ unsigned int _reserved_3_30:28;
+
+ /* gcregHiIdle: GCREG_HI_IDLE_AXI_LP */
+ unsigned int axilp:1;
+ } reg;
+
+ unsigned int raw;
+};
+
+/*******************************************************************************
+** Register gcregAxiConfig
+*/
+
+#define GCREG_AXI_CONFIG_Address 0x00008
+#define GCREG_AXI_CONFIG_MSB 15
+#define GCREG_AXI_CONFIG_LSB 0
+#define GCREG_AXI_CONFIG_BLK 0
+#define GCREG_AXI_CONFIG_Count 1
+#define GCREG_AXI_CONFIG_FieldMask 0x0000FFFF
+#define GCREG_AXI_CONFIG_ReadMask 0x0000FFFF
+#define GCREG_AXI_CONFIG_WriteMask 0x0000FFFF
+#define GCREG_AXI_CONFIG_ResetValue 0x00000000
+
+#define GCREG_AXI_CONFIG_AWID 3 : 0
+#define GCREG_AXI_CONFIG_AWID_End 3
+#define GCREG_AXI_CONFIG_AWID_Start 0
+#define GCREG_AXI_CONFIG_AWID_Type U04
+
+#define GCREG_AXI_CONFIG_ARID 7 : 4
+#define GCREG_AXI_CONFIG_ARID_End 7
+#define GCREG_AXI_CONFIG_ARID_Start 4
+#define GCREG_AXI_CONFIG_ARID_Type U04
+
+#define GCREG_AXI_CONFIG_AWCACHE 11 : 8
+#define GCREG_AXI_CONFIG_AWCACHE_End 11
+#define GCREG_AXI_CONFIG_AWCACHE_Start 8
+#define GCREG_AXI_CONFIG_AWCACHE_Type U04
+
+#define GCREG_AXI_CONFIG_ARCACHE 15 : 12
+#define GCREG_AXI_CONFIG_ARCACHE_End 15
+#define GCREG_AXI_CONFIG_ARCACHE_Start 12
+#define GCREG_AXI_CONFIG_ARCACHE_Type U04
+
+/*******************************************************************************
+** Register gcregAxiStatus
+*/
+
+#define GCREG_AXI_STATUS_Address 0x0000C
+#define GCREG_AXI_STATUS_MSB 15
+#define GCREG_AXI_STATUS_LSB 0
+#define GCREG_AXI_STATUS_BLK 0
+#define GCREG_AXI_STATUS_Count 1
+#define GCREG_AXI_STATUS_FieldMask 0x000003FF
+#define GCREG_AXI_STATUS_ReadMask 0x000003FF
+#define GCREG_AXI_STATUS_WriteMask 0x00000000
+#define GCREG_AXI_STATUS_ResetValue 0x00000000
+
+#define GCREG_AXI_STATUS_DET_RD_ERR 9 : 9
+#define GCREG_AXI_STATUS_DET_RD_ERR_End 9
+#define GCREG_AXI_STATUS_DET_RD_ERR_Start 9
+#define GCREG_AXI_STATUS_DET_RD_ERR_Type U01
+
+#define GCREG_AXI_STATUS_DET_WR_ERR 8 : 8
+#define GCREG_AXI_STATUS_DET_WR_ERR_End 8
+#define GCREG_AXI_STATUS_DET_WR_ERR_Start 8
+#define GCREG_AXI_STATUS_DET_WR_ERR_Type U01
+
+#define GCREG_AXI_STATUS_RD_ERR_ID 7 : 4
+#define GCREG_AXI_STATUS_RD_ERR_ID_End 7
+#define GCREG_AXI_STATUS_RD_ERR_ID_Start 4
+#define GCREG_AXI_STATUS_RD_ERR_ID_Type U04
+
+#define GCREG_AXI_STATUS_WR_ERR_ID 3 : 0
+#define GCREG_AXI_STATUS_WR_ERR_ID_End 3
+#define GCREG_AXI_STATUS_WR_ERR_ID_Start 0
+#define GCREG_AXI_STATUS_WR_ERR_ID_Type U04
+
+/*******************************************************************************
+** Register gcregIntrAcknowledge
+*/
+
+/* Interrupt acknowledge register. Each bit represents a corresponding event
+** being triggered. Reading from this register clears the outstanding interrupt.
+*/
+
+#define GCREG_INTR_ACKNOWLEDGE_Address 0x00010
+#define GCREG_INTR_ACKNOWLEDGE_MSB 15
+#define GCREG_INTR_ACKNOWLEDGE_LSB 0
+#define GCREG_INTR_ACKNOWLEDGE_BLK 0
+#define GCREG_INTR_ACKNOWLEDGE_Count 1
+#define GCREG_INTR_ACKNOWLEDGE_FieldMask 0xFFFFFFFF
+#define GCREG_INTR_ACKNOWLEDGE_ReadMask 0xFFFFFFFF
+#define GCREG_INTR_ACKNOWLEDGE_WriteMask 0x00000000
+#define GCREG_INTR_ACKNOWLEDGE_ResetValue 0x00000000
+
+#define GCREG_INTR_ACKNOWLEDGE_INTR_VEC 31 : 0
+#define GCREG_INTR_ACKNOWLEDGE_INTR_VEC_End 31
+#define GCREG_INTR_ACKNOWLEDGE_INTR_VEC_Start 0
+#define GCREG_INTR_ACKNOWLEDGE_INTR_VEC_Type U32
+
+/*******************************************************************************
+** Register gcregIntrEnbl
+*/
+
+/* Interrupt enable register. Each bit enables a corresponding event. */
+
+#define GCREG_INTR_ENBL_Address 0x00014
+#define GCREG_INTR_ENBL_MSB 15
+#define GCREG_INTR_ENBL_LSB 0
+#define GCREG_INTR_ENBL_BLK 0
+#define GCREG_INTR_ENBL_Count 1
+#define GCREG_INTR_ENBL_FieldMask 0xFFFFFFFF
+#define GCREG_INTR_ENBL_ReadMask 0xFFFFFFFF
+#define GCREG_INTR_ENBL_WriteMask 0xFFFFFFFF
+#define GCREG_INTR_ENBL_ResetValue 0x00000000
+
+#define GCREG_INTR_ENBL_INTR_ENBL_VEC 31 : 0
+#define GCREG_INTR_ENBL_INTR_ENBL_VEC_End 31
+#define GCREG_INTR_ENBL_INTR_ENBL_VEC_Start 0
+#define GCREG_INTR_ENBL_INTR_ENBL_VEC_Type U32
+
+/*******************************************************************************
+** Register GCFeatures
+*/
+
+/* Shows which features are enabled in this chip. This register has no set
+** reset value. It varies with the implementation.
+*/
+
+#define GC_FEATURES_Address 0x0001C
+#define GC_FEATURES_MSB 15
+#define GC_FEATURES_LSB 0
+#define GC_FEATURES_BLK 0
+#define GC_FEATURES_Count 1
+#define GC_FEATURES_FieldMask 0xFFFFFFFF
+#define GC_FEATURES_ReadMask 0xFFFFFFFF
+#define GC_FEATURES_WriteMask 0x00000000
+#define GC_FEATURES_ResetValue 0x00000000
+
+/* Fast clear. */
+#define GC_FEATURES_FAST_CLEAR 0 : 0
+#define GC_FEATURES_FAST_CLEAR_End 0
+#define GC_FEATURES_FAST_CLEAR_Start 0
+#define GC_FEATURES_FAST_CLEAR_Type U01
+#define GC_FEATURES_FAST_CLEAR_NONE 0x0
+#define GC_FEATURES_FAST_CLEAR_AVAILABLE 0x1
+
+/* Full-screen anti-aliasing. */
+#define GC_FEATURES_SPECIAL_ANTI_ALIASING 1 : 1
+#define GC_FEATURES_SPECIAL_ANTI_ALIASING_End 1
+#define GC_FEATURES_SPECIAL_ANTI_ALIASING_Start 1
+#define GC_FEATURES_SPECIAL_ANTI_ALIASING_Type U01
+#define GC_FEATURES_SPECIAL_ANTI_ALIASING_NONE 0x0
+#define GC_FEATURES_SPECIAL_ANTI_ALIASING_AVAILABLE 0x1
+
+/* 3D pipe. */
+#define GC_FEATURES_PIPE_3D 2 : 2
+#define GC_FEATURES_PIPE_3D_End 2
+#define GC_FEATURES_PIPE_3D_Start 2
+#define GC_FEATURES_PIPE_3D_Type U01
+#define GC_FEATURES_PIPE_3D_NONE 0x0
+#define GC_FEATURES_PIPE_3D_AVAILABLE 0x1
+
+/* DXT texture compression. */
+#define GC_FEATURES_DXT_TEXTURE_COMPRESSION 3 : 3
+#define GC_FEATURES_DXT_TEXTURE_COMPRESSION_End 3
+#define GC_FEATURES_DXT_TEXTURE_COMPRESSION_Start 3
+#define GC_FEATURES_DXT_TEXTURE_COMPRESSION_Type U01
+#define GC_FEATURES_DXT_TEXTURE_COMPRESSION_NONE 0x0
+#define GC_FEATURES_DXT_TEXTURE_COMPRESSION_AVAILABLE 0x1
+
+/* Debug registers. */
+#define GC_FEATURES_DEBUG_MODE 4 : 4
+#define GC_FEATURES_DEBUG_MODE_End 4
+#define GC_FEATURES_DEBUG_MODE_Start 4
+#define GC_FEATURES_DEBUG_MODE_Type U01
+#define GC_FEATURES_DEBUG_MODE_NONE 0x0
+#define GC_FEATURES_DEBUG_MODE_AVAILABLE 0x1
+
+/* Depth and color compression. */
+#define GC_FEATURES_ZCOMPRESSION 5 : 5
+#define GC_FEATURES_ZCOMPRESSION_End 5
+#define GC_FEATURES_ZCOMPRESSION_Start 5
+#define GC_FEATURES_ZCOMPRESSION_Type U01
+#define GC_FEATURES_ZCOMPRESSION_NONE 0x0
+#define GC_FEATURES_ZCOMPRESSION_AVAILABLE 0x1
+
+/* YUV 4:2:0 support in filter blit. */
+#define GC_FEATURES_YUV420_FILTER 6 : 6
+#define GC_FEATURES_YUV420_FILTER_End 6
+#define GC_FEATURES_YUV420_FILTER_Start 6
+#define GC_FEATURES_YUV420_FILTER_Type U01
+#define GC_FEATURES_YUV420_FILTER_NONE 0x0
+#define GC_FEATURES_YUV420_FILTER_AVAILABLE 0x1
+
+/* MSAA support. */
+#define GC_FEATURES_MSAA 7 : 7
+#define GC_FEATURES_MSAA_End 7
+#define GC_FEATURES_MSAA_Start 7
+#define GC_FEATURES_MSAA_Type U01
+#define GC_FEATURES_MSAA_NONE 0x0
+#define GC_FEATURES_MSAA_AVAILABLE 0x1
+
+/* Shows if there is a display controller in the IP. */
+#define GC_FEATURES_DC 8 : 8
+#define GC_FEATURES_DC_End 8
+#define GC_FEATURES_DC_Start 8
+#define GC_FEATURES_DC_Type U01
+#define GC_FEATURES_DC_NONE 0x0
+#define GC_FEATURES_DC_AVAILABLE 0x1
+
+/* Shows if there is 2D engine. */
+#define GC_FEATURES_PIPE_2D 9 : 9
+#define GC_FEATURES_PIPE_2D_End 9
+#define GC_FEATURES_PIPE_2D_Start 9
+#define GC_FEATURES_PIPE_2D_Type U01
+#define GC_FEATURES_PIPE_2D_NONE 0x0
+#define GC_FEATURES_PIPE_2D_AVAILABLE 0x1
+
+/* ETC1 texture compression. */
+#define GC_FEATURES_ETC1_TEXTURE_COMPRESSION 10 : 10
+#define GC_FEATURES_ETC1_TEXTURE_COMPRESSION_End 10
+#define GC_FEATURES_ETC1_TEXTURE_COMPRESSION_Start 10
+#define GC_FEATURES_ETC1_TEXTURE_COMPRESSION_Type U01
+#define GC_FEATURES_ETC1_TEXTURE_COMPRESSION_NONE 0x0
+#define GC_FEATURES_ETC1_TEXTURE_COMPRESSION_AVAILABLE 0x1
+
+/* Shows if the IP has HD scaler. */
+#define GC_FEATURES_FAST_SCALER 11 : 11
+#define GC_FEATURES_FAST_SCALER_End 11
+#define GC_FEATURES_FAST_SCALER_Start 11
+#define GC_FEATURES_FAST_SCALER_Type U01
+#define GC_FEATURES_FAST_SCALER_NONE 0x0
+#define GC_FEATURES_FAST_SCALER_AVAILABLE 0x1
+
+/* Shows if the IP has HDR support. */
+#define GC_FEATURES_HIGH_DYNAMIC_RANGE 12 : 12
+#define GC_FEATURES_HIGH_DYNAMIC_RANGE_End 12
+#define GC_FEATURES_HIGH_DYNAMIC_RANGE_Start 12
+#define GC_FEATURES_HIGH_DYNAMIC_RANGE_Type U01
+#define GC_FEATURES_HIGH_DYNAMIC_RANGE_NONE 0x0
+#define GC_FEATURES_HIGH_DYNAMIC_RANGE_AVAILABLE 0x1
+
+/* YUV 4:2:0 tiler is available. */
+#define GC_FEATURES_YUV420_TILER 13 : 13
+#define GC_FEATURES_YUV420_TILER_End 13
+#define GC_FEATURES_YUV420_TILER_Start 13
+#define GC_FEATURES_YUV420_TILER_Type U01
+#define GC_FEATURES_YUV420_TILER_NONE 0x0
+#define GC_FEATURES_YUV420_TILER_AVAILABLE 0x1
+
+/* Second level clock gating is available. */
+#define GC_FEATURES_MODULE_CG 14 : 14
+#define GC_FEATURES_MODULE_CG_End 14
+#define GC_FEATURES_MODULE_CG_Start 14
+#define GC_FEATURES_MODULE_CG_Type U01
+#define GC_FEATURES_MODULE_CG_NONE 0x0
+#define GC_FEATURES_MODULE_CG_AVAILABLE 0x1
+
+/* IP is configured to have minimum area. */
+#define GC_FEATURES_MIN_AREA 15 : 15
+#define GC_FEATURES_MIN_AREA_End 15
+#define GC_FEATURES_MIN_AREA_Start 15
+#define GC_FEATURES_MIN_AREA_Type U01
+#define GC_FEATURES_MIN_AREA_NONE 0x0
+#define GC_FEATURES_MIN_AREA_AVAILABLE 0x1
+
+/* IP does not have early-Z. */
+#define GC_FEATURES_NO_EZ 16 : 16
+#define GC_FEATURES_NO_EZ_End 16
+#define GC_FEATURES_NO_EZ_Start 16
+#define GC_FEATURES_NO_EZ_Type U01
+#define GC_FEATURES_NO_EZ_NONE 0x0
+#define GC_FEATURES_NO_EZ_AVAILABLE 0x1
+
+/* IP does not have 422 texture input format. */
+#define GC_FEATURES_NO422_TEXTURE 17 : 17
+#define GC_FEATURES_NO422_TEXTURE_End 17
+#define GC_FEATURES_NO422_TEXTURE_Start 17
+#define GC_FEATURES_NO422_TEXTURE_Type U01
+#define GC_FEATURES_NO422_TEXTURE_NONE 0x0
+#define GC_FEATURES_NO422_TEXTURE_AVAILABLE 0x1
+
+/* IP supports interleaving depth and color buffers. */
+#define GC_FEATURES_BUFFER_INTERLEAVING 18 : 18
+#define GC_FEATURES_BUFFER_INTERLEAVING_End 18
+#define GC_FEATURES_BUFFER_INTERLEAVING_Start 18
+#define GC_FEATURES_BUFFER_INTERLEAVING_Type U01
+#define GC_FEATURES_BUFFER_INTERLEAVING_NONE 0x0
+#define GC_FEATURES_BUFFER_INTERLEAVING_AVAILABLE 0x1
+
+/* Supports byte write in 2D. */
+#define GC_FEATURES_BYTE_WRITE_2D 19 : 19
+#define GC_FEATURES_BYTE_WRITE_2D_End 19
+#define GC_FEATURES_BYTE_WRITE_2D_Start 19
+#define GC_FEATURES_BYTE_WRITE_2D_Type U01
+#define GC_FEATURES_BYTE_WRITE_2D_NONE 0x0
+#define GC_FEATURES_BYTE_WRITE_2D_AVAILABLE 0x1
+
+/* IP does not have 2D scaler. */
+#define GC_FEATURES_NO_SCALER 20 : 20
+#define GC_FEATURES_NO_SCALER_End 20
+#define GC_FEATURES_NO_SCALER_Start 20
+#define GC_FEATURES_NO_SCALER_Type U01
+#define GC_FEATURES_NO_SCALER_NONE 0x0
+#define GC_FEATURES_NO_SCALER_AVAILABLE 0x1
+
+/* YUY2 averaging support in resolve. */
+#define GC_FEATURES_YUY2_AVERAGING 21 : 21
+#define GC_FEATURES_YUY2_AVERAGING_End 21
+#define GC_FEATURES_YUY2_AVERAGING_Start 21
+#define GC_FEATURES_YUY2_AVERAGING_Type U01
+#define GC_FEATURES_YUY2_AVERAGING_NONE 0x0
+#define GC_FEATURES_YUY2_AVERAGING_AVAILABLE 0x1
+
+/* PE cache is half. */
+#define GC_FEATURES_HALF_PE_CACHE 22 : 22
+#define GC_FEATURES_HALF_PE_CACHE_End 22
+#define GC_FEATURES_HALF_PE_CACHE_Start 22
+#define GC_FEATURES_HALF_PE_CACHE_Type U01
+#define GC_FEATURES_HALF_PE_CACHE_NONE 0x0
+#define GC_FEATURES_HALF_PE_CACHE_AVAILABLE 0x1
+
+/* TX cache is half. */
+#define GC_FEATURES_HALF_TX_CACHE 23 : 23
+#define GC_FEATURES_HALF_TX_CACHE_End 23
+#define GC_FEATURES_HALF_TX_CACHE_Start 23
+#define GC_FEATURES_HALF_TX_CACHE_Type U01
+#define GC_FEATURES_HALF_TX_CACHE_NONE 0x0
+#define GC_FEATURES_HALF_TX_CACHE_AVAILABLE 0x1
+
+/* YUY2 support in PE and YUY2 to RGB conversion in resolve. */
+#define GC_FEATURES_YUY2_RENDER_TARGET 24 : 24
+#define GC_FEATURES_YUY2_RENDER_TARGET_End 24
+#define GC_FEATURES_YUY2_RENDER_TARGET_Start 24
+#define GC_FEATURES_YUY2_RENDER_TARGET_Type U01
+#define GC_FEATURES_YUY2_RENDER_TARGET_NONE 0x0
+#define GC_FEATURES_YUY2_RENDER_TARGET_AVAILABLE 0x1
+
+/* 32 bit memory address support. */
+#define GC_FEATURES_MEM32_BIT_SUPPORT 25 : 25
+#define GC_FEATURES_MEM32_BIT_SUPPORT_End 25
+#define GC_FEATURES_MEM32_BIT_SUPPORT_Start 25
+#define GC_FEATURES_MEM32_BIT_SUPPORT_Type U01
+#define GC_FEATURES_MEM32_BIT_SUPPORT_NONE 0x0
+#define GC_FEATURES_MEM32_BIT_SUPPORT_AVAILABLE 0x1
+
+/* VG pipe is present. */
+#define GC_FEATURES_PIPE_VG 26 : 26
+#define GC_FEATURES_PIPE_VG_End 26
+#define GC_FEATURES_PIPE_VG_Start 26
+#define GC_FEATURES_PIPE_VG_Type U01
+#define GC_FEATURES_PIPE_VG_NONE 0x0
+#define GC_FEATURES_PIPE_VG_AVAILABLE 0x1
+
+/* VG tesselator is present. */
+#define GC_FEATURES_VGTS 27 : 27
+#define GC_FEATURES_VGTS_End 27
+#define GC_FEATURES_VGTS_Start 27
+#define GC_FEATURES_VGTS_Type U01
+#define GC_FEATURES_VGTS_NONE 0x0
+#define GC_FEATURES_VGTS_AVAILABLE 0x1
+
+/* FE 2.0 is present. */
+#define GC_FEATURES_FE20 28 : 28
+#define GC_FEATURES_FE20_End 28
+#define GC_FEATURES_FE20_Start 28
+#define GC_FEATURES_FE20_Type U01
+#define GC_FEATURES_FE20_NONE 0x0
+#define GC_FEATURES_FE20_AVAILABLE 0x1
+
+/* 3D PE has byte write capability. */
+#define GC_FEATURES_BYTE_WRITE_3D 29 : 29
+#define GC_FEATURES_BYTE_WRITE_3D_End 29
+#define GC_FEATURES_BYTE_WRITE_3D_Start 29
+#define GC_FEATURES_BYTE_WRITE_3D_Type U01
+#define GC_FEATURES_BYTE_WRITE_3D_NONE 0x0
+#define GC_FEATURES_BYTE_WRITE_3D_AVAILABLE 0x1
+
+/* Supports resolveing into YUV target. */
+#define GC_FEATURES_RS_YUV_TARGET 30 : 30
+#define GC_FEATURES_RS_YUV_TARGET_End 30
+#define GC_FEATURES_RS_YUV_TARGET_Start 30
+#define GC_FEATURES_RS_YUV_TARGET_Type U01
+#define GC_FEATURES_RS_YUV_TARGET_NONE 0x0
+#define GC_FEATURES_RS_YUV_TARGET_AVAILABLE 0x1
+
+/* Supports 20 bit index. */
+#define GC_FEATURES_FE20_BIT_INDEX 31 : 31
+#define GC_FEATURES_FE20_BIT_INDEX_End 31
+#define GC_FEATURES_FE20_BIT_INDEX_Start 31
+#define GC_FEATURES_FE20_BIT_INDEX_Type U01
+#define GC_FEATURES_FE20_BIT_INDEX_NONE 0x0
+#define GC_FEATURES_FE20_BIT_INDEX_AVAILABLE 0x1
+
+union gcfeatures {
+ struct {
+ /* GC_FEATURES_Address:FAST_CLEAR */
+ unsigned int fastclear:1;
+
+ /* GC_FEATURES_Address:SPECIAL_ANTI_ALIASING */
+ unsigned int specialantialiasing:1;
+
+ /* GC_FEATURES_Address:PIPE_3D */
+ unsigned int pipe3d:1;
+
+ /* GC_FEATURES_Address:DXT_TEXTURE_COMPRESSION */
+ unsigned int dxt:1;
+
+ /* GC_FEATURES_Address:DEBUG_MODE */
+ unsigned int debugmode:1;
+
+ /* GC_FEATURES_Address:ZCOMPRESSION */
+ unsigned int zcompression:1;
+
+ /* GC_FEATURES_Address:YUV420_FILTER */
+ unsigned int yuv420filter:1;
+
+ /* GC_FEATURES_Address:MSAA */
+ unsigned int msaa:1;
+
+ /* GC_FEATURES_Address:DC */
+ unsigned int dc:1;
+
+ /* GC_FEATURES_Address:PIPE_2D */
+ unsigned int pipe2d:1;
+
+ /* GC_FEATURES_Address:ETC1_TEXTURE_COMPRESSION */
+ unsigned int etc:1;
+
+ /* GC_FEATURES_Address:FAST_SCALER */
+ unsigned int fastscaler:1;
+
+ /* GC_FEATURES_Address:HIGH_DYNAMIC_RANGE */
+ unsigned int hdr:1;
+
+ /* GC_FEATURES_Address:YUV420_TILER */
+ unsigned int yuv420tiler:1;
+
+ /* GC_FEATURES_Address:MODULE_CG */
+ unsigned int clockgating:1;
+
+ /* GC_FEATURES_Address:MIN_AREA */
+ unsigned int minarea:1;
+
+ /* GC_FEATURES_Address:NO_EZ */
+ unsigned int noez:1;
+
+ /* GC_FEATURES_Address:NO422_TEXTURE */
+ unsigned int no422texture:1;
+
+ /* GC_FEATURES_Address:BUFFER_INTERLEAVING */
+ unsigned int bufinterleaving:1;
+
+ /* GC_FEATURES_Address:BYTE_WRITE_2D */
+ unsigned int bytewrite2d:1;
+
+ /* GC_FEATURES_Address:NO_SCALER */
+ unsigned int noscaler:1;
+
+ /* GC_FEATURES_Address:YUY2_AVERAGING */
+ unsigned int yuy2averaging:1;
+
+ /* GC_FEATURES_Address:HALF_PE_CACHE */
+ unsigned int halfpecache:1;
+
+ /* GC_FEATURES_Address:HALF_TX_CACHE */
+ unsigned int halftxcache:1;
+
+ /* GC_FEATURES_Address:YUY2_RENDER_TARGET */
+ unsigned int yuy2target:1;
+
+ /* GC_FEATURES_Address:MEM32_BIT_SUPPORT */
+ unsigned int mem32:1;
+
+ /* GC_FEATURES_Address:PIPE_VG */
+ unsigned int pipevg:1;
+
+ /* GC_FEATURES_Address:VGTS */
+ unsigned int vgts:1;
+
+ /* GC_FEATURES_Address:FE20 */
+ unsigned int fe20:1;
+
+ /* GC_FEATURES_Address:BYTE_WRITE_3D */
+ unsigned int bytewrite3d:1;
+
+ /* GC_FEATURES_Address:RS_YUV_TARGET */
+ unsigned int rsyuvtarget:1;
+
+ /* GC_FEATURES_Address:FE20_BIT_INDEX */
+ unsigned int fe20bit:1;
+ } reg;
+
+ unsigned int raw;
+};
+
+/*******************************************************************************
+** Register GCChipId
+*/
+
+/* Shows the ID for the chip in BCD. This register has no set reset value.
+** It varies with the implementation.
+*/
+
+#define GC_CHIP_ID_Address 0x00020
+#define GC_CHIP_ID_MSB 15
+#define GC_CHIP_ID_LSB 0
+#define GC_CHIP_ID_BLK 0
+#define GC_CHIP_ID_Count 1
+#define GC_CHIP_ID_FieldMask 0xFFFFFFFF
+#define GC_CHIP_ID_ReadMask 0xFFFFFFFF
+#define GC_CHIP_ID_WriteMask 0x00000000
+#define GC_CHIP_ID_ResetValue 0x00000000
+
+/* Id. */
+#define GC_CHIP_ID_ID 31 : 0
+#define GC_CHIP_ID_ID_End 31
+#define GC_CHIP_ID_ID_Start 0
+#define GC_CHIP_ID_ID_Type U32
+
+/*******************************************************************************
+** Register GCChipRev
+*/
+
+/* Shows the revision for the chip in BCD. This register has no set reset
+** value. It varies with the implementation.
+*/
+
+#define GC_CHIP_REV_Address 0x00024
+#define GC_CHIP_REV_MSB 15
+#define GC_CHIP_REV_LSB 0
+#define GC_CHIP_REV_BLK 0
+#define GC_CHIP_REV_Count 1
+#define GC_CHIP_REV_FieldMask 0xFFFFFFFF
+#define GC_CHIP_REV_ReadMask 0xFFFFFFFF
+#define GC_CHIP_REV_WriteMask 0x00000000
+#define GC_CHIP_REV_ResetValue 0x00000000
+
+/* Revision. */
+#define GC_CHIP_REV_REV 31 : 0
+#define GC_CHIP_REV_REV_End 31
+#define GC_CHIP_REV_REV_Start 0
+#define GC_CHIP_REV_REV_Type U32
+
+/*******************************************************************************
+** Register GCChipDate
+*/
+
+/* Shows the release date for the IP. This register has no set reset value.
+** It varies with the implementation.
+*/
+
+#define GC_CHIP_DATE_Address 0x00028
+#define GC_CHIP_DATE_MSB 15
+#define GC_CHIP_DATE_LSB 0
+#define GC_CHIP_DATE_BLK 0
+#define GC_CHIP_DATE_Count 1
+#define GC_CHIP_DATE_FieldMask 0xFFFFFFFF
+#define GC_CHIP_DATE_ReadMask 0xFFFFFFFF
+#define GC_CHIP_DATE_WriteMask 0x00000000
+#define GC_CHIP_DATE_ResetValue 0x00000000
+
+/* Date. */
+#define GC_CHIP_DATE_DATE 31 : 0
+#define GC_CHIP_DATE_DATE_End 31
+#define GC_CHIP_DATE_DATE_Start 0
+#define GC_CHIP_DATE_DATE_Type U32
+
+/*******************************************************************************
+** Register GCChipTime
+*/
+
+/* Shows the release time for the IP. This register has no set reset value.
+** It varies with the implementation.
+*/
+
+#define GC_CHIP_TIME_Address 0x0002C
+#define GC_CHIP_TIME_MSB 15
+#define GC_CHIP_TIME_LSB 0
+#define GC_CHIP_TIME_BLK 0
+#define GC_CHIP_TIME_Count 1
+#define GC_CHIP_TIME_FieldMask 0xFFFFFFFF
+#define GC_CHIP_TIME_ReadMask 0xFFFFFFFF
+#define GC_CHIP_TIME_WriteMask 0x00000000
+#define GC_CHIP_TIME_ResetValue 0x00000000
+
+/* Time. */
+#define GC_CHIP_TIME_TIME 31 : 0
+#define GC_CHIP_TIME_TIME_End 31
+#define GC_CHIP_TIME_TIME_Start 0
+#define GC_CHIP_TIME_TIME_Type U32
+
+/*******************************************************************************
+** Register GCMinorFeatures0
+*/
+
+/* Shows which minor features are enabled in this chip. This register has no
+** set reset value. It varies with the implementation.
+*/
+
+#define GC_FEATURES0_Address 0x00034
+#define GC_FEATURES0_MSB 15
+#define GC_FEATURES0_LSB 0
+#define GC_FEATURES0_BLK 0
+#define GC_FEATURES0_Count 1
+#define GC_FEATURES0_FieldMask 0xFFFFFFFF
+#define GC_FEATURES0_ReadMask 0xFFFFFFFF
+#define GC_FEATURES0_WriteMask 0x00000000
+#define GC_FEATURES0_ResetValue 0x00000000
+
+/* Y flipping capability is added to resolve. */
+#define GC_FEATURES0_FLIP_Y 0 : 0
+#define GC_FEATURES0_FLIP_Y_End 0
+#define GC_FEATURES0_FLIP_Y_Start 0
+#define GC_FEATURES0_FLIP_Y_Type U01
+#define GC_FEATURES0_FLIP_Y_NONE 0x0
+#define GC_FEATURES0_FLIP_Y_AVAILABLE 0x1
+
+/* Dual Return Bus from HI to clients. */
+#define GC_FEATURES0_DUAL_RETURN_BUS 1 : 1
+#define GC_FEATURES0_DUAL_RETURN_BUS_End 1
+#define GC_FEATURES0_DUAL_RETURN_BUS_Start 1
+#define GC_FEATURES0_DUAL_RETURN_BUS_Type U01
+#define GC_FEATURES0_DUAL_RETURN_BUS_NONE 0x0
+#define GC_FEATURES0_DUAL_RETURN_BUS_AVAILABLE 0x1
+
+/* Configurable endianness support. */
+#define GC_FEATURES0_ENDIANNESS_CONFIG 2 : 2
+#define GC_FEATURES0_ENDIANNESS_CONFIG_End 2
+#define GC_FEATURES0_ENDIANNESS_CONFIG_Start 2
+#define GC_FEATURES0_ENDIANNESS_CONFIG_Type U01
+#define GC_FEATURES0_ENDIANNESS_CONFIG_NONE 0x0
+#define GC_FEATURES0_ENDIANNESS_CONFIG_AVAILABLE 0x1
+
+/* Supports 8Kx8K textures. */
+#define GC_FEATURES0_TEXTURE8_K 3 : 3
+#define GC_FEATURES0_TEXTURE8_K_End 3
+#define GC_FEATURES0_TEXTURE8_K_Start 3
+#define GC_FEATURES0_TEXTURE8_K_Type U01
+#define GC_FEATURES0_TEXTURE8_K_NONE 0x0
+#define GC_FEATURES0_TEXTURE8_K_AVAILABLE 0x1
+
+/* Driver hack is not needed. */
+#define GC_FEATURES0_CORRECT_TEXTURE_CONVERTER 4 : 4
+#define GC_FEATURES0_CORRECT_TEXTURE_CONVERTER_End 4
+#define GC_FEATURES0_CORRECT_TEXTURE_CONVERTER_Start 4
+#define GC_FEATURES0_CORRECT_TEXTURE_CONVERTER_Type U01
+#define GC_FEATURES0_CORRECT_TEXTURE_CONVERTER_NONE 0x0
+#define GC_FEATURES0_CORRECT_TEXTURE_CONVERTER_AVAILABLE 0x1
+
+/* Special LOD calculation when MSAA is on. */
+#define GC_FEATURES0_SPECIAL_MSAA_LOD 5 : 5
+#define GC_FEATURES0_SPECIAL_MSAA_LOD_End 5
+#define GC_FEATURES0_SPECIAL_MSAA_LOD_Start 5
+#define GC_FEATURES0_SPECIAL_MSAA_LOD_Type U01
+#define GC_FEATURES0_SPECIAL_MSAA_LOD_NONE 0x0
+#define GC_FEATURES0_SPECIAL_MSAA_LOD_AVAILABLE 0x1
+
+/* Proper flush is done in fast clear cache. */
+#define GC_FEATURES0_FAST_CLEAR_FLUSH 6 : 6
+#define GC_FEATURES0_FAST_CLEAR_FLUSH_End 6
+#define GC_FEATURES0_FAST_CLEAR_FLUSH_Start 6
+#define GC_FEATURES0_FAST_CLEAR_FLUSH_Type U01
+#define GC_FEATURES0_FAST_CLEAR_FLUSH_NONE 0x0
+#define GC_FEATURES0_FAST_CLEAR_FLUSH_AVAILABLE 0x1
+
+/* 2D PE 2.0 is present. */
+#define GC_FEATURES0_2DPE20 7 : 7
+#define GC_FEATURES0_2DPE20_End 7
+#define GC_FEATURES0_2DPE20_Start 7
+#define GC_FEATURES0_2DPE20_Type U01
+#define GC_FEATURES0_2DPE20_NONE 0x0
+#define GC_FEATURES0_2DPE20_AVAILABLE 0x1
+
+/* Reserved. */
+#define GC_FEATURES0_CORRECT_AUTO_DISABLE 8 : 8
+#define GC_FEATURES0_CORRECT_AUTO_DISABLE_End 8
+#define GC_FEATURES0_CORRECT_AUTO_DISABLE_Start 8
+#define GC_FEATURES0_CORRECT_AUTO_DISABLE_Type U01
+#define GC_FEATURES0_CORRECT_AUTO_DISABLE_NONE 0x0
+#define GC_FEATURES0_CORRECT_AUTO_DISABLE_AVAILABLE 0x1
+
+/* Supports 8K render target. */
+#define GC_FEATURES0_RENDER_8K 9 : 9
+#define GC_FEATURES0_RENDER_8K_End 9
+#define GC_FEATURES0_RENDER_8K_Start 9
+#define GC_FEATURES0_RENDER_8K_Type U01
+#define GC_FEATURES0_RENDER_8K_NONE 0x0
+#define GC_FEATURES0_RENDER_8K_AVAILABLE 0x1
+
+/* 2 bits are used instead of 4 bits for tile status. */
+#define GC_FEATURES0_TILE_STATUS_2BITS 10 : 10
+#define GC_FEATURES0_TILE_STATUS_2BITS_End 10
+#define GC_FEATURES0_TILE_STATUS_2BITS_Start 10
+#define GC_FEATURES0_TILE_STATUS_2BITS_Type U01
+#define GC_FEATURES0_TILE_STATUS_2BITS_NONE 0x0
+#define GC_FEATURES0_TILE_STATUS_2BITS_AVAILABLE 0x1
+
+/* Use 2 separate tile status buffers in interleaved mode. */
+#define GC_FEATURES0_SEPARATE_TILE_STATUS_WHEN_INTERLEAVED 11 : 11
+#define GC_FEATURES0_SEPARATE_TILE_STATUS_WHEN_INTERLEAVED_End 11
+#define GC_FEATURES0_SEPARATE_TILE_STATUS_WHEN_INTERLEAVED_Start 11
+#define GC_FEATURES0_SEPARATE_TILE_STATUS_WHEN_INTERLEAVED_Type U01
+#define GC_FEATURES0_SEPARATE_TILE_STATUS_WHEN_INTERLEAVED_NONE 0x0
+#define GC_FEATURES0_SEPARATE_TILE_STATUS_WHEN_INTERLEAVED_AVAILABLE 0x1
+
+/* 32x32 super tile is available. */
+#define GC_FEATURES0_SUPER_TILED_32X32 12 : 12
+#define GC_FEATURES0_SUPER_TILED_32X32_End 12
+#define GC_FEATURES0_SUPER_TILED_32X32_Start 12
+#define GC_FEATURES0_SUPER_TILED_32X32_Type U01
+#define GC_FEATURES0_SUPER_TILED_32X32_NONE 0x0
+#define GC_FEATURES0_SUPER_TILED_32X32_AVAILABLE 0x1
+
+/* Major updates to VG pipe (TS buffer tiling. State masking.). */
+#define GC_FEATURES0_VG_20 13 : 13
+#define GC_FEATURES0_VG_20_End 13
+#define GC_FEATURES0_VG_20_Start 13
+#define GC_FEATURES0_VG_20_Type U01
+#define GC_FEATURES0_VG_20_NONE 0x0
+#define GC_FEATURES0_VG_20_AVAILABLE 0x1
+
+/* New commands added to the tessellator. */
+#define GC_FEATURES0_TS_EXTENDED_COMMANDS 14 : 14
+#define GC_FEATURES0_TS_EXTENDED_COMMANDS_End 14
+#define GC_FEATURES0_TS_EXTENDED_COMMANDS_Start 14
+#define GC_FEATURES0_TS_EXTENDED_COMMANDS_Type U01
+#define GC_FEATURES0_TS_EXTENDED_COMMANDS_NONE 0x0
+#define GC_FEATURES0_TS_EXTENDED_COMMANDS_AVAILABLE 0x1
+
+/* If this bit is not set, the FIFO counter should be set to 50. Else, the **
+** default should remain. */
+#define GC_FEATURES0_COMPRESSION_FIFO_FIXED 15 : 15
+#define GC_FEATURES0_COMPRESSION_FIFO_FIXED_End 15
+#define GC_FEATURES0_COMPRESSION_FIFO_FIXED_Start 15
+#define GC_FEATURES0_COMPRESSION_FIFO_FIXED_Type U01
+#define GC_FEATURES0_COMPRESSION_FIFO_FIXED_NONE 0x0
+#define GC_FEATURES0_COMPRESSION_FIFO_FIXED_AVAILABLE 0x1
+
+/* Floor, ceil, and sign instructions are available. */
+#define GC_FEATURES0_EXTRA_SHADER_INSTRUCTIONS0 16 : 16
+#define GC_FEATURES0_EXTRA_SHADER_INSTRUCTIONS0_End 16
+#define GC_FEATURES0_EXTRA_SHADER_INSTRUCTIONS0_Start 16
+#define GC_FEATURES0_EXTRA_SHADER_INSTRUCTIONS0_Type U01
+#define GC_FEATURES0_EXTRA_SHADER_INSTRUCTIONS0_NONE 0x0
+#define GC_FEATURES0_EXTRA_SHADER_INSTRUCTIONS0_AVAILABLE 0x1
+
+/* VG filter is available. */
+#define GC_FEATURES0_VG_FILTER 17 : 17
+#define GC_FEATURES0_VG_FILTER_End 17
+#define GC_FEATURES0_VG_FILTER_Start 17
+#define GC_FEATURES0_VG_FILTER_Type U01
+#define GC_FEATURES0_VG_FILTER_NONE 0x0
+#define GC_FEATURES0_VG_FILTER_AVAILABLE 0x1
+
+/* Minor updates to VG pipe (Event generation from VG, TS, PE). Tiled image **
+** support. */
+#define GC_FEATURES0_VG_21 18 : 18
+#define GC_FEATURES0_VG_21_End 18
+#define GC_FEATURES0_VG_21_Start 18
+#define GC_FEATURES0_VG_21_Type U01
+#define GC_FEATURES0_VG_21_NONE 0x0
+#define GC_FEATURES0_VG_21_AVAILABLE 0x1
+
+/* W is sent to SH from RA. */
+#define GC_FEATURES0_SHADER_GETS_W 19 : 19
+#define GC_FEATURES0_SHADER_GETS_W_End 19
+#define GC_FEATURES0_SHADER_GETS_W_Start 19
+#define GC_FEATURES0_SHADER_GETS_W_Type U01
+#define GC_FEATURES0_SHADER_GETS_W_NONE 0x0
+#define GC_FEATURES0_SHADER_GETS_W_AVAILABLE 0x1
+
+/* Sqrt, sin, cos instructions are available. */
+#define GC_FEATURES0_EXTRA_SHADER_INSTRUCTIONS1 20 : 20
+#define GC_FEATURES0_EXTRA_SHADER_INSTRUCTIONS1_End 20
+#define GC_FEATURES0_EXTRA_SHADER_INSTRUCTIONS1_Start 20
+#define GC_FEATURES0_EXTRA_SHADER_INSTRUCTIONS1_Type U01
+#define GC_FEATURES0_EXTRA_SHADER_INSTRUCTIONS1_NONE 0x0
+#define GC_FEATURES0_EXTRA_SHADER_INSTRUCTIONS1_AVAILABLE 0x1
+
+/* Unavailable registers will return 0. */
+#define GC_FEATURES0_DEFAULT_REG0 21 : 21
+#define GC_FEATURES0_DEFAULT_REG0_End 21
+#define GC_FEATURES0_DEFAULT_REG0_Start 21
+#define GC_FEATURES0_DEFAULT_REG0_Type U01
+#define GC_FEATURES0_DEFAULT_REG0_NONE 0x0
+#define GC_FEATURES0_DEFAULT_REG0_AVAILABLE 0x1
+
+/* New style MC with separate paths for color and depth. */
+#define GC_FEATURES0_MC_20 22 : 22
+#define GC_FEATURES0_MC_20_End 22
+#define GC_FEATURES0_MC_20_Start 22
+#define GC_FEATURES0_MC_20_Type U01
+#define GC_FEATURES0_MC_20_NONE 0x0
+#define GC_FEATURES0_MC_20_AVAILABLE 0x1
+
+/* Put the MSAA data into sideband fifo. */
+#define GC_FEATURES0_SHADER_MSAA_SIDEBAND 23 : 23
+#define GC_FEATURES0_SHADER_MSAA_SIDEBAND_End 23
+#define GC_FEATURES0_SHADER_MSAA_SIDEBAND_Start 23
+#define GC_FEATURES0_SHADER_MSAA_SIDEBAND_Type U01
+#define GC_FEATURES0_SHADER_MSAA_SIDEBAND_NONE 0x0
+#define GC_FEATURES0_SHADER_MSAA_SIDEBAND_AVAILABLE 0x1
+
+#define GC_FEATURES0_BUG_FIXES0 24 : 24
+#define GC_FEATURES0_BUG_FIXES0_End 24
+#define GC_FEATURES0_BUG_FIXES0_Start 24
+#define GC_FEATURES0_BUG_FIXES0_Type U01
+#define GC_FEATURES0_BUG_FIXES0_NONE 0x0
+#define GC_FEATURES0_BUG_FIXES0_AVAILABLE 0x1
+
+/* VAA is available or not. */
+#define GC_FEATURES0_VAA 25 : 25
+#define GC_FEATURES0_VAA_End 25
+#define GC_FEATURES0_VAA_Start 25
+#define GC_FEATURES0_VAA_Type U01
+#define GC_FEATURES0_VAA_NONE 0x0
+#define GC_FEATURES0_VAA_AVAILABLE 0x1
+
+/* Shader supports bypass mode when MSAA is enabled. */
+#define GC_FEATURES0_BYPASS_IN_MSAA 26 : 26
+#define GC_FEATURES0_BYPASS_IN_MSAA_End 26
+#define GC_FEATURES0_BYPASS_IN_MSAA_Start 26
+#define GC_FEATURES0_BYPASS_IN_MSAA_Type U01
+#define GC_FEATURES0_BYPASS_IN_MSAA_NONE 0x0
+#define GC_FEATURES0_BYPASS_IN_MSAA_AVAILABLE 0x1
+
+/* Hierarchiccal Z is supported. */
+#define GC_FEATURES0_HIERARCHICAL_Z 27 : 27
+#define GC_FEATURES0_HIERARCHICAL_Z_End 27
+#define GC_FEATURES0_HIERARCHICAL_Z_Start 27
+#define GC_FEATURES0_HIERARCHICAL_Z_Type U01
+#define GC_FEATURES0_HIERARCHICAL_Z_NONE 0x0
+#define GC_FEATURES0_HIERARCHICAL_Z_AVAILABLE 0x1
+
+/* New texture unit is available. */
+#define GC_FEATURES0_NEW_TEXTURE 28 : 28
+#define GC_FEATURES0_NEW_TEXTURE_End 28
+#define GC_FEATURES0_NEW_TEXTURE_Start 28
+#define GC_FEATURES0_NEW_TEXTURE_Type U01
+#define GC_FEATURES0_NEW_TEXTURE_NONE 0x0
+#define GC_FEATURES0_NEW_TEXTURE_AVAILABLE 0x1
+
+/* 2D engine supports A8 target. */
+#define GC_FEATURES0_A8_TARGET_SUPPORT 29 : 29
+#define GC_FEATURES0_A8_TARGET_SUPPORT_End 29
+#define GC_FEATURES0_A8_TARGET_SUPPORT_Start 29
+#define GC_FEATURES0_A8_TARGET_SUPPORT_Type U01
+#define GC_FEATURES0_A8_TARGET_SUPPORT_NONE 0x0
+#define GC_FEATURES0_A8_TARGET_SUPPORT_AVAILABLE 0x1
+
+/* Correct stencil behavior in depth only. */
+#define GC_FEATURES0_CORRECT_STENCIL 30 : 30
+#define GC_FEATURES0_CORRECT_STENCIL_End 30
+#define GC_FEATURES0_CORRECT_STENCIL_Start 30
+#define GC_FEATURES0_CORRECT_STENCIL_Type U01
+#define GC_FEATURES0_CORRECT_STENCIL_NONE 0x0
+#define GC_FEATURES0_CORRECT_STENCIL_AVAILABLE 0x1
+
+/* Enhance VR and add a mode to walk 16 pixels in 16-bit mode in Vertical **
+** pass to improve $ hit rate when rotating 90/270. */
+#define GC_FEATURES0_ENHANCE_VR 31 : 31
+#define GC_FEATURES0_ENHANCE_VR_End 31
+#define GC_FEATURES0_ENHANCE_VR_Start 31
+#define GC_FEATURES0_ENHANCE_VR_Type U01
+#define GC_FEATURES0_ENHANCE_VR_NONE 0x0
+#define GC_FEATURES0_ENHANCE_VR_AVAILABLE 0x1
+
+union gcfeatures0 {
+ struct {
+ /* GC_FEATURES0_Address:FLIP_Y */
+ unsigned int flipy:1;
+
+ /* GC_FEATURES0_Address:DUAL_RETURN_BUS */
+ unsigned int dualreturnbus:1;
+
+ /* GC_FEATURES0_Address:ENDIANNESS_CONFIG */
+ unsigned int endianessconfig:1;
+
+ /* GC_FEATURES0_Address:TEXTURE8_K */
+ unsigned int texture8k:1;
+
+ /* GC_FEATURES0_Address:CORRECT_TEXTURE_CONVERTER */
+ unsigned int correcttextureconverter:1;
+
+ /* GC_FEATURES0_Address:SPECIAL_MSAA_LOD */
+ unsigned int specialmsaalod:1;
+
+ /* GC_FEATURES0_Address:FAST_CLEAR_FLUSH */
+ unsigned int fastclearflush:1;
+
+ /* GC_FEATURES0_Address:2DPE20 */
+ unsigned int pe2d20:1;
+
+ /* GC_FEATURES0_Address:CORRECT_AUTO_DISABLE */
+ unsigned int correctautodisable:1;
+
+ /* GC_FEATURES0_Address:RENDER_8K */
+ unsigned int render8k:1;
+
+ /* GC_FEATURES0_Address:TILE_STATUS_2BITS */
+ unsigned int tilestatus2bits:1;
+
+ /* GC_FEATURES0_Address:SEPARATE_TILE_STATUS_WHEN_INTERLEAVED */
+ unsigned int separatetilestatus:1;
+
+ /* GC_FEATURES0_Address:SUPER_TILED_32X32 */
+ unsigned int supertiled32x32:1;
+
+ /* GC_FEATURES0_Address:VG_20 */
+ unsigned int vg20:1;
+
+ /* GC_FEATURES0_Address:TS_EXTENDED_COMMANDS */
+ unsigned int tsplus:1;
+
+ /* GC_FEATURES0_Address:COMPRESSION_FIFO_FIXED */
+ unsigned int compressionfifo:1;
+
+ /* GC_FEATURES0_Address:EXTRA_SHADER_INSTRUCTIONS0 */
+ unsigned int shaderinst0:1;
+
+ /* GC_FEATURES0_Address:VG_FILTER */
+ unsigned int vgfilter:1;
+
+ /* GC_FEATURES0_Address:VG_21 */
+ unsigned int vg21:1;
+
+ /* GC_FEATURES0_Address:SHADER_GETS_W */
+ unsigned int shadergetsw:1;
+
+ /* GC_FEATURES0_Address:EXTRA_SHADER_INSTRUCTIONS1 */
+ unsigned int shaderinst1:1;
+
+ /* GC_FEATURES0_Address:DEFAULT_REG0 */
+ unsigned int defaultreg0:1;
+
+ /* GC_FEATURES0_Address:MC_20 */
+ unsigned int mc20:1;
+
+ /* GC_FEATURES0_Address:SHADER_MSAA_SIDEBAND */
+ unsigned int shadermsaasideband:1;
+
+ /* GC_FEATURES0_Address:BUG_FIXES0 */
+ unsigned int bugfixes0:1;
+
+ /* GC_FEATURES0_Address:VAA */
+ unsigned int vaa:1;
+
+ /* GC_FEATURES0_Address:BYPASS_IN_MSAA */
+ unsigned int bypassmsaa:1;
+
+ /* GC_FEATURES0_Address:HIERARCHICAL_Z */
+ unsigned int hz:1;
+
+ /* GC_FEATURES0_Address:NEW_TEXTURE */
+ unsigned int newtx:1;
+
+ /* GC_FEATURES0_Address:A8_TARGET_SUPPORT */
+ unsigned int a8target:1;
+
+ /* GC_FEATURES0_Address:CORRECT_STENCIL */
+ unsigned int correctstencil:1;
+
+ /* GC_FEATURES0_Address:ENHANCE_VR */
+ unsigned int vr20:1;
+ } reg;
+
+ unsigned int raw;
+};
+
+/*******************************************************************************
+** Register GCMinorFeatures1
+*/
+
+/* Shows which features are enabled in this chip. This register has no set
+** reset value. It varies with the implementation.
+*/
+
+#define GC_FEATURES1_Address 0x00074
+#define GC_FEATURES1_MSB 15
+#define GC_FEATURES1_LSB 0
+#define GC_FEATURES1_BLK 0
+#define GC_FEATURES1_Count 1
+#define GC_FEATURES1_FieldMask 0xFFFFFFFF
+#define GC_FEATURES1_ReadMask 0xFFFFFFFF
+#define GC_FEATURES1_WriteMask 0x00000000
+#define GC_FEATURES1_ResetValue 0x00000000
+
+/* Resolve UV swizzle. */
+#define GC_FEATURES1_RSUV_SWIZZLE 0 : 0
+#define GC_FEATURES1_RSUV_SWIZZLE_End 0
+#define GC_FEATURES1_RSUV_SWIZZLE_Start 0
+#define GC_FEATURES1_RSUV_SWIZZLE_Type U01
+#define GC_FEATURES1_RSUV_SWIZZLE_NONE 0x0
+#define GC_FEATURES1_RSUV_SWIZZLE_AVAILABLE 0x1
+
+/* V2 compression. */
+#define GC_FEATURES1_V2_COMPRESSION 1 : 1
+#define GC_FEATURES1_V2_COMPRESSION_End 1
+#define GC_FEATURES1_V2_COMPRESSION_Start 1
+#define GC_FEATURES1_V2_COMPRESSION_Type U01
+#define GC_FEATURES1_V2_COMPRESSION_NONE 0x0
+#define GC_FEATURES1_V2_COMPRESSION_AVAILABLE 0x1
+
+/* Double buffering support for VG (second TS-->VG semaphore is present). */
+#define GC_FEATURES1_VG_DOUBLE_BUFFER 2 : 2
+#define GC_FEATURES1_VG_DOUBLE_BUFFER_End 2
+#define GC_FEATURES1_VG_DOUBLE_BUFFER_Start 2
+#define GC_FEATURES1_VG_DOUBLE_BUFFER_Type U01
+#define GC_FEATURES1_VG_DOUBLE_BUFFER_NONE 0x0
+#define GC_FEATURES1_VG_DOUBLE_BUFFER_AVAILABLE 0x1
+
+#define GC_FEATURES1_BUG_FIXES1 3 : 3
+#define GC_FEATURES1_BUG_FIXES1_End 3
+#define GC_FEATURES1_BUG_FIXES1_Start 3
+#define GC_FEATURES1_BUG_FIXES1_Type U01
+#define GC_FEATURES1_BUG_FIXES1_NONE 0x0
+#define GC_FEATURES1_BUG_FIXES1_AVAILABLE 0x1
+
+#define GC_FEATURES1_BUG_FIXES2 4 : 4
+#define GC_FEATURES1_BUG_FIXES2_End 4
+#define GC_FEATURES1_BUG_FIXES2_Start 4
+#define GC_FEATURES1_BUG_FIXES2_Type U01
+#define GC_FEATURES1_BUG_FIXES2_NONE 0x0
+#define GC_FEATURES1_BUG_FIXES2_AVAILABLE 0x1
+
+/* Texture has stride and memory addressing. */
+#define GC_FEATURES1_TEXTURE_STRIDE 5 : 5
+#define GC_FEATURES1_TEXTURE_STRIDE_End 5
+#define GC_FEATURES1_TEXTURE_STRIDE_Start 5
+#define GC_FEATURES1_TEXTURE_STRIDE_Type U01
+#define GC_FEATURES1_TEXTURE_STRIDE_NONE 0x0
+#define GC_FEATURES1_TEXTURE_STRIDE_AVAILABLE 0x1
+
+#define GC_FEATURES1_BUG_FIXES3 6 : 6
+#define GC_FEATURES1_BUG_FIXES3_End 6
+#define GC_FEATURES1_BUG_FIXES3_Start 6
+#define GC_FEATURES1_BUG_FIXES3_Type U01
+#define GC_FEATURES1_BUG_FIXES3_NONE 0x0
+#define GC_FEATURES1_BUG_FIXES3_AVAILABLE 0x1
+
+#define GC_FEATURES1_CORRECT_AUTO_DISABLE 7 : 7
+#define GC_FEATURES1_CORRECT_AUTO_DISABLE_End 7
+#define GC_FEATURES1_CORRECT_AUTO_DISABLE_Start 7
+#define GC_FEATURES1_CORRECT_AUTO_DISABLE_Type U01
+#define GC_FEATURES1_CORRECT_AUTO_DISABLE_NONE 0x0
+#define GC_FEATURES1_CORRECT_AUTO_DISABLE_AVAILABLE 0x1
+
+#define GC_FEATURES1_AUTO_RESTART_TS 8 : 8
+#define GC_FEATURES1_AUTO_RESTART_TS_End 8
+#define GC_FEATURES1_AUTO_RESTART_TS_Start 8
+#define GC_FEATURES1_AUTO_RESTART_TS_Type U01
+#define GC_FEATURES1_AUTO_RESTART_TS_NONE 0x0
+#define GC_FEATURES1_AUTO_RESTART_TS_AVAILABLE 0x1
+
+#define GC_FEATURES1_BUG_FIXES4 9 : 9
+#define GC_FEATURES1_BUG_FIXES4_End 9
+#define GC_FEATURES1_BUG_FIXES4_Start 9
+#define GC_FEATURES1_BUG_FIXES4_Type U01
+#define GC_FEATURES1_BUG_FIXES4_NONE 0x0
+#define GC_FEATURES1_BUG_FIXES4_AVAILABLE 0x1
+
+#define GC_FEATURES1_L2_WINDOWING 10 : 10
+#define GC_FEATURES1_L2_WINDOWING_End 10
+#define GC_FEATURES1_L2_WINDOWING_Start 10
+#define GC_FEATURES1_L2_WINDOWING_Type U01
+#define GC_FEATURES1_L2_WINDOWING_NONE 0x0
+#define GC_FEATURES1_L2_WINDOWING_AVAILABLE 0x1
+
+#define GC_FEATURES1_HALF_FLOAT_PIPE 11 : 11
+#define GC_FEATURES1_HALF_FLOAT_PIPE_End 11
+#define GC_FEATURES1_HALF_FLOAT_PIPE_Start 11
+#define GC_FEATURES1_HALF_FLOAT_PIPE_Type U01
+#define GC_FEATURES1_HALF_FLOAT_PIPE_NONE 0x0
+#define GC_FEATURES1_HALF_FLOAT_PIPE_AVAILABLE 0x1
+
+#define GC_FEATURES1_PIXEL_DITHER 12 : 12
+#define GC_FEATURES1_PIXEL_DITHER_End 12
+#define GC_FEATURES1_PIXEL_DITHER_Start 12
+#define GC_FEATURES1_PIXEL_DITHER_Type U01
+#define GC_FEATURES1_PIXEL_DITHER_NONE 0x0
+#define GC_FEATURES1_PIXEL_DITHER_AVAILABLE 0x1
+
+#define GC_FEATURES1_TWO_STENCIL_REFERENCE 13 : 13
+#define GC_FEATURES1_TWO_STENCIL_REFERENCE_End 13
+#define GC_FEATURES1_TWO_STENCIL_REFERENCE_Start 13
+#define GC_FEATURES1_TWO_STENCIL_REFERENCE_Type U01
+#define GC_FEATURES1_TWO_STENCIL_REFERENCE_NONE 0x0
+#define GC_FEATURES1_TWO_STENCIL_REFERENCE_AVAILABLE 0x1
+
+#define GC_FEATURES1_EXTENDED_PIXEL_FORMAT 14 : 14
+#define GC_FEATURES1_EXTENDED_PIXEL_FORMAT_End 14
+#define GC_FEATURES1_EXTENDED_PIXEL_FORMAT_Start 14
+#define GC_FEATURES1_EXTENDED_PIXEL_FORMAT_Type U01
+#define GC_FEATURES1_EXTENDED_PIXEL_FORMAT_NONE 0x0
+#define GC_FEATURES1_EXTENDED_PIXEL_FORMAT_AVAILABLE 0x1
+
+/* EEZ and HZ are correct. */
+#define GC_FEATURES1_CORRECT_MIN_MAX_DEPTH 15 : 15
+#define GC_FEATURES1_CORRECT_MIN_MAX_DEPTH_End 15
+#define GC_FEATURES1_CORRECT_MIN_MAX_DEPTH_Start 15
+#define GC_FEATURES1_CORRECT_MIN_MAX_DEPTH_Type U01
+#define GC_FEATURES1_CORRECT_MIN_MAX_DEPTH_NONE 0x0
+#define GC_FEATURES1_CORRECT_MIN_MAX_DEPTH_AVAILABLE 0x1
+
+/* Dither and filter+alpha available. */
+#define GC_FEATURES1_DITHER_AND_FILTER_PLUS_ALPHA_2D 16 : 16
+#define GC_FEATURES1_DITHER_AND_FILTER_PLUS_ALPHA_2D_End 16
+#define GC_FEATURES1_DITHER_AND_FILTER_PLUS_ALPHA_2D_Start 16
+#define GC_FEATURES1_DITHER_AND_FILTER_PLUS_ALPHA_2D_Type U01
+#define GC_FEATURES1_DITHER_AND_FILTER_PLUS_ALPHA_2D_NONE 0x0
+#define GC_FEATURES1_DITHER_AND_FILTER_PLUS_ALPHA_2D_AVAILABLE 0x1
+
+#define GC_FEATURES1_BUG_FIXES5 17 : 17
+#define GC_FEATURES1_BUG_FIXES5_End 17
+#define GC_FEATURES1_BUG_FIXES5_Start 17
+#define GC_FEATURES1_BUG_FIXES5_Type U01
+#define GC_FEATURES1_BUG_FIXES5_NONE 0x0
+#define GC_FEATURES1_BUG_FIXES5_AVAILABLE 0x1
+
+#define GC_FEATURES1_NEW_2D 18 : 18
+#define GC_FEATURES1_NEW_2D_End 18
+#define GC_FEATURES1_NEW_2D_Start 18
+#define GC_FEATURES1_NEW_2D_Type U01
+#define GC_FEATURES1_NEW_2D_NONE 0x0
+#define GC_FEATURES1_NEW_2D_AVAILABLE 0x1
+
+#define GC_FEATURES1_NEW_FLOATING_POINT_ARITHMETIC 19 : 19
+#define GC_FEATURES1_NEW_FLOATING_POINT_ARITHMETIC_End 19
+#define GC_FEATURES1_NEW_FLOATING_POINT_ARITHMETIC_Start 19
+#define GC_FEATURES1_NEW_FLOATING_POINT_ARITHMETIC_Type U01
+#define GC_FEATURES1_NEW_FLOATING_POINT_ARITHMETIC_NONE 0x0
+#define GC_FEATURES1_NEW_FLOATING_POINT_ARITHMETIC_AVAILABLE 0x1
+
+#define GC_FEATURES1_TEXTURE_HORIZONTAL_ALIGNMENT_SELECT 20 : 20
+#define GC_FEATURES1_TEXTURE_HORIZONTAL_ALIGNMENT_SELECT_End 20
+#define GC_FEATURES1_TEXTURE_HORIZONTAL_ALIGNMENT_SELECT_Start 20
+#define GC_FEATURES1_TEXTURE_HORIZONTAL_ALIGNMENT_SELECT_Type U01
+#define GC_FEATURES1_TEXTURE_HORIZONTAL_ALIGNMENT_SELECT_NONE 0x0
+#define GC_FEATURES1_TEXTURE_HORIZONTAL_ALIGNMENT_SELECT_AVAILABLE 0x1
+
+#define GC_FEATURES1_NON_POWER_OF_TWO 21 : 21
+#define GC_FEATURES1_NON_POWER_OF_TWO_End 21
+#define GC_FEATURES1_NON_POWER_OF_TWO_Start 21
+#define GC_FEATURES1_NON_POWER_OF_TWO_Type U01
+#define GC_FEATURES1_NON_POWER_OF_TWO_NONE 0x0
+#define GC_FEATURES1_NON_POWER_OF_TWO_AVAILABLE 0x1
+
+#define GC_FEATURES1_LINEAR_TEXTURE_SUPPORT 22 : 22
+#define GC_FEATURES1_LINEAR_TEXTURE_SUPPORT_End 22
+#define GC_FEATURES1_LINEAR_TEXTURE_SUPPORT_Start 22
+#define GC_FEATURES1_LINEAR_TEXTURE_SUPPORT_Type U01
+#define GC_FEATURES1_LINEAR_TEXTURE_SUPPORT_NONE 0x0
+#define GC_FEATURES1_LINEAR_TEXTURE_SUPPORT_AVAILABLE 0x1
+
+#define GC_FEATURES1_HALTI0 23 : 23
+#define GC_FEATURES1_HALTI0_End 23
+#define GC_FEATURES1_HALTI0_Start 23
+#define GC_FEATURES1_HALTI0_Type U01
+#define GC_FEATURES1_HALTI0_NONE 0x0
+#define GC_FEATURES1_HALTI0_AVAILABLE 0x1
+
+#define GC_FEATURES1_CORRECT_OVERFLOW_VG 24 : 24
+#define GC_FEATURES1_CORRECT_OVERFLOW_VG_End 24
+#define GC_FEATURES1_CORRECT_OVERFLOW_VG_Start 24
+#define GC_FEATURES1_CORRECT_OVERFLOW_VG_Type U01
+#define GC_FEATURES1_CORRECT_OVERFLOW_VG_NONE 0x0
+#define GC_FEATURES1_CORRECT_OVERFLOW_VG_AVAILABLE 0x1
+
+#define GC_FEATURES1_NEGATIVE_LOG_FIX 25 : 25
+#define GC_FEATURES1_NEGATIVE_LOG_FIX_End 25
+#define GC_FEATURES1_NEGATIVE_LOG_FIX_Start 25
+#define GC_FEATURES1_NEGATIVE_LOG_FIX_Type U01
+#define GC_FEATURES1_NEGATIVE_LOG_FIX_NONE 0x0
+#define GC_FEATURES1_NEGATIVE_LOG_FIX_AVAILABLE 0x1
+
+#define GC_FEATURES1_RESOLVE_OFFSET 26 : 26
+#define GC_FEATURES1_RESOLVE_OFFSET_End 26
+#define GC_FEATURES1_RESOLVE_OFFSET_Start 26
+#define GC_FEATURES1_RESOLVE_OFFSET_Type U01
+#define GC_FEATURES1_RESOLVE_OFFSET_NONE 0x0
+#define GC_FEATURES1_RESOLVE_OFFSET_AVAILABLE 0x1
+
+#define GC_FEATURES1_OK_TO_GATE_AXI_CLOCK 27 : 27
+#define GC_FEATURES1_OK_TO_GATE_AXI_CLOCK_End 27
+#define GC_FEATURES1_OK_TO_GATE_AXI_CLOCK_Start 27
+#define GC_FEATURES1_OK_TO_GATE_AXI_CLOCK_Type U01
+#define GC_FEATURES1_OK_TO_GATE_AXI_CLOCK_NONE 0x0
+#define GC_FEATURES1_OK_TO_GATE_AXI_CLOCK_AVAILABLE 0x1
+
+#define GC_FEATURES1_MMU 28 : 28
+#define GC_FEATURES1_MMU_End 28
+#define GC_FEATURES1_MMU_Start 28
+#define GC_FEATURES1_MMU_Type U01
+#define GC_FEATURES1_MMU_NONE 0x0
+#define GC_FEATURES1_MMU_AVAILABLE 0x1
+
+#define GC_FEATURES1_WIDE_LINE 29 : 29
+#define GC_FEATURES1_WIDE_LINE_End 29
+#define GC_FEATURES1_WIDE_LINE_Start 29
+#define GC_FEATURES1_WIDE_LINE_Type U01
+#define GC_FEATURES1_WIDE_LINE_NONE 0x0
+#define GC_FEATURES1_WIDE_LINE_AVAILABLE 0x1
+
+#define GC_FEATURES1_BUG_FIXES6 30 : 30
+#define GC_FEATURES1_BUG_FIXES6_End 30
+#define GC_FEATURES1_BUG_FIXES6_Start 30
+#define GC_FEATURES1_BUG_FIXES6_Type U01
+#define GC_FEATURES1_BUG_FIXES6_NONE 0x0
+#define GC_FEATURES1_BUG_FIXES6_AVAILABLE 0x1
+
+#define GC_FEATURES1_FC_FLUSH_STALL 31 : 31
+#define GC_FEATURES1_FC_FLUSH_STALL_End 31
+#define GC_FEATURES1_FC_FLUSH_STALL_Start 31
+#define GC_FEATURES1_FC_FLUSH_STALL_Type U01
+#define GC_FEATURES1_FC_FLUSH_STALL_NONE 0x0
+#define GC_FEATURES1_FC_FLUSH_STALL_AVAILABLE 0x1
+
+union gcfeatures1 {
+ struct {
+ /* GC_FEATURES1_Address:RSUV_SWIZZLE */
+ unsigned int rsuvswizzle:1;
+
+ /* GC_FEATURES1_Address:V2_COMPRESSION */
+ unsigned int v2compression:1;
+
+ /* GC_FEATURES1_Address:VG_DOUBLE_BUFFER */
+ unsigned int vgdblbuffer:1;
+
+ /* GC_FEATURES1_Address:BUG_FIXES1 */
+ unsigned int bugfixes1:1;
+
+ /* GC_FEATURES1_Address:BUG_FIXES2 */
+ unsigned int bugfixes2:1;
+
+ /* GC_FEATURES1_Address:TEXTURE_STRIDE */
+ unsigned int txstride:1;
+
+ /* GC_FEATURES1_Address:BUG_FIXES3 */
+ unsigned int bugfixes3:1;
+
+ /* GC_FEATURES1_Address:CORRECT_AUTO_DISABLE */
+ unsigned int correctautodisable:1;
+
+ /* GC_FEATURES1_Address:AUTO_RESTART_TS */
+ unsigned int autorestartts:1;
+
+ /* GC_FEATURES1_Address:BUG_FIXES4 */
+ unsigned int bugfixes4:1;
+
+ /* GC_FEATURES1_Address:L2_WINDOWING */
+ unsigned int l2win:1;
+
+ /* GC_FEATURES1_Address:HALF_FLOAT_PIPE */
+ unsigned int halffloatpipe:1;
+
+ /* GC_FEATURES1_Address:PIXEL_DITHER */
+ unsigned int pixeldither:1;
+
+ /* GC_FEATURES1_Address:TWO_STENCIL_REFERENCE */
+ unsigned int twostencilref:1;
+
+ /* GC_FEATURES1_Address:EXTENDED_PIXEL_FORMAT */
+ unsigned int pixformatex:1;
+
+ /* GC_FEATURES1_Address:CORRECT_MIN_MAX_DEPTH */
+ unsigned int correctminmaxdepth:1;
+
+ /* GC_FEATURES1_Address:DITHER_AND_FILTER_PLUS_ALPHA_2D */
+ unsigned int ditherfilter:1;
+
+ /* GC_FEATURES1_Address:BUG_FIXES5 */
+ unsigned int bugfixes5:1;
+
+ /* GC_FEATURES1_Address:NEW_2D */
+ unsigned int new2d:1;
+
+ /* GC_FEATURES1_Address:NEW_FLOATING_POINT_ARITHMETIC */
+ unsigned int newfp:1;
+
+ /* GC_FEATURES1_Address:TEXTURE_HORIZONTAL_ALIGNMENT_SELECT */
+ unsigned int txalign:1;
+
+ /* GC_FEATURES1_Address:NON_POWER_OF_TWO */
+ unsigned int nonpowof2:1;
+
+ /* GC_FEATURES1_Address:LINEAR_TEXTURE_SUPPORT */
+ unsigned int lineartx:1;
+
+ /* GC_FEATURES1_Address:HALTI0 */
+ unsigned int halti0:1;
+
+ /* GC_FEATURES1_Address:CORRECT_OVERFLOW_VG */
+ unsigned int correctoverflowvg:1;
+
+ /* GC_FEATURES1_Address:NEGATIVE_LOG_FIX */
+ unsigned int neglogfix:1;
+
+ /* GC_FEATURES1_Address:RESOLVE_OFFSET */
+ unsigned int rsoffset:1;
+
+ /* GC_FEATURES1_Address:OK_TO_GATE_AXI_CLOCK */
+ unsigned int axiclockgating:1;
+
+ /* GC_FEATURES1_Address:MMU */
+ unsigned int mmu:1;
+
+ /* GC_FEATURES1_Address:WIDE_LINE */
+ unsigned int wideline:1;
+
+ /* GC_FEATURES1_Address:BUG_FIXES6 */
+ unsigned int bugfixes6:1;
+
+ /* GC_FEATURES1_Address:FC_FLUSH_STALL */
+ unsigned int fcflushstall:1;
+ } reg;
+
+ unsigned int raw;
+};
+
+/*******************************************************************************
+** Register GCMinorFeatures2
+*/
+
+/* Shows which features are enabled in this chip. This register has no set **
+** reset value. It varies with the implementation. */
+
+#define GC_FEATURES2_Address 0x00084
+#define GC_FEATURES2_MSB 15
+#define GC_FEATURES2_LSB 0
+#define GC_FEATURES2_BLK 0
+#define GC_FEATURES2_Count 1
+#define GC_FEATURES2_FieldMask 0xFFFFFFFF
+#define GC_FEATURES2_ReadMask 0xFFFFFFFF
+#define GC_FEATURES2_WriteMask 0x00000000
+#define GC_FEATURES2_ResetValue 0x00000000
+
+#define GC_FEATURES2_LINE_LOOP 0 : 0
+#define GC_FEATURES2_LINE_LOOP_End 0
+#define GC_FEATURES2_LINE_LOOP_Start 0
+#define GC_FEATURES2_LINE_LOOP_Type U01
+#define GC_FEATURES2_LINE_LOOP_NONE 0x0
+#define GC_FEATURES2_LINE_LOOP_AVAILABLE 0x1
+
+#define GC_FEATURES2_LOGIC_OP 1 : 1
+#define GC_FEATURES2_LOGIC_OP_End 1
+#define GC_FEATURES2_LOGIC_OP_Start 1
+#define GC_FEATURES2_LOGIC_OP_Type U01
+#define GC_FEATURES2_LOGIC_OP_NONE 0x0
+#define GC_FEATURES2_LOGIC_OP_AVAILABLE 0x1
+
+#define GC_FEATURES2_SEAMLESS_CUBE_MAP 2 : 2
+#define GC_FEATURES2_SEAMLESS_CUBE_MAP_End 2
+#define GC_FEATURES2_SEAMLESS_CUBE_MAP_Start 2
+#define GC_FEATURES2_SEAMLESS_CUBE_MAP_Type U01
+#define GC_FEATURES2_SEAMLESS_CUBE_MAP_NONE 0x0
+#define GC_FEATURES2_SEAMLESS_CUBE_MAP_AVAILABLE 0x1
+
+#define GC_FEATURES2_SUPER_TILED_TEXTURE 3 : 3
+#define GC_FEATURES2_SUPER_TILED_TEXTURE_End 3
+#define GC_FEATURES2_SUPER_TILED_TEXTURE_Start 3
+#define GC_FEATURES2_SUPER_TILED_TEXTURE_Type U01
+#define GC_FEATURES2_SUPER_TILED_TEXTURE_NONE 0x0
+#define GC_FEATURES2_SUPER_TILED_TEXTURE_AVAILABLE 0x1
+
+#define GC_FEATURES2_LINEAR_PE 4 : 4
+#define GC_FEATURES2_LINEAR_PE_End 4
+#define GC_FEATURES2_LINEAR_PE_Start 4
+#define GC_FEATURES2_LINEAR_PE_Type U01
+#define GC_FEATURES2_LINEAR_PE_NONE 0x0
+#define GC_FEATURES2_LINEAR_PE_AVAILABLE 0x1
+
+#define GC_FEATURES2_RECT_PRIMITIVE 5 : 5
+#define GC_FEATURES2_RECT_PRIMITIVE_End 5
+#define GC_FEATURES2_RECT_PRIMITIVE_Start 5
+#define GC_FEATURES2_RECT_PRIMITIVE_Type U01
+#define GC_FEATURES2_RECT_PRIMITIVE_NONE 0x0
+#define GC_FEATURES2_RECT_PRIMITIVE_AVAILABLE 0x1
+
+#define GC_FEATURES2_COMPOSITION 6 : 6
+#define GC_FEATURES2_COMPOSITION_End 6
+#define GC_FEATURES2_COMPOSITION_Start 6
+#define GC_FEATURES2_COMPOSITION_Type U01
+#define GC_FEATURES2_COMPOSITION_NONE 0x0
+#define GC_FEATURES2_COMPOSITION_AVAILABLE 0x1
+
+#define GC_FEATURES2_CORRECT_AUTO_DISABLE_COUNT_WIDTH 7 : 7
+#define GC_FEATURES2_CORRECT_AUTO_DISABLE_COUNT_WIDTH_End 7
+#define GC_FEATURES2_CORRECT_AUTO_DISABLE_COUNT_WIDTH_Start 7
+#define GC_FEATURES2_CORRECT_AUTO_DISABLE_COUNT_WIDTH_Type U01
+#define GC_FEATURES2_CORRECT_AUTO_DISABLE_COUNT_WIDTH_NONE 0x0
+#define GC_FEATURES2_CORRECT_AUTO_DISABLE_COUNT_WIDTH_AVAILABLE 0x1
+
+#define GC_FEATURES2_PE_SWIZZLE 8 : 8
+#define GC_FEATURES2_PE_SWIZZLE_End 8
+#define GC_FEATURES2_PE_SWIZZLE_Start 8
+#define GC_FEATURES2_PE_SWIZZLE_Type U01
+#define GC_FEATURES2_PE_SWIZZLE_NONE 0x0
+#define GC_FEATURES2_PE_SWIZZLE_AVAILABLE 0x1
+
+#define GC_FEATURES2_END_EVENT 9 : 9
+#define GC_FEATURES2_END_EVENT_End 9
+#define GC_FEATURES2_END_EVENT_Start 9
+#define GC_FEATURES2_END_EVENT_Type U01
+#define GC_FEATURES2_END_EVENT_NONE 0x0
+#define GC_FEATURES2_END_EVENT_AVAILABLE 0x1
+
+#define GC_FEATURES2_S1S8 10 : 10
+#define GC_FEATURES2_S1S8_End 10
+#define GC_FEATURES2_S1S8_Start 10
+#define GC_FEATURES2_S1S8_Type U01
+#define GC_FEATURES2_S1S8_NONE 0x0
+#define GC_FEATURES2_S1S8_AVAILABLE 0x1
+
+#define GC_FEATURES2_HALTI1 11 : 11
+#define GC_FEATURES2_HALTI1_End 11
+#define GC_FEATURES2_HALTI1_Start 11
+#define GC_FEATURES2_HALTI1_Type U01
+#define GC_FEATURES2_HALTI1_NONE 0x0
+#define GC_FEATURES2_HALTI1_AVAILABLE 0x1
+
+#define GC_FEATURES2_RGB888 12 : 12
+#define GC_FEATURES2_RGB888_End 12
+#define GC_FEATURES2_RGB888_Start 12
+#define GC_FEATURES2_RGB888_Type U01
+#define GC_FEATURES2_RGB888_NONE 0x0
+#define GC_FEATURES2_RGB888_AVAILABLE 0x1
+
+#define GC_FEATURES2_TX__YUV_ASSEMBLER 13 : 13
+#define GC_FEATURES2_TX__YUV_ASSEMBLER_End 13
+#define GC_FEATURES2_TX__YUV_ASSEMBLER_Start 13
+#define GC_FEATURES2_TX__YUV_ASSEMBLER_Type U01
+#define GC_FEATURES2_TX__YUV_ASSEMBLER_NONE 0x0
+#define GC_FEATURES2_TX__YUV_ASSEMBLER_AVAILABLE 0x1
+
+#define GC_FEATURES2_DYNAMIC_FREQUENCY_SCALING 14 : 14
+#define GC_FEATURES2_DYNAMIC_FREQUENCY_SCALING_End 14
+#define GC_FEATURES2_DYNAMIC_FREQUENCY_SCALING_Start 14
+#define GC_FEATURES2_DYNAMIC_FREQUENCY_SCALING_Type U01
+#define GC_FEATURES2_DYNAMIC_FREQUENCY_SCALING_NONE 0x0
+#define GC_FEATURES2_DYNAMIC_FREQUENCY_SCALING_AVAILABLE 0x1
+
+#define GC_FEATURES2_TX_FILTER 15 : 15
+#define GC_FEATURES2_TX_FILTER_End 15
+#define GC_FEATURES2_TX_FILTER_Start 15
+#define GC_FEATURES2_TX_FILTER_Type U01
+#define GC_FEATURES2_TX_FILTER_NONE 0x0
+#define GC_FEATURES2_TX_FILTER_AVAILABLE 0x1
+
+#define GC_FEATURES2_FULL_DIRECT_FB 16 : 16
+#define GC_FEATURES2_FULL_DIRECT_FB_End 16
+#define GC_FEATURES2_FULL_DIRECT_FB_Start 16
+#define GC_FEATURES2_FULL_DIRECT_FB_Type U01
+#define GC_FEATURES2_FULL_DIRECT_FB_NONE 0x0
+#define GC_FEATURES2_FULL_DIRECT_FB_AVAILABLE 0x1
+
+#define GC_FEATURES2_ONE_PASS_2D_FILTER 17 : 17
+#define GC_FEATURES2_ONE_PASS_2D_FILTER_End 17
+#define GC_FEATURES2_ONE_PASS_2D_FILTER_Start 17
+#define GC_FEATURES2_ONE_PASS_2D_FILTER_Type U01
+#define GC_FEATURES2_ONE_PASS_2D_FILTER_NONE 0x0
+#define GC_FEATURES2_ONE_PASS_2D_FILTER_AVAILABLE 0x1
+
+#define GC_FEATURES2_THREAD_WALKER_IN_PS 18 : 18
+#define GC_FEATURES2_THREAD_WALKER_IN_PS_End 18
+#define GC_FEATURES2_THREAD_WALKER_IN_PS_Start 18
+#define GC_FEATURES2_THREAD_WALKER_IN_PS_Type U01
+#define GC_FEATURES2_THREAD_WALKER_IN_PS_NONE 0x0
+#define GC_FEATURES2_THREAD_WALKER_IN_PS_AVAILABLE 0x1
+
+#define GC_FEATURES2_TILE_FILLER 19 : 19
+#define GC_FEATURES2_TILE_FILLER_End 19
+#define GC_FEATURES2_TILE_FILLER_Start 19
+#define GC_FEATURES2_TILE_FILLER_Type U01
+#define GC_FEATURES2_TILE_FILLER_NONE 0x0
+#define GC_FEATURES2_TILE_FILLER_AVAILABLE 0x1
+
+#define GC_FEATURES2_YUV_STANDARD 20 : 20
+#define GC_FEATURES2_YUV_STANDARD_End 20
+#define GC_FEATURES2_YUV_STANDARD_Start 20
+#define GC_FEATURES2_YUV_STANDARD_Type U01
+#define GC_FEATURES2_YUV_STANDARD_NONE 0x0
+#define GC_FEATURES2_YUV_STANDARD_AVAILABLE 0x1
+
+#define GC_FEATURES2_MULTI_SOURCE_BLT 21 : 21
+#define GC_FEATURES2_MULTI_SOURCE_BLT_End 21
+#define GC_FEATURES2_MULTI_SOURCE_BLT_Start 21
+#define GC_FEATURES2_MULTI_SOURCE_BLT_Type U01
+#define GC_FEATURES2_MULTI_SOURCE_BLT_NONE 0x0
+#define GC_FEATURES2_MULTI_SOURCE_BLT_AVAILABLE 0x1
+
+#define GC_FEATURES2_YUV_CONVERSION 22 : 22
+#define GC_FEATURES2_YUV_CONVERSION_End 22
+#define GC_FEATURES2_YUV_CONVERSION_Start 22
+#define GC_FEATURES2_YUV_CONVERSION_Type U01
+#define GC_FEATURES2_YUV_CONVERSION_NONE 0x0
+#define GC_FEATURES2_YUV_CONVERSION_AVAILABLE 0x1
+
+#define GC_FEATURES2_FLUSH_FIXED_2D 23 : 23
+#define GC_FEATURES2_FLUSH_FIXED_2D_End 23
+#define GC_FEATURES2_FLUSH_FIXED_2D_Start 23
+#define GC_FEATURES2_FLUSH_FIXED_2D_Type U01
+#define GC_FEATURES2_FLUSH_FIXED_2D_NONE 0x0
+#define GC_FEATURES2_FLUSH_FIXED_2D_AVAILABLE 0x1
+
+#define GC_FEATURES2_INTERLEAVER 24 : 24
+#define GC_FEATURES2_INTERLEAVER_End 24
+#define GC_FEATURES2_INTERLEAVER_Start 24
+#define GC_FEATURES2_INTERLEAVER_Type U01
+#define GC_FEATURES2_INTERLEAVER_NONE 0x0
+#define GC_FEATURES2_INTERLEAVER_AVAILABLE 0x1
+
+#define GC_FEATURES2_MIXED_STREAMS 25 : 25
+#define GC_FEATURES2_MIXED_STREAMS_End 25
+#define GC_FEATURES2_MIXED_STREAMS_Start 25
+#define GC_FEATURES2_MIXED_STREAMS_Type U01
+#define GC_FEATURES2_MIXED_STREAMS_NONE 0x0
+#define GC_FEATURES2_MIXED_STREAMS_AVAILABLE 0x1
+
+#define GC_FEATURES2_L2_CACHE_FOR_2D_420 26 : 26
+#define GC_FEATURES2_L2_CACHE_FOR_2D_420_End 26
+#define GC_FEATURES2_L2_CACHE_FOR_2D_420_Start 26
+#define GC_FEATURES2_L2_CACHE_FOR_2D_420_Type U01
+#define GC_FEATURES2_L2_CACHE_FOR_2D_420_NONE 0x0
+#define GC_FEATURES2_L2_CACHE_FOR_2D_420_AVAILABLE 0x1
+
+#define GC_FEATURES2_BUG_FIXES7 27 : 27
+#define GC_FEATURES2_BUG_FIXES7_End 27
+#define GC_FEATURES2_BUG_FIXES7_Start 27
+#define GC_FEATURES2_BUG_FIXES7_Type U01
+#define GC_FEATURES2_BUG_FIXES7_NONE 0x0
+#define GC_FEATURES2_BUG_FIXES7_AVAILABLE 0x1
+
+#define GC_FEATURES2_NO_INDEX_PATTERN 28 : 28
+#define GC_FEATURES2_NO_INDEX_PATTERN_End 28
+#define GC_FEATURES2_NO_INDEX_PATTERN_Start 28
+#define GC_FEATURES2_NO_INDEX_PATTERN_Type U01
+#define GC_FEATURES2_NO_INDEX_PATTERN_NONE 0x0
+#define GC_FEATURES2_NO_INDEX_PATTERN_AVAILABLE 0x1
+
+#define GC_FEATURES2_TEXTURE_TILE_STATUS 29 : 29
+#define GC_FEATURES2_TEXTURE_TILE_STATUS_End 29
+#define GC_FEATURES2_TEXTURE_TILE_STATUS_Start 29
+#define GC_FEATURES2_TEXTURE_TILE_STATUS_Type U01
+#define GC_FEATURES2_TEXTURE_TILE_STATUS_NONE 0x0
+#define GC_FEATURES2_TEXTURE_TILE_STATUS_AVAILABLE 0x1
+
+#define GC_FEATURES2_DECOMPRESS_Z16 30 : 30
+#define GC_FEATURES2_DECOMPRESS_Z16_End 30
+#define GC_FEATURES2_DECOMPRESS_Z16_Start 30
+#define GC_FEATURES2_DECOMPRESS_Z16_Type U01
+#define GC_FEATURES2_DECOMPRESS_Z16_NONE 0x0
+#define GC_FEATURES2_DECOMPRESS_Z16_AVAILABLE 0x1
+
+#define GC_FEATURES2_BUG_FIXES8 31 : 31
+#define GC_FEATURES2_BUG_FIXES8_End 31
+#define GC_FEATURES2_BUG_FIXES8_Start 31
+#define GC_FEATURES2_BUG_FIXES8_Type U01
+#define GC_FEATURES2_BUG_FIXES8_NONE 0x0
+#define GC_FEATURES2_BUG_FIXES8_AVAILABLE 0x1
+
+union gcfeatures2 {
+ struct {
+ /* GC_FEATURES2_Address:LINE_LOOP */
+ unsigned int lineloop:1;
+
+ /* GC_FEATURES2_Address:LOGIC_OP */
+ unsigned int logop:1;
+
+ /* GC_FEATURES2_Address:SEAMLESS_CUBE_MAP */
+ unsigned int cubemap:1;
+
+ /* GC_FEATURES2_Address:SUPER_TILED_TEXTURE */
+ unsigned int supertiledtx:1;
+
+ /* GC_FEATURES2_Address:LINEAR_PE */
+ unsigned int linearpe:1;
+
+ /* GC_FEATURES2_Address:RECT_PRIMITIVE */
+ unsigned int rectprim:1;
+
+ /* GC_FEATURES2_Address:COMPOSITION */
+ unsigned int composition:1;
+
+ /* GC_FEATURES2_Address:CORRECT_AUTO_DISABLE_COUNT_WIDTH */
+ unsigned int correctcountwidth:1;
+
+ /* GC_FEATURES2_Address:PE_SWIZZLE */
+ unsigned int peswizzle:1;
+
+ /* GC_FEATURES2_Address:END_EVENT */
+ unsigned int endevent:1;
+
+ /* GC_FEATURES2_Address:S1S8 */
+ unsigned int s1s8:1;
+
+ /* GC_FEATURES2_Address:HALTI1 */
+ unsigned int halti1:1;
+
+ /* GC_FEATURES2_Address:RGB888 */
+ unsigned int rgb888:1;
+
+ /* GC_FEATURES2_Address:TX__YUV_ASSEMBLER */
+ unsigned int txyuvasm:1;
+
+ /* GC_FEATURES2_Address:DYNAMIC_FREQUENCY_SCALING */
+ unsigned int dynscaling:1;
+
+ /* GC_FEATURES2_Address:TX_FILTER */
+ unsigned int txfilter:1;
+
+ /* GC_FEATURES2_Address:FULL_DIRECT_FB */
+ unsigned int dfb:1;
+
+ /* GC_FEATURES2_Address:ONE_PASS_2D_FILTER */
+ unsigned int onepassfilter:1;
+
+ /* GC_FEATURES2_Address:THREAD_WALKER_IN_PS */
+ unsigned int pstw:1;
+
+ /* GC_FEATURES2_Address:TILE_FILLER */
+ unsigned int tilefiller:1;
+
+ /* GC_FEATURES2_Address:YUV_STANDARD */
+ unsigned int yuvstd:1;
+
+ /* GC_FEATURES2_Address:MULTI_SOURCE_BLT */
+ unsigned int multisrc:1;
+
+ /* GC_FEATURES2_Address:YUV_CONVERSION */
+ unsigned int yuvconvert:1;
+
+ /* GC_FEATURES2_Address:FLUSH_FIXED_2D */
+ unsigned int flushfixed2d:1;
+
+ /* GC_FEATURES2_Address:INTERLEAVER */
+ unsigned int interleaver:1;
+
+ /* GC_FEATURES2_Address:MIXED_STREAMS */
+ unsigned int mixedstreams:1;
+
+ /* GC_FEATURES2_Address:L2_CACHE_FOR_2D_420 */
+ unsigned int l2cachefor420:1;
+
+ /* GC_FEATURES2_Address:BUG_FIXES7 */
+ unsigned int bugfixes7:1;
+
+ /* GC_FEATURES2_Address:NO_INDEX_PATTERN */
+ unsigned int noindexpatern:1;
+
+ /* GC_FEATURES2_Address:TEXTURE_TILE_STATUS */
+ unsigned int tilestatustx:1;
+
+ /* GC_FEATURES2_Address:DECOMPRESS_Z16 */
+ unsigned int decompressz16:1;
+
+ /* GC_FEATURES2_Address:BUG_FIXES8 */
+ unsigned int bugfixes8:1;
+ } reg;
+
+ unsigned int raw;
+};
+
+/*******************************************************************************
+** Register GCMinorFeatures3
+*/
+
+/* Shows which features are enabled in this chip. This register has no set **
+** reset value, it varies with the implementation. */
+
+#define GC_FEATURES3_Address 0x00088
+#define GC_FEATURES3_MSB 15
+#define GC_FEATURES3_LSB 0
+#define GC_FEATURES3_BLK 0
+#define GC_FEATURES3_Count 1
+#define GC_FEATURES3_FieldMask 0x003FFFFF
+#define GC_FEATURES3_ReadMask 0x003FFFFF
+#define GC_FEATURES3_WriteMask 0x00000000
+#define GC_FEATURES3_ResetValue 0x00000000
+
+#define GC_FEATURES3_DE_ROTATION_STALL_FIX 0 : 0
+#define GC_FEATURES3_DE_ROTATION_STALL_FIX_End 0
+#define GC_FEATURES3_DE_ROTATION_STALL_FIX_Start 0
+#define GC_FEATURES3_DE_ROTATION_STALL_FIX_Type U01
+#define GC_FEATURES3_DE_ROTATION_STALL_FIX_NONE 0x0
+#define GC_FEATURES3_DE_ROTATION_STALL_FIX_AVAILABLE 0x1
+
+#define GC_FEATURES3_OCL_ONLY 1 : 1
+#define GC_FEATURES3_OCL_ONLY_End 1
+#define GC_FEATURES3_OCL_ONLY_Start 1
+#define GC_FEATURES3_OCL_ONLY_Type U01
+#define GC_FEATURES3_OCL_ONLY_NONE 0x0
+#define GC_FEATURES3_OCL_ONLY_AVAILABLE 0x1
+
+#define GC_FEATURES3_NEW_FEATURES0 2 : 2
+#define GC_FEATURES3_NEW_FEATURES0_End 2
+#define GC_FEATURES3_NEW_FEATURES0_Start 2
+#define GC_FEATURES3_NEW_FEATURES0_Type U01
+#define GC_FEATURES3_NEW_FEATURES0_NONE 0x0
+#define GC_FEATURES3_NEW_FEATURES0_AVAILABLE 0x1
+
+#define GC_FEATURES3_INSTRUCTION_CACHE 3 : 3
+#define GC_FEATURES3_INSTRUCTION_CACHE_End 3
+#define GC_FEATURES3_INSTRUCTION_CACHE_Start 3
+#define GC_FEATURES3_INSTRUCTION_CACHE_Type U01
+#define GC_FEATURES3_INSTRUCTION_CACHE_NONE 0x0
+#define GC_FEATURES3_INSTRUCTION_CACHE_AVAILABLE 0x1
+
+#define GC_FEATURES3_GEOMETRY_SHADER 4 : 4
+#define GC_FEATURES3_GEOMETRY_SHADER_End 4
+#define GC_FEATURES3_GEOMETRY_SHADER_Start 4
+#define GC_FEATURES3_GEOMETRY_SHADER_Type U01
+#define GC_FEATURES3_GEOMETRY_SHADER_NONE 0x0
+#define GC_FEATURES3_GEOMETRY_SHADER_AVAILABLE 0x1
+
+#define GC_FEATURES3_TEX_COMPRESSION_SUPERTILED 5 : 5
+#define GC_FEATURES3_TEX_COMPRESSION_SUPERTILED_End 5
+#define GC_FEATURES3_TEX_COMPRESSION_SUPERTILED_Start 5
+#define GC_FEATURES3_TEX_COMPRESSION_SUPERTILED_Type U01
+#define GC_FEATURES3_TEX_COMPRESSION_SUPERTILED_NONE 0x0
+#define GC_FEATURES3_TEX_COMPRESSION_SUPERTILED_AVAILABLE 0x1
+
+#define GC_FEATURES3_GENERICS 6 : 6
+#define GC_FEATURES3_GENERICS_End 6
+#define GC_FEATURES3_GENERICS_Start 6
+#define GC_FEATURES3_GENERICS_Type U01
+#define GC_FEATURES3_GENERICS_NONE 0x0
+#define GC_FEATURES3_GENERICS_AVAILABLE 0x1
+
+#define GC_FEATURES3_BUG_FIXES9 7 : 7
+#define GC_FEATURES3_BUG_FIXES9_End 7
+#define GC_FEATURES3_BUG_FIXES9_Start 7
+#define GC_FEATURES3_BUG_FIXES9_Type U01
+#define GC_FEATURES3_BUG_FIXES9_NONE 0x0
+#define GC_FEATURES3_BUG_FIXES9_AVAILABLE 0x1
+
+#define GC_FEATURES3_FAST_MSAA 8 : 8
+#define GC_FEATURES3_FAST_MSAA_End 8
+#define GC_FEATURES3_FAST_MSAA_Start 8
+#define GC_FEATURES3_FAST_MSAA_Type U01
+#define GC_FEATURES3_FAST_MSAA_NONE 0x0
+#define GC_FEATURES3_FAST_MSAA_AVAILABLE 0x1
+
+#define GC_FEATURES3_WCLIP 9 : 9
+#define GC_FEATURES3_WCLIP_End 9
+#define GC_FEATURES3_WCLIP_Start 9
+#define GC_FEATURES3_WCLIP_Type U01
+#define GC_FEATURES3_WCLIP_NONE 0x0
+#define GC_FEATURES3_WCLIP_AVAILABLE 0x1
+
+#define GC_FEATURES3_BUG_FIXES10 10 : 10
+#define GC_FEATURES3_BUG_FIXES10_End 10
+#define GC_FEATURES3_BUG_FIXES10_Start 10
+#define GC_FEATURES3_BUG_FIXES10_Type U01
+#define GC_FEATURES3_BUG_FIXES10_NONE 0x0
+#define GC_FEATURES3_BUG_FIXES10_AVAILABLE 0x1
+
+#define GC_FEATURES3_UNIFIED_SAMPLERS 11 : 11
+#define GC_FEATURES3_UNIFIED_SAMPLERS_End 11
+#define GC_FEATURES3_UNIFIED_SAMPLERS_Start 11
+#define GC_FEATURES3_UNIFIED_SAMPLERS_Type U01
+#define GC_FEATURES3_UNIFIED_SAMPLERS_NONE 0x0
+#define GC_FEATURES3_UNIFIED_SAMPLERS_AVAILABLE 0x1
+
+#define GC_FEATURES3_BUG_FIXES11 12 : 12
+#define GC_FEATURES3_BUG_FIXES11_End 12
+#define GC_FEATURES3_BUG_FIXES11_Start 12
+#define GC_FEATURES3_BUG_FIXES11_Type U01
+#define GC_FEATURES3_BUG_FIXES11_NONE 0x0
+#define GC_FEATURES3_BUG_FIXES11_AVAILABLE 0x1
+
+#define GC_FEATURES3_PERFORMANCE_COUNTERS 13 : 13
+#define GC_FEATURES3_PERFORMANCE_COUNTERS_End 13
+#define GC_FEATURES3_PERFORMANCE_COUNTERS_Start 13
+#define GC_FEATURES3_PERFORMANCE_COUNTERS_Type U01
+#define GC_FEATURES3_PERFORMANCE_COUNTERS_NONE 0x0
+#define GC_FEATURES3_PERFORMANCE_COUNTERS_AVAILABLE 0x1
+
+/* High precision transcendentals are available. */
+#define GC_FEATURES3_EXTRA_SHADER_INSTRUCTIONS2 14 : 14
+#define GC_FEATURES3_EXTRA_SHADER_INSTRUCTIONS2_End 14
+#define GC_FEATURES3_EXTRA_SHADER_INSTRUCTIONS2_Start 14
+#define GC_FEATURES3_EXTRA_SHADER_INSTRUCTIONS2_Type U01
+#define GC_FEATURES3_EXTRA_SHADER_INSTRUCTIONS2_NONE 0x0
+#define GC_FEATURES3_EXTRA_SHADER_INSTRUCTIONS2_AVAILABLE 0x1
+
+#define GC_FEATURES3_BUG_FIXES12 15 : 15
+#define GC_FEATURES3_BUG_FIXES12_End 15
+#define GC_FEATURES3_BUG_FIXES12_Start 15
+#define GC_FEATURES3_BUG_FIXES12_Type U01
+#define GC_FEATURES3_BUG_FIXES12_NONE 0x0
+#define GC_FEATURES3_BUG_FIXES12_AVAILABLE 0x1
+
+#define GC_FEATURES3_BUG_FIXES13 16 : 16
+#define GC_FEATURES3_BUG_FIXES13_End 16
+#define GC_FEATURES3_BUG_FIXES13_Start 16
+#define GC_FEATURES3_BUG_FIXES13_Type U01
+#define GC_FEATURES3_BUG_FIXES13_NONE 0x0
+#define GC_FEATURES3_BUG_FIXES13_AVAILABLE 0x1
+
+#define GC_FEATURES3_DE_ENHANCEMENTS1 17 : 17
+#define GC_FEATURES3_DE_ENHANCEMENTS1_End 17
+#define GC_FEATURES3_DE_ENHANCEMENTS1_Start 17
+#define GC_FEATURES3_DE_ENHANCEMENTS1_Type U01
+#define GC_FEATURES3_DE_ENHANCEMENTS1_NONE 0x0
+#define GC_FEATURES3_DE_ENHANCEMENTS1_AVAILABLE 0x1
+
+#define GC_FEATURES3_ACE 18 : 18
+#define GC_FEATURES3_ACE_End 18
+#define GC_FEATURES3_ACE_Start 18
+#define GC_FEATURES3_ACE_Type U01
+#define GC_FEATURES3_ACE_NONE 0x0
+#define GC_FEATURES3_ACE_AVAILABLE 0x1
+
+#define GC_FEATURES3_TX_ENHANCEMENTS1 19 : 19
+#define GC_FEATURES3_TX_ENHANCEMENTS1_End 19
+#define GC_FEATURES3_TX_ENHANCEMENTS1_Start 19
+#define GC_FEATURES3_TX_ENHANCEMENTS1_Type U01
+#define GC_FEATURES3_TX_ENHANCEMENTS1_NONE 0x0
+#define GC_FEATURES3_TX_ENHANCEMENTS1_AVAILABLE 0x1
+
+#define GC_FEATURES3_SH_ENHANCEMENTS1 20 : 20
+#define GC_FEATURES3_SH_ENHANCEMENTS1_End 20
+#define GC_FEATURES3_SH_ENHANCEMENTS1_Start 20
+#define GC_FEATURES3_SH_ENHANCEMENTS1_Type U01
+#define GC_FEATURES3_SH_ENHANCEMENTS1_NONE 0x0
+#define GC_FEATURES3_SH_ENHANCEMENTS1_AVAILABLE 0x1
+
+#define GC_FEATURES3_SH_ENHANCEMENTS2 21 : 21
+#define GC_FEATURES3_SH_ENHANCEMENTS2_End 21
+#define GC_FEATURES3_SH_ENHANCEMENTS2_Start 21
+#define GC_FEATURES3_SH_ENHANCEMENTS2_Type U01
+#define GC_FEATURES3_SH_ENHANCEMENTS2_NONE 0x0
+#define GC_FEATURES3_SH_ENHANCEMENTS2_AVAILABLE 0x1
+
+union gcfeatures3 {
+ struct {
+ /* GC_FEATURES3_Address:DE_ROTATION_STALL_FIX */
+ unsigned int rotationfix:1;
+
+ /* GC_FEATURES3_Address:OCL_ONLY */
+ unsigned int ocl:1;
+
+ /* GC_FEATURES3_Address:NEW_FEATURES0 */
+ unsigned int newfeatures0:1;
+
+ /* GC_FEATURES3_Address:INSTRUCTION_CACHE */
+ unsigned int icache:1;
+
+ /* GC_FEATURES3_Address:GEOMETRY_SHADER */
+ unsigned int gs:1;
+
+ /* GC_FEATURES3_Address:TEX_COMPRESSION_SUPERTILED */
+ unsigned int supertiledtxcompression:1;
+
+ /* GC_FEATURES3_Address:GENERICS */
+ unsigned int generics:1;
+
+ /* GC_FEATURES3_Address:BUG_FIXES9 */
+ unsigned int bugfixes9:1;
+
+ /* GC_FEATURES3_Address:FAST_MSAA */
+ unsigned int fastmsaa:1;
+
+ /* GC_FEATURES3_Address:WCLIP */
+ unsigned int wclip:1;
+
+ /* GC_FEATURES3_Address:BUG_FIXES10 */
+ unsigned int bugfixes10:1;
+
+ /* GC_FEATURES3_Address:UNIFIED_SAMPLERS */
+ unsigned int unifiedsamplers:1;
+
+ /* GC_FEATURES3_Address:BUG_FIXES11 */
+ unsigned int bugfixes11:1;
+
+ /* GC_FEATURES3_Address:PERFORMANCE_COUNTERS */
+ unsigned int perfcounters:1;
+
+ /* GC_FEATURES3_Address:EXTRA_SHADER_INSTRUCTIONS2 */
+ unsigned int shaderinst2:1;
+
+ /* GC_FEATURES3_Address:BUG_FIXES12 */
+ unsigned int bugfixes12:1;
+
+ /* GC_FEATURES3_Address:BUG_FIXES13 */
+ unsigned int bugfixes13:1;
+
+ /* GC_FEATURES3_Address:DE_ENHANCEMENTS1 */
+ unsigned int deenhancements1:1;
+
+ /* GC_FEATURES3_Address:ACE */
+ unsigned int ace:1;
+
+ /* GC_FEATURES3_Address:TX_ENHANCEMENTS1 */
+ unsigned int txenhancements1:1;
+
+ /* GC_FEATURES3_Address:SH_ENHANCEMENTS1 */
+ unsigned int shenhancements1:1;
+
+ /* GC_FEATURES3_Address:SH_ENHANCEMENTS2 */
+ unsigned int shenhancements2:1;
+
+ /* GC_FEATURES3_Address:reserved */
+ unsigned int _reserved_22_31:10;
+ } reg;
+
+ unsigned int raw;
+};
+
+/*******************************************************************************
+** Register GCResetMemCounters
+*/
+
+/* Writing 1 will reset the counters and stop counting. Write 0 to start
+** counting again. This register is write only so it has no reset value.
+*/
+
+#define GC_RESET_MEM_COUNTERS_Address 0x0003C
+#define GC_RESET_MEM_COUNTERS_MSB 15
+#define GC_RESET_MEM_COUNTERS_LSB 0
+#define GC_RESET_MEM_COUNTERS_BLK 0
+#define GC_RESET_MEM_COUNTERS_Count 1
+#define GC_RESET_MEM_COUNTERS_FieldMask 0x00000001
+#define GC_RESET_MEM_COUNTERS_ReadMask 0x00000000
+#define GC_RESET_MEM_COUNTERS_WriteMask 0x00000001
+#define GC_RESET_MEM_COUNTERS_ResetValue 0x00000000
+
+#define GC_RESET_MEM_COUNTERS_RESET 0 : 0
+#define GC_RESET_MEM_COUNTERS_RESET_End 0
+#define GC_RESET_MEM_COUNTERS_RESET_Start 0
+#define GC_RESET_MEM_COUNTERS_RESET_Type U01
+
+/*******************************************************************************
+** Register gcTotalReads
+*/
+
+/* Total reads in terms of 64bits. */
+
+#define GC_TOTAL_READS_Address 0x00040
+#define GC_TOTAL_READS_MSB 15
+#define GC_TOTAL_READS_LSB 0
+#define GC_TOTAL_READS_BLK 0
+#define GC_TOTAL_READS_Count 1
+#define GC_TOTAL_READS_FieldMask 0xFFFFFFFF
+#define GC_TOTAL_READS_ReadMask 0xFFFFFFFF
+#define GC_TOTAL_READS_WriteMask 0x00000000
+#define GC_TOTAL_READS_ResetValue 0x00000000
+
+#define GC_TOTAL_READS_COUNT 31 : 0
+#define GC_TOTAL_READS_COUNT_End 31
+#define GC_TOTAL_READS_COUNT_Start 0
+#define GC_TOTAL_READS_COUNT_Type U32
+
+/*******************************************************************************
+** Register gcTotalWrites
+*/
+
+/* Total writes in terms of 64bits. */
+
+#define GC_TOTAL_WRITES_Address 0x00044
+#define GC_TOTAL_WRITES_MSB 15
+#define GC_TOTAL_WRITES_LSB 0
+#define GC_TOTAL_WRITES_BLK 0
+#define GC_TOTAL_WRITES_Count 1
+#define GC_TOTAL_WRITES_FieldMask 0xFFFFFFFF
+#define GC_TOTAL_WRITES_ReadMask 0xFFFFFFFF
+#define GC_TOTAL_WRITES_WriteMask 0x00000000
+#define GC_TOTAL_WRITES_ResetValue 0x00000000
+
+#define GC_TOTAL_WRITES_COUNT 31 : 0
+#define GC_TOTAL_WRITES_COUNT_End 31
+#define GC_TOTAL_WRITES_COUNT_Start 0
+#define GC_TOTAL_WRITES_COUNT_Type U32
+
+/*******************************************************************************
+** Register gcTotalWriteBursts
+*/
+
+/* Total write Data Count in terms of 64bits value. */
+
+#define GC_TOTAL_WRITE_BURSTS_Address 0x0004C
+#define GC_TOTAL_WRITE_BURSTS_MSB 15
+#define GC_TOTAL_WRITE_BURSTS_LSB 0
+#define GC_TOTAL_WRITE_BURSTS_BLK 0
+#define GC_TOTAL_WRITE_BURSTS_Count 1
+#define GC_TOTAL_WRITE_BURSTS_FieldMask 0xFFFFFFFF
+#define GC_TOTAL_WRITE_BURSTS_ReadMask 0xFFFFFFFF
+#define GC_TOTAL_WRITE_BURSTS_WriteMask 0x00000000
+#define GC_TOTAL_WRITE_BURSTS_ResetValue 0x00000000
+
+#define GC_TOTAL_WRITE_BURSTS_COUNT 31 : 0
+#define GC_TOTAL_WRITE_BURSTS_COUNT_End 31
+#define GC_TOTAL_WRITE_BURSTS_COUNT_Start 0
+#define GC_TOTAL_WRITE_BURSTS_COUNT_Type U32
+
+/*******************************************************************************
+** Register gcTotalWriteReqs
+*/
+
+/* Total write Request Count. */
+
+#define GC_TOTAL_WRITE_REQS_Address 0x00050
+#define GC_TOTAL_WRITE_REQS_MSB 15
+#define GC_TOTAL_WRITE_REQS_LSB 0
+#define GC_TOTAL_WRITE_REQS_BLK 0
+#define GC_TOTAL_WRITE_REQS_Count 1
+#define GC_TOTAL_WRITE_REQS_FieldMask 0xFFFFFFFF
+#define GC_TOTAL_WRITE_REQS_ReadMask 0xFFFFFFFF
+#define GC_TOTAL_WRITE_REQS_WriteMask 0x00000000
+#define GC_TOTAL_WRITE_REQS_ResetValue 0x00000000
+
+#define GC_TOTAL_WRITE_REQS_COUNT 31 : 0
+#define GC_TOTAL_WRITE_REQS_COUNT_End 31
+#define GC_TOTAL_WRITE_REQS_COUNT_Start 0
+#define GC_TOTAL_WRITE_REQS_COUNT_Type U32
+
+/*******************************************************************************
+** Register gcTotalReadBursts
+*/
+
+/* Total Read Data Count in terms of 64bits. */
+
+#define GC_TOTAL_READ_BURSTS_Address 0x00058
+#define GC_TOTAL_READ_BURSTS_MSB 15
+#define GC_TOTAL_READ_BURSTS_LSB 0
+#define GC_TOTAL_READ_BURSTS_BLK 0
+#define GC_TOTAL_READ_BURSTS_Count 1
+#define GC_TOTAL_READ_BURSTS_FieldMask 0xFFFFFFFF
+#define GC_TOTAL_READ_BURSTS_ReadMask 0xFFFFFFFF
+#define GC_TOTAL_READ_BURSTS_WriteMask 0x00000000
+#define GC_TOTAL_READ_BURSTS_ResetValue 0x00000000
+
+#define GC_TOTAL_READ_BURSTS_COUNT 31 : 0
+#define GC_TOTAL_READ_BURSTS_COUNT_End 31
+#define GC_TOTAL_READ_BURSTS_COUNT_Start 0
+#define GC_TOTAL_READ_BURSTS_COUNT_Type U32
+
+/*******************************************************************************
+** Register gcTotalReadReqs
+*/
+
+/* Total Read Request Count. */
+
+#define GC_TOTAL_READ_REQS_Address 0x0005C
+#define GC_TOTAL_READ_REQS_MSB 15
+#define GC_TOTAL_READ_REQS_LSB 0
+#define GC_TOTAL_READ_REQS_BLK 0
+#define GC_TOTAL_READ_REQS_Count 1
+#define GC_TOTAL_READ_REQS_FieldMask 0xFFFFFFFF
+#define GC_TOTAL_READ_REQS_ReadMask 0xFFFFFFFF
+#define GC_TOTAL_READ_REQS_WriteMask 0x00000000
+#define GC_TOTAL_READ_REQS_ResetValue 0x00000000
+
+#define GC_TOTAL_READ_REQS_COUNT 31 : 0
+#define GC_TOTAL_READ_REQS_COUNT_End 31
+#define GC_TOTAL_READ_REQS_COUNT_Start 0
+#define GC_TOTAL_READ_REQS_COUNT_Type U32
+
+/*******************************************************************************
+** Register gcTotalReadLasts
+*/
+
+/* Total RLAST Count. This is used to match with GCTotalReadReqs. */
+
+#define GC_TOTAL_READ_LASTS_Address 0x00060
+#define GC_TOTAL_READ_LASTS_MSB 15
+#define GC_TOTAL_READ_LASTS_LSB 0
+#define GC_TOTAL_READ_LASTS_BLK 0
+#define GC_TOTAL_READ_LASTS_Count 1
+#define GC_TOTAL_READ_LASTS_FieldMask 0xFFFFFFFF
+#define GC_TOTAL_READ_LASTS_ReadMask 0xFFFFFFFF
+#define GC_TOTAL_READ_LASTS_WriteMask 0x00000000
+#define GC_TOTAL_READ_LASTS_ResetValue 0x00000000
+
+#define GC_TOTAL_READ_LASTS_COUNT 31 : 0
+#define GC_TOTAL_READ_LASTS_COUNT_End 31
+#define GC_TOTAL_READ_LASTS_COUNT_Start 0
+#define GC_TOTAL_READ_LASTS_COUNT_Type U32
+
+/*******************************************************************************
+** Register gcGpOut0
+*/
+
+/* General Purpose output register0. R/W but not connected to anywhere. */
+
+#define GC_GP_OUT0_Address 0x00064
+#define GC_GP_OUT0_MSB 15
+#define GC_GP_OUT0_LSB 0
+#define GC_GP_OUT0_BLK 0
+#define GC_GP_OUT0_Count 1
+#define GC_GP_OUT0_FieldMask 0xFFFFFFFF
+#define GC_GP_OUT0_ReadMask 0xFFFFFFFF
+#define GC_GP_OUT0_WriteMask 0xFFFFFFFF
+#define GC_GP_OUT0_ResetValue 0x00000000
+
+#define GC_GP_OUT0_COUNT 31 : 0
+#define GC_GP_OUT0_COUNT_End 31
+#define GC_GP_OUT0_COUNT_Start 0
+#define GC_GP_OUT0_COUNT_Type U32
+
+/*******************************************************************************
+** Register gcGpOut1
+*/
+
+/* General Purpose output register1. R/W but not connected to anywhere. */
+
+#define GC_GP_OUT1_Address 0x00068
+#define GC_GP_OUT1_MSB 15
+#define GC_GP_OUT1_LSB 0
+#define GC_GP_OUT1_BLK 0
+#define GC_GP_OUT1_Count 1
+#define GC_GP_OUT1_FieldMask 0xFFFFFFFF
+#define GC_GP_OUT1_ReadMask 0xFFFFFFFF
+#define GC_GP_OUT1_WriteMask 0xFFFFFFFF
+#define GC_GP_OUT1_ResetValue 0x00000000
+
+#define GC_GP_OUT1_COUNT 31 : 0
+#define GC_GP_OUT1_COUNT_End 31
+#define GC_GP_OUT1_COUNT_Start 0
+#define GC_GP_OUT1_COUNT_Type U32
+
+/*******************************************************************************
+** Register gcGpOut2
+*/
+
+/* General Purpose output register2. R/W but not connected to anywhere. */
+
+#define GC_GP_OUT2_Address 0x0006C
+#define GC_GP_OUT2_MSB 15
+#define GC_GP_OUT2_LSB 0
+#define GC_GP_OUT2_BLK 0
+#define GC_GP_OUT2_Count 1
+#define GC_GP_OUT2_FieldMask 0xFFFFFFFF
+#define GC_GP_OUT2_ReadMask 0xFFFFFFFF
+#define GC_GP_OUT2_WriteMask 0xFFFFFFFF
+#define GC_GP_OUT2_ResetValue 0x00000000
+
+#define GC_GP_OUT2_COUNT 31 : 0
+#define GC_GP_OUT2_COUNT_End 31
+#define GC_GP_OUT2_COUNT_Start 0
+#define GC_GP_OUT2_COUNT_Type U32
+
+/*******************************************************************************
+** Register gcAxiControl
+*/
+
+/* Special Handling on AXI Bus */
+
+#define GC_AXI_CONTROL_Address 0x00070
+#define GC_AXI_CONTROL_MSB 15
+#define GC_AXI_CONTROL_LSB 0
+#define GC_AXI_CONTROL_BLK 0
+#define GC_AXI_CONTROL_Count 1
+#define GC_AXI_CONTROL_FieldMask 0x00000001
+#define GC_AXI_CONTROL_ReadMask 0x00000001
+#define GC_AXI_CONTROL_WriteMask 0x00000001
+#define GC_AXI_CONTROL_ResetValue 0x00000000
+
+#define GC_AXI_CONTROL_WR_FULL_BURST_MODE 0 : 0
+#define GC_AXI_CONTROL_WR_FULL_BURST_MODE_End 0
+#define GC_AXI_CONTROL_WR_FULL_BURST_MODE_Start 0
+#define GC_AXI_CONTROL_WR_FULL_BURST_MODE_Type U01
+#define GC_AXI_CONTROL_WR_FULL_BURST_MODE_NO_BURST_RESET_VALUE 0x0
+#define GC_AXI_CONTROL_WR_FULL_BURST_MODE_BURST_RESET_VALUE 0x1
+
+/*******************************************************************************
+** Register gcTotalCycles
+*/
+
+/* Total cycles. This register is a free running counter. It can be reset by
+** writing 0 to it.
+*/
+
+#define GC_TOTAL_CYCLES_Address 0x00078
+#define GC_TOTAL_CYCLES_MSB 15
+#define GC_TOTAL_CYCLES_LSB 0
+#define GC_TOTAL_CYCLES_BLK 0
+#define GC_TOTAL_CYCLES_Count 1
+#define GC_TOTAL_CYCLES_FieldMask 0xFFFFFFFF
+#define GC_TOTAL_CYCLES_ReadMask 0xFFFFFFFF
+#define GC_TOTAL_CYCLES_WriteMask 0xFFFFFFFF
+#define GC_TOTAL_CYCLES_ResetValue 0x00000000
+
+#define GC_TOTAL_CYCLES_CYCLES 31 : 0
+#define GC_TOTAL_CYCLES_CYCLES_End 31
+#define GC_TOTAL_CYCLES_CYCLES_Start 0
+#define GC_TOTAL_CYCLES_CYCLES_Type U32
+
+/*******************************************************************************
+** Register gcTotalIdleCycles
+*/
+
+/* Total cycles where the GPU is idle. It is reset when gcTotalCycles register
+** is written to. It looks at all the blocks but FE when determining the IP is
+** idle.
+*/
+
+#define GC_TOTAL_IDLE_CYCLES_Address 0x0007C
+#define GC_TOTAL_IDLE_CYCLES_MSB 15
+#define GC_TOTAL_IDLE_CYCLES_LSB 0
+#define GC_TOTAL_IDLE_CYCLES_BLK 0
+#define GC_TOTAL_IDLE_CYCLES_Count 1
+#define GC_TOTAL_IDLE_CYCLES_FieldMask 0xFFFFFFFF
+#define GC_TOTAL_IDLE_CYCLES_ReadMask 0xFFFFFFFF
+#define GC_TOTAL_IDLE_CYCLES_WriteMask 0xFFFFFFFF
+#define GC_TOTAL_IDLE_CYCLES_ResetValue 0x00000000
+
+#define GC_TOTAL_IDLE_CYCLES_CYCLES 31 : 0
+#define GC_TOTAL_IDLE_CYCLES_CYCLES_End 31
+#define GC_TOTAL_IDLE_CYCLES_CYCLES_Start 0
+#define GC_TOTAL_IDLE_CYCLES_CYCLES_Type U32
+
+/*******************************************************************************
+** Command opcodes.
+*/
+
+#define GCREG_COMMAND_OPCODE_LOAD_STATE 0x01
+#define GCREG_COMMAND_OPCODE_END 0x02
+#define GCREG_COMMAND_OPCODE_NOP 0x03
+#define GCREG_COMMAND_OPCODE_STARTDE 0x04
+#define GCREG_COMMAND_OPCODE_WAIT 0x07
+#define GCREG_COMMAND_OPCODE_LINK 0x08
+#define GCREG_COMMAND_OPCODE_STALL 0x09
+#define GCREG_COMMAND_OPCODE_CALL 0x0A
+#define GCREG_COMMAND_OPCODE_RETURN 0x0B
+
+/*******************************************************************************
+** Command gcregCommandLoadState
+*/
+
+/* When enabled, convert 16.16 fixed point into 32-bit floating point. */
+#define GCREG_COMMAND_LOAD_STATE_FLOAT 26 : 26
+#define GCREG_COMMAND_LOAD_STATE_FLOAT_End 26
+#define GCREG_COMMAND_LOAD_STATE_FLOAT_Start 26
+#define GCREG_COMMAND_LOAD_STATE_FLOAT_Type U01
+#define GCREG_COMMAND_LOAD_STATE_FLOAT_NORMAL 0x0
+#define GCREG_COMMAND_LOAD_STATE_FLOAT_FIXED16_DOT16 0x1
+
+/* Number of states. 0 = 1024. */
+#define GCREG_COMMAND_LOAD_STATE_COUNT 25 : 16
+#define GCREG_COMMAND_LOAD_STATE_COUNT_End 25
+#define GCREG_COMMAND_LOAD_STATE_COUNT_Start 16
+#define GCREG_COMMAND_LOAD_STATE_COUNT_Type U10
+
+/* Starting state address. */
+#define GCREG_COMMAND_LOAD_STATE_ADDRESS 15 : 0
+#define GCREG_COMMAND_LOAD_STATE_ADDRESS_End 15
+#define GCREG_COMMAND_LOAD_STATE_ADDRESS_Start 0
+#define GCREG_COMMAND_LOAD_STATE_ADDRESS_Type U16
+
+#define GCREG_COMMAND_LOAD_STATE_OPCODE 31 : 27
+#define GCREG_COMMAND_LOAD_STATE_OPCODE_End 31
+#define GCREG_COMMAND_LOAD_STATE_OPCODE_Start 27
+#define GCREG_COMMAND_LOAD_STATE_OPCODE_Type U05
+
+struct gccmdldstate {
+ /* gcregCommandLoadState:GCREG_COMMAND_LOAD_STATE_ADDRESS */
+ unsigned int address:16;
+
+ /* gcregCommandLoadState:GCREG_COMMAND_LOAD_STATE_COUNT */
+ unsigned int count:10;
+
+ /* gcregCommandLoadState:GCREG_COMMAND_LOAD_STATE_FLOAT */
+ unsigned int fixed:1;
+
+ /* gcregCommandLoadState:GCREG_COMMAND_LOAD_STATE_OPCODE */
+ unsigned int opcode:5;
+};
+
+#define GCLDSTATE(Address, Count) \
+{ \
+ /* gcregCommandLoadState:GCREG_COMMAND_LOAD_STATE_ADDRESS */ \
+ Address, \
+ \
+ /* gcregCommandLoadState:GCREG_COMMAND_LOAD_STATE_COUNT */ \
+ Count, \
+ \
+ /* gcregCommandLoadState:GCREG_COMMAND_LOAD_STATE_FLOAT */ \
+ GCREG_COMMAND_LOAD_STATE_FLOAT_NORMAL, \
+ \
+ /* gcregCommandLoadState:GCREG_COMMAND_LOAD_STATE_OPCODE */ \
+ GCREG_COMMAND_OPCODE_LOAD_STATE \
+}
+
+/*******************************************************************************
+** Command gcregCommandEnd
+*/
+
+/* Send event when END is completed. */
+#define GCREG_COMMAND_END_EVENT 8 : 8
+#define GCREG_COMMAND_END_EVENT_End 8
+#define GCREG_COMMAND_END_EVENT_Start 8
+#define GCREG_COMMAND_END_EVENT_Type U01
+#define GCREG_COMMAND_END_EVENT_DISABLE 0x0
+#define GCREG_COMMAND_END_EVENT_ENABLE 0x1
+
+/* Event ID to be send. */
+#define GCREG_COMMAND_END_EVENT_ID 4 : 0
+#define GCREG_COMMAND_END_EVENT_ID_End 4
+#define GCREG_COMMAND_END_EVENT_ID_Start 0
+#define GCREG_COMMAND_END_EVENT_ID_Type U05
+
+#define GCREG_COMMAND_END_OPCODE 31 : 27
+#define GCREG_COMMAND_END_OPCODE_End 31
+#define GCREG_COMMAND_END_OPCODE_Start 27
+#define GCREG_COMMAND_END_OPCODE_Type U05
+
+struct gcfldend {
+ /* gcregCommandEnd:GCREG_COMMAND_END_EVENT_ID */
+ unsigned int signalid:5;
+
+ /* gcregCommandEnd:reserved */
+ unsigned int _reserved_5_7:3;
+
+ /* gcregCommandEnd:GCREG_COMMAND_END_EVENT_ENABLE */
+ unsigned int signal:1;
+
+ /* gcregCommandEnd:reserved */
+ unsigned int _reserved_9_26:18;
+
+ /* gcregCommandEnd:GCREG_COMMAND_END_OPCODE */
+ unsigned int opcode:5;
+};
+
+struct gccmdend {
+ union {
+ struct gcfldend fld;
+ unsigned int raw;
+ }
+ cmd;
+
+ /* Alignment filler. */
+ unsigned int _filler;
+};
+
+static const struct gccmdend gccmdend_const = {
+ /* cmd */
+ {
+ /* fld */
+ {
+ /* gcregCommandEnd:GCREG_COMMAND_END_EVENT_ID */
+ 0,
+
+ /* gcregCommandEnd:reserved */
+ 0,
+
+ /* gcregCommandEnd:GCREG_COMMAND_END_EVENT */
+ GCREG_COMMAND_END_EVENT_DISABLE,
+
+ /* gcregCommandEnd:reserved */
+ 0,
+
+ /* gcregCommandEnd:GCREG_COMMAND_END_OPCODE */
+ GCREG_COMMAND_OPCODE_END
+ }
+ },
+
+ /* Alignment filler. */
+ 0
+};
+
+/*******************************************************************************
+** Command gcregCommandNop
+*/
+
+#define GCREG_COMMAND_NOP_OPCODE 31 : 27
+#define GCREG_COMMAND_NOP_OPCODE_End 31
+#define GCREG_COMMAND_NOP_OPCODE_Start 27
+#define GCREG_COMMAND_NOP_OPCODE_Type U05
+
+struct gcfldnop {
+ /* gcregCommandNop:reserved */
+ unsigned int _reserved_0_26:27;
+
+ /* gcregCommandNop:GCREG_COMMAND_NOP_OPCODE */
+ unsigned int opcode:5;
+};
+
+struct gccmdnop {
+ union {
+ struct gcfldnop fld;
+ unsigned int raw;
+ }
+ cmd;
+
+ /* Alignment filler. */
+ unsigned int _filler;
+};
+
+static const struct gccmdnop gccmdnop_const = {
+ /* cmd */
+ {
+ /* fld */
+ {
+ /* gcregCommandNop:reserved */
+ 0,
+
+ /* gcregCommandNop:GCREG_COMMAND_NOP_OPCODE */
+ GCREG_COMMAND_OPCODE_NOP
+ }
+ },
+
+ /* Alignment filler. */
+ 0
+};
+
+/*******************************************************************************
+** Command gcregCommandStartDE
+*/
+
+/* Offset Command
+** ~~~~~~~~~~~~~~ */
+
+/* Number of 32-bit data words to send.
+** The data follows the rectangles, aligned at 64-bit.
+*/
+#define GCREG_COMMAND_STARTDE_DATA_COUNT 26 : 16
+#define GCREG_COMMAND_STARTDE_DATA_COUNT_End 26
+#define GCREG_COMMAND_STARTDE_DATA_COUNT_Start 16
+#define GCREG_COMMAND_STARTDE_DATA_COUNT_Type U11
+
+/* Number of rectangles to send.
+** The rectangles follow the command, aligned at 64-bit.
+*/
+#define GCREG_COMMAND_STARTDE_COUNT 15 : 8
+#define GCREG_COMMAND_STARTDE_COUNT_End 15
+#define GCREG_COMMAND_STARTDE_COUNT_Start 8
+#define GCREG_COMMAND_STARTDE_COUNT_Type U08
+
+#define GCREG_COMMAND_STARTDE_OPCODE 31 : 27
+#define GCREG_COMMAND_STARTDE_OPCODE_End 31
+#define GCREG_COMMAND_STARTDE_OPCODE_Start 27
+#define GCREG_COMMAND_STARTDE_OPCODE_Type U05
+
+struct gcfldstartde {
+ /* gcregCommandStartDE:reserved */
+ unsigned int _reserved_0_7:8;
+
+ /* gcregCommandStartDE:GCREG_COMMAND_STARTDE_COUNT */
+ unsigned int rectcount:8;
+
+ /* gcregCommandStartDE:GCREG_COMMAND_STARTDE_DATA_COUNT */
+ unsigned int datacount:11;
+
+ /* gcregCommandStartDE:GCREG_COMMAND_STARTDE_OPCODE */
+ unsigned int opcode:5;
+};
+
+struct gccmdstartde {
+ union {
+ struct gcfldstartde fld;
+ unsigned int raw;
+ } cmd;
+
+ /* Alignment filler. */
+ unsigned int _filler;
+};
+
+static const struct gcfldstartde gcfldstartde = {
+ /* gcregCommandStartDE:reserved */
+ 0,
+
+ /* gcregCommandStartDE:GCREG_COMMAND_STARTDE_COUNT */
+ 1,
+
+ /* gcregCommandStartDE:GCREG_COMMAND_STARTDE_DATA_COUNT */
+ 0,
+
+ /* gcregCommandStartDE:GCREG_COMMAND_STARTDE_OPCODE */
+ GCREG_COMMAND_OPCODE_STARTDE
+};
+
+/* Offset TopLeft
+** ~~~~~~~~~~~~~~ */
+
+#define GCREG_COMMAND_TOP_LEFT_Y 31 : 16
+#define GCREG_COMMAND_TOP_LEFT_Y_End 31
+#define GCREG_COMMAND_TOP_LEFT_Y_Start 16
+#define GCREG_COMMAND_TOP_LEFT_Y_Type U16
+
+#define GCREG_COMMAND_TOP_LEFT_X 15 : 0
+#define GCREG_COMMAND_TOP_LEFT_X_End 15
+#define GCREG_COMMAND_TOP_LEFT_X_Start 0
+#define GCREG_COMMAND_TOP_LEFT_X_Type U16
+
+/* Offset BottomRight
+** ~~~~~~~~~~~~~~~~~~ */
+
+#define GCREG_COMMAND_BOTTOM_RIGHT_Y 31 : 16
+#define GCREG_COMMAND_BOTTOM_RIGHT_Y_End 31
+#define GCREG_COMMAND_BOTTOM_RIGHT_Y_Start 16
+#define GCREG_COMMAND_BOTTOM_RIGHT_Y_Type U16
+
+#define GCREG_COMMAND_BOTTOM_RIGHT_X 15 : 0
+#define GCREG_COMMAND_BOTTOM_RIGHT_X_End 15
+#define GCREG_COMMAND_BOTTOM_RIGHT_X_Start 0
+#define GCREG_COMMAND_BOTTOM_RIGHT_X_Type U16
+
+struct gccmdstartderect {
+ /* GCREG_COMMAND_TOP_LEFT_X */
+ unsigned int left:16;
+
+ /* GCREG_COMMAND_TOP_LEFT_Y */
+ unsigned int top:16;
+
+ /* GCREG_COMMAND_BOTTOM_RIGHT_X */
+ unsigned int right:16;
+
+ /* GCREG_COMMAND_BOTTOM_RIGHT_Y */
+ unsigned int bottom:16;
+};
+
+/*******************************************************************************
+** Command gcregCommandWait
+*/
+
+/* Number of cycles to wait until the next command gets fetched. */
+#define GCREG_COMMAND_WAIT_DELAY 15 : 0
+#define GCREG_COMMAND_WAIT_DELAY_End 15
+#define GCREG_COMMAND_WAIT_DELAY_Start 0
+#define GCREG_COMMAND_WAIT_DELAY_Type U16
+
+#define GCREG_COMMAND_WAIT_OPCODE 31 : 27
+#define GCREG_COMMAND_WAIT_OPCODE_End 31
+#define GCREG_COMMAND_WAIT_OPCODE_Start 27
+#define GCREG_COMMAND_WAIT_OPCODE_Type U05
+
+struct gcfldwait {
+ /* gcregCommandWait:GCREG_COMMAND_WAIT_DELAY */
+ unsigned int delay:16;
+
+ /* gcregCommandWait:reserved */
+ unsigned int _reserved_16_26:11;
+
+ /* gcregCommandWait:GCREG_COMMAND_WAIT_OPCODE */
+ unsigned int opcode:5;
+};
+
+struct gccmdwait {
+ union {
+ struct gcfldwait fld;
+ unsigned int raw;
+ } cmd;
+
+ /* Alignment filler. */
+ unsigned int _filler;
+};
+
+static const struct gcfldwait gcfldwait200 = {
+ /* gcregCommandWait:GCREG_COMMAND_WAIT_DELAY */
+ 200,
+
+ /* gcregCommandWait:reserved */
+ 0,
+
+ /* gcregCommandWait:GCREG_COMMAND_WAIT_OPCODE */
+ GCREG_COMMAND_OPCODE_WAIT
+};
+
+/*******************************************************************************
+** Command gcregCommandLink
+*/
+
+/* Number of 64-bit words to fetch. Make sure this number is not too low,
+** nothing else will be fetched. So, make sure that the last command in the
+** new command buffer is either an END, a LINK, a CALL, or a RETURN.
+*/
+#define GCREG_COMMAND_LINK_PREFETCH 15 : 0
+#define GCREG_COMMAND_LINK_PREFETCH_End 15
+#define GCREG_COMMAND_LINK_PREFETCH_Start 0
+#define GCREG_COMMAND_LINK_PREFETCH_Type U16
+
+#define GCREG_COMMAND_LINK_OPCODE 31 : 27
+#define GCREG_COMMAND_LINK_OPCODE_End 31
+#define GCREG_COMMAND_LINK_OPCODE_Start 27
+#define GCREG_COMMAND_LINK_OPCODE_Type U05
+
+/* Offset Address
+** ~~~~~~~~~~~~~~ */
+#define GCREG_COMMAND_LINK_ADDRESS_Index 1
+#define GCREG_COMMAND_LINK_ADDRESS_CmdAddrs 0x0F0D
+
+#define GCREG_COMMAND_LINK_ADDRESS_ADDRESS 31 : 0
+#define GCREG_COMMAND_LINK_ADDRESS_ADDRESS_End 30
+#define GCREG_COMMAND_LINK_ADDRESS_ADDRESS_Start 0
+#define GCREG_COMMAND_LINK_ADDRESS_ADDRESS_Type U31
+
+struct gcfldlink {
+ /* gcregCommandLink:GCREG_COMMAND_LINK_PREFETCH */
+ unsigned int count:16;
+
+ /* gcregCommandLink:reserved */
+ unsigned int _reserved_16_26:11;
+
+ /* gcregCommandLink:GCREG_COMMAND_LINK_OPCODE */
+ unsigned int opcode:5;
+};
+
+struct gccmdlink {
+ union {
+ struct gcfldlink fld;
+ unsigned int raw;
+ } cmd;
+
+ /* gcregCommandLink:GCREG_COMMAND_LINK_ADDRESS_ADDRESS */
+ unsigned int address;
+};
+
+static const struct gcfldlink gcfldlink2 = {
+ /* gcregCommandLink:GCREG_COMMAND_LINK_PREFETCH */
+ 2,
+
+ /* gcregCommandLink:reserved */
+ 0,
+
+ /* gcregCommandLink:GCREG_COMMAND_LINK_OPCODE */
+ GCREG_COMMAND_OPCODE_LINK
+};
+
+static const struct gcfldlink gcfldlink4 = {
+ /* gcregCommandLink:GCREG_COMMAND_LINK_PREFETCH */
+ 4,
+
+ /* gcregCommandLink:reserved */
+ 0,
+
+ /* gcregCommandLink:GCREG_COMMAND_LINK_OPCODE */
+ GCREG_COMMAND_OPCODE_LINK
+};
+
+/*******************************************************************************
+** Command gcregCommandStall
+*/
+
+/* Offset Command
+** ~~~~~~~~~~~~~~ */
+#define GCREG_COMMAND_STALL_OPCODE 31 : 27
+#define GCREG_COMMAND_STALL_OPCODE_End 31
+#define GCREG_COMMAND_STALL_OPCODE_Start 27
+#define GCREG_COMMAND_STALL_OPCODE_Type U05
+
+/* Offset Stall
+** ~~~~~~~~~~~~ */
+#define GCREG_COMMAND_STALL_STALL_SOURCE 4 : 0
+#define GCREG_COMMAND_STALL_STALL_SOURCE_End 4
+#define GCREG_COMMAND_STALL_STALL_SOURCE_Start 0
+#define GCREG_COMMAND_STALL_STALL_SOURCE_Type U05
+#define GCREG_COMMAND_STALL_STALL_SOURCE_FRONT_END 0x01
+#define GCREG_COMMAND_STALL_STALL_SOURCE_PIXEL_ENGINE 0x07
+#define GCREG_COMMAND_STALL_STALL_SOURCE_DRAWING_ENGINE 0x0B
+
+#define GCREG_COMMAND_STALL_STALL_DESTINATION 12 : 8
+#define GCREG_COMMAND_STALL_STALL_DESTINATION_End 12
+#define GCREG_COMMAND_STALL_STALL_DESTINATION_Start 8
+#define GCREG_COMMAND_STALL_STALL_DESTINATION_Type U05
+#define GCREG_COMMAND_STALL_STALL_DESTINATION_FRONT_END 0x01
+#define GCREG_COMMAND_STALL_STALL_DESTINATION_PIXEL_ENGINE 0x07
+#define GCREG_COMMAND_STALL_STALL_DESTINATION_DRAWING_ENGINE 0x0B
+
+struct gcfldstall {
+ /* gcregCommandStall:reserved */
+ unsigned int _reserved_0_26:27;
+
+ /* gcregCommandStall:GCREG_COMMAND_STALL_OPCODE */
+ unsigned int opcode:5;
+};
+
+struct gcfldstallarg {
+ /* gcregCommandStall:GCREG_COMMAND_STALL_STALL_SOURCE */
+ unsigned int src:5;
+
+ /* gcregCommandStall:reserved */
+ unsigned int _reserved_5_7:3;
+
+ /* gcregCommandStall:GCREG_COMMAND_STALL_STALL_DESTINATION */
+ unsigned int dst:5;
+
+ /* gcregCommandStall:reserved */
+ unsigned int _reserved_13_31:19;
+};
+
+struct gccmdstall {
+ union {
+ struct gcfldstall fld;
+ unsigned int raw;
+ } cmd;
+
+ union {
+ struct gcfldstallarg fld;
+ unsigned int raw;
+ } arg;
+};
+
+static const struct gcfldstall gcfldstall = {
+ /* gcregCommandStall:reserved */
+ 0,
+
+ /* gcregCommandStall:GCREG_COMMAND_STALL_OPCODE */
+ GCREG_COMMAND_OPCODE_STALL
+};
+
+static const struct gcfldstallarg gcfldstall_fe_pe = {
+ /* gcregCommandStall:GCREG_COMMAND_STALL_STALL_SOURCE */
+ GCREG_COMMAND_STALL_STALL_SOURCE_FRONT_END,
+
+ /* gcregCommandStall:reserved */
+ 0,
+
+ /* gcregCommandStall:GCREG_COMMAND_STALL_STALL_DESTINATION */
+ GCREG_COMMAND_STALL_STALL_DESTINATION_PIXEL_ENGINE,
+
+ /* gcregCommandStall:reserved */
+ 0
+};
+
+/*******************************************************************************
+** Command gcregCommandCall
+*/
+
+/* Offset Command
+** ~~~~~~~~~~~~~~ */
+
+/* Number of 64-bit words to fetch. Make sure this number is not too low,
+** nothing else will be fetched. So, make sure that the last command in the
+** new command buffer is either an END, a LINK, a CALL, or a RETURN.
+*/
+#define GCREG_COMMAND_CALL_PREFETCH 15 : 0
+#define GCREG_COMMAND_CALL_PREFETCH_End 15
+#define GCREG_COMMAND_CALL_PREFETCH_Start 0
+#define GCREG_COMMAND_CALL_PREFETCH_Type U16
+
+#define GCREG_COMMAND_CALL_OPCODE 31 : 27
+#define GCREG_COMMAND_CALL_OPCODE_End 31
+#define GCREG_COMMAND_CALL_OPCODE_Start 27
+#define GCREG_COMMAND_CALL_OPCODE_Type U05
+
+/* Offset Address
+** ~~~~~~~~~~~~~~ */
+
+#define GCREG_COMMAND_CALL_ADDRESS_ADDRESS 31 : 0
+#define GCREG_COMMAND_CALL_ADDRESS_ADDRESS_End 30
+#define GCREG_COMMAND_CALL_ADDRESS_ADDRESS_Start 0
+#define GCREG_COMMAND_CALL_ADDRESS_ADDRESS_Type U31
+
+/* Offset ReturnPrefetch
+** ~~~~~~~~~~~~~~~~~~~~~ */
+
+/* Number of 64-bit words to fetch after a Return has been issued. Make sure **
+** this number if not too low nothing else will be fetched. So, make sure **
+** the last command in this prefetch block is either an END, a LINK, a CALL, **
+** or a RETURN. */
+#define GCREG_COMMAND_CALL_RETURN_PREFETCH_PREFETCH 15 : 0
+#define GCREG_COMMAND_CALL_RETURN_PREFETCH_PREFETCH_End 15
+#define GCREG_COMMAND_CALL_RETURN_PREFETCH_PREFETCH_Start 0
+#define GCREG_COMMAND_CALL_RETURN_PREFETCH_PREFETCH_Type U16
+
+/* Offset ReturnAddress
+** ~~~~~~~~~~~~~~~~~~~~ */
+
+#define GCREG_COMMAND_CALL_RETURN_ADDRESS_ADDRESS 31 : 0
+#define GCREG_COMMAND_CALL_RETURN_ADDRESS_ADDRESS_End 30
+#define GCREG_COMMAND_CALL_RETURN_ADDRESS_ADDRESS_Start 0
+#define GCREG_COMMAND_CALL_RETURN_ADDRESS_ADDRESS_Type U31
+
+struct gccmdcall {
+ /* gcregCommandCall:GCREG_COMMAND_CALL_PREFETCH */
+ unsigned int count:16;
+
+ /* gcregCommandCall:reserved */
+ unsigned int _reserved_16_26:11;
+
+ /* gcregCommandCall:GCREG_COMMAND_CALL_OPCODE */
+ unsigned int opcode:5;
+
+ /* gcregCommandCall:GCREG_COMMAND_CALL_ADDRESS_ADDRESS */
+ unsigned int address;
+
+ /* gcregCommandCall:GCREG_COMMAND_CALL_RETURN_PREFETCH_PREFETCH */
+ unsigned int retcount;
+
+ /* gcregCommandCall:GCREG_COMMAND_CALL_RETURN_ADDRESS_ADDRESS */
+ unsigned int retaddress;
+};
+
+/*******************************************************************************
+** Command gccmdCommandReturn
+*/
+
+#define GCREG_COMMAND_RETURN_OPCODE 31 : 27
+#define GCREG_COMMAND_RETURN_OPCODE_End 31
+#define GCREG_COMMAND_RETURN_OPCODE_Start 27
+#define GCREG_COMMAND_RETURN_OPCODE_Type U05
+
+struct gcfldret {
+ /* gccmdCommandReturn:reserved */
+ unsigned int _reserved_0_26:27;
+
+ /* gccmdCommandReturn:GCREG_COMMAND_RETURN_OPCODE */
+ unsigned int opcode:5;
+};
+
+struct gccmdret {
+ union {
+ struct gcfldret fld;
+ unsigned int raw;
+ }
+ cmd;
+
+ /* Alignment filler. */
+ unsigned int _filler;
+};
+
+static const struct gcfldret gcfldret = {
+ /* gccmdCommandReturn:reserved */
+ 0,
+
+ /* gccmdCommandReturn:GCREG_COMMAND_RETURN_OPCODE */
+ GCREG_COMMAND_OPCODE_RETURN
+};
+
+/*******************************************************************************
+** State gcregStall
+*/
+
+#define gcregStallRegAddrs 0x0F00
+#define GCREG_STALL_Count 1
+#define GCREG_STALL_ResetValue 0x00000000
+
+#define GCREG_STALL_FLIP0 30 : 30
+#define GCREG_STALL_FLIP0_End 30
+#define GCREG_STALL_FLIP0_Start 30
+#define GCREG_STALL_FLIP0_Type U01
+
+#define GCREG_STALL_FLIP1 31 : 31
+#define GCREG_STALL_FLIP1_End 31
+#define GCREG_STALL_FLIP1_Start 31
+#define GCREG_STALL_FLIP1_Type U01
+
+#define GCREG_STALL_SOURCE 4 : 0
+#define GCREG_STALL_SOURCE_End 4
+#define GCREG_STALL_SOURCE_Start 0
+#define GCREG_STALL_SOURCE_Type U05
+#define GCREG_STALL_SOURCE_FRONT_END 0x01
+#define GCREG_STALL_SOURCE_PIXEL_ENGINE 0x07
+#define GCREG_STALL_SOURCE_DRAWING_ENGINE 0x0B
+
+#define GCREG_STALL_DESTINATION 12 : 8
+#define GCREG_STALL_DESTINATION_End 12
+#define GCREG_STALL_DESTINATION_Start 8
+#define GCREG_STALL_DESTINATION_Type U05
+#define GCREG_STALL_DESTINATION_FRONT_END 0x01
+#define GCREG_STALL_DESTINATION_PIXEL_ENGINE 0x07
+#define GCREG_STALL_DESTINATION_DRAWING_ENGINE 0x0B
+
+/*******************************************************************************
+** State gcregPipeSelect
+*/
+
+/* Select the current graphics pipe. */
+
+#define gcregPipeSelectRegAddrs 0x0E00
+#define GCREG_PIPE_SELECT_MSB 15
+#define GCREG_PIPE_SELECT_LSB 0
+#define GCREG_PIPE_SELECT_BLK 0
+#define GCREG_PIPE_SELECT_Count 1
+#define GCREG_PIPE_SELECT_FieldMask 0x00000001
+#define GCREG_PIPE_SELECT_ReadMask 0x00000001
+#define GCREG_PIPE_SELECT_WriteMask 0x00000001
+#define GCREG_PIPE_SELECT_ResetValue 0x00000000
+
+/* Selects the pipe to send states and data to. Make sure the PE is idle **
+** before you switch pipes. */
+#define GCREG_PIPE_SELECT_PIPE 0 : 0
+#define GCREG_PIPE_SELECT_PIPE_End 0
+#define GCREG_PIPE_SELECT_PIPE_Start 0
+#define GCREG_PIPE_SELECT_PIPE_Type U01
+#define GCREG_PIPE_SELECT_PIPE_PIPE3D 0x0
+#define GCREG_PIPE_SELECT_PIPE_PIPE2D 0x1
+
+struct gcregpipeselect {
+ /* gcregPipeSelectRegAddrs:GCREG_PIPE_SELECT_PIPE */
+ unsigned int pipe:1;
+
+ /* gcregPipeSelectRegAddrs:reserved */
+ unsigned int _reserved_1_31:31;
+};
+
+static const struct gcregpipeselect gcregpipeselect_2D = {
+ /* gcregPipeSelectRegAddrs:GCREG_PIPE_SELECT_PIPE */
+ GCREG_PIPE_SELECT_PIPE_PIPE2D,
+
+ /* gcregPipeSelectRegAddrs:reserved */
+ 0
+};
+
+static const struct gcregpipeselect gcregpipeselect_3D = {
+ /* gcregPipeSelectRegAddrs:GCREG_PIPE_SELECT_PIPE */
+ GCREG_PIPE_SELECT_PIPE_PIPE3D,
+
+ /* gcregPipeSelectRegAddrs:reserved */
+ 0
+};
+
+/*******************************************************************************
+** State gcregEvent
+*/
+
+/* Send an event. */
+
+#define gcregEventRegAddrs 0x0E01
+#define GCREG_EVENT_MSB 15
+#define GCREG_EVENT_LSB 0
+#define GCREG_EVENT_BLK 0
+#define GCREG_EVENT_Count 1
+#define GCREG_EVENT_FieldMask 0x0000007F
+#define GCREG_EVENT_ReadMask 0x0000007F
+#define GCREG_EVENT_WriteMask 0x0000007F
+#define GCREG_EVENT_ResetValue 0x00000000
+
+/* 5-bit event ID to send. */
+#define GCREG_EVENT_EVENT_ID 4 : 0
+#define GCREG_EVENT_EVENT_ID_End 4
+#define GCREG_EVENT_EVENT_ID_Start 0
+#define GCREG_EVENT_EVENT_ID_Type U05
+
+/* The event is sent by the FE. */
+#define GCREG_EVENT_FE_SRC 5 : 5
+#define GCREG_EVENT_FE_SRC_End 5
+#define GCREG_EVENT_FE_SRC_Start 5
+#define GCREG_EVENT_FE_SRC_Type U01
+#define GCREG_EVENT_FE_SRC_DISABLE 0x0
+#define GCREG_EVENT_FE_SRC_ENABLE 0x1
+
+/* The event is sent by the PE. */
+#define GCREG_EVENT_PE_SRC 6 : 6
+#define GCREG_EVENT_PE_SRC_End 6
+#define GCREG_EVENT_PE_SRC_Start 6
+#define GCREG_EVENT_PE_SRC_Type U01
+#define GCREG_EVENT_PE_SRC_DISABLE 0x0
+#define GCREG_EVENT_PE_SRC_ENABLE 0x1
+
+struct gcregevent {
+ /* gcregEventRegAddrs:GCREG_EVENT_EVENT_ID */
+ unsigned int id:5;
+
+ /* gcregEventRegAddrs:GCREG_EVENT_FE_SRC */
+ unsigned int fe:1;
+
+ /* gcregEventRegAddrs:GCREG_EVENT_PE_SRC */
+ unsigned int pe:1;
+
+ /* gcregEventRegAddrs:reserved */
+ unsigned int _reserved_7_31:25;
+};
+
+/*******************************************************************************
+** State gcregSemaphore
+*/
+
+/* A sempahore state arms the semaphore in the destination. */
+
+#define gcregSemaphoreRegAddrs 0x0E02
+#define GCREG_SEMAPHORE_MSB 15
+#define GCREG_SEMAPHORE_LSB 0
+#define GCREG_SEMAPHORE_BLK 0
+#define GCREG_SEMAPHORE_Count 1
+#define GCREG_SEMAPHORE_FieldMask 0x00001F1F
+#define GCREG_SEMAPHORE_ReadMask 0x00001F1F
+#define GCREG_SEMAPHORE_WriteMask 0x00001F1F
+#define GCREG_SEMAPHORE_ResetValue 0x00000000
+
+#define GCREG_SEMAPHORE_SOURCE 4 : 0
+#define GCREG_SEMAPHORE_SOURCE_End 4
+#define GCREG_SEMAPHORE_SOURCE_Start 0
+#define GCREG_SEMAPHORE_SOURCE_Type U05
+#define GCREG_SEMAPHORE_SOURCE_FRONT_END 0x01
+#define GCREG_SEMAPHORE_SOURCE_PIXEL_ENGINE 0x07
+#define GCREG_SEMAPHORE_SOURCE_DRAWING_ENGINE 0x0B
+
+#define GCREG_SEMAPHORE_DESTINATION 12 : 8
+#define GCREG_SEMAPHORE_DESTINATION_End 12
+#define GCREG_SEMAPHORE_DESTINATION_Start 8
+#define GCREG_SEMAPHORE_DESTINATION_Type U05
+#define GCREG_SEMAPHORE_DESTINATION_FRONT_END 0x01
+#define GCREG_SEMAPHORE_DESTINATION_PIXEL_ENGINE 0x07
+#define GCREG_SEMAPHORE_DESTINATION_DRAWING_ENGINE 0x0B
+
+struct gcregsemaphore {
+ /* gcregSemaphoreRegAddrs:GCREG_SEMAPHORE_SOURCE */
+ unsigned int src:5;
+
+ /* gcregSemaphoreRegAddrs:reserved */
+ unsigned int _reserved_5_7:3;
+
+ /* gcregSemaphoreRegAddrs:GCREG_SEMAPHORE_DESTINATION */
+ unsigned int dst:5;
+
+ /* gcregSemaphoreRegAddrs:reserved */
+ unsigned int _reserved_13_31:19;
+};
+
+static const struct gcregsemaphore gcregsema_fe_pe = {
+ /* gcregSemaphoreRegAddrs:GCREG_SEMAPHORE_SOURCE */
+ GCREG_SEMAPHORE_SOURCE_FRONT_END,
+
+ /* gcregSemaphoreRegAddrs:reserved */
+ 0,
+
+ /* gcregSemaphoreRegAddrs:GCREG_SEMAPHORE_DESTINATION */
+ GCREG_SEMAPHORE_DESTINATION_PIXEL_ENGINE,
+
+ /* gcregSemaphoreRegAddrs:reserved */
+ 0
+};
+
+
+/*******************************************************************************
+** State gcregFlush
+*/
+
+/* Flush the current pipe. */
+
+#define gcregFlushRegAddrs 0x0E03
+#define GCREG_FLUSH_MSB 15
+#define GCREG_FLUSH_LSB 0
+#define GCREG_FLUSH_BLK 0
+#define GCREG_FLUSH_Count 1
+#define GCREG_FLUSH_FieldMask 0x00000008
+#define GCREG_FLUSH_ReadMask 0x00000008
+#define GCREG_FLUSH_WriteMask 0x00000008
+#define GCREG_FLUSH_ResetValue 0x00000000
+
+/* Flush the 2D pixel cache. */
+#define GCREG_FLUSH_PE2D_CACHE 3 : 3
+#define GCREG_FLUSH_PE2D_CACHE_End 3
+#define GCREG_FLUSH_PE2D_CACHE_Start 3
+#define GCREG_FLUSH_PE2D_CACHE_Type U01
+#define GCREG_FLUSH_PE2D_CACHE_DISABLE 0x0
+#define GCREG_FLUSH_PE2D_CACHE_ENABLE 0x1
+
+struct gcregflush {
+ /* gcregFlushRegAddrs:reserved */
+ unsigned int _reserved_0_2:3;
+
+ /* gcregFlushRegAddrs:GCREG_FLUSH_PE2D_CACHE */
+ unsigned int enable:1;
+
+ /* gcregFlushRegAddrs:reserved */
+ unsigned int _reserved_4_31:28;
+};
+
+static const struct gcregflush gcregflush_pe2D = {
+ /* gcregFlushRegAddrs:reserved */
+ 0,
+
+ /* gcregFlushRegAddrs:GCREG_FLUSH_PE2D_CACHE */
+ GCREG_FLUSH_PE2D_CACHE_ENABLE,
+
+ /* gcregFlushRegAddrs:reserved */
+ 0
+};
+
+/*******************************************************************************
+** State gcregMMUFlush
+*/
+
+/* Flush the virtual addrses lookup cache inside the MC. */
+
+#define gcregMMUFlushRegAddrs 0x0E04
+#define gcregMMU_FLUSH_MSB 15
+#define gcregMMU_FLUSH_LSB 0
+#define gcregMMU_FLUSH_BLK 0
+#define gcregMMU_FLUSH_Count 1
+#define gcregMMU_FLUSH_FieldMask 0x00000009
+#define gcregMMU_FLUSH_ReadMask 0x00000009
+#define gcregMMU_FLUSH_WriteMask 0x00000009
+#define gcregMMU_FLUSH_ResetValue 0x00000000
+
+/* Flush the FE address translation caches. */
+#define gcregMMU_FLUSH_FEMMU 0 : 0
+#define gcregMMU_FLUSH_FEMMU_End 0
+#define gcregMMU_FLUSH_FEMMU_Start 0
+#define gcregMMU_FLUSH_FEMMU_Type U01
+#define gcregMMU_FLUSH_FEMMU_DISABLE 0x0
+#define gcregMMU_FLUSH_FEMMU_ENABLE 0x1
+
+/* Flush the PE render target address translation caches. */
+#define gcregMMU_FLUSH_PEMMU 3 : 3
+#define gcregMMU_FLUSH_PEMMU_End 3
+#define gcregMMU_FLUSH_PEMMU_Start 3
+#define gcregMMU_FLUSH_PEMMU_Type U01
+#define gcregMMU_FLUSH_PEMMU_DISABLE 0x0
+#define gcregMMU_FLUSH_PEMMU_ENABLE 0x1
+
+/*******************************************************************************
+** Register gcregCmdBufferAddr
+*/
+
+/* Base address for the command buffer. The address must be 64-bit aligned
+** and it is always physical. This register cannot be read. To check the value
+** of the current fetch address use gcregFEDebugCurCmdAdr. Since this is a write
+** only register is has no reset value.
+*/
+
+#define GCREG_CMD_BUFFER_ADDR_Address 0x00654
+#define GCREG_CMD_BUFFER_ADDR_MSB 15
+#define GCREG_CMD_BUFFER_ADDR_LSB 0
+#define GCREG_CMD_BUFFER_ADDR_BLK 0
+#define GCREG_CMD_BUFFER_ADDR_Count 1
+#define GCREG_CMD_BUFFER_ADDR_FieldMask 0xFFFFFFFF
+#define GCREG_CMD_BUFFER_ADDR_ReadMask 0x00000000
+#define GCREG_CMD_BUFFER_ADDR_WriteMask 0xFFFFFFFC
+#define GCREG_CMD_BUFFER_ADDR_ResetValue 0x00000000
+
+#define GCREG_CMD_BUFFER_ADDR_ADDRESS 31 : 0
+#define GCREG_CMD_BUFFER_ADDR_ADDRESS_End 30
+#define GCREG_CMD_BUFFER_ADDR_ADDRESS_Start 0
+#define GCREG_CMD_BUFFER_ADDR_ADDRESS_Type U31
+
+/*******************************************************************************
+** Register gcregCmdBufferCtrl
+*/
+
+/* Since this is a write only register is has no reset value. */
+
+#define GCREG_CMD_BUFFER_CTRL_Address 0x00658
+#define GCREG_CMD_BUFFER_CTRL_MSB 15
+#define GCREG_CMD_BUFFER_CTRL_LSB 0
+#define GCREG_CMD_BUFFER_CTRL_BLK 0
+#define GCREG_CMD_BUFFER_CTRL_Count 1
+#define GCREG_CMD_BUFFER_CTRL_FieldMask 0x0001FFFF
+#define GCREG_CMD_BUFFER_CTRL_ReadMask 0x00010000
+#define GCREG_CMD_BUFFER_CTRL_WriteMask 0x0001FFFF
+#define GCREG_CMD_BUFFER_CTRL_ResetValue 0x00000000
+
+/* Number of 64-bit words to fetch from the command buffer. */
+#define GCREG_CMD_BUFFER_CTRL_PREFETCH 15 : 0
+#define GCREG_CMD_BUFFER_CTRL_PREFETCH_End 15
+#define GCREG_CMD_BUFFER_CTRL_PREFETCH_Start 0
+#define GCREG_CMD_BUFFER_CTRL_PREFETCH_Type U16
+
+/* Enable the command parser. */
+#define GCREG_CMD_BUFFER_CTRL_ENABLE 16 : 16
+#define GCREG_CMD_BUFFER_CTRL_ENABLE_End 16
+#define GCREG_CMD_BUFFER_CTRL_ENABLE_Start 16
+#define GCREG_CMD_BUFFER_CTRL_ENABLE_Type U01
+#define GCREG_CMD_BUFFER_CTRL_ENABLE_DISABLE 0x0
+#define GCREG_CMD_BUFFER_CTRL_ENABLE_ENABLE 0x1
+
+/*******************************************************************************
+** Register gcregFEDebugState
+*/
+
+#define GCREG_FE_DEBUG_STATE_Address 0x00660
+#define GCREG_FE_DEBUG_STATE_MSB 15
+#define GCREG_FE_DEBUG_STATE_LSB 0
+#define GCREG_FE_DEBUG_STATE_BLK 0
+#define GCREG_FE_DEBUG_STATE_Count 1
+#define GCREG_FE_DEBUG_STATE_FieldMask 0x0003FF1F
+#define GCREG_FE_DEBUG_STATE_ReadMask 0x0003FF1F
+#define GCREG_FE_DEBUG_STATE_WriteMask 0x00000000
+#define GCREG_FE_DEBUG_STATE_ResetValue 0x00000000
+
+#define GCREG_FE_DEBUG_STATE_CMD_STATE 4 : 0
+#define GCREG_FE_DEBUG_STATE_CMD_STATE_End 4
+#define GCREG_FE_DEBUG_STATE_CMD_STATE_Start 0
+#define GCREG_FE_DEBUG_STATE_CMD_STATE_Type U05
+
+#define GCREG_FE_DEBUG_STATE_CMD_DMA_STATE 9 : 8
+#define GCREG_FE_DEBUG_STATE_CMD_DMA_STATE_End 9
+#define GCREG_FE_DEBUG_STATE_CMD_DMA_STATE_Start 8
+#define GCREG_FE_DEBUG_STATE_CMD_DMA_STATE_Type U02
+
+#define GCREG_FE_DEBUG_STATE_CMD_FETCH_STATE 11 : 10
+#define GCREG_FE_DEBUG_STATE_CMD_FETCH_STATE_End 11
+#define GCREG_FE_DEBUG_STATE_CMD_FETCH_STATE_Start 10
+#define GCREG_FE_DEBUG_STATE_CMD_FETCH_STATE_Type U02
+
+#define GCREG_FE_DEBUG_STATE_REQ_DMA_STATE 13 : 12
+#define GCREG_FE_DEBUG_STATE_REQ_DMA_STATE_End 13
+#define GCREG_FE_DEBUG_STATE_REQ_DMA_STATE_Start 12
+#define GCREG_FE_DEBUG_STATE_REQ_DMA_STATE_Type U02
+
+#define GCREG_FE_DEBUG_STATE_CAL_STATE 15 : 14
+#define GCREG_FE_DEBUG_STATE_CAL_STATE_End 15
+#define GCREG_FE_DEBUG_STATE_CAL_STATE_Start 14
+#define GCREG_FE_DEBUG_STATE_CAL_STATE_Type U02
+
+#define GCREG_FE_DEBUG_STATE_VE_REQ_STATE 17 : 16
+#define GCREG_FE_DEBUG_STATE_VE_REQ_STATE_End 17
+#define GCREG_FE_DEBUG_STATE_VE_REQ_STATE_Start 16
+#define GCREG_FE_DEBUG_STATE_VE_REQ_STATE_Type U02
+
+/*******************************************************************************
+** Register gcregFEDebugCurCmdAdr
+*/
+
+/* This is the command decoder address. The address is always physical so
+** the MSB should always be 0. It has no reset value.
+*/
+
+#define GCREG_FE_DEBUG_CUR_CMD_ADR_Address 0x00664
+#define GCREG_FE_DEBUG_CUR_CMD_ADR_MSB 15
+#define GCREG_FE_DEBUG_CUR_CMD_ADR_LSB 0
+#define GCREG_FE_DEBUG_CUR_CMD_ADR_BLK 0
+#define GCREG_FE_DEBUG_CUR_CMD_ADR_Count 1
+#define GCREG_FE_DEBUG_CUR_CMD_ADR_FieldMask 0xFFFFFFF8
+#define GCREG_FE_DEBUG_CUR_CMD_ADR_ReadMask 0xFFFFFFF8
+#define GCREG_FE_DEBUG_CUR_CMD_ADR_WriteMask 0x00000000
+#define GCREG_FE_DEBUG_CUR_CMD_ADR_ResetValue 0x00000000
+
+#define GCREG_FE_DEBUG_CUR_CMD_ADR_CUR_CMD_ADR 31 : 3
+#define GCREG_FE_DEBUG_CUR_CMD_ADR_CUR_CMD_ADR_End 31
+#define GCREG_FE_DEBUG_CUR_CMD_ADR_CUR_CMD_ADR_Start 3
+#define GCREG_FE_DEBUG_CUR_CMD_ADR_CUR_CMD_ADR_Type U29
+
+/*******************************************************************************
+** Register gcregFEDebugCmdLowReg
+*/
+
+#define GCREG_FE_DEBUG_CMD_LOW_REG_Address 0x00668
+#define GCREG_FE_DEBUG_CMD_LOW_REG_MSB 15
+#define GCREG_FE_DEBUG_CMD_LOW_REG_LSB 0
+#define GCREG_FE_DEBUG_CMD_LOW_REG_BLK 0
+#define GCREG_FE_DEBUG_CMD_LOW_REG_Count 1
+#define GCREG_FE_DEBUG_CMD_LOW_REG_FieldMask 0xFFFFFFFF
+#define GCREG_FE_DEBUG_CMD_LOW_REG_ReadMask 0xFFFFFFFF
+#define GCREG_FE_DEBUG_CMD_LOW_REG_WriteMask 0x00000000
+#define GCREG_FE_DEBUG_CMD_LOW_REG_ResetValue 0x00000000
+
+/* Command register used by CmdState. */
+#define GCREG_FE_DEBUG_CMD_LOW_REG_CMD_LOW_REG 31 : 0
+#define GCREG_FE_DEBUG_CMD_LOW_REG_CMD_LOW_REG_End 31
+#define GCREG_FE_DEBUG_CMD_LOW_REG_CMD_LOW_REG_Start 0
+#define GCREG_FE_DEBUG_CMD_LOW_REG_CMD_LOW_REG_Type U32
+
+/*******************************************************************************
+** Register gcregFEDebugCmdHiReg
+*/
+
+#define GCREG_FE_DEBUG_CMD_HI_REG_Address 0x0066C
+#define GCREG_FE_DEBUG_CMD_HI_REG_MSB 15
+#define GCREG_FE_DEBUG_CMD_HI_REG_LSB 0
+#define GCREG_FE_DEBUG_CMD_HI_REG_BLK 0
+#define GCREG_FE_DEBUG_CMD_HI_REG_Count 1
+#define GCREG_FE_DEBUG_CMD_HI_REG_FieldMask 0xFFFFFFFF
+#define GCREG_FE_DEBUG_CMD_HI_REG_ReadMask 0xFFFFFFFF
+#define GCREG_FE_DEBUG_CMD_HI_REG_WriteMask 0x00000000
+#define GCREG_FE_DEBUG_CMD_HI_REG_ResetValue 0x00000000
+
+/* Command register used by CmdState. */
+#define GCREG_FE_DEBUG_CMD_HI_REG_CMD_HI_REG 31 : 0
+#define GCREG_FE_DEBUG_CMD_HI_REG_CMD_HI_REG_End 31
+#define GCREG_FE_DEBUG_CMD_HI_REG_CMD_HI_REG_Start 0
+#define GCREG_FE_DEBUG_CMD_HI_REG_CMD_HI_REG_Type U32
+
+/*******************************************************************************
+** State gcregMMUSafeAddress
+*/
+
+/* A 64-byte address that will acts as a 'safe' zone. Any address that would
+** cause an exception is routed to this safe zone. Reads will happend and
+** writes will go to this address, but with a write-enable of 0. This
+** register can only be programmed once after a reset - any attempt to write
+** to this register after the initial write-after-reset will be ignored.
+*/
+
+#define gcregMMUSafeAddressRegAddrs 0x0060
+#define GCREG_MMU_SAFE_ADDRESS_MSB 15
+#define GCREG_MMU_SAFE_ADDRESS_LSB 0
+#define GCREG_MMU_SAFE_ADDRESS_BLK 0
+#define GCREG_MMU_SAFE_ADDRESS_Count 1
+#define GCREG_MMU_SAFE_ADDRESS_FieldMask 0xFFFFFFFF
+#define GCREG_MMU_SAFE_ADDRESS_ReadMask 0xFFFFFFC0
+#define GCREG_MMU_SAFE_ADDRESS_WriteMask 0xFFFFFFC0
+#define GCREG_MMU_SAFE_ADDRESS_ResetValue 0x00000000
+
+#define GCREG_MMU_SAFE_ADDRESS_ADDRESS 31 : 0
+#define GCREG_MMU_SAFE_ADDRESS_ADDRESS_End 31
+#define GCREG_MMU_SAFE_ADDRESS_ADDRESS_Start 0
+#define GCREG_MMU_SAFE_ADDRESS_ADDRESS_Type U32
+
+/*******************************************************************************
+** State gcregMMUConfiguration
+*/
+
+/* This register controls the master TLB of the MMU. */
+
+#define gcregMMUConfigurationRegAddrs 0x0061
+#define GCREG_MMU_CONFIGURATION_MSB 15
+#define GCREG_MMU_CONFIGURATION_LSB 0
+#define GCREG_MMU_CONFIGURATION_BLK 0
+#define GCREG_MMU_CONFIGURATION_Count 1
+#define GCREG_MMU_CONFIGURATION_FieldMask 0xFFFFFD99
+#define GCREG_MMU_CONFIGURATION_ReadMask 0xFFFFFD99
+#define GCREG_MMU_CONFIGURATION_WriteMask 0xFFFFFD99
+#define GCREG_MMU_CONFIGURATION_ResetValue 0x00000000
+
+/* Upper bits of the page aligned (depending on the mode) master TLB. */
+#define GCREG_MMU_CONFIGURATION_ADDRESS 31 : 10
+#define GCREG_MMU_CONFIGURATION_ADDRESS_End 31
+#define GCREG_MMU_CONFIGURATION_ADDRESS_Start 10
+#define GCREG_MMU_CONFIGURATION_ADDRESS_Type U22
+
+/* Mask for Address field. */
+#define GCREG_MMU_CONFIGURATION_MASK_ADDRESS 8 : 8
+#define GCREG_MMU_CONFIGURATION_MASK_ADDRESS_End 8
+#define GCREG_MMU_CONFIGURATION_MASK_ADDRESS_Start 8
+#define GCREG_MMU_CONFIGURATION_MASK_ADDRESS_Type U01
+#define GCREG_MMU_CONFIGURATION_MASK_ADDRESS_ENABLED 0x0
+#define GCREG_MMU_CONFIGURATION_MASK_ADDRESS_MASKED 0x1
+
+/* Mask Flush field. */
+#define GCREG_MMU_CONFIGURATION_MASK_FLUSH 7 : 7
+#define GCREG_MMU_CONFIGURATION_MASK_FLUSH_End 7
+#define GCREG_MMU_CONFIGURATION_MASK_FLUSH_Start 7
+#define GCREG_MMU_CONFIGURATION_MASK_FLUSH_Type U01
+#define GCREG_MMU_CONFIGURATION_MASK_FLUSH_ENABLED 0x0
+#define GCREG_MMU_CONFIGURATION_MASK_FLUSH_MASKED 0x1
+
+/* Flush the MMU caches. */
+#define GCREG_MMU_CONFIGURATION_FLUSH 4 : 4
+#define GCREG_MMU_CONFIGURATION_FLUSH_End 4
+#define GCREG_MMU_CONFIGURATION_FLUSH_Start 4
+#define GCREG_MMU_CONFIGURATION_FLUSH_Type U01
+#define GCREG_MMU_CONFIGURATION_FLUSH_FLUSH 0x1
+
+/* Mask Mode field. */
+#define GCREG_MMU_CONFIGURATION_MASK_MODE 3 : 3
+#define GCREG_MMU_CONFIGURATION_MASK_MODE_End 3
+#define GCREG_MMU_CONFIGURATION_MASK_MODE_Start 3
+#define GCREG_MMU_CONFIGURATION_MASK_MODE_Type U01
+#define GCREG_MMU_CONFIGURATION_MASK_MODE_ENABLED 0x0
+#define GCREG_MMU_CONFIGURATION_MASK_MODE_MASKED 0x1
+
+/* Set the mode for the Master TLB. */
+#define GCREG_MMU_CONFIGURATION_MODE 0 : 0
+#define GCREG_MMU_CONFIGURATION_MODE_End 0
+#define GCREG_MMU_CONFIGURATION_MODE_Start 0
+#define GCREG_MMU_CONFIGURATION_MODE_Type U01
+/* The Master TLB is 4kB in size and contains 1024 entries. Each page can be **
+** 4kB or 64kB in size. */
+#define GCREG_MMU_CONFIGURATION_MODE_MODE4_K 0x0
+/* The Master TLB is 1kB in size and contains 256 entries. Each page can be **
+** 4kB, 64kB, 1MB or 16MB in size. */
+#define GCREG_MMU_CONFIGURATION_MODE_MODE1_K 0x1
+
+struct gcregmmuconfiguration {
+ /* gcregMMUConfiguration:GCREG_MMU_CONFIGURATION_MODE */
+ unsigned int master:1;
+
+ /* gcregMMUConfiguration:reserved */
+ unsigned int _reserved_1_2:2;
+
+ /* gcregMMUConfiguration:GCREG_MMU_CONFIGURATION_MASK_MODE */
+ unsigned int master_mask:1;
+
+ /* gcregMMUConfiguration:GCREG_MMU_CONFIGURATION_FLUSH */
+ unsigned int flush:1;
+
+ /* gcregMMUConfiguration:reserved */
+ unsigned int _reserved_5_6:2;
+
+ /* gcregMMUConfiguration:GCREG_MMU_CONFIGURATION_MASK_FLUSH */
+ unsigned int flush_mask:1;
+
+ /* gcregMMUConfiguration:GCREG_MMU_CONFIGURATION_MASK_ADDRESS */
+ unsigned int address_mask:1;
+
+ /* gcregMMUConfiguration:reserved */
+ unsigned int _reserved_9:1;
+
+ /* gcregMMUConfiguration:GCREG_MMU_CONFIGURATION_ADDRESS */
+ unsigned int address:22;
+};
+
+static const struct gcregmmuconfiguration gcregmmu_flush = {
+ /* gcregMMUConfiguration:GCREG_MMU_CONFIGURATION_MODE */
+ 0,
+
+ /* gcregMMUConfiguration:reserved */
+ 0,
+
+ /* gcregMMUConfiguration:GCREG_MMU_CONFIGURATION_MASK_MODE */
+ GCREG_MMU_CONFIGURATION_MASK_MODE_MASKED,
+
+ /* gcregMMUConfiguration:GCREG_MMU_CONFIGURATION_FLUSH */
+ GCREG_MMU_CONFIGURATION_FLUSH_FLUSH,
+
+ /* gcregMMUConfiguration:reserved */
+ 0,
+
+ /* gcregMMUConfiguration:GCREG_MMU_CONFIGURATION_MASK_FLUSH */
+ GCREG_MMU_CONFIGURATION_MASK_FLUSH_ENABLED,
+
+ /* gcregMMUConfiguration:GCREG_MMU_CONFIGURATION_MASK_ADDRESS */
+ GCREG_MMU_CONFIGURATION_MASK_ADDRESS_MASKED,
+
+ /* gcregMMUConfiguration:reserved */
+ 0,
+
+ /* gcregMMUConfiguration:GCREG_MMU_CONFIGURATION_ADDRESS */
+ 0
+};
+
+/*******************************************************************************
+** Register gcregMMUStatus
+*/
+
+/* Status register that holds which MMU generated an exception. */
+
+#define GCREG_MMU_STATUS_Address 0x00188
+#define GCREG_MMU_STATUS_MSB 15
+#define GCREG_MMU_STATUS_LSB 0
+#define GCREG_MMU_STATUS_BLK 0
+#define GCREG_MMU_STATUS_Count 1
+#define GCREG_MMU_STATUS_FieldMask 0x00003333
+#define GCREG_MMU_STATUS_ReadMask 0x00003333
+#define GCREG_MMU_STATUS_WriteMask 0x00000000
+#define GCREG_MMU_STATUS_ResetValue 0x00000000
+
+/* MMU 3 caused an exception and the fourth gcregMMUException register holds **
+** the offending address. */
+#define GCREG_MMU_STATUS_EXCEPTION3 13 : 12
+#define GCREG_MMU_STATUS_EXCEPTION3_End 13
+#define GCREG_MMU_STATUS_EXCEPTION3_Start 12
+#define GCREG_MMU_STATUS_EXCEPTION3_Type U02
+#define GCREG_MMU_STATUS_EXCEPTION3_SLAVE_NOT_PRESENT 0x1
+#define GCREG_MMU_STATUS_EXCEPTION3_PAGE_NOT_PRESENT 0x2
+#define GCREG_MMU_STATUS_EXCEPTION3_WRITE_VIOLATION 0x3
+
+/* MMU 2 caused an exception and the third gcregMMUException register holds **
+** the offending address. */
+#define GCREG_MMU_STATUS_EXCEPTION2 9 : 8
+#define GCREG_MMU_STATUS_EXCEPTION2_End 9
+#define GCREG_MMU_STATUS_EXCEPTION2_Start 8
+#define GCREG_MMU_STATUS_EXCEPTION2_Type U02
+#define GCREG_MMU_STATUS_EXCEPTION2_SLAVE_NOT_PRESENT 0x1
+#define GCREG_MMU_STATUS_EXCEPTION2_PAGE_NOT_PRESENT 0x2
+#define GCREG_MMU_STATUS_EXCEPTION2_WRITE_VIOLATION 0x3
+
+/* MMU 1 caused an exception and the second gcregMMUException register holds **
+** the offending address. */
+#define GCREG_MMU_STATUS_EXCEPTION1 5 : 4
+#define GCREG_MMU_STATUS_EXCEPTION1_End 5
+#define GCREG_MMU_STATUS_EXCEPTION1_Start 4
+#define GCREG_MMU_STATUS_EXCEPTION1_Type U02
+#define GCREG_MMU_STATUS_EXCEPTION1_SLAVE_NOT_PRESENT 0x1
+#define GCREG_MMU_STATUS_EXCEPTION1_PAGE_NOT_PRESENT 0x2
+#define GCREG_MMU_STATUS_EXCEPTION1_WRITE_VIOLATION 0x3
+
+/* MMU 0 caused an exception and the first gcregMMUException register holds **
+** the offending address. */
+#define GCREG_MMU_STATUS_EXCEPTION0 1 : 0
+#define GCREG_MMU_STATUS_EXCEPTION0_End 1
+#define GCREG_MMU_STATUS_EXCEPTION0_Start 0
+#define GCREG_MMU_STATUS_EXCEPTION0_Type U02
+#define GCREG_MMU_STATUS_EXCEPTION0_SLAVE_NOT_PRESENT 0x1
+#define GCREG_MMU_STATUS_EXCEPTION0_PAGE_NOT_PRESENT 0x2
+#define GCREG_MMU_STATUS_EXCEPTION0_WRITE_VIOLATION 0x3
+
+/*******************************************************************************
+** Register gcregMMUControl
+*/
+
+/* Control register that enables the MMU (only time shot). */
+
+#define GCREG_MMU_CONTROL_Address 0x0018C
+#define GCREG_MMU_CONTROL_MSB 15
+#define GCREG_MMU_CONTROL_LSB 0
+#define GCREG_MMU_CONTROL_BLK 0
+#define GCREG_MMU_CONTROL_Count 1
+#define GCREG_MMU_CONTROL_FieldMask 0x00000001
+#define GCREG_MMU_CONTROL_ReadMask 0x00000000
+#define GCREG_MMU_CONTROL_WriteMask 0x00000001
+#define GCREG_MMU_CONTROL_ResetValue 0x00000000
+
+/* Enable the MMU. For security reasons, once the MMU is enabled it cannot **
+** be disabled anymore. */
+#define GCREG_MMU_CONTROL_ENABLE 0 : 0
+#define GCREG_MMU_CONTROL_ENABLE_End 0
+#define GCREG_MMU_CONTROL_ENABLE_Start 0
+#define GCREG_MMU_CONTROL_ENABLE_Type U01
+#define GCREG_MMU_CONTROL_ENABLE_ENABLE 0x1
+
+/*******************************************************************************
+** State/Register gcregMMUException (4 in total)
+*/
+
+/* Up to 4 registers that will hold the original address that generated an
+** exception. Use load state form for exception resolution.
+*/
+
+#define gcregMMUExceptionRegAddrs 0x0064
+#define GCREG_MMU_EXCEPTION_Address 0x00190
+#define GCREG_MMU_EXCEPTION_MSB 15
+#define GCREG_MMU_EXCEPTION_LSB 2
+#define GCREG_MMU_EXCEPTION_BLK 2
+#define GCREG_MMU_EXCEPTION_Count 4
+#define GCREG_MMU_EXCEPTION_FieldMask 0xFFFFFFFF
+#define GCREG_MMU_EXCEPTION_ReadMask 0xFFFFFFFF
+#define GCREG_MMU_EXCEPTION_WriteMask 0xFFFFFFFF
+#define GCREG_MMU_EXCEPTION_ResetValue 0x00000000
+
+#define GCREG_MMU_EXCEPTION_ADDRESS 31 : 0
+#define GCREG_MMU_EXCEPTION_ADDRESS_End 31
+#define GCREG_MMU_EXCEPTION_ADDRESS_Start 0
+#define GCREG_MMU_EXCEPTION_ADDRESS_Type U32
+
+/*******************************************************************************
+** Register gcModulePowerControls
+*/
+
+/* Control register for module level power controls. */
+
+#define GC_MODULE_POWER_CONTROLS_Address 0x00100
+#define GC_MODULE_POWER_CONTROLS_MSB 15
+#define GC_MODULE_POWER_CONTROLS_LSB 0
+#define GC_MODULE_POWER_CONTROLS_BLK 0
+#define GC_MODULE_POWER_CONTROLS_Count 1
+#define GC_MODULE_POWER_CONTROLS_FieldMask 0xFFFF00F7
+#define GC_MODULE_POWER_CONTROLS_ReadMask 0xFFFF00F7
+#define GC_MODULE_POWER_CONTROLS_WriteMask 0xFFFF00F7
+#define GC_MODULE_POWER_CONTROLS_ResetValue 0x00140020
+
+/* Enables module level clock gating. */
+#define GC_MODULE_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING 0 : 0
+#define GC_MODULE_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING_End 0
+#define GC_MODULE_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING_Start 0
+#define GC_MODULE_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING_Type U01
+
+/* Disables module level clock gating for stall condition. */
+#define GC_MODULE_POWER_CONTROLS_DISABLE_STALL_MODULE_CLOCK_GATING 1 : 1
+#define GC_MODULE_POWER_CONTROLS_DISABLE_STALL_MODULE_CLOCK_GATING_End 1
+#define GC_MODULE_POWER_CONTROLS_DISABLE_STALL_MODULE_CLOCK_GATING_Start 1
+#define GC_MODULE_POWER_CONTROLS_DISABLE_STALL_MODULE_CLOCK_GATING_Type U01
+
+/* Disables module level clock gating for starve/idle condition. */
+#define GC_MODULE_POWER_CONTROLS_DISABLE_STARVE_MODULE_CLOCK_GATING 2 : 2
+#define GC_MODULE_POWER_CONTROLS_DISABLE_STARVE_MODULE_CLOCK_GATING_End 2
+#define GC_MODULE_POWER_CONTROLS_DISABLE_STARVE_MODULE_CLOCK_GATING_Start 2
+#define GC_MODULE_POWER_CONTROLS_DISABLE_STARVE_MODULE_CLOCK_GATING_Type U01
+
+/* Number of clock cycles to wait after turning on the clock. */
+#define GC_MODULE_POWER_CONTROLS_TURN_ON_COUNTER 7 : 4
+#define GC_MODULE_POWER_CONTROLS_TURN_ON_COUNTER_End 7
+#define GC_MODULE_POWER_CONTROLS_TURN_ON_COUNTER_Start 4
+#define GC_MODULE_POWER_CONTROLS_TURN_ON_COUNTER_Type U04
+
+/* Counter value for clock gating the module if the module is idle for this **
+** amount of clock cycles. */
+#define GC_MODULE_POWER_CONTROLS_TURN_OFF_COUNTER 31 : 16
+#define GC_MODULE_POWER_CONTROLS_TURN_OFF_COUNTER_End 31
+#define GC_MODULE_POWER_CONTROLS_TURN_OFF_COUNTER_Start 16
+#define GC_MODULE_POWER_CONTROLS_TURN_OFF_COUNTER_Type U16
+
+/*******************************************************************************
+** Register gcModulePowerModuleControl
+*/
+
+/* Module level control registers. */
+
+#define GC_MODULE_POWER_MODULE_CONTROL_Address 0x00104
+#define GC_MODULE_POWER_MODULE_CONTROL_MSB 15
+#define GC_MODULE_POWER_MODULE_CONTROL_LSB 0
+#define GC_MODULE_POWER_MODULE_CONTROL_BLK 0
+#define GC_MODULE_POWER_MODULE_CONTROL_Count 1
+#define GC_MODULE_POWER_MODULE_CONTROL_FieldMask 0x00000007
+#define GC_MODULE_POWER_MODULE_CONTROL_ReadMask 0x00000007
+#define GC_MODULE_POWER_MODULE_CONTROL_WriteMask 0x00000007
+#define GC_MODULE_POWER_MODULE_CONTROL_ResetValue 0x00000000
+
+/* Disables module level clock gating for FE. */
+#define GC_MODULE_POWER_MODULE_CONTROL_DISABLE_MODULE_CLOCK_GATING_FE 0 : 0
+#define GC_MODULE_POWER_MODULE_CONTROL_DISABLE_MODULE_CLOCK_GATING_FE_End 0
+#define GC_MODULE_POWER_MODULE_CONTROL_DISABLE_MODULE_CLOCK_GATING_FE_Start 0
+#define GC_MODULE_POWER_MODULE_CONTROL_DISABLE_MODULE_CLOCK_GATING_FE_Type U01
+
+/* Disables module level clock gating for DE. */
+#define GC_MODULE_POWER_MODULE_CONTROL_DISABLE_MODULE_CLOCK_GATING_DE 1 : 1
+#define GC_MODULE_POWER_MODULE_CONTROL_DISABLE_MODULE_CLOCK_GATING_DE_End 1
+#define GC_MODULE_POWER_MODULE_CONTROL_DISABLE_MODULE_CLOCK_GATING_DE_Start 1
+#define GC_MODULE_POWER_MODULE_CONTROL_DISABLE_MODULE_CLOCK_GATING_DE_Type U01
+
+/* Disables module level clock gating for PE. */
+#define GC_MODULE_POWER_MODULE_CONTROL_DISABLE_MODULE_CLOCK_GATING_PE 2 : 2
+#define GC_MODULE_POWER_MODULE_CONTROL_DISABLE_MODULE_CLOCK_GATING_PE_End 2
+#define GC_MODULE_POWER_MODULE_CONTROL_DISABLE_MODULE_CLOCK_GATING_PE_Start 2
+#define GC_MODULE_POWER_MODULE_CONTROL_DISABLE_MODULE_CLOCK_GATING_PE_Type U01
+
+/*******************************************************************************
+** Register gcModulePowerModuleStatus
+*/
+
+/* Module level control status. */
+
+#define GC_MODULE_POWER_MODULE_STATUS_Address 0x00108
+#define GC_MODULE_POWER_MODULE_STATUS_MSB 15
+#define GC_MODULE_POWER_MODULE_STATUS_LSB 0
+#define GC_MODULE_POWER_MODULE_STATUS_BLK 0
+#define GC_MODULE_POWER_MODULE_STATUS_Count 1
+#define GC_MODULE_POWER_MODULE_STATUS_FieldMask 0x00000007
+#define GC_MODULE_POWER_MODULE_STATUS_ReadMask 0x00000007
+#define GC_MODULE_POWER_MODULE_STATUS_WriteMask 0x00000000
+#define GC_MODULE_POWER_MODULE_STATUS_ResetValue 0x00000000
+
+/* Module level clock gating is ON for FE. */
+#define GC_MODULE_POWER_MODULE_STATUS_MODULE_CLOCK_GATED_FE 0 : 0
+#define GC_MODULE_POWER_MODULE_STATUS_MODULE_CLOCK_GATED_FE_End 0
+#define GC_MODULE_POWER_MODULE_STATUS_MODULE_CLOCK_GATED_FE_Start 0
+#define GC_MODULE_POWER_MODULE_STATUS_MODULE_CLOCK_GATED_FE_Type U01
+
+/* Module level clock gating is ON for DE. */
+#define GC_MODULE_POWER_MODULE_STATUS_MODULE_CLOCK_GATED_DE 1 : 1
+#define GC_MODULE_POWER_MODULE_STATUS_MODULE_CLOCK_GATED_DE_End 1
+#define GC_MODULE_POWER_MODULE_STATUS_MODULE_CLOCK_GATED_DE_Start 1
+#define GC_MODULE_POWER_MODULE_STATUS_MODULE_CLOCK_GATED_DE_Type U01
+
+/* Module level clock gating is ON for PE. */
+#define GC_MODULE_POWER_MODULE_STATUS_MODULE_CLOCK_GATED_PE 2 : 2
+#define GC_MODULE_POWER_MODULE_STATUS_MODULE_CLOCK_GATED_PE_End 2
+#define GC_MODULE_POWER_MODULE_STATUS_MODULE_CLOCK_GATED_PE_Start 2
+#define GC_MODULE_POWER_MODULE_STATUS_MODULE_CLOCK_GATED_PE_Type U01
+
+/*******************************************************************************
+** State gcregSrcAddress
+*/
+
+/* 32-bit aligned base address of the source surface. */
+
+#define gcregSrcAddressRegAddrs 0x0480
+#define GCREG_SRC_ADDRESS_MSB 15
+#define GCREG_SRC_ADDRESS_LSB 0
+#define GCREG_SRC_ADDRESS_BLK 0
+#define GCREG_SRC_ADDRESS_Count 1
+#define GCREG_SRC_ADDRESS_FieldMask 0xFFFFFFFF
+#define GCREG_SRC_ADDRESS_ReadMask 0xFFFFFFFC
+#define GCREG_SRC_ADDRESS_WriteMask 0xFFFFFFFC
+#define GCREG_SRC_ADDRESS_ResetValue 0x00000000
+
+#define GCREG_SRC_ADDRESS_ADDRESS 31 : 0
+#define GCREG_SRC_ADDRESS_ADDRESS_End 30
+#define GCREG_SRC_ADDRESS_ADDRESS_Start 0
+#define GCREG_SRC_ADDRESS_ADDRESS_Type U31
+
+/*******************************************************************************
+** State gcregSrcStride
+*/
+
+/* Stride of the source surface in bytes. To calculate the stride multiply
+** the surface width in pixels (8-pixel aligned) by the number of bytes per
+** pixel.
+*/
+
+#define gcregSrcStrideRegAddrs 0x0481
+#define GCREG_SRC_STRIDE_MSB 15
+#define GCREG_SRC_STRIDE_LSB 0
+#define GCREG_SRC_STRIDE_BLK 0
+#define GCREG_SRC_STRIDE_Count 1
+#define GCREG_SRC_STRIDE_FieldMask 0x0003FFFF
+#define GCREG_SRC_STRIDE_ReadMask 0x0003FFFC
+#define GCREG_SRC_STRIDE_WriteMask 0x0003FFFC
+#define GCREG_SRC_STRIDE_ResetValue 0x00000000
+
+#define GCREG_SRC_STRIDE_STRIDE 17 : 0
+#define GCREG_SRC_STRIDE_STRIDE_End 17
+#define GCREG_SRC_STRIDE_STRIDE_Start 0
+#define GCREG_SRC_STRIDE_STRIDE_Type U18
+
+/*******************************************************************************
+** State gcregSrcRotationConfig
+*/
+
+/* 90 degree rotation configuration for the source surface. Width field
+** specifies the width of the surface in pixels.
+*/
+
+#define gcregSrcRotationConfigRegAddrs 0x0482
+#define GCREG_SRC_ROTATION_CONFIG_MSB 15
+#define GCREG_SRC_ROTATION_CONFIG_LSB 0
+#define GCREG_SRC_ROTATION_CONFIG_BLK 0
+#define GCREG_SRC_ROTATION_CONFIG_Count 1
+#define GCREG_SRC_ROTATION_CONFIG_FieldMask 0x0001FFFF
+#define GCREG_SRC_ROTATION_CONFIG_ReadMask 0x0001FFFF
+#define GCREG_SRC_ROTATION_CONFIG_WriteMask 0x0001FFFF
+#define GCREG_SRC_ROTATION_CONFIG_ResetValue 0x00000000
+
+#define GCREG_SRC_ROTATION_CONFIG_WIDTH 15 : 0
+#define GCREG_SRC_ROTATION_CONFIG_WIDTH_End 15
+#define GCREG_SRC_ROTATION_CONFIG_WIDTH_Start 0
+#define GCREG_SRC_ROTATION_CONFIG_WIDTH_Type U16
+
+#define GCREG_SRC_ROTATION_CONFIG_ROTATION 16 : 16
+#define GCREG_SRC_ROTATION_CONFIG_ROTATION_End 16
+#define GCREG_SRC_ROTATION_CONFIG_ROTATION_Start 16
+#define GCREG_SRC_ROTATION_CONFIG_ROTATION_Type U01
+#define GCREG_SRC_ROTATION_CONFIG_ROTATION_DISABLE 0x0
+#define GCREG_SRC_ROTATION_CONFIG_ROTATION_ENABLE 0x1
+
+struct gcregsrcrotationconfig {
+ /* gcregSrcRotationConfigRegAddrs:GCREG_SRC_ROTATION_CONFIG_WIDTH */
+ unsigned int surf_width:16;
+
+ /* gcregSrcRotationConfigRegAddrs:GCREG_SRC_ROTATION_CONFIG_ROTATION */
+ unsigned int enable:1;
+
+ /* gcregSrcRotationConfigRegAddrs:reserved */
+ unsigned int _reserved_17_31:15;
+};
+
+/*******************************************************************************
+** State gcregSrcConfig
+*/
+
+/* Source surface configuration register. */
+
+#define gcregSrcConfigRegAddrs 0x0483
+#define GCREG_SRC_CONFIG_MSB 15
+#define GCREG_SRC_CONFIG_LSB 0
+#define GCREG_SRC_CONFIG_BLK 0
+#define GCREG_SRC_CONFIG_Count 1
+#define GCREG_SRC_CONFIG_FieldMask 0xFF31B1FF
+#define GCREG_SRC_CONFIG_ReadMask 0xFF31B1FF
+#define GCREG_SRC_CONFIG_WriteMask 0xFF31B1FF
+#define GCREG_SRC_CONFIG_ResetValue 0x00000000
+
+/* Control source endianess. */
+#define GCREG_SRC_CONFIG_ENDIAN_CONTROL 31 : 30
+#define GCREG_SRC_CONFIG_ENDIAN_CONTROL_End 31
+#define GCREG_SRC_CONFIG_ENDIAN_CONTROL_Start 30
+#define GCREG_SRC_CONFIG_ENDIAN_CONTROL_Type U02
+#define GCREG_SRC_CONFIG_ENDIAN_CONTROL_NO_SWAP 0x0
+#define GCREG_SRC_CONFIG_ENDIAN_CONTROL_SWAP_WORD 0x1
+#define GCREG_SRC_CONFIG_ENDIAN_CONTROL_SWAP_DWORD 0x2
+
+/* Disable 420 L2 cache NOTE: the field is valid for chips with 420 L2 cache **
+** defined. */
+#define GCREG_SRC_CONFIG_DISABLE420_L2_CACHE 29 : 29
+#define GCREG_SRC_CONFIG_DISABLE420_L2_CACHE_End 29
+#define GCREG_SRC_CONFIG_DISABLE420_L2_CACHE_Start 29
+#define GCREG_SRC_CONFIG_DISABLE420_L2_CACHE_Type U01
+#define GCREG_SRC_CONFIG_DISABLE420_L2_CACHE_ENABLED 0x0
+#define GCREG_SRC_CONFIG_DISABLE420_L2_CACHE_DISABLED 0x1
+
+/* Defines the pixel format of the source surface. */
+#define GCREG_SRC_CONFIG_SOURCE_FORMAT 28 : 24
+#define GCREG_SRC_CONFIG_SOURCE_FORMAT_End 28
+#define GCREG_SRC_CONFIG_SOURCE_FORMAT_Start 24
+#define GCREG_SRC_CONFIG_SOURCE_FORMAT_Type U05
+#define GCREG_SRC_CONFIG_SOURCE_FORMAT_X4R4G4B4 0x00
+#define GCREG_SRC_CONFIG_SOURCE_FORMAT_A4R4G4B4 0x01
+#define GCREG_SRC_CONFIG_SOURCE_FORMAT_X1R5G5B5 0x02
+#define GCREG_SRC_CONFIG_SOURCE_FORMAT_A1R5G5B5 0x03
+#define GCREG_SRC_CONFIG_SOURCE_FORMAT_R5G6B5 0x04
+#define GCREG_SRC_CONFIG_SOURCE_FORMAT_X8R8G8B8 0x05
+#define GCREG_SRC_CONFIG_SOURCE_FORMAT_A8R8G8B8 0x06
+#define GCREG_SRC_CONFIG_SOURCE_FORMAT_YUY2 0x07
+#define GCREG_SRC_CONFIG_SOURCE_FORMAT_UYVY 0x08
+#define GCREG_SRC_CONFIG_SOURCE_FORMAT_INDEX8 0x09
+#define GCREG_SRC_CONFIG_SOURCE_FORMAT_MONOCHROME 0x0A
+#define GCREG_SRC_CONFIG_SOURCE_FORMAT_YV12 0x0F
+#define GCREG_SRC_CONFIG_SOURCE_FORMAT_A8 0x10
+#define GCREG_SRC_CONFIG_SOURCE_FORMAT_NV12 0x11
+#define GCREG_SRC_CONFIG_SOURCE_FORMAT_NV16 0x12
+#define GCREG_SRC_CONFIG_SOURCE_FORMAT_RG16 0x13
+
+/* Color channel swizzles. */
+#define GCREG_SRC_CONFIG_SWIZZLE 21 : 20
+#define GCREG_SRC_CONFIG_SWIZZLE_End 21
+#define GCREG_SRC_CONFIG_SWIZZLE_Start 20
+#define GCREG_SRC_CONFIG_SWIZZLE_Type U02
+#define GCREG_SRC_CONFIG_SWIZZLE_ARGB 0x0
+#define GCREG_SRC_CONFIG_SWIZZLE_RGBA 0x1
+#define GCREG_SRC_CONFIG_SWIZZLE_ABGR 0x2
+#define GCREG_SRC_CONFIG_SWIZZLE_BGRA 0x3
+
+/* Mono expansion: if 0, transparency color will be 0, otherwise transparency **
+** color will be 1. */
+#define GCREG_SRC_CONFIG_MONO_TRANSPARENCY 15 : 15
+#define GCREG_SRC_CONFIG_MONO_TRANSPARENCY_End 15
+#define GCREG_SRC_CONFIG_MONO_TRANSPARENCY_Start 15
+#define GCREG_SRC_CONFIG_MONO_TRANSPARENCY_Type U01
+#define GCREG_SRC_CONFIG_MONO_TRANSPARENCY_BACKGROUND 0x0
+#define GCREG_SRC_CONFIG_MONO_TRANSPARENCY_FOREGROUND 0x1
+
+/* Mono expansion or masked blit: stream packing in pixels. Determines how **
+** many horizontal pixels are there per each 32-bit chunk. For example, if **
+** set to Packed8, each 32-bit chunk is 8-pixel wide, which also means that **
+** it defines 4 vertical lines of pixels. */
+#define GCREG_SRC_CONFIG_PACK 13 : 12
+#define GCREG_SRC_CONFIG_PACK_End 13
+#define GCREG_SRC_CONFIG_PACK_Start 12
+#define GCREG_SRC_CONFIG_PACK_Type U02
+#define GCREG_SRC_CONFIG_PACK_PACKED8 0x0
+#define GCREG_SRC_CONFIG_PACK_PACKED16 0x1
+#define GCREG_SRC_CONFIG_PACK_PACKED32 0x2
+#define GCREG_SRC_CONFIG_PACK_UNPACKED 0x3
+
+/* Source data location: set to STREAM for mono expansion blits or masked **
+** blits. For mono expansion blits the complete bitmap comes from the command **
+** stream. For masked blits the source data comes from the memory and the **
+** mask from the command stream. */
+#define GCREG_SRC_CONFIG_LOCATION 8 : 8
+#define GCREG_SRC_CONFIG_LOCATION_End 8
+#define GCREG_SRC_CONFIG_LOCATION_Start 8
+#define GCREG_SRC_CONFIG_LOCATION_Type U01
+#define GCREG_SRC_CONFIG_LOCATION_MEMORY 0x0
+#define GCREG_SRC_CONFIG_LOCATION_STREAM 0x1
+
+/* Source linear/tiled address computation control. */
+#define GCREG_SRC_CONFIG_TILED 7 : 7
+#define GCREG_SRC_CONFIG_TILED_End 7
+#define GCREG_SRC_CONFIG_TILED_Start 7
+#define GCREG_SRC_CONFIG_TILED_Type U01
+#define GCREG_SRC_CONFIG_TILED_DISABLED 0x0
+#define GCREG_SRC_CONFIG_TILED_ENABLED 0x1
+
+/* If set to ABSOLUTE, the source coordinates are treated as absolute **
+** coordinates inside the source surface. If set to RELATIVE, the source **
+** coordinates are treated as the offsets from the destination coordinates **
+** with the source size equal to the size of the destination. */
+#define GCREG_SRC_CONFIG_SRC_RELATIVE 6 : 6
+#define GCREG_SRC_CONFIG_SRC_RELATIVE_End 6
+#define GCREG_SRC_CONFIG_SRC_RELATIVE_Start 6
+#define GCREG_SRC_CONFIG_SRC_RELATIVE_Type U01
+#define GCREG_SRC_CONFIG_SRC_RELATIVE_ABSOLUTE 0x0
+#define GCREG_SRC_CONFIG_SRC_RELATIVE_RELATIVE 0x1
+
+struct gcregsrcconfig {
+ /* gcregSrcConfigRegAddrs:reserved */
+ unsigned int _reserved_0_5:6;
+
+ /* gcregSrcConfigRegAddrs:GCREG_SRC_CONFIG_SRC_RELATIVE */
+ unsigned int relative:1;
+
+ /* gcregSrcConfigRegAddrs:GCREG_SRC_CONFIG_TILED */
+ unsigned int tiled:1;
+
+ /* gcregSrcConfigRegAddrs:GCREG_SRC_CONFIG_LOCATION */
+ unsigned int stream:1;
+
+ /* gcregSrcConfigRegAddrs:reserved */
+ unsigned int _reserved_9_11:3;
+
+ /* gcregSrcConfigRegAddrs:GCREG_SRC_CONFIG_PACK */
+ unsigned int monopack:2;
+
+ /* gcregSrcConfigRegAddrs:reserved */
+ unsigned int _reserved_14:1;
+
+ /* gcregSrcConfigRegAddrs:GCREG_SRC_CONFIG_MONO_TRANSPARENCY */
+ unsigned int monotransp:1;
+
+ /* gcregSrcConfigRegAddrs:reserved */
+ unsigned int _reserved_16_19:4;
+
+ /* gcregSrcConfigRegAddrs:GCREG_SRC_CONFIG_SWIZZLE */
+ unsigned int swizzle:2;
+
+ /* gcregSrcConfigRegAddrs:reserved */
+ unsigned int _reserved_22_23:2;
+
+ /* gcregSrcConfigRegAddrs:GCREG_SRC_CONFIG_SOURCE_FORMAT */
+ unsigned int format:5;
+
+ /* gcregSrcConfigRegAddrs:GCREG_SRC_CONFIG_DISABLE420_L2_CACHE */
+ unsigned int disable420L2cache:1;
+
+ /* gcregSrcConfigRegAddrs:GCREG_SRC_CONFIG_ENDIAN_CONTROL */
+ unsigned int endian:2;
+};
+
+/*******************************************************************************
+** State gcregSrcOrigin
+*/
+
+/* Absolute or relative (see SRC_RELATIVE field of gcregSrcConfig register) X
+** and Y coordinates in pixels of the top left corner of the source rectangle
+** within the source surface.
+*/
+
+#define gcregSrcOriginRegAddrs 0x0484
+#define GCREG_SRC_ORIGIN_MSB 15
+#define GCREG_SRC_ORIGIN_LSB 0
+#define GCREG_SRC_ORIGIN_BLK 0
+#define GCREG_SRC_ORIGIN_Count 1
+#define GCREG_SRC_ORIGIN_FieldMask 0xFFFFFFFF
+#define GCREG_SRC_ORIGIN_ReadMask 0xFFFFFFFF
+#define GCREG_SRC_ORIGIN_WriteMask 0xFFFFFFFF
+#define GCREG_SRC_ORIGIN_ResetValue 0x00000000
+
+#define GCREG_SRC_ORIGIN_Y 31 : 16
+#define GCREG_SRC_ORIGIN_Y_End 31
+#define GCREG_SRC_ORIGIN_Y_Start 16
+#define GCREG_SRC_ORIGIN_Y_Type U16
+
+#define GCREG_SRC_ORIGIN_X 15 : 0
+#define GCREG_SRC_ORIGIN_X_End 15
+#define GCREG_SRC_ORIGIN_X_Start 0
+#define GCREG_SRC_ORIGIN_X_Type U16
+
+struct gcregsrcorigin {
+ /* gcregSrcOriginRegAddrs:GCREG_SRC_ORIGIN_X */
+ unsigned int x:16;
+
+ /* gcregSrcOriginRegAddrs:GCREG_SRC_ORIGIN_Y */
+ unsigned int y:16;
+};
+
+static const struct gcregsrcorigin gcregsrcorigin_min = {
+ /* gcregSrcOriginRegAddrs:GCREG_SRC_ORIGIN_X */
+ 0,
+
+ /* gcregSrcOriginRegAddrs:GCREG_SRC_ORIGIN_Y */
+ 0
+};
+
+/*******************************************************************************
+** State gcregSrcSize
+*/
+
+/* Width and height of the source rectangle in pixels. If the source is
+** relative (see SRC_RELATIVE field of gcregSrcConfig register) or a regular
+** bitblt is being performed without stretching, this register is ignored and
+** the source size is assumed to be the same as the destination.
+*/
+
+#define gcregSrcSizeRegAddrs 0x0485
+#define GCREG_SRC_SIZE_MSB 15
+#define GCREG_SRC_SIZE_LSB 0
+#define GCREG_SRC_SIZE_BLK 0
+#define GCREG_SRC_SIZE_Count 1
+#define GCREG_SRC_SIZE_FieldMask 0xFFFFFFFF
+#define GCREG_SRC_SIZE_ReadMask 0xFFFFFFFF
+#define GCREG_SRC_SIZE_WriteMask 0xFFFFFFFF
+#define GCREG_SRC_SIZE_ResetValue 0x00000000
+
+#define GCREG_SRC_SIZE_Y 31 : 16
+#define GCREG_SRC_SIZE_Y_End 31
+#define GCREG_SRC_SIZE_Y_Start 16
+#define GCREG_SRC_SIZE_Y_Type U16
+
+#define GCREG_SRC_SIZE_X 15 : 0
+#define GCREG_SRC_SIZE_X_End 15
+#define GCREG_SRC_SIZE_X_Start 0
+#define GCREG_SRC_SIZE_X_Type U16
+
+struct gcregsrcsize {
+ /* gcregSrcOriginRegAddrs:GCREG_SRC_SIZE_X */
+ unsigned int width:16;
+
+ /* gcregSrcOriginRegAddrs:GCREG_SRC_SIZE_Y */
+ unsigned int height:16;
+};
+
+static const struct gcregsrcsize gcregsrcsize_max = {
+ /* gcregSrcOriginRegAddrs:GCREG_SRC_SIZE_X */
+ 32767,
+
+ /* gcregSrcOriginRegAddrs:GCREG_SRC_SIZE_Y */
+ 32767
+};
+
+/*******************************************************************************
+** State gcregSrcColorBg
+*/
+
+/* In mono expansion defines the source color if the mono pixel is 0. The color
+** must be set in A8R8G8B8 format. In color blits defines the source
+** transparency color and must be of the same format as the source surface.
+*/
+
+#define gcregSrcColorBgRegAddrs 0x0486
+#define GCREG_SRC_COLOR_BG_MSB 15
+#define GCREG_SRC_COLOR_BG_LSB 0
+#define GCREG_SRC_COLOR_BG_BLK 0
+#define GCREG_SRC_COLOR_BG_Count 1
+#define GCREG_SRC_COLOR_BG_FieldMask 0xFFFFFFFF
+#define GCREG_SRC_COLOR_BG_ReadMask 0xFFFFFFFF
+#define GCREG_SRC_COLOR_BG_WriteMask 0xFFFFFFFF
+#define GCREG_SRC_COLOR_BG_ResetValue 0x00000000
+
+#define GCREG_SRC_COLOR_BG_ALPHA 31 : 24
+#define GCREG_SRC_COLOR_BG_ALPHA_End 31
+#define GCREG_SRC_COLOR_BG_ALPHA_Start 24
+#define GCREG_SRC_COLOR_BG_ALPHA_Type U08
+
+#define GCREG_SRC_COLOR_BG_RED 23 : 16
+#define GCREG_SRC_COLOR_BG_RED_End 23
+#define GCREG_SRC_COLOR_BG_RED_Start 16
+#define GCREG_SRC_COLOR_BG_RED_Type U08
+
+#define GCREG_SRC_COLOR_BG_GREEN 15 : 8
+#define GCREG_SRC_COLOR_BG_GREEN_End 15
+#define GCREG_SRC_COLOR_BG_GREEN_Start 8
+#define GCREG_SRC_COLOR_BG_GREEN_Type U08
+
+#define GCREG_SRC_COLOR_BG_BLUE 7 : 0
+#define GCREG_SRC_COLOR_BG_BLUE_End 7
+#define GCREG_SRC_COLOR_BG_BLUE_Start 0
+#define GCREG_SRC_COLOR_BG_BLUE_Type U08
+
+/*******************************************************************************
+** State gcregSrcColorFg
+*/
+
+/* In mono expansion defines the source color if the mono pixel is 1. The color
+** must be set in A8R8G8B8.
+*/
+
+#define gcregSrcColorFgRegAddrs 0x0487
+#define GCREG_SRC_COLOR_FG_MSB 15
+#define GCREG_SRC_COLOR_FG_LSB 0
+#define GCREG_SRC_COLOR_FG_BLK 0
+#define GCREG_SRC_COLOR_FG_Count 1
+#define GCREG_SRC_COLOR_FG_FieldMask 0xFFFFFFFF
+#define GCREG_SRC_COLOR_FG_ReadMask 0xFFFFFFFF
+#define GCREG_SRC_COLOR_FG_WriteMask 0xFFFFFFFF
+#define GCREG_SRC_COLOR_FG_ResetValue 0x00000000
+
+#define GCREG_SRC_COLOR_FG_ALPHA 31 : 24
+#define GCREG_SRC_COLOR_FG_ALPHA_End 31
+#define GCREG_SRC_COLOR_FG_ALPHA_Start 24
+#define GCREG_SRC_COLOR_FG_ALPHA_Type U08
+
+#define GCREG_SRC_COLOR_FG_RED 23 : 16
+#define GCREG_SRC_COLOR_FG_RED_End 23
+#define GCREG_SRC_COLOR_FG_RED_Start 16
+#define GCREG_SRC_COLOR_FG_RED_Type U08
+
+#define GCREG_SRC_COLOR_FG_GREEN 15 : 8
+#define GCREG_SRC_COLOR_FG_GREEN_End 15
+#define GCREG_SRC_COLOR_FG_GREEN_Start 8
+#define GCREG_SRC_COLOR_FG_GREEN_Type U08
+
+#define GCREG_SRC_COLOR_FG_BLUE 7 : 0
+#define GCREG_SRC_COLOR_FG_BLUE_End 7
+#define GCREG_SRC_COLOR_FG_BLUE_Start 0
+#define GCREG_SRC_COLOR_FG_BLUE_Type U08
+
+/*******************************************************************************
+** State gcregStretchFactorLow
+*/
+
+#define gcregStretchFactorLowRegAddrs 0x0488
+#define GCREG_STRETCH_FACTOR_LOW_MSB 15
+#define GCREG_STRETCH_FACTOR_LOW_LSB 0
+#define GCREG_STRETCH_FACTOR_LOW_BLK 0
+#define GCREG_STRETCH_FACTOR_LOW_Count 1
+#define GCREG_STRETCH_FACTOR_LOW_FieldMask 0x7FFFFFFF
+#define GCREG_STRETCH_FACTOR_LOW_ReadMask 0x7FFFFFFF
+#define GCREG_STRETCH_FACTOR_LOW_WriteMask 0x7FFFFFFF
+#define GCREG_STRETCH_FACTOR_LOW_ResetValue 0x00000000
+
+/* Horizontal stretch factor in 15.16 fixed point format. The value is **
+** calculated using the following formula: factor = ((srcWidth - 1) << 16) / **
+** (dstWidth - 1). Stretch blit uses only the integer part of the value, **
+** while Filter blit uses all 31 bits. */
+#define GCREG_STRETCH_FACTOR_LOW_X 30 : 0
+#define GCREG_STRETCH_FACTOR_LOW_X_End 30
+#define GCREG_STRETCH_FACTOR_LOW_X_Start 0
+#define GCREG_STRETCH_FACTOR_LOW_X_Type U31
+
+/*******************************************************************************
+** State gcregStretchFactorHigh
+*/
+
+#define gcregStretchFactorHighRegAddrs 0x0489
+#define GCREG_STRETCH_FACTOR_HIGH_MSB 15
+#define GCREG_STRETCH_FACTOR_HIGH_LSB 0
+#define GCREG_STRETCH_FACTOR_LOW_HIGH_BLK 0
+#define GCREG_STRETCH_FACTOR_HIGH_Count 1
+#define GCREG_STRETCH_FACTOR_HIGH_FieldMask 0x7FFFFFFF
+#define GCREG_STRETCH_FACTOR_HIGH_ReadMask 0x7FFFFFFF
+#define GCREG_STRETCH_FACTOR_HIGH_WriteMask 0x7FFFFFFF
+#define GCREG_STRETCH_FACTOR_HIGH_ResetValue 0x00000000
+
+/* Vertical stretch factor in 15.16 fixed point format. The value is **
+** calculated using the following formula: factor = ((srcHeight - 1) << 16) / **
+** (dstHeight - 1). Stretch blit uses only the integer part of the value, **
+** while Filter blit uses all 31 bits. */
+#define GCREG_STRETCH_FACTOR_HIGH_Y 30 : 0
+#define GCREG_STRETCH_FACTOR_HIGH_Y_End 30
+#define GCREG_STRETCH_FACTOR_HIGH_Y_Start 0
+#define GCREG_STRETCH_FACTOR_HIGH_Y_Type U31
+
+/*******************************************************************************
+** State gcregDestAddress
+*/
+
+/* 32-bit aligned base address of the destination surface. */
+
+#define gcregDestAddressRegAddrs 0x048A
+#define GCREG_DEST_ADDRESS_MSB 15
+#define GCREG_DEST_ADDRESS_LSB 0
+#define GCREG_DEST_ADDRESS_BLK 0
+#define GCREG_DEST_ADDRESS_Count 1
+#define GCREG_DEST_ADDRESS_FieldMask 0xFFFFFFFF
+#define GCREG_DEST_ADDRESS_ReadMask 0xFFFFFFFC
+#define GCREG_DEST_ADDRESS_WriteMask 0xFFFFFFFC
+#define GCREG_DEST_ADDRESS_ResetValue 0x00000000
+
+#define GCREG_DEST_ADDRESS_ADDRESS 31 : 0
+#define GCREG_DEST_ADDRESS_ADDRESS_End 30
+#define GCREG_DEST_ADDRESS_ADDRESS_Start 0
+#define GCREG_DEST_ADDRESS_ADDRESS_Type U31
+
+/*******************************************************************************
+** State gcregDestStride
+*/
+
+/* Stride of the destination surface in bytes. To calculate the stride
+** multiply the surface width in pixels (8-pixel aligned) by the number of
+** bytes per pixel.
+*/
+
+#define gcregDestStrideRegAddrs 0x048B
+#define GCREG_DEST_STRIDE_MSB 15
+#define GCREG_DEST_STRIDE_LSB 0
+#define GCREG_DEST_STRIDE_BLK 0
+#define GCREG_DEST_STRIDE_Count 1
+#define GCREG_DEST_STRIDE_FieldMask 0x0003FFFF
+#define GCREG_DEST_STRIDE_ReadMask 0x0003FFFC
+#define GCREG_DEST_STRIDE_WriteMask 0x0003FFFC
+#define GCREG_DEST_STRIDE_ResetValue 0x00000000
+
+#define GCREG_DEST_STRIDE_STRIDE 17 : 0
+#define GCREG_DEST_STRIDE_STRIDE_End 17
+#define GCREG_DEST_STRIDE_STRIDE_Start 0
+#define GCREG_DEST_STRIDE_STRIDE_Type U18
+
+/*******************************************************************************
+** State gcregDestRotationConfig
+*/
+
+/* 90 degree rotation configuration for the destination surface. Width field
+** specifies the width of the surface in pixels.
+*/
+
+#define gcregDestRotationConfigRegAddrs 0x048C
+#define GCREG_DEST_ROTATION_CONFIG_MSB 15
+#define GCREG_DEST_ROTATION_CONFIG_LSB 0
+#define GCREG_DEST_ROTATION_CONFIG_BLK 0
+#define GCREG_DEST_ROTATION_CONFIG_Count 1
+#define GCREG_DEST_ROTATION_CONFIG_FieldMask 0x0001FFFF
+#define GCREG_DEST_ROTATION_CONFIG_ReadMask 0x0001FFFF
+#define GCREG_DEST_ROTATION_CONFIG_WriteMask 0x0001FFFF
+#define GCREG_DEST_ROTATION_CONFIG_ResetValue 0x00000000
+
+#define GCREG_DEST_ROTATION_CONFIG_WIDTH 15 : 0
+#define GCREG_DEST_ROTATION_CONFIG_WIDTH_End 15
+#define GCREG_DEST_ROTATION_CONFIG_WIDTH_Start 0
+#define GCREG_DEST_ROTATION_CONFIG_WIDTH_Type U16
+
+#define GCREG_DEST_ROTATION_CONFIG_ROTATION 16 : 16
+#define GCREG_DEST_ROTATION_CONFIG_ROTATION_End 16
+#define GCREG_DEST_ROTATION_CONFIG_ROTATION_Start 16
+#define GCREG_DEST_ROTATION_CONFIG_ROTATION_Type U01
+#define GCREG_DEST_ROTATION_CONFIG_ROTATION_DISABLE 0x0
+#define GCREG_DEST_ROTATION_CONFIG_ROTATION_ENABLE 0x1
+
+struct gcregdstrotationconfig {
+ /* gcregDestRotationConfigRegAddrs:GCREG_DEST_ROTATION_CONFIG_WIDTH */
+ unsigned int surf_width:16;
+
+ /* gcregDestRotationConfigRegAddrs:GCREG_DEST_ROTATION_CONFIG_ROTATION*/
+ unsigned int enable:1;
+
+ /* gcregDestRotationConfigRegAddrs:reserved */
+ unsigned int _reserved_17_31:15;
+};
+
+/*******************************************************************************
+** State gcregDestConfig
+*/
+
+/* Destination surface configuration register. */
+
+#define gcregDestConfigRegAddrs 0x048D
+#define GCREG_DEST_CONFIG_MSB 15
+#define GCREG_DEST_CONFIG_LSB 0
+#define GCREG_DEST_CONFIG_BLK 0
+#define GCREG_DEST_CONFIG_Count 1
+#define GCREG_DEST_CONFIG_FieldMask 0x0733F11F
+#define GCREG_DEST_CONFIG_ReadMask 0x0733F11F
+#define GCREG_DEST_CONFIG_WriteMask 0x0733F11F
+#define GCREG_DEST_CONFIG_ResetValue 0x00000000
+
+/* MinorTile. */
+#define GCREG_DEST_CONFIG_MINOR_TILED 26 : 26
+#define GCREG_DEST_CONFIG_MINOR_TILED_End 26
+#define GCREG_DEST_CONFIG_MINOR_TILED_Start 26
+#define GCREG_DEST_CONFIG_MINOR_TILED_Type U01
+#define GCREG_DEST_CONFIG_MINOR_TILED_DISABLED 0x0
+#define GCREG_DEST_CONFIG_MINOR_TILED_ENABLED 0x1
+
+/* Performance fix for de. */
+#define GCREG_DEST_CONFIG_INTER_TILE_PER_FIX 25 : 25
+#define GCREG_DEST_CONFIG_INTER_TILE_PER_FIX_End 25
+#define GCREG_DEST_CONFIG_INTER_TILE_PER_FIX_Start 25
+#define GCREG_DEST_CONFIG_INTER_TILE_PER_FIX_Type U01
+#define GCREG_DEST_CONFIG_INTER_TILE_PER_FIX_DISABLED 0x1
+#define GCREG_DEST_CONFIG_INTER_TILE_PER_FIX_ENABLED 0x0
+
+/* Control GDI Strecth Blit. */
+#define GCREG_DEST_CONFIG_GDI_STRE 24 : 24
+#define GCREG_DEST_CONFIG_GDI_STRE_End 24
+#define GCREG_DEST_CONFIG_GDI_STRE_Start 24
+#define GCREG_DEST_CONFIG_GDI_STRE_Type U01
+#define GCREG_DEST_CONFIG_GDI_STRE_DISABLED 0x0
+#define GCREG_DEST_CONFIG_GDI_STRE_ENABLED 0x1
+
+/* Control destination endianess. */
+#define GCREG_DEST_CONFIG_ENDIAN_CONTROL 21 : 20
+#define GCREG_DEST_CONFIG_ENDIAN_CONTROL_End 21
+#define GCREG_DEST_CONFIG_ENDIAN_CONTROL_Start 20
+#define GCREG_DEST_CONFIG_ENDIAN_CONTROL_Type U02
+#define GCREG_DEST_CONFIG_ENDIAN_CONTROL_NO_SWAP 0x0
+#define GCREG_DEST_CONFIG_ENDIAN_CONTROL_SWAP_WORD 0x1
+#define GCREG_DEST_CONFIG_ENDIAN_CONTROL_SWAP_DWORD 0x2
+
+/* Color channel swizzles. */
+#define GCREG_DEST_CONFIG_SWIZZLE 17 : 16
+#define GCREG_DEST_CONFIG_SWIZZLE_End 17
+#define GCREG_DEST_CONFIG_SWIZZLE_Start 16
+#define GCREG_DEST_CONFIG_SWIZZLE_Type U02
+#define GCREG_DEST_CONFIG_SWIZZLE_ARGB 0x0
+#define GCREG_DEST_CONFIG_SWIZZLE_RGBA 0x1
+#define GCREG_DEST_CONFIG_SWIZZLE_ABGR 0x2
+#define GCREG_DEST_CONFIG_SWIZZLE_BGRA 0x3
+
+/* Determines the type of primitive to be rendered. BIT_BLT_REVERSED and **
+** INVALID_COMMAND values are defined for internal use and should not be **
+** used. */
+#define GCREG_DEST_CONFIG_COMMAND 15 : 12
+#define GCREG_DEST_CONFIG_COMMAND_End 15
+#define GCREG_DEST_CONFIG_COMMAND_Start 12
+#define GCREG_DEST_CONFIG_COMMAND_Type U04
+#define GCREG_DEST_CONFIG_COMMAND_CLEAR 0x0
+#define GCREG_DEST_CONFIG_COMMAND_LINE 0x1
+#define GCREG_DEST_CONFIG_COMMAND_BIT_BLT 0x2
+#define GCREG_DEST_CONFIG_COMMAND_BIT_BLT_REVERSED 0x3
+#define GCREG_DEST_CONFIG_COMMAND_STRETCH_BLT 0x4
+#define GCREG_DEST_CONFIG_COMMAND_HOR_FILTER_BLT 0x5
+#define GCREG_DEST_CONFIG_COMMAND_VER_FILTER_BLT 0x6
+#define GCREG_DEST_CONFIG_COMMAND_ONE_PASS_FILTER_BLT 0x7
+#define GCREG_DEST_CONFIG_COMMAND_MULTI_SOURCE_BLT 0x8
+
+/* Destination linear/tiled address computation control. Reserved field for **
+** future expansion. */
+#define GCREG_DEST_CONFIG_TILED 8 : 8
+#define GCREG_DEST_CONFIG_TILED_End 8
+#define GCREG_DEST_CONFIG_TILED_Start 8
+#define GCREG_DEST_CONFIG_TILED_Type U01
+#define GCREG_DEST_CONFIG_TILED_DISABLED 0x0
+#define GCREG_DEST_CONFIG_TILED_ENABLED 0x1
+
+/* Defines the pixel format of the destination surface. */
+#define GCREG_DEST_CONFIG_FORMAT 4 : 0
+#define GCREG_DEST_CONFIG_FORMAT_End 4
+#define GCREG_DEST_CONFIG_FORMAT_Start 0
+#define GCREG_DEST_CONFIG_FORMAT_Type U05
+#define GCREG_DEST_CONFIG_FORMAT_X4R4G4B4 0x00
+#define GCREG_DEST_CONFIG_FORMAT_A4R4G4B4 0x01
+#define GCREG_DEST_CONFIG_FORMAT_X1R5G5B5 0x02
+#define GCREG_DEST_CONFIG_FORMAT_A1R5G5B5 0x03
+#define GCREG_DEST_CONFIG_FORMAT_R5G6B5 0x04
+#define GCREG_DEST_CONFIG_FORMAT_X8R8G8B8 0x05
+#define GCREG_DEST_CONFIG_FORMAT_A8R8G8B8 0x06
+#define GCREG_DEST_CONFIG_FORMAT_YUY2 0x07
+#define GCREG_DEST_CONFIG_FORMAT_UYVY 0x08
+#define GCREG_DEST_CONFIG_FORMAT_INDEX8 0x09
+#define GCREG_DEST_CONFIG_FORMAT_MONOCHROME 0x0A
+#define GCREG_DEST_CONFIG_FORMAT_YV12 0x0F
+#define GCREG_DEST_CONFIG_FORMAT_A8 0x10
+#define GCREG_DEST_CONFIG_FORMAT_NV12 0x11
+#define GCREG_DEST_CONFIG_FORMAT_NV16 0x12
+#define GCREG_DEST_CONFIG_FORMAT_RG16 0x13
+
+struct gcregdstconfig {
+ /* gcregDestConfigRegAddrs:GCREG_DEST_CONFIG_FORMAT */
+ unsigned int format:5;
+
+ /* gcregDestConfigRegAddrs:reserved */
+ unsigned int _reserved_5_7:3;
+
+ /* gcregDestConfigRegAddrs:GCREG_DEST_CONFIG_TILED */
+ unsigned int tiled:1;
+
+ /* gcregDestConfigRegAddrs:reserved */
+ unsigned int _reserved_9_11:3;
+
+ /* gcregDestConfigRegAddrs:GCREG_DEST_CONFIG_COMMAND */
+ unsigned int command:4;
+
+ /* gcregDestConfigRegAddrs:GCREG_DEST_CONFIG_SWIZZLE */
+ unsigned int swizzle:2;
+
+ /* gcregDestConfigRegAddrs:reserved */
+ unsigned int _reserved_18_19:2;
+
+ /* gcregDestConfigRegAddrs:GCREG_DEST_CONFIG_ENDIAN_CONTROL */
+ unsigned int endian:2;
+
+ /* gcregDestConfigRegAddrs:reserved */
+ unsigned int _reserved_22_23:2;
+
+ /* gcregDestConfigRegAddrs:GCREG_DEST_CONFIG_GDI_STRE */
+ unsigned int gdi:1;
+
+ /* gcregDestConfigRegAddrs:GCREG_DEST_CONFIG_INTER_TILE_PER_FIX */
+ unsigned int inner_tile_fix:1;
+
+ /* gcregDestConfigRegAddrs:GCREG_DEST_CONFIG_MINOR_TILED */
+ unsigned int minor_tile:1;
+
+ /* gcregDestConfigRegAddrs:reserved */
+ unsigned int _reserved_27_31:5;
+};
+
+/*******************************************************************************
+** State gcregFilterKernel
+*/
+
+/* Filter blit coefficient table. The algorithm uses 5 bits of pixel
+** coordinate's fraction to index the kernel array, which makes it a 32-entry
+** array. Each entry consists of 9 kernel values. In practice we store only a
+** half of the table, because the other half is a mirror of the first,
+** therefore:
+** rows_to_store = 32 / 2 + 1 = 17
+** values_to_store = rows_to_store * 9 = 153
+** even_value_count = (values_to_store + 1) & ~1 = 154
+** dword_count = even_value_count / 2 = 77
+*/
+
+#define gcregFilterKernelRegAddrs 0x0600
+#define GCREG_FILTER_KERNEL_MSB 15
+#define GCREG_FILTER_KERNEL_LSB 7
+#define GCREG_FILTER_KERNEL_BLK 7
+#define GCREG_FILTER_KERNEL_Count 128
+#define GCREG_FILTER_KERNEL_FieldMask 0xFFFFFFFF
+#define GCREG_FILTER_KERNEL_ReadMask 0xFFFFFFFF
+#define GCREG_FILTER_KERNEL_WriteMask 0xFFFFFFFF
+#define GCREG_FILTER_KERNEL_ResetValue 0x00000000
+
+#define GCREG_FILTER_KERNEL_COEFFICIENT0 15 : 0
+#define GCREG_FILTER_KERNEL_COEFFICIENT0_End 15
+#define GCREG_FILTER_KERNEL_COEFFICIENT0_Start 0
+#define GCREG_FILTER_KERNEL_COEFFICIENT0_Type U16
+
+#define GCREG_FILTER_KERNEL_COEFFICIENT1 31 : 16
+#define GCREG_FILTER_KERNEL_COEFFICIENT1_End 31
+#define GCREG_FILTER_KERNEL_COEFFICIENT1_Start 16
+#define GCREG_FILTER_KERNEL_COEFFICIENT1_Type U16
+
+struct gcregfilterkernelpair {
+ /* gcregFilterKernelRegAddrs:COEFFICIENT0 */
+ unsigned int coeff0:16;
+
+ /* gcregFilterKernelRegAddrs:COEFFICIENT1 */
+ unsigned int coeff1:16;
+};
+
+struct gcregfilterkernel {
+ struct gcregfilterkernelpair filter[77];
+};
+
+/*******************************************************************************
+** State gcregHoriFilterKernel
+*/
+
+/* One Pass filter Filter blit hori coefficient table. */
+
+#define gcregHoriFilterKernelRegAddrs 0x0A00
+#define GCREG_HORI_FILTER_KERNEL_MSB 15
+#define GCREG_HORI_FILTER_KERNEL_LSB 7
+#define GCREG_HORI_FILTER_KERNEL_BLK 7
+#define GCREG_HORI_FILTER_KERNEL_Count 128
+#define GCREG_HORI_FILTER_KERNEL_FieldMask 0xFFFFFFFF
+#define GCREG_HORI_FILTER_KERNEL_ReadMask 0xFFFFFFFF
+#define GCREG_HORI_FILTER_KERNEL_WriteMask 0xFFFFFFFF
+#define GCREG_HORI_FILTER_KERNEL_ResetValue 0x00000000
+
+#define GCREG_HORI_FILTER_KERNEL_COEFFICIENT0 15 : 0
+#define GCREG_HORI_FILTER_KERNEL_COEFFICIENT0_End 15
+#define GCREG_HORI_FILTER_KERNEL_COEFFICIENT0_Start 0
+#define GCREG_HORI_FILTER_KERNEL_COEFFICIENT0_Type U16
+
+#define GCREG_HORI_FILTER_KERNEL_COEFFICIENT1 31 : 16
+#define GCREG_HORI_FILTER_KERNEL_COEFFICIENT1_End 31
+#define GCREG_HORI_FILTER_KERNEL_COEFFICIENT1_Start 16
+#define GCREG_HORI_FILTER_KERNEL_COEFFICIENT1_Type U16
+
+/*******************************************************************************
+** State gcregVertiFilterKernel
+*/
+
+/* One Pass Filter blit vertical coefficient table. */
+
+#define gcregVertiFilterKernelRegAddrs 0x0A80
+#define GCREG_VERTI_FILTER_KERNEL_MSB 15
+#define GCREG_VERTI_FILTER_KERNEL_LSB 7
+#define GCREG_VERTI_FILTER_KERNEL_BLK 7
+#define GCREG_VERTI_FILTER_KERNEL_Count 128
+#define GCREG_VERTI_FILTER_KERNEL_FieldMask 0xFFFFFFFF
+#define GCREG_VERTI_FILTER_KERNEL_ReadMask 0xFFFFFFFF
+#define GCREG_VERTI_FILTER_KERNEL_WriteMask 0xFFFFFFFF
+#define GCREG_VERTI_FILTER_KERNEL_ResetValue 0x00000000
+
+#define GCREG_VERTI_FILTER_KERNEL_COEFFICIENT0 15 : 0
+#define GCREG_VERTI_FILTER_KERNEL_COEFFICIENT0_End 15
+#define GCREG_VERTI_FILTER_KERNEL_COEFFICIENT0_Start 0
+#define GCREG_VERTI_FILTER_KERNEL_COEFFICIENT0_Type U16
+
+#define GCREG_VERTI_FILTER_KERNEL_COEFFICIENT1 31 : 16
+#define GCREG_VERTI_FILTER_KERNEL_COEFFICIENT1_End 31
+#define GCREG_VERTI_FILTER_KERNEL_COEFFICIENT1_Start 16
+#define GCREG_VERTI_FILTER_KERNEL_COEFFICIENT1_Type U16
+
+/*******************************************************************************
+** State gcregVRConfig
+*/
+
+/* Video Rasterizer kick-off register. */
+
+#define gcregVRConfigRegAddrs 0x04A5
+#define GCREG_VR_CONFIG_MSB 15
+#define GCREG_VR_CONFIG_LSB 0
+#define GCREG_VR_CONFIG_BLK 0
+#define GCREG_VR_CONFIG_Count 1
+#define GCREG_VR_CONFIG_FieldMask 0x0000000B
+#define GCREG_VR_CONFIG_ReadMask 0x0000000B
+#define GCREG_VR_CONFIG_WriteMask 0x0000000B
+#define GCREG_VR_CONFIG_ResetValue 0x00000000
+
+/* Kick-off command. */
+#define GCREG_VR_CONFIG_START 1 : 0
+#define GCREG_VR_CONFIG_START_End 1
+#define GCREG_VR_CONFIG_START_Start 0
+#define GCREG_VR_CONFIG_START_Type U02
+#define GCREG_VR_CONFIG_START_HORIZONTAL_BLIT 0x0
+#define GCREG_VR_CONFIG_START_VERTICAL_BLIT 0x1
+#define GCREG_VR_CONFIG_START_ONE_PASS_BLIT 0x2
+
+#define GCREG_VR_CONFIG_MASK_START 3 : 3
+#define GCREG_VR_CONFIG_MASK_START_End 3
+#define GCREG_VR_CONFIG_MASK_START_Start 3
+#define GCREG_VR_CONFIG_MASK_START_Type U01
+#define GCREG_VR_CONFIG_MASK_START_ENABLED 0x0
+#define GCREG_VR_CONFIG_MASK_START_MASKED 0x1
+
+struct gcregvrconfig {
+ /* gcregVRConfigRegAddrs:START */
+ unsigned int start:2;
+
+ /* gcregVRConfigRegAddrs:reserved */
+ unsigned int _reserved_2:1;
+
+ /* gcregVRConfigRegAddrs:MASK_START */
+ unsigned int start_mask:1;
+
+ /* gcregVRConfigRegAddrs:reserved */
+ unsigned int _reserved_4_31:28;
+};
+
+static const struct gcregvrconfig gcregvrconfig_horizontal = {
+ /* gcregVRConfigRegAddrs:START */
+ GCREG_VR_CONFIG_START_HORIZONTAL_BLIT,
+
+ /* gcregVRConfigRegAddrs:reserved */
+ 0,
+
+ /* gcregVRConfigRegAddrs:MASK_START */
+ GCREG_VR_CONFIG_MASK_START_ENABLED,
+
+ /* gcregVRConfigRegAddrs:reserved */
+ 0
+};
+
+static const struct gcregvrconfig gcregvrconfig_vertical = {
+ /* gcregVRConfigRegAddrs:START */
+ GCREG_VR_CONFIG_START_VERTICAL_BLIT,
+
+ /* gcregVRConfigRegAddrs:reserved */
+ 0,
+
+ /* gcregVRConfigRegAddrs:MASK_START */
+ GCREG_VR_CONFIG_MASK_START_ENABLED,
+
+ /* gcregVRConfigRegAddrs:reserved */
+ 0
+};
+
+static const struct gcregvrconfig gcregvrconfig_onepass = {
+ /* gcregVRConfigRegAddrs:START */
+ GCREG_VR_CONFIG_START_ONE_PASS_BLIT,
+
+ /* gcregVRConfigRegAddrs:reserved */
+ 0,
+
+ /* gcregVRConfigRegAddrs:MASK_START */
+ GCREG_VR_CONFIG_MASK_START_ENABLED,
+
+ /* gcregVRConfigRegAddrs:reserved */
+ 0
+};
+
+/*******************************************************************************
+** State gcregVRSourceImageLow
+*/
+
+/* Bounding box of the source image. */
+
+#define gcregVRSourceImageLowRegAddrs 0x04A6
+#define GCREG_VR_SOURCE_IMAGE_LOW_Address 0x01298
+#define GCREG_VR_SOURCE_IMAGE_LOW_MSB 15
+#define GCREG_VR_SOURCE_IMAGE_LOW_LSB 0
+#define GCREG_VR_SOURCE_IMAGE_LOW_BLK 0
+#define GCREG_VR_SOURCE_IMAGE_LOW_Count 1
+#define GCREG_VR_SOURCE_IMAGE_LOW_FieldMask 0xFFFFFFFF
+#define GCREG_VR_SOURCE_IMAGE_LOW_ReadMask 0xFFFFFFFF
+#define GCREG_VR_SOURCE_IMAGE_LOW_WriteMask 0xFFFFFFFF
+#define GCREG_VR_SOURCE_IMAGE_LOW_ResetValue 0x00000000
+
+#define GCREG_VR_SOURCE_IMAGE_LOW_LEFT 15 : 0
+#define GCREG_VR_SOURCE_IMAGE_LOW_LEFT_End 15
+#define GCREG_VR_SOURCE_IMAGE_LOW_LEFT_Start 0
+#define GCREG_VR_SOURCE_IMAGE_LOW_LEFT_Type U16
+
+#define GCREG_VR_SOURCE_IMAGE_LOW_TOP 31 : 16
+#define GCREG_VR_SOURCE_IMAGE_LOW_TOP_End 31
+#define GCREG_VR_SOURCE_IMAGE_LOW_TOP_Start 16
+#define GCREG_VR_SOURCE_IMAGE_LOW_TOP_Type U16
+
+struct gcregvrsourceimagelow {
+ /* gcregVRSourceImageLowRegAddrs:LEFT */
+ unsigned int left:16;
+
+ /* gcregVRSourceImageLowRegAddrs:TOP */
+ unsigned int top:16;
+};
+
+/*******************************************************************************
+** State gcregVRSourceImageHigh
+*/
+
+#define gcregVRSourceImageHighRegAddrs 0x04A7
+#define GCREG_VR_SOURCE_IMAGE_HIGH_MSB 15
+#define GCREG_VR_SOURCE_IMAGE_HIGH_LSB 0
+#define GCREG_VR_SOURCE_IMAGE_LOW_HIGH_BLK 0
+#define GCREG_VR_SOURCE_IMAGE_HIGH_Count 1
+#define GCREG_VR_SOURCE_IMAGE_HIGH_FieldMask 0xFFFFFFFF
+#define GCREG_VR_SOURCE_IMAGE_HIGH_ReadMask 0xFFFFFFFF
+#define GCREG_VR_SOURCE_IMAGE_HIGH_WriteMask 0xFFFFFFFF
+#define GCREG_VR_SOURCE_IMAGE_HIGH_ResetValue 0x00000000
+
+#define GCREG_VR_SOURCE_IMAGE_HIGH_RIGHT 15 : 0
+#define GCREG_VR_SOURCE_IMAGE_HIGH_RIGHT_End 15
+#define GCREG_VR_SOURCE_IMAGE_HIGH_RIGHT_Start 0
+#define GCREG_VR_SOURCE_IMAGE_HIGH_RIGHT_Type U16
+
+#define GCREG_VR_SOURCE_IMAGE_HIGH_BOTTOM 31 : 16
+#define GCREG_VR_SOURCE_IMAGE_HIGH_BOTTOM_End 31
+#define GCREG_VR_SOURCE_IMAGE_HIGH_BOTTOM_Start 16
+#define GCREG_VR_SOURCE_IMAGE_HIGH_BOTTOM_Type U16
+
+struct gcregvrsourceimagehigh {
+ /* gcregVRSourceImageHighRegAddrs:RIGHT */
+ unsigned int right:16;
+
+ /* gcregVRSourceImageHighRegAddrs:BOTTOM */
+ unsigned int bottom:16;
+};
+
+/*******************************************************************************
+** State gcregVRSourceOriginLow
+*/
+
+/* Fractional origin of the source window to be rendered within the source
+** image.
+*/
+
+#define gcregVRSourceOriginLowRegAddrs 0x04A8
+#define GCREG_VR_SOURCE_ORIGIN_LOW_MSB 15
+#define GCREG_VR_SOURCE_ORIGIN_LOW_LSB 0
+#define GCREG_VR_SOURCE_ORIGIN_LOW_BLK 0
+#define GCREG_VR_SOURCE_ORIGIN_LOW_Count 1
+#define GCREG_VR_SOURCE_ORIGIN_LOW_FieldMask 0xFFFFFFFF
+#define GCREG_VR_SOURCE_ORIGIN_LOW_ReadMask 0xFFFFFFFF
+#define GCREG_VR_SOURCE_ORIGIN_LOW_WriteMask 0xFFFFFFFF
+#define GCREG_VR_SOURCE_ORIGIN_LOW_ResetValue 0x00000000
+
+#define GCREG_VR_SOURCE_ORIGIN_LOW_X 31 : 0
+#define GCREG_VR_SOURCE_ORIGIN_LOW_X_End 31
+#define GCREG_VR_SOURCE_ORIGIN_LOW_X_Start 0
+#define GCREG_VR_SOURCE_ORIGIN_LOW_X_Type U32
+
+/*******************************************************************************
+** State gcregVRSourceOriginHigh
+*/
+
+#define gcregVRSourceOriginHighRegAddrs 0x04A9
+#define GCREG_VR_SOURCE_ORIGIN_HIGH_MSB 15
+#define GCREG_VR_SOURCE_ORIGIN_HIGH_LSB 0
+#define GCREG_VR_SOURCE_ORIGIN_LOW_HIGH_BLK 0
+#define GCREG_VR_SOURCE_ORIGIN_HIGH_Count 1
+#define GCREG_VR_SOURCE_ORIGIN_HIGH_FieldMask 0xFFFFFFFF
+#define GCREG_VR_SOURCE_ORIGIN_HIGH_ReadMask 0xFFFFFFFF
+#define GCREG_VR_SOURCE_ORIGIN_HIGH_WriteMask 0xFFFFFFFF
+#define GCREG_VR_SOURCE_ORIGIN_HIGH_ResetValue 0x00000000
+
+#define GCREG_VR_SOURCE_ORIGIN_HIGH_Y 31 : 0
+#define GCREG_VR_SOURCE_ORIGIN_HIGH_Y_End 31
+#define GCREG_VR_SOURCE_ORIGIN_HIGH_Y_Start 0
+#define GCREG_VR_SOURCE_ORIGIN_HIGH_Y_Type U32
+
+/*******************************************************************************
+** State gcregVRTargetWindowLow
+*/
+
+/* Bounding box of the destination window to be rendered within the
+** destination image.
+*/
+
+#define gcregVRTargetWindowLowRegAddrs 0x04AA
+#define GCREG_VR_TARGET_WINDOW_LOW_Address 0x012A8
+#define GCREG_VR_TARGET_WINDOW_LOW_MSB 15
+#define GCREG_VR_TARGET_WINDOW_LOW_LSB 0
+#define GCREG_VR_TARGET_WINDOW_LOW_BLK 0
+#define GCREG_VR_TARGET_WINDOW_LOW_Count 1
+#define GCREG_VR_TARGET_WINDOW_LOW_FieldMask 0xFFFFFFFF
+#define GCREG_VR_TARGET_WINDOW_LOW_ReadMask 0xFFFFFFFF
+#define GCREG_VR_TARGET_WINDOW_LOW_WriteMask 0xFFFFFFFF
+#define GCREG_VR_TARGET_WINDOW_LOW_ResetValue 0x00000000
+
+#define GCREG_VR_TARGET_WINDOW_LOW_LEFT 15 : 0
+#define GCREG_VR_TARGET_WINDOW_LOW_LEFT_End 15
+#define GCREG_VR_TARGET_WINDOW_LOW_LEFT_Start 0
+#define GCREG_VR_TARGET_WINDOW_LOW_LEFT_Type U16
+
+#define GCREG_VR_TARGET_WINDOW_LOW_TOP 31 : 16
+#define GCREG_VR_TARGET_WINDOW_LOW_TOP_End 31
+#define GCREG_VR_TARGET_WINDOW_LOW_TOP_Start 16
+#define GCREG_VR_TARGET_WINDOW_LOW_TOP_Type U16
+
+struct gcregvrtargetwindowlow {
+ /* gcregVRTargetWindowLowRegAddrs:LEFT */
+ unsigned int left:16;
+
+ /* gcregVRTargetWindowLowRegAddrs:TOP */
+ unsigned int top:16;
+};
+
+/*******************************************************************************
+** State gcregVRTargetWindowHigh
+*/
+
+#define gcregVRTargetWindowHighRegAddrs 0x04AB
+#define GCREG_VR_TARGET_WINDOW_HIGH_MSB 15
+#define GCREG_VR_TARGET_WINDOW_HIGH_LSB 0
+#define GCREG_VR_TARGET_WINDOW_LOW_HIGH_BLK 0
+#define GCREG_VR_TARGET_WINDOW_HIGH_Count 1
+#define GCREG_VR_TARGET_WINDOW_HIGH_FieldMask 0xFFFFFFFF
+#define GCREG_VR_TARGET_WINDOW_HIGH_ReadMask 0xFFFFFFFF
+#define GCREG_VR_TARGET_WINDOW_HIGH_WriteMask 0xFFFFFFFF
+#define GCREG_VR_TARGET_WINDOW_HIGH_ResetValue 0x00000000
+
+#define GCREG_VR_TARGET_WINDOW_HIGH_RIGHT 15 : 0
+#define GCREG_VR_TARGET_WINDOW_HIGH_RIGHT_End 15
+#define GCREG_VR_TARGET_WINDOW_HIGH_RIGHT_Start 0
+#define GCREG_VR_TARGET_WINDOW_HIGH_RIGHT_Type U16
+
+#define GCREG_VR_TARGET_WINDOW_HIGH_BOTTOM 31 : 16
+#define GCREG_VR_TARGET_WINDOW_HIGH_BOTTOM_End 31
+#define GCREG_VR_TARGET_WINDOW_HIGH_BOTTOM_Start 16
+#define GCREG_VR_TARGET_WINDOW_HIGH_BOTTOM_Type U16
+
+struct gcregvrtargetwindowhigh {
+ /* gcregVRTargetWindowHighRegAddrs:LEFT */
+ unsigned int right:16;
+
+ /* gcregVRTargetWindowHighRegAddrs:TOP */
+ unsigned int bottom:16;
+};
+
+/*******************************************************************************
+** State gcregVRConfigEx
+*/
+
+/* Video Rasterizer configuration register. */
+
+#define gcregVRConfigExRegAddrs 0x04B9
+#define GCREG_VR_CONFIG_EX_Address 0x012E4
+#define GCREG_VR_CONFIG_EX_MSB 15
+#define GCREG_VR_CONFIG_EX_LSB 0
+#define GCREG_VR_CONFIG_EX_BLK 0
+#define GCREG_VR_CONFIG_EX_Count 1
+#define GCREG_VR_CONFIG_EX_FieldMask 0x000001FB
+#define GCREG_VR_CONFIG_EX_ReadMask 0x000001FB
+#define GCREG_VR_CONFIG_EX_WriteMask 0x000001FB
+#define GCREG_VR_CONFIG_EX_ResetValue 0x00000000
+
+/* Line width in pixels for vertical pass. */
+#define GCREG_VR_CONFIG_EX_VERTICAL_LINE_WIDTH 1 : 0
+#define GCREG_VR_CONFIG_EX_VERTICAL_LINE_WIDTH_End 1
+#define GCREG_VR_CONFIG_EX_VERTICAL_LINE_WIDTH_Start 0
+#define GCREG_VR_CONFIG_EX_VERTICAL_LINE_WIDTH_Type U02
+#define GCREG_VR_CONFIG_EX_VERTICAL_LINE_WIDTH_AUTO 0x0
+#define GCREG_VR_CONFIG_EX_VERTICAL_LINE_WIDTH_PIXELS16 0x1
+#define GCREG_VR_CONFIG_EX_VERTICAL_LINE_WIDTH_PIXELS32 0x2
+
+#define GCREG_VR_CONFIG_EX_MASK_VERTICAL_LINE_WIDTH 3 : 3
+#define GCREG_VR_CONFIG_EX_MASK_VERTICAL_LINE_WIDTH_End 3
+#define GCREG_VR_CONFIG_EX_MASK_VERTICAL_LINE_WIDTH_Start 3
+#define GCREG_VR_CONFIG_EX_MASK_VERTICAL_LINE_WIDTH_Type U01
+#define GCREG_VR_CONFIG_EX_MASK_VERTICAL_LINE_WIDTH_ENABLED 0x0
+#define GCREG_VR_CONFIG_EX_MASK_VERTICAL_LINE_WIDTH_MASKED 0x1
+
+/* one pass filter tap. */
+#define GCREG_VR_CONFIG_EX_FILTER_TAP 7 : 4
+#define GCREG_VR_CONFIG_EX_FILTER_TAP_End 7
+#define GCREG_VR_CONFIG_EX_FILTER_TAP_Start 4
+#define GCREG_VR_CONFIG_EX_FILTER_TAP_Type U04
+
+#define GCREG_VR_CONFIG_EX_MASK_FILTER_TAP 8 : 8
+#define GCREG_VR_CONFIG_EX_MASK_FILTER_TAP_End 8
+#define GCREG_VR_CONFIG_EX_MASK_FILTER_TAP_Start 8
+#define GCREG_VR_CONFIG_EX_MASK_FILTER_TAP_Type U01
+#define GCREG_VR_CONFIG_EX_MASK_FILTER_TAP_ENABLED 0x0
+#define GCREG_VR_CONFIG_EX_MASK_FILTER_TAP_MASKED 0x1
+
+struct gcregvrconfigex {
+ /* gcregVRConfigExRegAddrs:VERTICAL_LINE_WIDTH */
+ unsigned int stripe:2;
+
+ /* gcregVRConfigExRegAddrs:reserved */
+ unsigned int _reserved_2:1;
+
+ /* gcregVRConfigExRegAddrs:MASK_VERTICAL_LINE_WIDTH */
+ unsigned int mask_stripe:1;
+
+ /* gcregVRConfigExRegAddrs:FILTER_TAP */
+ unsigned int kernelsize:4;
+
+ /* gcregVRConfigExRegAddrs:MASK_FILTER_TAP */
+ unsigned int mask_kernelsize:1;
+
+ /* gcregVRConfigExRegAddrs:reserved */
+ unsigned int _reserved_9_31:23;
+};
+
+/*******************************************************************************
+** State gcregBWConfig
+*/
+
+#define gcregBWConfigRegAddrs 0x04BC
+#define GCREG_BW_CONFIG_MSB 15
+#define GCREG_BW_CONFIG_LSB 0
+#define GCREG_BW_CONFIG_BLK 0
+#define GCREG_BW_CONFIG_Count 1
+#define GCREG_BW_CONFIG_FieldMask 0x00009999
+#define GCREG_BW_CONFIG_ReadMask 0x00009999
+#define GCREG_BW_CONFIG_WriteMask 0x00009999
+#define GCREG_BW_CONFIG_ResetValue 0x00000000
+
+/* One Pass Filter Block Config. */
+#define GCREG_BW_CONFIG_BLOCK_CONFIG 0 : 0
+#define GCREG_BW_CONFIG_BLOCK_CONFIG_End 0
+#define GCREG_BW_CONFIG_BLOCK_CONFIG_Start 0
+#define GCREG_BW_CONFIG_BLOCK_CONFIG_Type U01
+#define GCREG_BW_CONFIG_BLOCK_CONFIG_AUTO 0x0
+#define GCREG_BW_CONFIG_BLOCK_CONFIG_CUSTOMIZE 0x1
+
+#define GCREG_BW_CONFIG_MASK_BLOCK_CONFIG 3 : 3
+#define GCREG_BW_CONFIG_MASK_BLOCK_CONFIG_End 3
+#define GCREG_BW_CONFIG_MASK_BLOCK_CONFIG_Start 3
+#define GCREG_BW_CONFIG_MASK_BLOCK_CONFIG_Type U01
+#define GCREG_BW_CONFIG_MASK_BLOCK_CONFIG_ENABLED 0x0
+#define GCREG_BW_CONFIG_MASK_BLOCK_CONFIG_MASKED 0x1
+
+/* block walk direction in one pass filter blit. */
+#define GCREG_BW_CONFIG_BLOCK_WALK_DIRECTION 4 : 4
+#define GCREG_BW_CONFIG_BLOCK_WALK_DIRECTION_End 4
+#define GCREG_BW_CONFIG_BLOCK_WALK_DIRECTION_Start 4
+#define GCREG_BW_CONFIG_BLOCK_WALK_DIRECTION_Type U01
+#define GCREG_BW_CONFIG_BLOCK_WALK_DIRECTION_RIGHT_BOTTOM 0x0
+#define GCREG_BW_CONFIG_BLOCK_WALK_DIRECTION_BOTTOM_RIGHT 0x1
+
+#define GCREG_BW_CONFIG_MASK_BLOCK_WALK_DIRECTION 7 : 7
+#define GCREG_BW_CONFIG_MASK_BLOCK_WALK_DIRECTION_End 7
+#define GCREG_BW_CONFIG_MASK_BLOCK_WALK_DIRECTION_Start 7
+#define GCREG_BW_CONFIG_MASK_BLOCK_WALK_DIRECTION_Type U01
+#define GCREG_BW_CONFIG_MASK_BLOCK_WALK_DIRECTION_ENABLED 0x0
+#define GCREG_BW_CONFIG_MASK_BLOCK_WALK_DIRECTION_MASKED 0x1
+
+/* block walk direction in one pass filter blit. */
+#define GCREG_BW_CONFIG_TILE_WALK_DIRECTION 8 : 8
+#define GCREG_BW_CONFIG_TILE_WALK_DIRECTION_End 8
+#define GCREG_BW_CONFIG_TILE_WALK_DIRECTION_Start 8
+#define GCREG_BW_CONFIG_TILE_WALK_DIRECTION_Type U01
+#define GCREG_BW_CONFIG_TILE_WALK_DIRECTION_RIGHT_BOTTOM 0x0
+#define GCREG_BW_CONFIG_TILE_WALK_DIRECTION_BOTTOM_RIGHT 0x1
+
+#define GCREG_BW_CONFIG_MASK_TILE_WALK_DIRECTION 11 : 11
+#define GCREG_BW_CONFIG_MASK_TILE_WALK_DIRECTION_End 11
+#define GCREG_BW_CONFIG_MASK_TILE_WALK_DIRECTION_Start 11
+#define GCREG_BW_CONFIG_MASK_TILE_WALK_DIRECTION_Type U01
+#define GCREG_BW_CONFIG_MASK_TILE_WALK_DIRECTION_ENABLED 0x0
+#define GCREG_BW_CONFIG_MASK_TILE_WALK_DIRECTION_MASKED 0x1
+
+/* block walk direction in one pass filter blit. */
+#define GCREG_BW_CONFIG_PIXEL_WALK_DIRECTION 12 : 12
+#define GCREG_BW_CONFIG_PIXEL_WALK_DIRECTION_End 12
+#define GCREG_BW_CONFIG_PIXEL_WALK_DIRECTION_Start 12
+#define GCREG_BW_CONFIG_PIXEL_WALK_DIRECTION_Type U01
+#define GCREG_BW_CONFIG_PIXEL_WALK_DIRECTION_RIGHT_BOTTOM 0x0
+#define GCREG_BW_CONFIG_PIXEL_WALK_DIRECTION_BOTTOM_RIGHT 0x1
+
+#define GCREG_BW_CONFIG_MASK_PIXEL_WALK_DIRECTION 15 : 15
+#define GCREG_BW_CONFIG_MASK_PIXEL_WALK_DIRECTION_End 15
+#define GCREG_BW_CONFIG_MASK_PIXEL_WALK_DIRECTION_Start 15
+#define GCREG_BW_CONFIG_MASK_PIXEL_WALK_DIRECTION_Type U01
+#define GCREG_BW_CONFIG_MASK_PIXEL_WALK_DIRECTION_ENABLED 0x0
+#define GCREG_BW_CONFIG_MASK_PIXEL_WALK_DIRECTION_MASKED 0x1
+
+/*******************************************************************************
+** State gcregBWBlockSize
+*/
+
+/* Walker Block size. */
+
+#define gcregBWBlockSizeRegAddrs 0x04BD
+#define GCREG_BW_BLOCK_SIZE_MSB 15
+#define GCREG_BW_BLOCK_SIZE_LSB 0
+#define GCREG_BW_BLOCK_SIZE_BLK 0
+#define GCREG_BW_BLOCK_SIZE_Count 1
+#define GCREG_BW_BLOCK_SIZE_FieldMask 0xFFFFFFFF
+#define GCREG_BW_BLOCK_SIZE_ReadMask 0xFFFFFFFF
+#define GCREG_BW_BLOCK_SIZE_WriteMask 0xFFFFFFFF
+#define GCREG_BW_BLOCK_SIZE_ResetValue 0x00000000
+
+#define GCREG_BW_BLOCK_SIZE_WIDTH 15 : 0
+#define GCREG_BW_BLOCK_SIZE_WIDTH_End 15
+#define GCREG_BW_BLOCK_SIZE_WIDTH_Start 0
+#define GCREG_BW_BLOCK_SIZE_WIDTH_Type U16
+
+#define GCREG_BW_BLOCK_SIZE_HEIGHT 31 : 16
+#define GCREG_BW_BLOCK_SIZE_HEIGHT_End 31
+#define GCREG_BW_BLOCK_SIZE_HEIGHT_Start 16
+#define GCREG_BW_BLOCK_SIZE_HEIGHT_Type U16
+
+/*******************************************************************************
+** State gcregBWTileSize
+*/
+
+/* Walker tile size. */
+
+#define gcregBWTileSizeRegAddrs 0x04BE
+#define GCREG_BW_TILE_SIZE_MSB 15
+#define GCREG_BW_TILE_SIZE_LSB 0
+#define GCREG_BW_TILE_SIZE_BLK 0
+#define GCREG_BW_TILE_SIZE_Count 1
+#define GCREG_BW_TILE_SIZE_FieldMask 0xFFFFFFFF
+#define GCREG_BW_TILE_SIZE_ReadMask 0xFFFFFFFF
+#define GCREG_BW_TILE_SIZE_WriteMask 0xFFFFFFFF
+#define GCREG_BW_TILE_SIZE_ResetValue 0x00000000
+
+#define GCREG_BW_TILE_SIZE_WIDTH 15 : 0
+#define GCREG_BW_TILE_SIZE_WIDTH_End 15
+#define GCREG_BW_TILE_SIZE_WIDTH_Start 0
+#define GCREG_BW_TILE_SIZE_WIDTH_Type U16
+
+#define GCREG_BW_TILE_SIZE_HEIGHT 31 : 16
+#define GCREG_BW_TILE_SIZE_HEIGHT_End 31
+#define GCREG_BW_TILE_SIZE_HEIGHT_Start 16
+#define GCREG_BW_TILE_SIZE_HEIGHT_Type U16
+
+/*******************************************************************************
+** State gcregBWBlockMask
+*/
+
+/* Walker Block Mask. */
+
+#define gcregBWBlockMaskRegAddrs 0x04BF
+#define GCREG_BW_BLOCK_MASK_MSB 15
+#define GCREG_BW_BLOCK_MASK_LSB 0
+#define GCREG_BW_BLOCK_MASK_BLK 0
+#define GCREG_BW_BLOCK_MASK_Count 1
+#define GCREG_BW_BLOCK_MASK_FieldMask 0xFFFFFFFF
+#define GCREG_BW_BLOCK_MASK_ReadMask 0xFFFFFFFF
+#define GCREG_BW_BLOCK_MASK_WriteMask 0xFFFFFFFF
+#define GCREG_BW_BLOCK_MASK_ResetValue 0x00000000
+
+#define GCREG_BW_BLOCK_MASK_HORIZONTAL 15 : 0
+#define GCREG_BW_BLOCK_MASK_HORIZONTAL_End 15
+#define GCREG_BW_BLOCK_MASK_HORIZONTAL_Start 0
+#define GCREG_BW_BLOCK_MASK_HORIZONTAL_Type U16
+
+#define GCREG_BW_BLOCK_MASK_VERTICAL 31 : 16
+#define GCREG_BW_BLOCK_MASK_VERTICAL_End 31
+#define GCREG_BW_BLOCK_MASK_VERTICAL_Start 16
+#define GCREG_BW_BLOCK_MASK_VERTICAL_Type U16
+
+/*******************************************************************************
+** State gcregIndexColorTable
+*/
+
+/* 256 color entries for the indexed color mode. Colors are assumed to be in
+** the destination format and no color conversion is done on the values.
+*/
+
+#define gcregIndexColorTableRegAddrs 0x0700
+#define GCREG_INDEX_COLOR_TABLE_MSB 15
+#define GCREG_INDEX_COLOR_TABLE_LSB 8
+#define GCREG_INDEX_COLOR_TABLE_BLK 8
+#define GCREG_INDEX_COLOR_TABLE_Count 256
+#define GCREG_INDEX_COLOR_TABLE_FieldMask 0xFFFFFFFF
+#define GCREG_INDEX_COLOR_TABLE_ReadMask 0xFFFFFFFF
+#define GCREG_INDEX_COLOR_TABLE_WriteMask 0xFFFFFFFF
+#define GCREG_INDEX_COLOR_TABLE_ResetValue 0x00000000
+
+#define GCREG_INDEX_COLOR_TABLE_ALPHA 31 : 24
+#define GCREG_INDEX_COLOR_TABLE_ALPHA_End 31
+#define GCREG_INDEX_COLOR_TABLE_ALPHA_Start 24
+#define GCREG_INDEX_COLOR_TABLE_ALPHA_Type U08
+
+#define GCREG_INDEX_COLOR_TABLE_RED 23 : 16
+#define GCREG_INDEX_COLOR_TABLE_RED_End 23
+#define GCREG_INDEX_COLOR_TABLE_RED_Start 16
+#define GCREG_INDEX_COLOR_TABLE_RED_Type U08
+
+#define GCREG_INDEX_COLOR_TABLE_GREEN 15 : 8
+#define GCREG_INDEX_COLOR_TABLE_GREEN_End 15
+#define GCREG_INDEX_COLOR_TABLE_GREEN_Start 8
+#define GCREG_INDEX_COLOR_TABLE_GREEN_Type U08
+
+#define GCREG_INDEX_COLOR_TABLE_BLUE 7 : 0
+#define GCREG_INDEX_COLOR_TABLE_BLUE_End 7
+#define GCREG_INDEX_COLOR_TABLE_BLUE_Start 0
+#define GCREG_INDEX_COLOR_TABLE_BLUE_Type U08
+
+/*******************************************************************************
+** State gcregIndexColorTable32
+*/
+
+/* 256 color entries for the indexed color mode. Colors are assumed to be in
+** the A8R8G8B8 format and no color conversion is done on the values. This
+** register is used only with chips with PE20 feature available.
+*/
+
+#define gcregIndexColorTable32RegAddrs 0x0D00
+#define GCREG_INDEX_COLOR_TABLE32_MSB 15
+#define GCREG_INDEX_COLOR_TABLE32_LSB 8
+#define GCREG_INDEX_COLOR_TABLE32_BLK 8
+#define GCREG_INDEX_COLOR_TABLE32_Count 256
+#define GCREG_INDEX_COLOR_TABLE32_FieldMask 0xFFFFFFFF
+#define GCREG_INDEX_COLOR_TABLE32_ReadMask 0xFFFFFFFF
+#define GCREG_INDEX_COLOR_TABLE32_WriteMask 0xFFFFFFFF
+#define GCREG_INDEX_COLOR_TABLE32_ResetValue 0x00000000
+
+#define GCREG_INDEX_COLOR_TABLE32_ALPHA 31 : 24
+#define GCREG_INDEX_COLOR_TABLE32_ALPHA_End 31
+#define GCREG_INDEX_COLOR_TABLE32_ALPHA_Start 24
+#define GCREG_INDEX_COLOR_TABLE32_ALPHA_Type U08
+
+#define GCREG_INDEX_COLOR_TABLE32_RED 23 : 16
+#define GCREG_INDEX_COLOR_TABLE32_RED_End 23
+#define GCREG_INDEX_COLOR_TABLE32_RED_Start 16
+#define GCREG_INDEX_COLOR_TABLE32_RED_Type U08
+
+#define GCREG_INDEX_COLOR_TABLE32_GREEN 15 : 8
+#define GCREG_INDEX_COLOR_TABLE32_GREEN_End 15
+#define GCREG_INDEX_COLOR_TABLE32_GREEN_Start 8
+#define GCREG_INDEX_COLOR_TABLE32_GREEN_Type U08
+
+#define GCREG_INDEX_COLOR_TABLE32_BLUE 7 : 0
+#define GCREG_INDEX_COLOR_TABLE32_BLUE_End 7
+#define GCREG_INDEX_COLOR_TABLE32_BLUE_Start 0
+#define GCREG_INDEX_COLOR_TABLE32_BLUE_Type U08
+
+/*******************************************************************************
+** State gcregRop
+*/
+
+/* Raster operation foreground and background codes. Even though ROP is not
+** used in CLEAR, HOR_FILTER_BLT, VER_FILTER_BLT and alpha-eanbled BIT_BLTs,
+** ROP code still has to be programmed, because the engine makes the decision
+** whether source, destination and pattern are involved in the current
+** operation and the correct decision is essential for the engine to complete
+** the operation as expected.
+*/
+
+#define gcregRopRegAddrs 0x0497
+#define GCREG_ROP_MSB 15
+#define GCREG_ROP_LSB 0
+#define GCREG_ROP_BLK 0
+#define GCREG_ROP_Count 1
+#define GCREG_ROP_FieldMask 0x0030FFFF
+#define GCREG_ROP_ReadMask 0x0030FFFF
+#define GCREG_ROP_WriteMask 0x0030FFFF
+#define GCREG_ROP_ResetValue 0x00000000
+
+/* ROP type: ROP2, ROP3 or ROP4 */
+#define GCREG_ROP_TYPE 21 : 20
+#define GCREG_ROP_TYPE_End 21
+#define GCREG_ROP_TYPE_Start 20
+#define GCREG_ROP_TYPE_Type U02
+#define GCREG_ROP_TYPE_ROP2_PATTERN 0x0
+#define GCREG_ROP_TYPE_ROP2_SOURCE 0x1
+#define GCREG_ROP_TYPE_ROP3 0x2
+#define GCREG_ROP_TYPE_ROP4 0x3
+
+/* Background ROP code is used for transparent pixels. */
+#define GCREG_ROP_ROP_BG 15 : 8
+#define GCREG_ROP_ROP_BG_End 15
+#define GCREG_ROP_ROP_BG_Start 8
+#define GCREG_ROP_ROP_BG_Type U08
+
+/* Background ROP code is used for opaque pixels. */
+#define GCREG_ROP_ROP_FG 7 : 0
+#define GCREG_ROP_ROP_FG_End 7
+#define GCREG_ROP_ROP_FG_Start 0
+#define GCREG_ROP_ROP_FG_Type U08
+
+struct gcregrop {
+ /* gcregRopRegAddrs:ROP_FG */
+ unsigned int fg:8;
+
+ /* gcregRopRegAddrs:ROP_BG */
+ unsigned int bg:8;
+
+ /* gcregRopRegAddrs:reserved */
+ unsigned int _reserved_16_19:4;
+
+ /* gcregRopRegAddrs:ROP_TYPE */
+ unsigned int type:2;
+
+ /* gcregRopRegAddrs:reserved */
+ unsigned int _reserved_22_31:10;
+};
+
+/*******************************************************************************
+** State gcregClipTopLeft
+*/
+
+/* Top left corner of the clipping rectangle defined in pixels. Clipping is
+** always on and everything beyond the clipping rectangle will be clipped
+** out. Clipping is not used with filter blits.
+*/
+
+#define gcregClipTopLeftRegAddrs 0x0498
+#define GCREG_CLIP_TOP_LEFT_MSB 15
+#define GCREG_CLIP_TOP_LEFT_LSB 0
+#define GCREG_CLIP_TOP_LEFT_BLK 0
+#define GCREG_CLIP_TOP_LEFT_Count 1
+#define GCREG_CLIP_TOP_LEFT_FieldMask 0x7FFF7FFF
+#define GCREG_CLIP_TOP_LEFT_ReadMask 0x7FFF7FFF
+#define GCREG_CLIP_TOP_LEFT_WriteMask 0x7FFF7FFF
+#define GCREG_CLIP_TOP_LEFT_ResetValue 0x00000000
+
+#define GCREG_CLIP_TOP_LEFT_Y 30 : 16
+#define GCREG_CLIP_TOP_LEFT_Y_End 30
+#define GCREG_CLIP_TOP_LEFT_Y_Start 16
+#define GCREG_CLIP_TOP_LEFT_Y_Type U15
+
+#define GCREG_CLIP_TOP_LEFT_X 14 : 0
+#define GCREG_CLIP_TOP_LEFT_X_End 14
+#define GCREG_CLIP_TOP_LEFT_X_Start 0
+#define GCREG_CLIP_TOP_LEFT_X_Type U15
+
+struct gcregcliplt {
+ /* gcregClipTopLeftRegAddrs:X */
+ unsigned int left:15;
+
+ /* gcregClipTopLeftRegAddrs:reserved */
+ unsigned int _reserved_15:1;
+
+ /* gcregClipTopLeftRegAddrs:Y */
+ unsigned int top:15;
+
+ /* gcregClipTopLeftRegAddrs:reserved */
+ unsigned int _reserved_31:1;
+};
+
+/*******************************************************************************
+** State gcregClipBottomRight
+*/
+
+/* Bottom right corner of the clipping rectangle defined in pixels. Clipping
+** is always on and everything beyond the clipping rectangle will be clipped
+** out. Clipping is not used with filter blits.
+*/
+
+#define gcregClipBottomRightRegAddrs 0x0499
+#define GCREG_CLIP_BOTTOM_RIGHT_MSB 15
+#define GCREG_CLIP_BOTTOM_RIGHT_LSB 0
+#define GCREG_CLIP_BOTTOM_RIGHT_BLK 0
+#define GCREG_CLIP_BOTTOM_RIGHT_Count 1
+#define GCREG_CLIP_BOTTOM_RIGHT_FieldMask 0x7FFF7FFF
+#define GCREG_CLIP_BOTTOM_RIGHT_ReadMask 0x7FFF7FFF
+#define GCREG_CLIP_BOTTOM_RIGHT_WriteMask 0x7FFF7FFF
+#define GCREG_CLIP_BOTTOM_RIGHT_ResetValue 0x00000000
+
+#define GCREG_CLIP_BOTTOM_RIGHT_Y 30 : 16
+#define GCREG_CLIP_BOTTOM_RIGHT_Y_End 30
+#define GCREG_CLIP_BOTTOM_RIGHT_Y_Start 16
+#define GCREG_CLIP_BOTTOM_RIGHT_Y_Type U15
+
+#define GCREG_CLIP_BOTTOM_RIGHT_X 14 : 0
+#define GCREG_CLIP_BOTTOM_RIGHT_X_End 14
+#define GCREG_CLIP_BOTTOM_RIGHT_X_Start 0
+#define GCREG_CLIP_BOTTOM_RIGHT_X_Type U15
+
+struct gcregcliprb {
+ /* gcregClipBottomRightRegAddrs:X */
+ unsigned int right:15;
+
+ /* gcregClipBottomRightRegAddrs:reserved */
+ unsigned int _reserved_15:1;
+
+ /* gcregClipBottomRightRegAddrs:Y */
+ unsigned int bottom:15;
+
+ /* gcregClipBottomRightRegAddrs:reserved */
+ unsigned int _reserved_31:1;
+};
+
+/*******************************************************************************
+** State gcregConfig
+*/
+
+#define gcregConfigRegAddrs 0x049B
+#define GCREG_CONFIG_MSB 15
+#define GCREG_CONFIG_LSB 0
+#define GCREG_CONFIG_BLK 0
+#define GCREG_CONFIG_Count 1
+#define GCREG_CONFIG_FieldMask 0x00370031
+#define GCREG_CONFIG_ReadMask 0x00370031
+#define GCREG_CONFIG_WriteMask 0x00370031
+#define GCREG_CONFIG_ResetValue 0x00000000
+
+#define GCREG_CONFIG_MIRROR_BLT_MODE 5 : 4
+#define GCREG_CONFIG_MIRROR_BLT_MODE_End 5
+#define GCREG_CONFIG_MIRROR_BLT_MODE_Start 4
+#define GCREG_CONFIG_MIRROR_BLT_MODE_Type U02
+#define GCREG_CONFIG_MIRROR_BLT_MODE_NORMAL 0x0
+#define GCREG_CONFIG_MIRROR_BLT_MODE_HMIRROR 0x1
+#define GCREG_CONFIG_MIRROR_BLT_MODE_VMIRROR 0x2
+#define GCREG_CONFIG_MIRROR_BLT_MODE_FULL_MIRROR 0x3
+
+#define GCREG_CONFIG_MIRROR_BLT_ENABLE 0 : 0
+#define GCREG_CONFIG_MIRROR_BLT_ENABLE_End 0
+#define GCREG_CONFIG_MIRROR_BLT_ENABLE_Start 0
+#define GCREG_CONFIG_MIRROR_BLT_ENABLE_Type U01
+#define GCREG_CONFIG_MIRROR_BLT_ENABLE_OFF 0x0
+#define GCREG_CONFIG_MIRROR_BLT_ENABLE_ON 0x1
+
+/* Source select for the old walkers. */
+#define GCREG_CONFIG_SOURCE_SELECT 18 : 16
+#define GCREG_CONFIG_SOURCE_SELECT_End 18
+#define GCREG_CONFIG_SOURCE_SELECT_Start 16
+#define GCREG_CONFIG_SOURCE_SELECT_Type U03
+
+/* Destination select for the old walkers. */
+#define GCREG_CONFIG_DESTINATION_SELECT 21 : 20
+#define GCREG_CONFIG_DESTINATION_SELECT_End 21
+#define GCREG_CONFIG_DESTINATION_SELECT_Start 20
+#define GCREG_CONFIG_DESTINATION_SELECT_Type U02
+
+/*******************************************************************************
+** State gcregSrcOriginFraction
+*/
+
+/* Fraction for the source origin. Together with values in gcregSrcOrigin
+** these values form signed 16.16 fixed point origin for the source
+** rectangle. Fractions are only used in filter blit in split frame mode.
+*/
+
+#define gcregSrcOriginFractionRegAddrs 0x049E
+#define GCREG_SRC_ORIGIN_FRACTION_MSB 15
+#define GCREG_SRC_ORIGIN_FRACTION_LSB 0
+#define GCREG_SRC_ORIGIN_FRACTION_BLK 0
+#define GCREG_SRC_ORIGIN_FRACTION_Count 1
+#define GCREG_SRC_ORIGIN_FRACTION_FieldMask 0xFFFFFFFF
+#define GCREG_SRC_ORIGIN_FRACTION_ReadMask 0xFFFFFFFF
+#define GCREG_SRC_ORIGIN_FRACTION_WriteMask 0xFFFFFFFF
+#define GCREG_SRC_ORIGIN_FRACTION_ResetValue 0x00000000
+
+#define GCREG_SRC_ORIGIN_FRACTION_Y 31 : 16
+#define GCREG_SRC_ORIGIN_FRACTION_Y_End 31
+#define GCREG_SRC_ORIGIN_FRACTION_Y_Start 16
+#define GCREG_SRC_ORIGIN_FRACTION_Y_Type U16
+
+#define GCREG_SRC_ORIGIN_FRACTION_X 15 : 0
+#define GCREG_SRC_ORIGIN_FRACTION_X_End 15
+#define GCREG_SRC_ORIGIN_FRACTION_X_Start 0
+#define GCREG_SRC_ORIGIN_FRACTION_X_Type U16
+
+/*******************************************************************************
+** State gcregAlphaControl
+*/
+
+#define gcregAlphaControlRegAddrs 0x049F
+#define GCREG_ALPHA_CONTROL_MSB 15
+#define GCREG_ALPHA_CONTROL_LSB 0
+#define GCREG_ALPHA_CONTROL_BLK 0
+#define GCREG_ALPHA_CONTROL_Count 1
+#define GCREG_ALPHA_CONTROL_FieldMask 0xFFFF0001
+#define GCREG_ALPHA_CONTROL_ReadMask 0xFFFF0001
+#define GCREG_ALPHA_CONTROL_WriteMask 0xFFFF0001
+#define GCREG_ALPHA_CONTROL_ResetValue 0x00000000
+
+#define GCREG_ALPHA_CONTROL_ENABLE 0 : 0
+#define GCREG_ALPHA_CONTROL_ENABLE_End 0
+#define GCREG_ALPHA_CONTROL_ENABLE_Start 0
+#define GCREG_ALPHA_CONTROL_ENABLE_Type U01
+#define GCREG_ALPHA_CONTROL_ENABLE_OFF 0x0
+#define GCREG_ALPHA_CONTROL_ENABLE_ON 0x1
+
+struct gcregalphacontrol {
+ /* gcregAlphaControlRegAddrs:GCREG_ALPHA_CONTROL_ENABLE */
+ unsigned int enable:1;
+
+ /* gcregAlphaControlRegAddrs:reserved */
+ unsigned int _reserved_1_31:31;
+};
+
+static const struct gcregalphacontrol gcregalpha_off = {
+ /* gcregAlphaControlRegAddrs:GCREG_ALPHA_CONTROL_ENABLE */
+ GCREG_ALPHA_CONTROL_ENABLE_OFF,
+
+ /* gcregAlphaControlRegAddrs:reserved */
+ 0
+};
+
+static const struct gcregalphacontrol gcregalpha_on = {
+ /* gcregAlphaControlRegAddrs:GCREG_ALPHA_CONTROL_ENABLE */
+ GCREG_ALPHA_CONTROL_ENABLE_ON,
+
+ /* gcregAlphaControlRegAddrs:reserved */
+ 0
+};
+
+/*******************************************************************************
+** State gcregAlphaModes
+*/
+
+#define gcregAlphaModesRegAddrs 0x04A0
+#define GCREG_ALPHA_MODES_MSB 15
+#define GCREG_ALPHA_MODES_LSB 0
+#define GCREG_ALPHA_MODES_BLK 0
+#define GCREG_ALPHA_MODES_Count 1
+#define GCREG_ALPHA_MODES_FieldMask 0xFF113311
+#define GCREG_ALPHA_MODES_ReadMask 0xFF113311
+#define GCREG_ALPHA_MODES_WriteMask 0xFF113311
+#define GCREG_ALPHA_MODES_ResetValue 0x00000000
+
+#define GCREG_ALPHA_MODES_SRC_ALPHA_MODE 0 : 0
+#define GCREG_ALPHA_MODES_SRC_ALPHA_MODE_End 0
+#define GCREG_ALPHA_MODES_SRC_ALPHA_MODE_Start 0
+#define GCREG_ALPHA_MODES_SRC_ALPHA_MODE_Type U01
+#define GCREG_ALPHA_MODES_SRC_ALPHA_MODE_NORMAL 0x0
+#define GCREG_ALPHA_MODES_SRC_ALPHA_MODE_INVERSED 0x1
+
+#define GCREG_ALPHA_MODES_DST_ALPHA_MODE 4 : 4
+#define GCREG_ALPHA_MODES_DST_ALPHA_MODE_End 4
+#define GCREG_ALPHA_MODES_DST_ALPHA_MODE_Start 4
+#define GCREG_ALPHA_MODES_DST_ALPHA_MODE_Type U01
+#define GCREG_ALPHA_MODES_DST_ALPHA_MODE_NORMAL 0x0
+#define GCREG_ALPHA_MODES_DST_ALPHA_MODE_INVERSED 0x1
+
+#define GCREG_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE 9 : 8
+#define GCREG_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE_End 9
+#define GCREG_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE_Start 8
+#define GCREG_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE_Type U02
+#define GCREG_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE_NORMAL 0x0
+#define GCREG_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE_GLOBAL 0x1
+#define GCREG_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE_SCALED 0x2
+
+#define GCREG_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE 13 : 12
+#define GCREG_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE_End 13
+#define GCREG_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE_Start 12
+#define GCREG_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE_Type U02
+#define GCREG_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE_NORMAL 0x0
+#define GCREG_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE_GLOBAL 0x1
+#define GCREG_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE_SCALED 0x2
+
+#define GCREG_ALPHA_MODES_SRC_BLENDING_MODE 26 : 24
+#define GCREG_ALPHA_MODES_SRC_BLENDING_MODE_End 26
+#define GCREG_ALPHA_MODES_SRC_BLENDING_MODE_Start 24
+#define GCREG_ALPHA_MODES_SRC_BLENDING_MODE_Type U03
+#define GCREG_ALPHA_MODES_SRC_BLENDING_MODE_ZERO 0x0
+#define GCREG_ALPHA_MODES_SRC_BLENDING_MODE_ONE 0x1
+#define GCREG_ALPHA_MODES_SRC_BLENDING_MODE_NORMAL 0x2
+#define GCREG_ALPHA_MODES_SRC_BLENDING_MODE_INVERSED 0x3
+#define GCREG_ALPHA_MODES_SRC_BLENDING_MODE_COLOR 0x4
+#define GCREG_ALPHA_MODES_SRC_BLENDING_MODE_COLOR_INVERSED 0x5
+#define GCREG_ALPHA_MODES_SRC_BLENDING_MODE_SATURATED_ALPHA 0x6
+#define GCREG_ALPHA_MODES_SRC_BLENDING_MODE_SATURATED_DEST_ALPHA 0x7
+
+/* Src Blending factor is calculate from Src alpha. */
+#define GCREG_ALPHA_MODES_SRC_ALPHA_FACTOR 27 : 27
+#define GCREG_ALPHA_MODES_SRC_ALPHA_FACTOR_End 27
+#define GCREG_ALPHA_MODES_SRC_ALPHA_FACTOR_Start 27
+#define GCREG_ALPHA_MODES_SRC_ALPHA_FACTOR_Type U01
+#define GCREG_ALPHA_MODES_SRC_ALPHA_FACTOR_DISABLED 0x0
+#define GCREG_ALPHA_MODES_SRC_ALPHA_FACTOR_ENABLED 0x1
+
+#define GCREG_ALPHA_MODES_DST_BLENDING_MODE 30 : 28
+#define GCREG_ALPHA_MODES_DST_BLENDING_MODE_End 30
+#define GCREG_ALPHA_MODES_DST_BLENDING_MODE_Start 28
+#define GCREG_ALPHA_MODES_DST_BLENDING_MODE_Type U03
+#define GCREG_ALPHA_MODES_DST_BLENDING_MODE_ZERO 0x0
+#define GCREG_ALPHA_MODES_DST_BLENDING_MODE_ONE 0x1
+#define GCREG_ALPHA_MODES_DST_BLENDING_MODE_NORMAL 0x2
+#define GCREG_ALPHA_MODES_DST_BLENDING_MODE_INVERSED 0x3
+#define GCREG_ALPHA_MODES_DST_BLENDING_MODE_COLOR 0x4
+#define GCREG_ALPHA_MODES_DST_BLENDING_MODE_COLOR_INVERSED 0x5
+#define GCREG_ALPHA_MODES_DST_BLENDING_MODE_SATURATED_ALPHA 0x6
+#define GCREG_ALPHA_MODES_DST_BLENDING_MODE_SATURATED_DEST_ALPHA 0x7
+
+/* Dst Blending factor is calculate from Dst alpha. */
+#define GCREG_ALPHA_MODES_DST_ALPHA_FACTOR 31 : 31
+#define GCREG_ALPHA_MODES_DST_ALPHA_FACTOR_End 31
+#define GCREG_ALPHA_MODES_DST_ALPHA_FACTOR_Start 31
+#define GCREG_ALPHA_MODES_DST_ALPHA_FACTOR_Type U01
+#define GCREG_ALPHA_MODES_DST_ALPHA_FACTOR_DISABLED 0x0
+#define GCREG_ALPHA_MODES_DST_ALPHA_FACTOR_ENABLED 0x1
+
+struct gcregalphamodes {
+ /* gcregAlphaModes:GCREG_ALPHA_MODES_SRC_ALPHA_MODE */
+ unsigned int src_inverse:1;
+
+ /* gcregAlphaModes:reserved */
+ unsigned int _reserved_1_3:3;
+
+ /* gcregAlphaModes:GCREG_ALPHA_MODES_DST_ALPHA_MODE */
+ unsigned int dst_inverse:1;
+
+ /* gcregAlphaModes:reserved */
+ unsigned int _reserved_5_7:3;
+
+ /* gcregAlphaModes:GCREG_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE */
+ unsigned int src_global_alpha_mode:2;
+
+ /* gcregAlphaModes:reserved */
+ unsigned int _reserved_10_11:2;
+
+ /* gcregAlphaModes:GCREG_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE */
+ unsigned int dst_global_alpha_mode:2;
+
+ /* gcregAlphaModes:reserved */
+ unsigned int _reserved_14_23:10;
+
+ /* gcregAlphaModes:GCREG_ALPHA_MODES_SRC_BLENDING_MODE */
+ unsigned int src_blend:3;
+
+ /* gcregAlphaModes:GCREG_ALPHA_MODES_SRC_ALPHA_FACTOR */
+ unsigned int src_color_reverse:1;
+
+ /* gcregAlphaModes:GCREG_ALPHA_MODES_DST_BLENDING_MODE */
+ unsigned int dst_blend:3;
+
+ /* gcregAlphaModes:GCREG_ALPHA_MODES_DST_ALPHA_FACTOR */
+ unsigned int dst_color_reverse:1;
+};
+
+/*******************************************************************************
+** State UPlaneAddress
+*/
+
+/* 32-bit aligned base address of the source U plane. */
+
+#define gcregUPlaneAddressRegAddrs 0x04A1
+#define GCREG_UPLANE_ADDRESS_MSB 15
+#define GCREG_UPLANE_ADDRESS_LSB 0
+#define GCREG_UPLANE_ADDRESS_BLK 0
+#define GCREG_UPLANE_ADDRESS_Count 1
+#define GCREG_UPLANE_ADDRESS_FieldMask 0xFFFFFFFF
+#define GCREG_UPLANE_ADDRESS_ReadMask 0xFFFFFFFC
+#define GCREG_UPLANE_ADDRESS_WriteMask 0xFFFFFFFC
+#define GCREG_UPLANE_ADDRESS_ResetValue 0x00000000
+
+#define GCREG_UPLANE_ADDRESS_ADDRESS 31 : 0
+#define GCREG_UPLANE_ADDRESS_ADDRESS_End 30
+#define GCREG_UPLANE_ADDRESS_ADDRESS_Start 0
+#define GCREG_UPLANE_ADDRESS_ADDRESS_Type U31
+
+/*******************************************************************************
+** State UPlaneStride
+*/
+
+/* Stride of the source U plane in bytes. */
+
+#define gcregUPlaneStrideRegAddrs 0x04A2
+#define GCREG_UPLANE_STRIDE_MSB 15
+#define GCREG_UPLANE_STRIDE_LSB 0
+#define GCREG_UPLANE_STRIDE_BLK 0
+#define GCREG_UPLANE_STRIDE_Count 1
+#define GCREG_UPLANE_STRIDE_FieldMask 0x0003FFFF
+#define GCREG_UPLANE_STRIDE_ReadMask 0x0003FFFC
+#define GCREG_UPLANE_STRIDE_WriteMask 0x0003FFFC
+#define GCREG_UPLANE_STRIDE_ResetValue 0x00000000
+
+#define GCREG_UPLANE_STRIDE_STRIDE 17 : 0
+#define GCREG_UPLANE_STRIDE_STRIDE_End 17
+#define GCREG_UPLANE_STRIDE_STRIDE_Start 0
+#define GCREG_UPLANE_STRIDE_STRIDE_Type U18
+
+/*******************************************************************************
+** State VPlaneAddress
+*/
+
+/* 32-bit aligned base address of the source V plane. */
+
+#define gcregVPlaneAddressRegAddrs 0x04A3
+#define GCREG_VPLANE_ADDRESS_MSB 15
+#define GCREG_VPLANE_ADDRESS_LSB 0
+#define GCREG_VPLANE_ADDRESS_BLK 0
+#define GCREG_VPLANE_ADDRESS_Count 1
+#define GCREG_VPLANE_ADDRESS_FieldMask 0xFFFFFFFF
+#define GCREG_VPLANE_ADDRESS_ReadMask 0xFFFFFFFC
+#define GCREG_VPLANE_ADDRESS_WriteMask 0xFFFFFFFC
+#define GCREG_VPLANE_ADDRESS_ResetValue 0x00000000
+
+#define GCREG_VPLANE_ADDRESS_ADDRESS 31 : 0
+#define GCREG_VPLANE_ADDRESS_ADDRESS_End 30
+#define GCREG_VPLANE_ADDRESS_ADDRESS_Start 0
+#define GCREG_VPLANE_ADDRESS_ADDRESS_Type U31
+
+/*******************************************************************************
+** State VPlaneStride
+*/
+
+/* Stride of the source V plane in bytes. */
+
+#define gcregVPlaneStrideRegAddrs 0x04A4
+#define GCREG_VPLANE_STRIDE_MSB 15
+#define GCREG_VPLANE_STRIDE_LSB 0
+#define GCREG_VPLANE_STRIDE_BLK 0
+#define GCREG_VPLANE_STRIDE_Count 1
+#define GCREG_VPLANE_STRIDE_FieldMask 0x0003FFFF
+#define GCREG_VPLANE_STRIDE_ReadMask 0x0003FFFC
+#define GCREG_VPLANE_STRIDE_WriteMask 0x0003FFFC
+#define GCREG_VPLANE_STRIDE_ResetValue 0x00000000
+
+#define GCREG_VPLANE_STRIDE_STRIDE 17 : 0
+#define GCREG_VPLANE_STRIDE_STRIDE_End 17
+#define GCREG_VPLANE_STRIDE_STRIDE_Start 0
+#define GCREG_VPLANE_STRIDE_STRIDE_Type U18
+
+/*******************************************************************************
+** State gcregPEConfig
+*/
+
+/* PE debug register. */
+
+#define gcregPEConfigRegAddrs 0x04AC
+#define GCREG_PE_CONFIG_Address 0x012B0
+#define GCREG_PE_CONFIG_MSB 15
+#define GCREG_PE_CONFIG_LSB 0
+#define GCREG_PE_CONFIG_BLK 0
+#define GCREG_PE_CONFIG_Count 1
+#define GCREG_PE_CONFIG_FieldMask 0x0000000B
+#define GCREG_PE_CONFIG_ReadMask 0x0000000B
+#define GCREG_PE_CONFIG_WriteMask 0x0000000B
+#define GCREG_PE_CONFIG_ResetValue 0x00000000
+
+#define GCREG_PE_CONFIG_DESTINATION_FETCH 1 : 0
+#define GCREG_PE_CONFIG_DESTINATION_FETCH_End 1
+#define GCREG_PE_CONFIG_DESTINATION_FETCH_Start 0
+#define GCREG_PE_CONFIG_DESTINATION_FETCH_Type U02
+#define GCREG_PE_CONFIG_DESTINATION_FETCH_DISABLE 0x0
+#define GCREG_PE_CONFIG_DESTINATION_FETCH_DEFAULT 0x1
+#define GCREG_PE_CONFIG_DESTINATION_FETCH_ALWAYS 0x2
+
+#define GCREG_PE_CONFIG_MASK_DESTINATION_FETCH 3 : 3
+#define GCREG_PE_CONFIG_MASK_DESTINATION_FETCH_End 3
+#define GCREG_PE_CONFIG_MASK_DESTINATION_FETCH_Start 3
+#define GCREG_PE_CONFIG_MASK_DESTINATION_FETCH_Type U01
+#define GCREG_PE_CONFIG_MASK_DESTINATION_FETCH_ENABLED 0x0
+#define GCREG_PE_CONFIG_MASK_DESTINATION_FETCH_MASKED 0x1
+
+/*******************************************************************************
+** State gcregDstRotationHeight
+*/
+
+/* 180/270 degree rotation configuration for the destination surface. Height
+** field specifies the height of the surface in pixels.
+*/
+
+#define gcregDstRotationHeightRegAddrs 0x04AD
+#define GCREG_DST_ROTATION_HEIGHT_MSB 15
+#define GCREG_DST_ROTATION_HEIGHT_LSB 0
+#define GCREG_DST_ROTATION_HEIGHT_BLK 0
+#define GCREG_DST_ROTATION_HEIGHT_Count 1
+#define GCREG_DST_ROTATION_HEIGHT_FieldMask 0x0000FFFF
+#define GCREG_DST_ROTATION_HEIGHT_ReadMask 0x0000FFFF
+#define GCREG_DST_ROTATION_HEIGHT_WriteMask 0x0000FFFF
+#define GCREG_DST_ROTATION_HEIGHT_ResetValue 0x00000000
+
+#define GCREG_DST_ROTATION_HEIGHT_HEIGHT 15 : 0
+#define GCREG_DST_ROTATION_HEIGHT_HEIGHT_End 15
+#define GCREG_DST_ROTATION_HEIGHT_HEIGHT_Start 0
+#define GCREG_DST_ROTATION_HEIGHT_HEIGHT_Type U16
+
+struct gcregdstrotationheight {
+ /* gcregDstRotationHeightRegAddrs:GCREG_DST_ROTATION_HEIGHT_HEIGHT */
+ unsigned int height:16;
+
+ /* gcregDstRotationHeightRegAddrs:reserved */
+ unsigned int _reserved_16_31:16;
+};
+
+/*******************************************************************************
+** State gcregSrcRotationHeight
+*/
+
+/* 180/270 degree rotation configuration for the Source surface. Height field
+** specifies the height of the surface in pixels.
+*/
+
+#define gcregSrcRotationHeightRegAddrs 0x04AE
+#define GCREG_SRC_ROTATION_HEIGHT_MSB 15
+#define GCREG_SRC_ROTATION_HEIGHT_LSB 0
+#define GCREG_SRC_ROTATION_HEIGHT_BLK 0
+#define GCREG_SRC_ROTATION_HEIGHT_Count 1
+#define GCREG_SRC_ROTATION_HEIGHT_FieldMask 0x0000FFFF
+#define GCREG_SRC_ROTATION_HEIGHT_ReadMask 0x0000FFFF
+#define GCREG_SRC_ROTATION_HEIGHT_WriteMask 0x0000FFFF
+#define GCREG_SRC_ROTATION_HEIGHT_ResetValue 0x00000000
+
+#define GCREG_SRC_ROTATION_HEIGHT_HEIGHT 15 : 0
+#define GCREG_SRC_ROTATION_HEIGHT_HEIGHT_End 15
+#define GCREG_SRC_ROTATION_HEIGHT_HEIGHT_Start 0
+#define GCREG_SRC_ROTATION_HEIGHT_HEIGHT_Type U16
+
+struct gcregsrcrotationheight {
+ /* gcregSrcRotationHeightRegAddrs:GCREG_SRC_ROTATION_HEIGHT_HEIGHT */
+ unsigned int height:16;
+
+ /* gcregSrcRotationHeightRegAddrs:reserved */
+ unsigned int _reserved_16_31:16;
+};
+
+/*******************************************************************************
+** State gcregRotAngle
+*/
+
+/* 0/90/180/270 degree rotation configuration for the Source surface. Height
+** field specifies the height of the surface in pixels.
+*/
+
+#define gcregRotAngleRegAddrs 0x04AF
+#define GCREG_ROT_ANGLE_MSB 15
+#define GCREG_ROT_ANGLE_LSB 0
+#define GCREG_ROT_ANGLE_BLK 0
+#define GCREG_ROT_ANGLE_Count 1
+#define GCREG_ROT_ANGLE_FieldMask 0x000BB33F
+#define GCREG_ROT_ANGLE_ReadMask 0x000BB33F
+#define GCREG_ROT_ANGLE_WriteMask 0x000BB33F
+#define GCREG_ROT_ANGLE_ResetValue 0x00000000
+
+#define GCREG_ROT_ANGLE_SRC 2 : 0
+#define GCREG_ROT_ANGLE_SRC_End 2
+#define GCREG_ROT_ANGLE_SRC_Start 0
+#define GCREG_ROT_ANGLE_SRC_Type U03
+#define GCREG_ROT_ANGLE_SRC_ROT0 0x0
+#define GCREG_ROT_ANGLE_SRC_FLIP_X 0x1
+#define GCREG_ROT_ANGLE_SRC_FLIP_Y 0x2
+#define GCREG_ROT_ANGLE_SRC_ROT90 0x4
+#define GCREG_ROT_ANGLE_SRC_ROT180 0x5
+#define GCREG_ROT_ANGLE_SRC_ROT270 0x6
+
+#define GCREG_ROT_ANGLE_DST 5 : 3
+#define GCREG_ROT_ANGLE_DST_End 5
+#define GCREG_ROT_ANGLE_DST_Start 3
+#define GCREG_ROT_ANGLE_DST_Type U03
+#define GCREG_ROT_ANGLE_DST_ROT0 0x0
+#define GCREG_ROT_ANGLE_DST_FLIP_X 0x1
+#define GCREG_ROT_ANGLE_DST_FLIP_Y 0x2
+#define GCREG_ROT_ANGLE_DST_ROT90 0x4
+#define GCREG_ROT_ANGLE_DST_ROT180 0x5
+#define GCREG_ROT_ANGLE_DST_ROT270 0x6
+
+#define GCREG_ROT_ANGLE_MASK_SRC 8 : 8
+#define GCREG_ROT_ANGLE_MASK_SRC_End 8
+#define GCREG_ROT_ANGLE_MASK_SRC_Start 8
+#define GCREG_ROT_ANGLE_MASK_SRC_Type U01
+#define GCREG_ROT_ANGLE_MASK_SRC_ENABLED 0x0
+#define GCREG_ROT_ANGLE_MASK_SRC_MASKED 0x1
+
+#define GCREG_ROT_ANGLE_MASK_DST 9 : 9
+#define GCREG_ROT_ANGLE_MASK_DST_End 9
+#define GCREG_ROT_ANGLE_MASK_DST_Start 9
+#define GCREG_ROT_ANGLE_MASK_DST_Type U01
+#define GCREG_ROT_ANGLE_MASK_DST_ENABLED 0x0
+#define GCREG_ROT_ANGLE_MASK_DST_MASKED 0x1
+
+#define GCREG_ROT_ANGLE_SRC_MIRROR 13 : 12
+#define GCREG_ROT_ANGLE_SRC_MIRROR_End 13
+#define GCREG_ROT_ANGLE_SRC_MIRROR_Start 12
+#define GCREG_ROT_ANGLE_SRC_MIRROR_Type U02
+#define GCREG_ROT_ANGLE_SRC_MIRROR_NONE 0x0
+#define GCREG_ROT_ANGLE_SRC_MIRROR_MIRROR_X 0x1
+#define GCREG_ROT_ANGLE_SRC_MIRROR_MIRROR_Y 0x2
+#define GCREG_ROT_ANGLE_SRC_MIRROR_MIRROR_XY 0x3
+
+#define GCREG_ROT_ANGLE_MASK_SRC_MIRROR 15 : 15
+#define GCREG_ROT_ANGLE_MASK_SRC_MIRROR_End 15
+#define GCREG_ROT_ANGLE_MASK_SRC_MIRROR_Start 15
+#define GCREG_ROT_ANGLE_MASK_SRC_MIRROR_Type U01
+#define GCREG_ROT_ANGLE_MASK_SRC_MIRROR_ENABLED 0x0
+#define GCREG_ROT_ANGLE_MASK_SRC_MIRROR_MASKED 0x1
+
+#define GCREG_ROT_ANGLE_DST_MIRROR 17 : 16
+#define GCREG_ROT_ANGLE_DST_MIRROR_End 17
+#define GCREG_ROT_ANGLE_DST_MIRROR_Start 16
+#define GCREG_ROT_ANGLE_DST_MIRROR_Type U02
+#define GCREG_ROT_ANGLE_DST_MIRROR_NONE 0x0
+#define GCREG_ROT_ANGLE_DST_MIRROR_MIRROR_X 0x1
+#define GCREG_ROT_ANGLE_DST_MIRROR_MIRROR_Y 0x2
+#define GCREG_ROT_ANGLE_DST_MIRROR_MIRROR_XY 0x3
+
+#define GCREG_ROT_ANGLE_MASK_DST_MIRROR 19 : 19
+#define GCREG_ROT_ANGLE_MASK_DST_MIRROR_End 19
+#define GCREG_ROT_ANGLE_MASK_DST_MIRROR_Start 19
+#define GCREG_ROT_ANGLE_MASK_DST_MIRROR_Type U01
+#define GCREG_ROT_ANGLE_MASK_DST_MIRROR_ENABLED 0x0
+#define GCREG_ROT_ANGLE_MASK_DST_MIRROR_MASKED 0x1
+
+struct gcregrotangle {
+ /* gcregRotAngleRegAddrs:GCREG_ROT_ANGLE_SRC */
+ unsigned int src:3;
+
+ /* gcregRotAngleRegAddrs:GCREG_ROT_ANGLE_DST */
+ unsigned int dst:3;
+
+ /* gcregRotAngleRegAddrs:reserved */
+ unsigned int _reserved_6_7:2;
+
+ /* gcregRotAngleRegAddrs:GCREG_ROT_ANGLE_MASK_SRC */
+ unsigned int src_mask:1;
+
+ /* gcregRotAngleRegAddrs:GCREG_ROT_ANGLE_MASK_DST */
+ unsigned int dst_mask:1;
+
+ /* gcregRotAngleRegAddrs:reserved */
+ unsigned int _reserved_10_11:2;
+
+ /* gcregRotAngleRegAddrs:GCREG_ROT_ANGLE_SRC_MIRROR */
+ unsigned int src_mirror:2;
+
+ /* gcregRotAngleRegAddrs:reserved */
+ unsigned int _reserved_14:1;
+
+ /* gcregRotAngleRegAddrs:GCREG_ROT_ANGLE_MASK_SRC_MIRROR */
+ unsigned int src_mirror_mask:1;
+
+ /* gcregRotAngleRegAddrs:GCREG_ROT_ANGLE_DST_MIRROR */
+ unsigned int dst_mirror:2;
+
+ /* gcregRotAngleRegAddrs:reserved */
+ unsigned int _reserved_18:1;
+
+ /* gcregRotAngleRegAddrs:GCREG_ROT_ANGLE_MASK_DST_MIRROR */
+ unsigned int dst_mirror_mask:1;
+
+ /* gcregRotAngleRegAddrs:reserved */
+ unsigned int _reserved_20_31:12;
+};
+
+/*******************************************************************************
+** State gcregClearPixelValue32
+*/
+
+/* Clear color value in A8R8G8B8 format. */
+
+#define gcregClearPixelValue32RegAddrs 0x04B0
+#define GCREG_CLEAR_PIXEL_VALUE32_MSB 15
+#define GCREG_CLEAR_PIXEL_VALUE32_LSB 0
+#define GCREG_CLEAR_PIXEL_VALUE32_BLK 0
+#define GCREG_CLEAR_PIXEL_VALUE32_Count 1
+#define GCREG_CLEAR_PIXEL_VALUE32_FieldMask 0xFFFFFFFF
+#define GCREG_CLEAR_PIXEL_VALUE32_ReadMask 0xFFFFFFFF
+#define GCREG_CLEAR_PIXEL_VALUE32_WriteMask 0xFFFFFFFF
+#define GCREG_CLEAR_PIXEL_VALUE32_ResetValue 0x00000000
+
+#define GCREG_CLEAR_PIXEL_VALUE32_ALPHA 31 : 24
+#define GCREG_CLEAR_PIXEL_VALUE32_ALPHA_End 31
+#define GCREG_CLEAR_PIXEL_VALUE32_ALPHA_Start 24
+#define GCREG_CLEAR_PIXEL_VALUE32_ALPHA_Type U08
+
+#define GCREG_CLEAR_PIXEL_VALUE32_RED 23 : 16
+#define GCREG_CLEAR_PIXEL_VALUE32_RED_End 23
+#define GCREG_CLEAR_PIXEL_VALUE32_RED_Start 16
+#define GCREG_CLEAR_PIXEL_VALUE32_RED_Type U08
+
+#define GCREG_CLEAR_PIXEL_VALUE32_GREEN 15 : 8
+#define GCREG_CLEAR_PIXEL_VALUE32_GREEN_End 15
+#define GCREG_CLEAR_PIXEL_VALUE32_GREEN_Start 8
+#define GCREG_CLEAR_PIXEL_VALUE32_GREEN_Type U08
+
+#define GCREG_CLEAR_PIXEL_VALUE32_BLUE 7 : 0
+#define GCREG_CLEAR_PIXEL_VALUE32_BLUE_End 7
+#define GCREG_CLEAR_PIXEL_VALUE32_BLUE_Start 0
+#define GCREG_CLEAR_PIXEL_VALUE32_BLUE_Type U08
+
+struct gcregclearcolor {
+ /* gcregClearPixelValue32RegAddrs:GCREG_CLEAR_PIXEL_VALUE32_BLUE */
+ unsigned int b:8;
+
+ /* gcregClearPixelValue32RegAddrs:GCREG_CLEAR_PIXEL_VALUE32_GREEN */
+ unsigned int g:8;
+
+ /* gcregClearPixelValue32RegAddrs:GCREG_CLEAR_PIXEL_VALUE32_RED */
+ unsigned int r:8;
+
+ /* gcregClearPixelValue32RegAddrs:GCREG_CLEAR_PIXEL_VALUE32_ALPHA */
+ unsigned int a:8;
+};
+
+/*******************************************************************************
+** State gcregDestColorKey
+*/
+
+/* Defines the destination transparency color in destination format. */
+
+#define gcregDestColorKeyRegAddrs 0x04B1
+#define GCREG_DEST_COLOR_KEY_MSB 15
+#define GCREG_DEST_COLOR_KEY_LSB 0
+#define GCREG_DEST_COLOR_KEY_BLK 0
+#define GCREG_DEST_COLOR_KEY_Count 1
+#define GCREG_DEST_COLOR_KEY_FieldMask 0xFFFFFFFF
+#define GCREG_DEST_COLOR_KEY_ReadMask 0xFFFFFFFF
+#define GCREG_DEST_COLOR_KEY_WriteMask 0xFFFFFFFF
+#define GCREG_DEST_COLOR_KEY_ResetValue 0x00000000
+
+#define GCREG_DEST_COLOR_KEY_ALPHA 31 : 24
+#define GCREG_DEST_COLOR_KEY_ALPHA_End 31
+#define GCREG_DEST_COLOR_KEY_ALPHA_Start 24
+#define GCREG_DEST_COLOR_KEY_ALPHA_Type U08
+
+#define GCREG_DEST_COLOR_KEY_RED 23 : 16
+#define GCREG_DEST_COLOR_KEY_RED_End 23
+#define GCREG_DEST_COLOR_KEY_RED_Start 16
+#define GCREG_DEST_COLOR_KEY_RED_Type U08
+
+#define GCREG_DEST_COLOR_KEY_GREEN 15 : 8
+#define GCREG_DEST_COLOR_KEY_GREEN_End 15
+#define GCREG_DEST_COLOR_KEY_GREEN_Start 8
+#define GCREG_DEST_COLOR_KEY_GREEN_Type U08
+
+#define GCREG_DEST_COLOR_KEY_BLUE 7 : 0
+#define GCREG_DEST_COLOR_KEY_BLUE_End 7
+#define GCREG_DEST_COLOR_KEY_BLUE_Start 0
+#define GCREG_DEST_COLOR_KEY_BLUE_Type U08
+
+/*******************************************************************************
+** State gcregGlobalSrcColor
+*/
+
+/* Defines the global source color and alpha values. */
+
+#define gcregGlobalSrcColorRegAddrs 0x04B2
+#define GCREG_GLOBAL_SRC_COLOR_MSB 15
+#define GCREG_GLOBAL_SRC_COLOR_LSB 0
+#define GCREG_GLOBAL_SRC_COLOR_BLK 0
+#define GCREG_GLOBAL_SRC_COLOR_Count 1
+#define GCREG_GLOBAL_SRC_COLOR_FieldMask 0xFFFFFFFF
+#define GCREG_GLOBAL_SRC_COLOR_ReadMask 0xFFFFFFFF
+#define GCREG_GLOBAL_SRC_COLOR_WriteMask 0xFFFFFFFF
+#define GCREG_GLOBAL_SRC_COLOR_ResetValue 0x00000000
+
+#define GCREG_GLOBAL_SRC_COLOR_ALPHA 31 : 24
+#define GCREG_GLOBAL_SRC_COLOR_ALPHA_End 31
+#define GCREG_GLOBAL_SRC_COLOR_ALPHA_Start 24
+#define GCREG_GLOBAL_SRC_COLOR_ALPHA_Type U08
+
+#define GCREG_GLOBAL_SRC_COLOR_RED 23 : 16
+#define GCREG_GLOBAL_SRC_COLOR_RED_End 23
+#define GCREG_GLOBAL_SRC_COLOR_RED_Start 16
+#define GCREG_GLOBAL_SRC_COLOR_RED_Type U08
+
+#define GCREG_GLOBAL_SRC_COLOR_GREEN 15 : 8
+#define GCREG_GLOBAL_SRC_COLOR_GREEN_End 15
+#define GCREG_GLOBAL_SRC_COLOR_GREEN_Start 8
+#define GCREG_GLOBAL_SRC_COLOR_GREEN_Type U08
+
+#define GCREG_GLOBAL_SRC_COLOR_BLUE 7 : 0
+#define GCREG_GLOBAL_SRC_COLOR_BLUE_End 7
+#define GCREG_GLOBAL_SRC_COLOR_BLUE_Start 0
+#define GCREG_GLOBAL_SRC_COLOR_BLUE_Type U08
+
+struct gcregglobalsrccolor {
+ /* gcregGlobalSrcColorRegAddrs:GCREG_GLOBAL_SRC_COLOR_BLUE */
+ unsigned int b:8;
+
+ /* gcregGlobalSrcColorRegAddrs:GCREG_GLOBAL_SRC_COLOR_GREEN */
+ unsigned int g:8;
+
+ /* gcregGlobalSrcColorRegAddrs:GCREG_GLOBAL_SRC_COLOR_RED */
+ unsigned int r:8;
+
+ /* gcregGlobalSrcColorRegAddrs:GCREG_GLOBAL_SRC_COLOR_ALPHA */
+ unsigned int a:8;
+};
+
+/*******************************************************************************
+** State gcregGlobalDestColor
+*/
+
+/* Defines the global destination color and alpha values. */
+
+#define gcregGlobalDestColorRegAddrs 0x04B3
+#define GCREG_GLOBAL_DEST_COLOR_MSB 15
+#define GCREG_GLOBAL_DEST_COLOR_LSB 0
+#define GCREG_GLOBAL_DEST_COLOR_BLK 0
+#define GCREG_GLOBAL_DEST_COLOR_Count 1
+#define GCREG_GLOBAL_DEST_COLOR_FieldMask 0xFFFFFFFF
+#define GCREG_GLOBAL_DEST_COLOR_ReadMask 0xFFFFFFFF
+#define GCREG_GLOBAL_DEST_COLOR_WriteMask 0xFFFFFFFF
+#define GCREG_GLOBAL_DEST_COLOR_ResetValue 0x00000000
+
+#define GCREG_GLOBAL_DEST_COLOR_ALPHA 31 : 24
+#define GCREG_GLOBAL_DEST_COLOR_ALPHA_End 31
+#define GCREG_GLOBAL_DEST_COLOR_ALPHA_Start 24
+#define GCREG_GLOBAL_DEST_COLOR_ALPHA_Type U08
+
+#define GCREG_GLOBAL_DEST_COLOR_RED 23 : 16
+#define GCREG_GLOBAL_DEST_COLOR_RED_End 23
+#define GCREG_GLOBAL_DEST_COLOR_RED_Start 16
+#define GCREG_GLOBAL_DEST_COLOR_RED_Type U08
+
+#define GCREG_GLOBAL_DEST_COLOR_GREEN 15 : 8
+#define GCREG_GLOBAL_DEST_COLOR_GREEN_End 15
+#define GCREG_GLOBAL_DEST_COLOR_GREEN_Start 8
+#define GCREG_GLOBAL_DEST_COLOR_GREEN_Type U08
+
+#define GCREG_GLOBAL_DEST_COLOR_BLUE 7 : 0
+#define GCREG_GLOBAL_DEST_COLOR_BLUE_End 7
+#define GCREG_GLOBAL_DEST_COLOR_BLUE_Start 0
+#define GCREG_GLOBAL_DEST_COLOR_BLUE_Type U08
+
+struct gcregglobaldstcolor {
+ /* gcregGlobalDestColorRegAddrs:GCREG_GLOBAL_DEST_COLOR_BLUE */
+ unsigned int b:8;
+
+ /* gcregGlobalDestColorRegAddrs:GCREG_GLOBAL_DEST_COLOR_GREEN */
+ unsigned int g:8;
+
+ /* gcregGlobalDestColorRegAddrs:GCREG_GLOBAL_DEST_COLOR_RED */
+ unsigned int r:8;
+
+ /* gcregGlobalDestColorRegAddrs:GCREG_GLOBAL_DEST_COLOR_ALPHA */
+ unsigned int a:8;
+};
+
+/*******************************************************************************
+** State gcregColorMultiplyModes
+*/
+
+/* Color modes to multiply Source or Destination pixel color by alpha
+** channel. Alpha can be from global color source or current pixel.
+*/
+
+#define gcregColorMultiplyModesRegAddrs 0x04B4
+#define GCREG_COLOR_MULTIPLY_MODES_MSB 15
+#define GCREG_COLOR_MULTIPLY_MODES_LSB 0
+#define GCREG_COLOR_MULTIPLY_MODES_BLK 0
+#define GCREG_COLOR_MULTIPLY_MODES_Count 1
+#define GCREG_COLOR_MULTIPLY_MODES_FieldMask 0x00100311
+#define GCREG_COLOR_MULTIPLY_MODES_ReadMask 0x00100311
+#define GCREG_COLOR_MULTIPLY_MODES_WriteMask 0x00100311
+#define GCREG_COLOR_MULTIPLY_MODES_ResetValue 0x00000000
+
+#define GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY 0 : 0
+#define GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_End 0
+#define GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_Start 0
+#define GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_Type U01
+#define GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_DISABLE 0x0
+#define GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_ENABLE 0x1
+
+#define GCREG_COLOR_MULTIPLY_MODES_DST_PREMULTIPLY 4 : 4
+#define GCREG_COLOR_MULTIPLY_MODES_DST_PREMULTIPLY_End 4
+#define GCREG_COLOR_MULTIPLY_MODES_DST_PREMULTIPLY_Start 4
+#define GCREG_COLOR_MULTIPLY_MODES_DST_PREMULTIPLY_Type U01
+#define GCREG_COLOR_MULTIPLY_MODES_DST_PREMULTIPLY_DISABLE 0x0
+#define GCREG_COLOR_MULTIPLY_MODES_DST_PREMULTIPLY_ENABLE 0x1
+
+#define GCREG_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY 9 : 8
+#define GCREG_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_End 9
+#define GCREG_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_Start 8
+#define GCREG_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_Type U02
+#define GCREG_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_DISABLE 0x0
+#define GCREG_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_ALPHA 0x1
+#define GCREG_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_COLOR 0x2
+
+#define GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY 20 : 20
+#define GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_End 20
+#define GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_Start 20
+#define GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_Type U01
+#define GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_DISABLE 0x0
+#define GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_ENABLE 0x1
+
+struct gcregcolormultiplymodes {
+ /* gcregColorMultiplyModesRegAddrs:
+ GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY */
+ unsigned int srcpremul:1;
+
+ /* gcregColorMultiplyModesRegAddrs:
+ reserved */
+ unsigned int _reserved_1_3:3;
+
+ /* gcregColorMultiplyModesRegAddrs:
+ GCREG_COLOR_MULTIPLY_MODES_DST_PREMULTIPLY */
+ unsigned int dstpremul:1;
+
+ /* gcregColorMultiplyModesRegAddrs:
+ reserved */
+ unsigned int _reserved_5_7:3;
+
+ /* gcregColorMultiplyModesRegAddrs:
+ GCREG_COLOR_MULTIPLY_MODES_DST_PREMULTIPLY */
+ unsigned int srcglobalpremul:2;
+
+ /* gcregColorMultiplyModesRegAddrs:
+ reserved */
+ unsigned int _reserved_10_19:10;
+
+ /* gcregColorMultiplyModesRegAddrs:
+ GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY */
+ unsigned int dstdemul:1;
+
+ /* gcregColorMultiplyModesRegAddrs:
+ reserved */
+ unsigned int _reserved_21_31:11;
+};
+
+/*******************************************************************************
+** State gcregPETransparency
+*/
+
+#define gcregPETransparencyRegAddrs 0x04B5
+#define GCREG_PE_TRANSPARENCY_MSB 15
+#define GCREG_PE_TRANSPARENCY_LSB 0
+#define GCREG_PE_TRANSPARENCY_BLK 0
+#define GCREG_PE_TRANSPARENCY_Count 1
+#define GCREG_PE_TRANSPARENCY_FieldMask 0xB3331333
+#define GCREG_PE_TRANSPARENCY_ReadMask 0xB3331333
+#define GCREG_PE_TRANSPARENCY_WriteMask 0xB3331333
+#define GCREG_PE_TRANSPARENCY_ResetValue 0x00000000
+
+/* Source transparency mode. */
+#define GCREG_PE_TRANSPARENCY_SOURCE 1 : 0
+#define GCREG_PE_TRANSPARENCY_SOURCE_End 1
+#define GCREG_PE_TRANSPARENCY_SOURCE_Start 0
+#define GCREG_PE_TRANSPARENCY_SOURCE_Type U02
+#define GCREG_PE_TRANSPARENCY_SOURCE_OPAQUE 0x0
+#define GCREG_PE_TRANSPARENCY_SOURCE_MASK 0x1
+#define GCREG_PE_TRANSPARENCY_SOURCE_KEY 0x2
+
+/* Pattern transparency mode. KEY transparency mode is reserved. */
+#define GCREG_PE_TRANSPARENCY_PATTERN 5 : 4
+#define GCREG_PE_TRANSPARENCY_PATTERN_End 5
+#define GCREG_PE_TRANSPARENCY_PATTERN_Start 4
+#define GCREG_PE_TRANSPARENCY_PATTERN_Type U02
+#define GCREG_PE_TRANSPARENCY_PATTERN_OPAQUE 0x0
+#define GCREG_PE_TRANSPARENCY_PATTERN_MASK 0x1
+#define GCREG_PE_TRANSPARENCY_PATTERN_KEY 0x2
+
+/* Destination transparency mode. MASK transparency mode is reserved. */
+#define GCREG_PE_TRANSPARENCY_DESTINATION 9 : 8
+#define GCREG_PE_TRANSPARENCY_DESTINATION_End 9
+#define GCREG_PE_TRANSPARENCY_DESTINATION_Start 8
+#define GCREG_PE_TRANSPARENCY_DESTINATION_Type U02
+#define GCREG_PE_TRANSPARENCY_DESTINATION_OPAQUE 0x0
+#define GCREG_PE_TRANSPARENCY_DESTINATION_MASK 0x1
+#define GCREG_PE_TRANSPARENCY_DESTINATION_KEY 0x2
+
+/* Mask field for Source/Pattern/Destination fields. */
+#define GCREG_PE_TRANSPARENCY_MASK_TRANSPARENCY 12 : 12
+#define GCREG_PE_TRANSPARENCY_MASK_TRANSPARENCY_End 12
+#define GCREG_PE_TRANSPARENCY_MASK_TRANSPARENCY_Start 12
+#define GCREG_PE_TRANSPARENCY_MASK_TRANSPARENCY_Type U01
+#define GCREG_PE_TRANSPARENCY_MASK_TRANSPARENCY_ENABLED 0x0
+#define GCREG_PE_TRANSPARENCY_MASK_TRANSPARENCY_MASKED 0x1
+
+/* Source usage override. */
+#define GCREG_PE_TRANSPARENCY_USE_SRC_OVERRIDE 17 : 16
+#define GCREG_PE_TRANSPARENCY_USE_SRC_OVERRIDE_End 17
+#define GCREG_PE_TRANSPARENCY_USE_SRC_OVERRIDE_Start 16
+#define GCREG_PE_TRANSPARENCY_USE_SRC_OVERRIDE_Type U02
+#define GCREG_PE_TRANSPARENCY_USE_SRC_OVERRIDE_DEFAULT 0x0
+#define GCREG_PE_TRANSPARENCY_USE_SRC_OVERRIDE_USE_ENABLE 0x1
+#define GCREG_PE_TRANSPARENCY_USE_SRC_OVERRIDE_USE_DISABLE 0x2
+
+/* Pattern usage override. */
+#define GCREG_PE_TRANSPARENCY_USE_PAT_OVERRIDE 21 : 20
+#define GCREG_PE_TRANSPARENCY_USE_PAT_OVERRIDE_End 21
+#define GCREG_PE_TRANSPARENCY_USE_PAT_OVERRIDE_Start 20
+#define GCREG_PE_TRANSPARENCY_USE_PAT_OVERRIDE_Type U02
+#define GCREG_PE_TRANSPARENCY_USE_PAT_OVERRIDE_DEFAULT 0x0
+#define GCREG_PE_TRANSPARENCY_USE_PAT_OVERRIDE_USE_ENABLE 0x1
+#define GCREG_PE_TRANSPARENCY_USE_PAT_OVERRIDE_USE_DISABLE 0x2
+
+/* Destination usage override. */
+#define GCREG_PE_TRANSPARENCY_USE_DST_OVERRIDE 25 : 24
+#define GCREG_PE_TRANSPARENCY_USE_DST_OVERRIDE_End 25
+#define GCREG_PE_TRANSPARENCY_USE_DST_OVERRIDE_Start 24
+#define GCREG_PE_TRANSPARENCY_USE_DST_OVERRIDE_Type U02
+#define GCREG_PE_TRANSPARENCY_USE_DST_OVERRIDE_DEFAULT 0x0
+#define GCREG_PE_TRANSPARENCY_USE_DST_OVERRIDE_USE_ENABLE 0x1
+#define GCREG_PE_TRANSPARENCY_USE_DST_OVERRIDE_USE_DISABLE 0x2
+
+/* 2D resource usage override mask field. */
+#define GCREG_PE_TRANSPARENCY_MASK_RESOURCE_OVERRIDE 28 : 28
+#define GCREG_PE_TRANSPARENCY_MASK_RESOURCE_OVERRIDE_End 28
+#define GCREG_PE_TRANSPARENCY_MASK_RESOURCE_OVERRIDE_Start 28
+#define GCREG_PE_TRANSPARENCY_MASK_RESOURCE_OVERRIDE_Type U01
+#define GCREG_PE_TRANSPARENCY_MASK_RESOURCE_OVERRIDE_ENABLED 0x0
+#define GCREG_PE_TRANSPARENCY_MASK_RESOURCE_OVERRIDE_MASKED 0x1
+
+/* DEB Color Key. */
+#define GCREG_PE_TRANSPARENCY_DFB_COLOR_KEY 29 : 29
+#define GCREG_PE_TRANSPARENCY_DFB_COLOR_KEY_End 29
+#define GCREG_PE_TRANSPARENCY_DFB_COLOR_KEY_Start 29
+#define GCREG_PE_TRANSPARENCY_DFB_COLOR_KEY_Type U01
+#define GCREG_PE_TRANSPARENCY_DFB_COLOR_KEY_DISABLED 0x0
+#define GCREG_PE_TRANSPARENCY_DFB_COLOR_KEY_ENABLED 0x1
+
+#define GCREG_PE_TRANSPARENCY_MASK_DFB_COLOR_KEY 31 : 31
+#define GCREG_PE_TRANSPARENCY_MASK_DFB_COLOR_KEY_End 31
+#define GCREG_PE_TRANSPARENCY_MASK_DFB_COLOR_KEY_Start 31
+#define GCREG_PE_TRANSPARENCY_MASK_DFB_COLOR_KEY_Type U01
+#define GCREG_PE_TRANSPARENCY_MASK_DFB_COLOR_KEY_ENABLED 0x0
+#define GCREG_PE_TRANSPARENCY_MASK_DFB_COLOR_KEY_MASKED 0x1
+
+/*******************************************************************************
+** State gcregPEControl
+*/
+
+/* General purpose control register. */
+
+#define gcregPEControlRegAddrs 0x04B6
+#define GCREG_PE_CONTROL_MSB 15
+#define GCREG_PE_CONTROL_LSB 0
+#define GCREG_PE_CONTROL_BLK 0
+#define GCREG_PE_CONTROL_Count 1
+#define GCREG_PE_CONTROL_FieldMask 0x00000999
+#define GCREG_PE_CONTROL_ReadMask 0x00000999
+#define GCREG_PE_CONTROL_WriteMask 0x00000999
+#define GCREG_PE_CONTROL_ResetValue 0x00000000
+
+#define GCREG_PE_CONTROL_YUV 0 : 0
+#define GCREG_PE_CONTROL_YUV_End 0
+#define GCREG_PE_CONTROL_YUV_Start 0
+#define GCREG_PE_CONTROL_YUV_Type U01
+#define GCREG_PE_CONTROL_YUV_601 0x0
+#define GCREG_PE_CONTROL_YUV_709 0x1
+
+#define GCREG_PE_CONTROL_MASK_YUV 3 : 3
+#define GCREG_PE_CONTROL_MASK_YUV_End 3
+#define GCREG_PE_CONTROL_MASK_YUV_Start 3
+#define GCREG_PE_CONTROL_MASK_YUV_Type U01
+#define GCREG_PE_CONTROL_MASK_YUV_ENABLED 0x0
+#define GCREG_PE_CONTROL_MASK_YUV_MASKED 0x1
+
+#define GCREG_PE_CONTROL_UV_SWIZZLE 4 : 4
+#define GCREG_PE_CONTROL_UV_SWIZZLE_End 4
+#define GCREG_PE_CONTROL_UV_SWIZZLE_Start 4
+#define GCREG_PE_CONTROL_UV_SWIZZLE_Type U01
+#define GCREG_PE_CONTROL_UV_SWIZZLE_UV 0x0
+#define GCREG_PE_CONTROL_UV_SWIZZLE_VU 0x1
+
+#define GCREG_PE_CONTROL_MASK_UV_SWIZZLE 7 : 7
+#define GCREG_PE_CONTROL_MASK_UV_SWIZZLE_End 7
+#define GCREG_PE_CONTROL_MASK_UV_SWIZZLE_Start 7
+#define GCREG_PE_CONTROL_MASK_UV_SWIZZLE_Type U01
+#define GCREG_PE_CONTROL_MASK_UV_SWIZZLE_ENABLED 0x0
+#define GCREG_PE_CONTROL_MASK_UV_SWIZZLE_MASKED 0x1
+
+/* YUV to RGB convert enable */
+#define GCREG_PE_CONTROL_YUVRGB 8 : 8
+#define GCREG_PE_CONTROL_YUVRGB_End 8
+#define GCREG_PE_CONTROL_YUVRGB_Start 8
+#define GCREG_PE_CONTROL_YUVRGB_Type U01
+#define GCREG_PE_CONTROL_YUVRGB_DISABLED 0x0
+#define GCREG_PE_CONTROL_YUVRGB_ENABLED 0x1
+
+#define GCREG_PE_CONTROL_MASK_YUVRGB 11 : 11
+#define GCREG_PE_CONTROL_MASK_YUVRGB_End 11
+#define GCREG_PE_CONTROL_MASK_YUVRGB_Start 11
+#define GCREG_PE_CONTROL_MASK_YUVRGB_Type U01
+#define GCREG_PE_CONTROL_MASK_YUVRGB_ENABLED 0x0
+#define GCREG_PE_CONTROL_MASK_YUVRGB_MASKED 0x1
+
+struct gcregpecontrol {
+ /* gcregPEControlRegAddrs:YUV */
+ unsigned int standard:1;
+
+ /* gcregPEControlRegAddrs:reserved */
+ unsigned int _reserved_1_2:2;
+
+ /* gcregPEControlRegAddrs:MASK_YUV */
+ unsigned int standard_mask:1;
+
+ /* gcregPEControlRegAddrs:UV_SWIZZLE */
+ unsigned int swizzle:1;
+
+ /* gcregPEControlRegAddrs:reserved */
+ unsigned int _reserved_5_6:2;
+
+ /* gcregPEControlRegAddrs:MASK_UV_SWIZZLE */
+ unsigned int swizzle_mask:1;
+
+ /* gcregPEControlRegAddrs:YUVRGB */
+ unsigned int convert:1;
+
+ /* gcregPEControlRegAddrs:reserved */
+ unsigned int _reserved_9_10:2;
+
+ /* gcregPEControlRegAddrs:MASK_YUVRGB */
+ unsigned int convert_mask:1;
+
+ /* gcregPEControlRegAddrs:reserved */
+ unsigned int _reserved_12_31:20;
+};
+
+/*******************************************************************************
+** State gcregSrcColorKeyHigh
+*/
+
+/* Defines the source transparency color in source format. */
+
+#define gcregSrcColorKeyHighRegAddrs 0x04B7
+#define GCREG_SRC_COLOR_KEY_HIGH_Address 0x012DC
+#define GCREG_SRC_COLOR_KEY_HIGH_MSB 15
+#define GCREG_SRC_COLOR_KEY_HIGH_LSB 0
+#define GCREG_SRC_COLOR_KEY_HIGH_BLK 0
+#define GCREG_SRC_COLOR_KEY_HIGH_Count 1
+#define GCREG_SRC_COLOR_KEY_HIGH_FieldMask 0xFFFFFFFF
+#define GCREG_SRC_COLOR_KEY_HIGH_ReadMask 0xFFFFFFFF
+#define GCREG_SRC_COLOR_KEY_HIGH_WriteMask 0xFFFFFFFF
+#define GCREG_SRC_COLOR_KEY_HIGH_ResetValue 0x00000000
+
+#define GCREG_SRC_COLOR_KEY_HIGH_ALPHA 31 : 24
+#define GCREG_SRC_COLOR_KEY_HIGH_ALPHA_End 31
+#define GCREG_SRC_COLOR_KEY_HIGH_ALPHA_Start 24
+#define GCREG_SRC_COLOR_KEY_HIGH_ALPHA_Type U08
+
+#define GCREG_SRC_COLOR_KEY_HIGH_RED 23 : 16
+#define GCREG_SRC_COLOR_KEY_HIGH_RED_End 23
+#define GCREG_SRC_COLOR_KEY_HIGH_RED_Start 16
+#define GCREG_SRC_COLOR_KEY_HIGH_RED_Type U08
+
+#define GCREG_SRC_COLOR_KEY_HIGH_GREEN 15 : 8
+#define GCREG_SRC_COLOR_KEY_HIGH_GREEN_End 15
+#define GCREG_SRC_COLOR_KEY_HIGH_GREEN_Start 8
+#define GCREG_SRC_COLOR_KEY_HIGH_GREEN_Type U08
+
+#define GCREG_SRC_COLOR_KEY_HIGH_BLUE 7 : 0
+#define GCREG_SRC_COLOR_KEY_HIGH_BLUE_End 7
+#define GCREG_SRC_COLOR_KEY_HIGH_BLUE_Start 0
+#define GCREG_SRC_COLOR_KEY_HIGH_BLUE_Type U08
+
+/*******************************************************************************
+** State gcregDestColorKeyHigh
+*/
+
+/* Defines the destination transparency color in destination format. */
+
+#define gcregDestColorKeyHighRegAddrs 0x04B8
+#define GCREG_DEST_COLOR_KEY_HIGH_MSB 15
+#define GCREG_DEST_COLOR_KEY_HIGH_LSB 0
+#define GCREG_DEST_COLOR_KEY_HIGH_BLK 0
+#define GCREG_DEST_COLOR_KEY_HIGH_Count 1
+#define GCREG_DEST_COLOR_KEY_HIGH_FieldMask 0xFFFFFFFF
+#define GCREG_DEST_COLOR_KEY_HIGH_ReadMask 0xFFFFFFFF
+#define GCREG_DEST_COLOR_KEY_HIGH_WriteMask 0xFFFFFFFF
+#define GCREG_DEST_COLOR_KEY_HIGH_ResetValue 0x00000000
+
+#define GCREG_DEST_COLOR_KEY_HIGH_ALPHA 31 : 24
+#define GCREG_DEST_COLOR_KEY_HIGH_ALPHA_End 31
+#define GCREG_DEST_COLOR_KEY_HIGH_ALPHA_Start 24
+#define GCREG_DEST_COLOR_KEY_HIGH_ALPHA_Type U08
+
+#define GCREG_DEST_COLOR_KEY_HIGH_RED 23 : 16
+#define GCREG_DEST_COLOR_KEY_HIGH_RED_End 23
+#define GCREG_DEST_COLOR_KEY_HIGH_RED_Start 16
+#define GCREG_DEST_COLOR_KEY_HIGH_RED_Type U08
+
+#define GCREG_DEST_COLOR_KEY_HIGH_GREEN 15 : 8
+#define GCREG_DEST_COLOR_KEY_HIGH_GREEN_End 15
+#define GCREG_DEST_COLOR_KEY_HIGH_GREEN_Start 8
+#define GCREG_DEST_COLOR_KEY_HIGH_GREEN_Type U08
+
+#define GCREG_DEST_COLOR_KEY_HIGH_BLUE 7 : 0
+#define GCREG_DEST_COLOR_KEY_HIGH_BLUE_End 7
+#define GCREG_DEST_COLOR_KEY_HIGH_BLUE_Start 0
+#define GCREG_DEST_COLOR_KEY_HIGH_BLUE_Type U08
+
+/*******************************************************************************
+** State gcregPEDitherLow
+*/
+
+/* PE dither register.
+** If you don't want dither, set all fields to their reset values.
+*/
+
+#define gcregPEDitherLowRegAddrs 0x04BA
+#define GCREG_PE_DITHER_LOW_MSB 15
+#define GCREG_PE_DITHER_LOW_LSB 0
+#define GCREG_PE_DITHER_LOW_BLK 0
+#define GCREG_PE_DITHER_LOW_Count 1
+#define GCREG_PE_DITHER_LOW_FieldMask 0xFFFFFFFF
+#define GCREG_PE_DITHER_LOW_ReadMask 0xFFFFFFFF
+#define GCREG_PE_DITHER_LOW_WriteMask 0xFFFFFFFF
+#define GCREG_PE_DITHER_LOW_ResetValue 0xFFFFFFFF
+
+/* X,Y = 0,0 */
+#define GCREG_PE_DITHER_LOW_PIXEL_X0_Y0 3 : 0
+#define GCREG_PE_DITHER_LOW_PIXEL_X0_Y0_End 3
+#define GCREG_PE_DITHER_LOW_PIXEL_X0_Y0_Start 0
+#define GCREG_PE_DITHER_LOW_PIXEL_X0_Y0_Type U04
+
+/* X,Y = 1,0 */
+#define GCREG_PE_DITHER_LOW_PIXEL_X1_Y0 7 : 4
+#define GCREG_PE_DITHER_LOW_PIXEL_X1_Y0_End 7
+#define GCREG_PE_DITHER_LOW_PIXEL_X1_Y0_Start 4
+#define GCREG_PE_DITHER_LOW_PIXEL_X1_Y0_Type U04
+
+/* X,Y = 2,0 */
+#define GCREG_PE_DITHER_LOW_PIXEL_X2_Y0 11 : 8
+#define GCREG_PE_DITHER_LOW_PIXEL_X2_Y0_End 11
+#define GCREG_PE_DITHER_LOW_PIXEL_X2_Y0_Start 8
+#define GCREG_PE_DITHER_LOW_PIXEL_X2_Y0_Type U04
+
+/* X,Y = 3,0 */
+#define GCREG_PE_DITHER_LOW_PIXEL_X3_Y0 15 : 12
+#define GCREG_PE_DITHER_LOW_PIXEL_X3_Y0_End 15
+#define GCREG_PE_DITHER_LOW_PIXEL_X3_Y0_Start 12
+#define GCREG_PE_DITHER_LOW_PIXEL_X3_Y0_Type U04
+
+/* X,Y = 0,1 */
+#define GCREG_PE_DITHER_LOW_PIXEL_X0_Y1 19 : 16
+#define GCREG_PE_DITHER_LOW_PIXEL_X0_Y1_End 19
+#define GCREG_PE_DITHER_LOW_PIXEL_X0_Y1_Start 16
+#define GCREG_PE_DITHER_LOW_PIXEL_X0_Y1_Type U04
+
+/* X,Y = 1,1 */
+#define GCREG_PE_DITHER_LOW_PIXEL_X1_Y1 23 : 20
+#define GCREG_PE_DITHER_LOW_PIXEL_X1_Y1_End 23
+#define GCREG_PE_DITHER_LOW_PIXEL_X1_Y1_Start 20
+#define GCREG_PE_DITHER_LOW_PIXEL_X1_Y1_Type U04
+
+/* X,Y = 2,1 */
+#define GCREG_PE_DITHER_LOW_PIXEL_X2_Y1 27 : 24
+#define GCREG_PE_DITHER_LOW_PIXEL_X2_Y1_End 27
+#define GCREG_PE_DITHER_LOW_PIXEL_X2_Y1_Start 24
+#define GCREG_PE_DITHER_LOW_PIXEL_X2_Y1_Type U04
+
+/* X,Y = 3,1 */
+#define GCREG_PE_DITHER_LOW_PIXEL_X3_Y1 31 : 28
+#define GCREG_PE_DITHER_LOW_PIXEL_X3_Y1_End 31
+#define GCREG_PE_DITHER_LOW_PIXEL_X3_Y1_Start 28
+#define GCREG_PE_DITHER_LOW_PIXEL_X3_Y1_Type U04
+
+/*******************************************************************************
+** State gcregPEDitherHigh
+*/
+
+#define gcregPEDitherHighRegAddrs 0x04BB
+#define GCREG_PE_DITHER_HIGH_MSB 15
+#define GCREG_PE_DITHER_HIGH_LSB 0
+#define GCREG_PE_DITHER_LOW_HIGH_BLK 0
+#define GCREG_PE_DITHER_HIGH_Count 1
+#define GCREG_PE_DITHER_HIGH_FieldMask 0xFFFFFFFF
+#define GCREG_PE_DITHER_HIGH_ReadMask 0xFFFFFFFF
+#define GCREG_PE_DITHER_HIGH_WriteMask 0xFFFFFFFF
+#define GCREG_PE_DITHER_HIGH_ResetValue 0xFFFFFFFF
+
+/* X,Y = 0,2 */
+#define GCREG_PE_DITHER_HIGH_PIXEL_X0_Y2 3 : 0
+#define GCREG_PE_DITHER_HIGH_PIXEL_X0_Y2_End 3
+#define GCREG_PE_DITHER_HIGH_PIXEL_X0_Y2_Start 0
+#define GCREG_PE_DITHER_HIGH_PIXEL_X0_Y2_Type U04
+
+/* X,Y = 1,2 */
+#define GCREG_PE_DITHER_HIGH_PIXEL_X1_Y2 7 : 4
+#define GCREG_PE_DITHER_HIGH_PIXEL_X1_Y2_End 7
+#define GCREG_PE_DITHER_HIGH_PIXEL_X1_Y2_Start 4
+#define GCREG_PE_DITHER_HIGH_PIXEL_X1_Y2_Type U04
+
+/* X,Y = 2,2 */
+#define GCREG_PE_DITHER_HIGH_PIXEL_X2_Y2 11 : 8
+#define GCREG_PE_DITHER_HIGH_PIXEL_X2_Y2_End 11
+#define GCREG_PE_DITHER_HIGH_PIXEL_X2_Y2_Start 8
+#define GCREG_PE_DITHER_HIGH_PIXEL_X2_Y2_Type U04
+
+/* X,Y = 0,3 */
+#define GCREG_PE_DITHER_HIGH_PIXEL_X3_Y2 15 : 12
+#define GCREG_PE_DITHER_HIGH_PIXEL_X3_Y2_End 15
+#define GCREG_PE_DITHER_HIGH_PIXEL_X3_Y2_Start 12
+#define GCREG_PE_DITHER_HIGH_PIXEL_X3_Y2_Type U04
+
+/* X,Y = 1,3 */
+#define GCREG_PE_DITHER_HIGH_PIXEL_X0_Y3 19 : 16
+#define GCREG_PE_DITHER_HIGH_PIXEL_X0_Y3_End 19
+#define GCREG_PE_DITHER_HIGH_PIXEL_X0_Y3_Start 16
+#define GCREG_PE_DITHER_HIGH_PIXEL_X0_Y3_Type U04
+
+/* X,Y = 2,3 */
+#define GCREG_PE_DITHER_HIGH_PIXEL_X1_Y3 23 : 20
+#define GCREG_PE_DITHER_HIGH_PIXEL_X1_Y3_End 23
+#define GCREG_PE_DITHER_HIGH_PIXEL_X1_Y3_Start 20
+#define GCREG_PE_DITHER_HIGH_PIXEL_X1_Y3_Type U04
+
+/* X,Y = 3,3 */
+#define GCREG_PE_DITHER_HIGH_PIXEL_X2_Y3 27 : 24
+#define GCREG_PE_DITHER_HIGH_PIXEL_X2_Y3_End 27
+#define GCREG_PE_DITHER_HIGH_PIXEL_X2_Y3_Start 24
+#define GCREG_PE_DITHER_HIGH_PIXEL_X2_Y3_Type U04
+
+/* X,Y = 3,2 */
+#define GCREG_PE_DITHER_HIGH_PIXEL_X3_Y3 31 : 28
+#define GCREG_PE_DITHER_HIGH_PIXEL_X3_Y3_End 31
+#define GCREG_PE_DITHER_HIGH_PIXEL_X3_Y3_Start 28
+#define GCREG_PE_DITHER_HIGH_PIXEL_X3_Y3_Type U04
+
+/*******************************************************************************
+** State gcregSrcExConfig
+*/
+
+#define gcregSrcExConfigRegAddrs 0x04C0
+#define GCREG_SRC_EX_CONFIG_MSB 15
+#define GCREG_SRC_EX_CONFIG_LSB 0
+#define GCREG_SRC_EX_CONFIG_BLK 0
+#define GCREG_SRC_EX_CONFIG_Count 1
+#define GCREG_SRC_EX_CONFIG_FieldMask 0x00000109
+#define GCREG_SRC_EX_CONFIG_ReadMask 0x00000109
+#define GCREG_SRC_EX_CONFIG_WriteMask 0x00000109
+#define GCREG_SRC_EX_CONFIG_ResetValue 0x00000000
+
+/* Source multi tiled address computation control. */
+#define GCREG_SRC_EX_CONFIG_MULTI_TILED 0 : 0
+#define GCREG_SRC_EX_CONFIG_MULTI_TILED_End 0
+#define GCREG_SRC_EX_CONFIG_MULTI_TILED_Start 0
+#define GCREG_SRC_EX_CONFIG_MULTI_TILED_Type U01
+#define GCREG_SRC_EX_CONFIG_MULTI_TILED_DISABLED 0x0
+#define GCREG_SRC_EX_CONFIG_MULTI_TILED_ENABLED 0x1
+
+/* Source super tiled address computation control. */
+#define GCREG_SRC_EX_CONFIG_SUPER_TILED 3 : 3
+#define GCREG_SRC_EX_CONFIG_SUPER_TILED_End 3
+#define GCREG_SRC_EX_CONFIG_SUPER_TILED_Start 3
+#define GCREG_SRC_EX_CONFIG_SUPER_TILED_Type U01
+#define GCREG_SRC_EX_CONFIG_SUPER_TILED_DISABLED 0x0
+#define GCREG_SRC_EX_CONFIG_SUPER_TILED_ENABLED 0x1
+
+/* Source super tiled address computation control. */
+#define GCREG_SRC_EX_CONFIG_MINOR_TILED 8 : 8
+#define GCREG_SRC_EX_CONFIG_MINOR_TILED_End 8
+#define GCREG_SRC_EX_CONFIG_MINOR_TILED_Start 8
+#define GCREG_SRC_EX_CONFIG_MINOR_TILED_Type U01
+#define GCREG_SRC_EX_CONFIG_MINOR_TILED_DISABLED 0x0
+#define GCREG_SRC_EX_CONFIG_MINOR_TILED_ENABLED 0x1
+
+/* Source CacheMode. */
+#define GCREG_SRC_SRC_EX_CONFIG_CACHE_MODE 12 : 12
+#define GCREG_SRC_SRC_EX_CONFIG_CACHE_MODE_End 12
+#define GCREG_SRC_SRC_EX_CONFIG_CACHE_MODE_Start 12
+#define GCREG_SRC_SRC_EX_CONFIG_CACHE_MODE_Type U01
+#define GCREG_SRC_SRC_EX_CONFIG_CACHE_MODE_DISABLED 0x0
+#define GCREG_SRC_SRC_EX_CONFIG_CACHE_MODE_ENABLED 0x1
+
+/*******************************************************************************
+** State gcregSrcExAddress
+*/
+
+/* 32-bit aligned base address of the source extra surface. */
+
+#define gcregSrcExAddressRegAddrs 0x04C1
+#define GCREG_SRC_EX_ADDRESS_MSB 15
+#define GCREG_SRC_EX_ADDRESS_LSB 0
+#define GCREG_SRC_EX_ADDRESS_BLK 0
+#define GCREG_SRC_EX_ADDRESS_Count 1
+#define GCREG_SRC_EX_ADDRESS_FieldMask 0xFFFFFFFF
+#define GCREG_SRC_EX_ADDRESS_ReadMask 0xFFFFFFFC
+#define GCREG_SRC_EX_ADDRESS_WriteMask 0xFFFFFFFC
+#define GCREG_SRC_EX_ADDRESS_ResetValue 0x00000000
+
+#define GCREG_SRC_EX_ADDRESS_ADDRESS 31 : 0
+#define GCREG_SRC_EX_ADDRESS_ADDRESS_End 30
+#define GCREG_SRC_EX_ADDRESS_ADDRESS_Start 0
+#define GCREG_SRC_EX_ADDRESS_ADDRESS_Type U31
+
+/*******************************************************************************
+** State gcregDEMultiSource
+*/
+
+/* MutiSource control register. */
+
+#define gcregDEMultiSourceRegAddrs 0x04C2
+#define GCREG_DE_MULTI_SOURCE_MSB 15
+#define GCREG_DE_MULTI_SOURCE_LSB 0
+#define GCREG_DE_MULTI_SOURCE_BLK 0
+#define GCREG_DE_MULTI_SOURCE_Count 1
+#define GCREG_DE_MULTI_SOURCE_FieldMask 0x00070707
+#define GCREG_DE_MULTI_SOURCE_ReadMask 0x00070707
+#define GCREG_DE_MULTI_SOURCE_WriteMask 0x00070707
+#define GCREG_DE_MULTI_SOURCE_ResetValue 0x00000000
+
+/* Number of source surfaces minus 1. */
+#define GCREG_DE_MULTI_SOURCE_MAX_SOURCE 2 : 0
+#define GCREG_DE_MULTI_SOURCE_MAX_SOURCE_End 2
+#define GCREG_DE_MULTI_SOURCE_MAX_SOURCE_Start 0
+#define GCREG_DE_MULTI_SOURCE_MAX_SOURCE_Type U03
+
+/* Number of pixels for horizontal block walker. */
+#define GCREG_DE_MULTI_SOURCE_HORIZONTAL_BLOCK 10 : 8
+#define GCREG_DE_MULTI_SOURCE_HORIZONTAL_BLOCK_End 10
+#define GCREG_DE_MULTI_SOURCE_HORIZONTAL_BLOCK_Start 8
+#define GCREG_DE_MULTI_SOURCE_HORIZONTAL_BLOCK_Type U03
+#define GCREG_DE_MULTI_SOURCE_HORIZONTAL_BLOCK_PIXEL16 0x0
+#define GCREG_DE_MULTI_SOURCE_HORIZONTAL_BLOCK_PIXEL32 0x1
+#define GCREG_DE_MULTI_SOURCE_HORIZONTAL_BLOCK_PIXEL64 0x2
+#define GCREG_DE_MULTI_SOURCE_HORIZONTAL_BLOCK_PIXEL128 0x3
+#define GCREG_DE_MULTI_SOURCE_HORIZONTAL_BLOCK_PIXEL256 0x4
+#define GCREG_DE_MULTI_SOURCE_HORIZONTAL_BLOCK_PIXEL512 0x5
+
+/* Number of lines for vertical block walker. */
+#define GCREG_DE_MULTI_SOURCE_VERTICAL_BLOCK 18 : 16
+#define GCREG_DE_MULTI_SOURCE_VERTICAL_BLOCK_End 18
+#define GCREG_DE_MULTI_SOURCE_VERTICAL_BLOCK_Start 16
+#define GCREG_DE_MULTI_SOURCE_VERTICAL_BLOCK_Type U03
+#define GCREG_DE_MULTI_SOURCE_VERTICAL_BLOCK_LINE1 0x0
+#define GCREG_DE_MULTI_SOURCE_VERTICAL_BLOCK_LINE2 0x1
+#define GCREG_DE_MULTI_SOURCE_VERTICAL_BLOCK_LINE4 0x2
+#define GCREG_DE_MULTI_SOURCE_VERTICAL_BLOCK_LINE8 0x3
+#define GCREG_DE_MULTI_SOURCE_VERTICAL_BLOCK_LINE16 0x4
+#define GCREG_DE_MULTI_SOURCE_VERTICAL_BLOCK_LINE32 0x5
+#define GCREG_DE_MULTI_SOURCE_VERTICAL_BLOCK_LINE64 0x6
+#define GCREG_DE_MULTI_SOURCE_VERTICAL_BLOCK_LINE128 0x7
+
+struct gcregmultisource {
+ /* gcregDEMultiSourceRegAddrs:GCREG_DE_MULTI_SOURCE_MAX_SOURCE */
+ unsigned int srccount:3;
+
+ /* gcregDEMultiSourceRegAddrs:reserved */
+ unsigned int _reserved_3_7:5;
+
+ /* gcregDEMultiSourceRegAddrs:GCREG_DE_MULTI_SOURCE_HORIZONTAL_BLOCK */
+ unsigned int horblock:3;
+
+ /* gcregDEMultiSourceRegAddrs:reserved */
+ unsigned int _reserved_11_15:5;
+
+ /* gcregDEMultiSourceRegAddrs:GCREG_DE_MULTI_SOURCE_VERTICAL_BLOCK */
+ unsigned int verblock:3;
+
+ /* gcregDEMultiSourceRegAddrs:reserved */
+ unsigned int _reserved_19_31:13;
+};
+
+/*******************************************************************************
+** State gcregDEYUVConversion
+*/
+
+/* Configure the YUV to YUV conversion. */
+
+#define gcregDEYUVConversionRegAddrs 0x04C3
+#define GCREG_DEYUV_CONVERSION_MSB 15
+#define GCREG_DEYUV_CONVERSION_LSB 0
+#define GCREG_DEYUV_CONVERSION_BLK 0
+#define GCREG_DEYUV_CONVERSION_Count 1
+#define GCREG_DEYUV_CONVERSION_FieldMask 0xFFFFFFFF
+#define GCREG_DEYUV_CONVERSION_ReadMask 0xFFFFFFFF
+#define GCREG_DEYUV_CONVERSION_WriteMask 0xFFFFFFFF
+#define GCREG_DEYUV_CONVERSION_ResetValue 0x00000000
+
+/* Select the number of planes we need to process. */
+#define GCREG_DEYUV_CONVERSION_ENABLE 1 : 0
+#define GCREG_DEYUV_CONVERSION_ENABLE_End 1
+#define GCREG_DEYUV_CONVERSION_ENABLE_Start 0
+#define GCREG_DEYUV_CONVERSION_ENABLE_Type U02
+/* YUV to YUV conversion is turned off. */
+#define GCREG_DEYUV_CONVERSION_ENABLE_OFF 0x0
+/* YUV to YUV conversion is writing to 1 plane. */
+#define GCREG_DEYUV_CONVERSION_ENABLE_PLANE1 0x1
+/* YUV to YUV conversion is writing to 2 planes. */
+#define GCREG_DEYUV_CONVERSION_ENABLE_PLANE2 0x2
+/* YUV to YUV conversion is writing to 3 planes. */
+#define GCREG_DEYUV_CONVERSION_ENABLE_PLANE3 0x3
+
+/* Number of channels to process - 1 for plane 1. */
+#define GCREG_DEYUV_CONVERSION_PLANE1_COUNT 3 : 2
+#define GCREG_DEYUV_CONVERSION_PLANE1_COUNT_End 3
+#define GCREG_DEYUV_CONVERSION_PLANE1_COUNT_Start 2
+#define GCREG_DEYUV_CONVERSION_PLANE1_COUNT_Type U02
+
+/* Number of channels to process - 1 for plane 2. */
+#define GCREG_DEYUV_CONVERSION_PLANE2_COUNT 5 : 4
+#define GCREG_DEYUV_CONVERSION_PLANE2_COUNT_End 5
+#define GCREG_DEYUV_CONVERSION_PLANE2_COUNT_Start 4
+#define GCREG_DEYUV_CONVERSION_PLANE2_COUNT_Type U02
+
+/* Number of channels to process - 1 for plane 3. */
+#define GCREG_DEYUV_CONVERSION_PLANE3_COUNT 7 : 6
+#define GCREG_DEYUV_CONVERSION_PLANE3_COUNT_End 7
+#define GCREG_DEYUV_CONVERSION_PLANE3_COUNT_Start 6
+#define GCREG_DEYUV_CONVERSION_PLANE3_COUNT_Type U02
+
+/* Select which color channel to pick for B channel for plane 1. */
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_B 9 : 8
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_B_End 9
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_B_Start 8
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_B_Type U02
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_B_BLUE 0x0
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_B_GREEN 0x1
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_B_RED 0x2
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_B_ALPHA 0x3
+
+/* Select which color channel to pick for G channel for plane 1. */
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_G 11 : 10
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_G_End 11
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_G_Start 10
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_G_Type U02
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_G_BLUE 0x0
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_G_GREEN 0x1
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_G_RED 0x2
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_G_ALPHA 0x3
+
+/* Select which color channel to pick for R channel for plane 1. */
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_R 13 : 12
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_R_End 13
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_R_Start 12
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_R_Type U02
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_R_BLUE 0x0
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_R_GREEN 0x1
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_R_RED 0x2
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_R_ALPHA 0x3
+
+/* Select which color channel to pick for A channel for plane 1. */
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_A 15 : 14
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_A_End 15
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_A_Start 14
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_A_Type U02
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_A_BLUE 0x0
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_A_GREEN 0x1
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_A_RED 0x2
+#define GCREG_DEYUV_CONVERSION_PLANE1_SWIZZLE_A_ALPHA 0x3
+
+/* Select which color channel to pick for B channel for plane 2. */
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_B 17 : 16
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_B_End 17
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_B_Start 16
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_B_Type U02
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_B_BLUE 0x0
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_B_GREEN 0x1
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_B_RED 0x2
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_B_ALPHA 0x3
+
+/* Select which color channel to pick for G channel for plane 2. */
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_G 19 : 18
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_G_End 19
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_G_Start 18
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_G_Type U02
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_G_BLUE 0x0
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_G_GREEN 0x1
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_G_RED 0x2
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_G_ALPHA 0x3
+
+/* Select which color channel to pick for R channel for plane 2. */
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_R 21 : 20
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_R_End 21
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_R_Start 20
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_R_Type U02
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_R_BLUE 0x0
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_R_GREEN 0x1
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_R_RED 0x2
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_R_ALPHA 0x3
+
+/* Select which color channel to pick for A channel for plane 2. */
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_A 23 : 22
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_A_End 23
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_A_Start 22
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_A_Type U02
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_A_BLUE 0x0
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_A_GREEN 0x1
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_A_RED 0x2
+#define GCREG_DEYUV_CONVERSION_PLANE2_SWIZZLE_A_ALPHA 0x3
+
+/* Select which color channel to pick for B channel for plane 3. */
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_B 25 : 24
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_B_End 25
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_B_Start 24
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_B_Type U02
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_B_BLUE 0x0
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_B_GREEN 0x1
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_B_RED 0x2
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_B_ALPHA 0x3
+
+/* Select which color channel to pick for G channel for plane 3. */
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_G 27 : 26
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_G_End 27
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_G_Start 26
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_G_Type U02
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_G_BLUE 0x0
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_G_GREEN 0x1
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_G_RED 0x2
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_G_ALPHA 0x3
+
+/* Select which color channel to pick for R channel for plane 3. */
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_R 29 : 28
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_R_End 29
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_R_Start 28
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_R_Type U02
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_R_BLUE 0x0
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_R_GREEN 0x1
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_R_RED 0x2
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_R_ALPHA 0x3
+
+/* Select which color channel to pick for A channel for plane 3. */
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_A 31 : 30
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_A_End 31
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_A_Start 30
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_A_Type U02
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_A_BLUE 0x0
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_A_GREEN 0x1
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_A_RED 0x2
+#define GCREG_DEYUV_CONVERSION_PLANE3_SWIZZLE_A_ALPHA 0x3
+
+/*******************************************************************************
+** State gcregDEPlane2Address
+*/
+
+/* Address for plane 2 if gcregDEYUVConversion.
+** Enable is set to Plane2 or Plane3.
+*/
+
+#define gcregDEPlane2AddressRegAddrs 0x04C4
+#define GCREG_DE_PLANE2_ADDRESS_Address 0x01310
+#define GCREG_DE_PLANE2_ADDRESS_MSB 15
+#define GCREG_DE_PLANE2_ADDRESS_LSB 0
+#define GCREG_DE_PLANE2_ADDRESS_BLK 0
+#define GCREG_DE_PLANE2_ADDRESS_Count 1
+#define GCREG_DE_PLANE2_ADDRESS_FieldMask 0xFFFFFFFF
+#define GCREG_DE_PLANE2_ADDRESS_ReadMask 0xFFFFFFFC
+#define GCREG_DE_PLANE2_ADDRESS_WriteMask 0xFFFFFFFC
+#define GCREG_DE_PLANE2_ADDRESS_ResetValue 0x00000000
+
+#define GCREG_DE_PLANE2_ADDRESS_ADDRESS 31 : 0
+#define GCREG_DE_PLANE2_ADDRESS_ADDRESS_End 30
+#define GCREG_DE_PLANE2_ADDRESS_ADDRESS_Start 0
+#define GCREG_DE_PLANE2_ADDRESS_ADDRESS_Type U31
+
+/*******************************************************************************
+** State gcregDEPlane2Stride
+*/
+
+/* Stride for plane 2 if gcregDEYUVConversion.
+** Enable is set to Plane2 or Plane3.
+*/
+
+#define gcregDEPlane2StrideRegAddrs 0x04C5
+#define GCREG_DE_PLANE2_STRIDE_MSB 15
+#define GCREG_DE_PLANE2_STRIDE_LSB 0
+#define GCREG_DE_PLANE2_STRIDE_BLK 0
+#define GCREG_DE_PLANE2_STRIDE_Count 1
+#define GCREG_DE_PLANE2_STRIDE_FieldMask 0x0003FFFF
+#define GCREG_DE_PLANE2_STRIDE_ReadMask 0x0003FFFC
+#define GCREG_DE_PLANE2_STRIDE_WriteMask 0x0003FFFC
+#define GCREG_DE_PLANE2_STRIDE_ResetValue 0x00000000
+
+#define GCREG_DE_PLANE2_STRIDE_STRIDE 17 : 0
+#define GCREG_DE_PLANE2_STRIDE_STRIDE_End 17
+#define GCREG_DE_PLANE2_STRIDE_STRIDE_Start 0
+#define GCREG_DE_PLANE2_STRIDE_STRIDE_Type U18
+
+/*******************************************************************************
+** State gcregDEPlane3Address
+*/
+
+/* Address for plane 3 if gcregDEYUVConversion.
+** Enable is set to Plane3.
+*/
+
+#define gcregDEPlane3AddressRegAddrs 0x04C6
+#define GCREG_DE_PLANE3_ADDRESS_MSB 15
+#define GCREG_DE_PLANE3_ADDRESS_LSB 0
+#define GCREG_DE_PLANE3_ADDRESS_BLK 0
+#define GCREG_DE_PLANE3_ADDRESS_Count 1
+#define GCREG_DE_PLANE3_ADDRESS_FieldMask 0xFFFFFFFF
+#define GCREG_DE_PLANE3_ADDRESS_ReadMask 0xFFFFFFFC
+#define GCREG_DE_PLANE3_ADDRESS_WriteMask 0xFFFFFFFC
+#define GCREG_DE_PLANE3_ADDRESS_ResetValue 0x00000000
+
+#define GCREG_DE_PLANE3_ADDRESS_ADDRESS 31 : 0
+#define GCREG_DE_PLANE3_ADDRESS_ADDRESS_End 30
+#define GCREG_DE_PLANE3_ADDRESS_ADDRESS_Start 0
+#define GCREG_DE_PLANE3_ADDRESS_ADDRESS_Type U31
+
+/*******************************************************************************
+** State gcregDEPlane3Stride
+*/
+
+/* Stride for plane 3 if gcregDEYUVConversion.
+** Enable is set to Plane3.
+*/
+
+#define gcregDEPlane3StrideRegAddrs 0x04C7
+#define GCREG_DE_PLANE3_STRIDE_MSB 15
+#define GCREG_DE_PLANE3_STRIDE_LSB 0
+#define GCREG_DE_PLANE3_STRIDE_BLK 0
+#define GCREG_DE_PLANE3_STRIDE_Count 1
+#define GCREG_DE_PLANE3_STRIDE_FieldMask 0x0003FFFF
+#define GCREG_DE_PLANE3_STRIDE_ReadMask 0x0003FFFC
+#define GCREG_DE_PLANE3_STRIDE_WriteMask 0x0003FFFC
+#define GCREG_DE_PLANE3_STRIDE_ResetValue 0x00000000
+
+#define GCREG_DE_PLANE3_STRIDE_STRIDE 17 : 0
+#define GCREG_DE_PLANE3_STRIDE_STRIDE_End 17
+#define GCREG_DE_PLANE3_STRIDE_STRIDE_Start 0
+#define GCREG_DE_PLANE3_STRIDE_STRIDE_Type U18
+
+/*******************************************************************************
+** State gcregDEStallDE
+*/
+
+#define gcregDEStallDERegAddrs 0x04C8
+#define GCREG_DE_STALL_DE_MSB 15
+#define GCREG_DE_STALL_DE_LSB 0
+#define GCREG_DE_STALL_DE_BLK 0
+#define GCREG_DE_STALL_DE_Count 1
+#define GCREG_DE_STALL_DE_FieldMask 0x00000001
+#define GCREG_DE_STALL_DE_ReadMask 0x00000001
+#define GCREG_DE_STALL_DE_WriteMask 0x00000001
+#define GCREG_DE_STALL_DE_ResetValue 0x00000000
+
+/* Stall de enable. */
+#define GCREG_DE_STALL_DE_ENABLE 0 : 0
+#define GCREG_DE_STALL_DE_ENABLE_End 0
+#define GCREG_DE_STALL_DE_ENABLE_Start 0
+#define GCREG_DE_STALL_DE_ENABLE_Type U01
+#define GCREG_DE_STALL_DE_ENABLE_DISABLED 0x0
+#define GCREG_DE_STALL_DE_ENABLE_ENABLED 0x1
+
+/*******************************************************************************
+** State gcregBlock4SrcAddress
+*/
+
+/* 32-bit aligned base address of the source surface. */
+
+#define gcregBlock4SrcAddressRegAddrs 0x4A00
+#define GCREG_BLOCK4_SRC_ADDRESS_MSB 15
+#define GCREG_BLOCK4_SRC_ADDRESS_LSB 2
+#define GCREG_BLOCK4_SRC_ADDRESS_BLK 0
+#define GCREG_BLOCK4_SRC_ADDRESS_Count 4
+#define GCREG_BLOCK4_SRC_ADDRESS_FieldMask 0xFFFFFFFF
+#define GCREG_BLOCK4_SRC_ADDRESS_ReadMask 0xFFFFFFFC
+#define GCREG_BLOCK4_SRC_ADDRESS_WriteMask 0xFFFFFFFC
+#define GCREG_BLOCK4_SRC_ADDRESS_ResetValue 0x00000000
+
+#define GCREG_BLOCK4_SRC_ADDRESS_ADDRESS 31 : 0
+#define GCREG_BLOCK4_SRC_ADDRESS_ADDRESS_End 30
+#define GCREG_BLOCK4_SRC_ADDRESS_ADDRESS_Start 0
+#define GCREG_BLOCK4_SRC_ADDRESS_ADDRESS_Type U31
+
+/*******************************************************************************
+** State gcregBlock4SrcStride
+*/
+
+/* Stride of the source surface in bytes. To calculate the stride multiply
+** the surface width in pixels by the number of bytes per pixel.
+*/
+
+#define gcregBlock4SrcStrideRegAddrs 0x4A04
+#define GCREG_BLOCK4_SRC_STRIDE_MSB 15
+#define GCREG_BLOCK4_SRC_STRIDE_LSB 2
+#define GCREG_BLOCK4_SRC_STRIDE_BLK 0
+#define GCREG_BLOCK4_SRC_STRIDE_Count 4
+#define GCREG_BLOCK4_SRC_STRIDE_FieldMask 0x0003FFFF
+#define GCREG_BLOCK4_SRC_STRIDE_ReadMask 0x0003FFFC
+#define GCREG_BLOCK4_SRC_STRIDE_WriteMask 0x0003FFFC
+#define GCREG_BLOCK4_SRC_STRIDE_ResetValue 0x00000000
+
+#define GCREG_BLOCK4_SRC_STRIDE_STRIDE 17 : 0
+#define GCREG_BLOCK4_SRC_STRIDE_STRIDE_End 17
+#define GCREG_BLOCK4_SRC_STRIDE_STRIDE_Start 0
+#define GCREG_BLOCK4_SRC_STRIDE_STRIDE_Type U18
+
+/*******************************************************************************
+** State gcregBlock4SrcRotationConfig
+*/
+
+/* 90 degree rotation configuration for the source surface. Width field
+** specifies the width of the surface in pixels.
+*/
+
+#define gcregBlock4SrcRotationConfigRegAddrs 0x4A08
+#define GCREG_BLOCK4_SRC_ROTATION_CONFIG_MSB 15
+#define GCREG_BLOCK4_SRC_ROTATION_CONFIG_LSB 2
+#define GCREG_BLOCK4_SRC_ROTATION_CONFIG_BLK 0
+#define GCREG_BLOCK4_SRC_ROTATION_CONFIG_Count 4
+#define GCREG_BLOCK4_SRC_ROTATION_CONFIG_FieldMask 0x0001FFFF
+#define GCREG_BLOCK4_SRC_ROTATION_CONFIG_ReadMask 0x0001FFFF
+#define GCREG_BLOCK4_SRC_ROTATION_CONFIG_WriteMask 0x0001FFFF
+#define GCREG_BLOCK4_SRC_ROTATION_CONFIG_ResetValue 0x00000000
+
+#define GCREG_BLOCK4_SRC_ROTATION_CONFIG_WIDTH 15 : 0
+#define GCREG_BLOCK4_SRC_ROTATION_CONFIG_WIDTH_End 15
+#define GCREG_BLOCK4_SRC_ROTATION_CONFIG_WIDTH_Start 0
+#define GCREG_BLOCK4_SRC_ROTATION_CONFIG_WIDTH_Type U16
+
+#define GCREG_BLOCK4_SRC_ROTATION_CONFIG_ROTATION 16 : 16
+#define GCREG_BLOCK4_SRC_ROTATION_CONFIG_ROTATION_End 16
+#define GCREG_BLOCK4_SRC_ROTATION_CONFIG_ROTATION_Start 16
+#define GCREG_BLOCK4_SRC_ROTATION_CONFIG_ROTATION_Type U01
+#define GCREG_BLOCK4_SRC_ROTATION_CONFIG_ROTATION_DISABLE 0x0
+#define GCREG_BLOCK4_SRC_ROTATION_CONFIG_ROTATION_ENABLE 0x1
+
+/*******************************************************************************
+** State gcregBlock4SrcConfig
+*/
+
+/* Source surface configuration register. */
+
+#define gcregBlock4SrcConfigRegAddrs 0x4A0C
+#define GCREG_BLOCK4_SRC_CONFIG_MSB 15
+#define GCREG_BLOCK4_SRC_CONFIG_LSB 2
+#define GCREG_BLOCK4_SRC_CONFIG_BLK 0
+#define GCREG_BLOCK4_SRC_CONFIG_Count 4
+#define GCREG_BLOCK4_SRC_CONFIG_FieldMask 0xDF30B1C0
+#define GCREG_BLOCK4_SRC_CONFIG_ReadMask 0xDF30B1C0
+#define GCREG_BLOCK4_SRC_CONFIG_WriteMask 0xDF30B1C0
+#define GCREG_BLOCK4_SRC_CONFIG_ResetValue 0x00000000
+
+/* Control source endianess. */
+#define GCREG_BLOCK4_SRC_CONFIG_ENDIAN_CONTROL 31 : 30
+#define GCREG_BLOCK4_SRC_CONFIG_ENDIAN_CONTROL_End 31
+#define GCREG_BLOCK4_SRC_CONFIG_ENDIAN_CONTROL_Start 30
+#define GCREG_BLOCK4_SRC_CONFIG_ENDIAN_CONTROL_Type U02
+#define GCREG_BLOCK4_SRC_CONFIG_ENDIAN_CONTROL_NO_SWAP 0x0
+#define GCREG_BLOCK4_SRC_CONFIG_ENDIAN_CONTROL_SWAP_WORD 0x1
+#define GCREG_BLOCK4_SRC_CONFIG_ENDIAN_CONTROL_SWAP_DWORD 0x2
+
+/* Defines the pixel format of the source surface. */
+#define GCREG_BLOCK4_SRC_CONFIG_SOURCE_FORMAT 28 : 24
+#define GCREG_BLOCK4_SRC_CONFIG_SOURCE_FORMAT_End 28
+#define GCREG_BLOCK4_SRC_CONFIG_SOURCE_FORMAT_Start 24
+#define GCREG_BLOCK4_SRC_CONFIG_SOURCE_FORMAT_Type U05
+#define GCREG_BLOCK4_SRC_CONFIG_SOURCE_FORMAT_X4R4G4B4 0x00
+#define GCREG_BLOCK4_SRC_CONFIG_SOURCE_FORMAT_A4R4G4B4 0x01
+#define GCREG_BLOCK4_SRC_CONFIG_SOURCE_FORMAT_X1R5G5B5 0x02
+#define GCREG_BLOCK4_SRC_CONFIG_SOURCE_FORMAT_A1R5G5B5 0x03
+#define GCREG_BLOCK4_SRC_CONFIG_SOURCE_FORMAT_R5G6B5 0x04
+#define GCREG_BLOCK4_SRC_CONFIG_SOURCE_FORMAT_X8R8G8B8 0x05
+#define GCREG_BLOCK4_SRC_CONFIG_SOURCE_FORMAT_A8R8G8B8 0x06
+#define GCREG_BLOCK4_SRC_CONFIG_SOURCE_FORMAT_YUY2 0x07
+#define GCREG_BLOCK4_SRC_CONFIG_SOURCE_FORMAT_UYVY 0x08
+#define GCREG_BLOCK4_SRC_CONFIG_SOURCE_FORMAT_INDEX8 0x09
+#define GCREG_BLOCK4_SRC_CONFIG_SOURCE_FORMAT_MONOCHROME 0x0A
+#define GCREG_BLOCK4_SRC_CONFIG_SOURCE_FORMAT_YV12 0x0F
+#define GCREG_BLOCK4_SRC_CONFIG_SOURCE_FORMAT_A8 0x10
+#define GCREG_BLOCK4_SRC_CONFIG_SOURCE_FORMAT_NV12 0x11
+#define GCREG_BLOCK4_SRC_CONFIG_SOURCE_FORMAT_NV16 0x12
+#define GCREG_BLOCK4_SRC_CONFIG_SOURCE_FORMAT_RG16 0x13
+
+/* Color channel swizzles. */
+#define GCREG_BLOCK4_SRC_CONFIG_SWIZZLE 21 : 20
+#define GCREG_BLOCK4_SRC_CONFIG_SWIZZLE_End 21
+#define GCREG_BLOCK4_SRC_CONFIG_SWIZZLE_Start 20
+#define GCREG_BLOCK4_SRC_CONFIG_SWIZZLE_Type U02
+#define GCREG_BLOCK4_SRC_CONFIG_SWIZZLE_ARGB 0x0
+#define GCREG_BLOCK4_SRC_CONFIG_SWIZZLE_RGBA 0x1
+#define GCREG_BLOCK4_SRC_CONFIG_SWIZZLE_ABGR 0x2
+#define GCREG_BLOCK4_SRC_CONFIG_SWIZZLE_BGRA 0x3
+
+/* Mono expansion: if 0, transparency color will be 0, otherwise transparency **
+** color will be 1. */
+#define GCREG_BLOCK4_SRC_CONFIG_MONO_TRANSPARENCY 15 : 15
+#define GCREG_BLOCK4_SRC_CONFIG_MONO_TRANSPARENCY_End 15
+#define GCREG_BLOCK4_SRC_CONFIG_MONO_TRANSPARENCY_Start 15
+#define GCREG_BLOCK4_SRC_CONFIG_MONO_TRANSPARENCY_Type U01
+#define GCREG_BLOCK4_SRC_CONFIG_MONO_TRANSPARENCY_BACKGROUND 0x0
+#define GCREG_BLOCK4_SRC_CONFIG_MONO_TRANSPARENCY_FOREGROUND 0x1
+
+/* Mono expansion or masked blit: stream packing in pixels. Determines how **
+** many horizontal pixels are there per each 32-bit chunk. For example, if **
+** set to Packed8, each 32-bit chunk is 8-pixel wide, which also means that **
+** it defines 4 vertical lines of pixels. */
+#define GCREG_BLOCK4_SRC_CONFIG_PACK 13 : 12
+#define GCREG_BLOCK4_SRC_CONFIG_PACK_End 13
+#define GCREG_BLOCK4_SRC_CONFIG_PACK_Start 12
+#define GCREG_BLOCK4_SRC_CONFIG_PACK_Type U02
+#define GCREG_BLOCK4_SRC_CONFIG_PACK_PACKED8 0x0
+#define GCREG_BLOCK4_SRC_CONFIG_PACK_PACKED16 0x1
+#define GCREG_BLOCK4_SRC_CONFIG_PACK_PACKED32 0x2
+#define GCREG_BLOCK4_SRC_CONFIG_PACK_UNPACKED 0x3
+
+/* Source data location: set to STREAM for mono expansion blits or masked **
+** blits. For mono expansion blits the complete bitmap comes from the command **
+** stream. For masked blits the source data comes from the memory and the **
+** mask from the command stream. */
+#define GCREG_BLOCK4_SRC_CONFIG_LOCATION 8 : 8
+#define GCREG_BLOCK4_SRC_CONFIG_LOCATION_End 8
+#define GCREG_BLOCK4_SRC_CONFIG_LOCATION_Start 8
+#define GCREG_BLOCK4_SRC_CONFIG_LOCATION_Type U01
+#define GCREG_BLOCK4_SRC_CONFIG_LOCATION_MEMORY 0x0
+#define GCREG_BLOCK4_SRC_CONFIG_LOCATION_STREAM 0x1
+
+/* Source linear/tiled address computation control. */
+#define GCREG_BLOCK4_SRC_CONFIG_TILED 7 : 7
+#define GCREG_BLOCK4_SRC_CONFIG_TILED_End 7
+#define GCREG_BLOCK4_SRC_CONFIG_TILED_Start 7
+#define GCREG_BLOCK4_SRC_CONFIG_TILED_Type U01
+#define GCREG_BLOCK4_SRC_CONFIG_TILED_DISABLED 0x0
+#define GCREG_BLOCK4_SRC_CONFIG_TILED_ENABLED 0x1
+
+/* If set to ABSOLUTE, the source coordinates are treated as absolute **
+** coordinates inside the source surface. If set to RELATIVE, the source **
+** coordinates are treated as the offsets from the destination coordinates **
+** with the source size equal to the size of the destination. */
+#define GCREG_BLOCK4_SRC_CONFIG_SRC_RELATIVE 6 : 6
+#define GCREG_BLOCK4_SRC_CONFIG_SRC_RELATIVE_End 6
+#define GCREG_BLOCK4_SRC_CONFIG_SRC_RELATIVE_Start 6
+#define GCREG_BLOCK4_SRC_CONFIG_SRC_RELATIVE_Type U01
+#define GCREG_BLOCK4_SRC_CONFIG_SRC_RELATIVE_ABSOLUTE 0x0
+#define GCREG_BLOCK4_SRC_CONFIG_SRC_RELATIVE_RELATIVE 0x1
+
+/*******************************************************************************
+** State gcregBlock4SrcOrigin
+*/
+
+/* Absolute or relative (see SRC_RELATIVE field of gcregBlock4SrcConfig
+** register) X and Y coordinates in pixels of the top left corner of the
+** source rectangle within the source surface.
+*/
+
+#define gcregBlock4SrcOriginRegAddrs 0x4A10
+#define GCREG_BLOCK4_SRC_ORIGIN_MSB 15
+#define GCREG_BLOCK4_SRC_ORIGIN_LSB 2
+#define GCREG_BLOCK4_SRC_ORIGIN_BLK 0
+#define GCREG_BLOCK4_SRC_ORIGIN_Count 4
+#define GCREG_BLOCK4_SRC_ORIGIN_FieldMask 0xFFFFFFFF
+#define GCREG_BLOCK4_SRC_ORIGIN_ReadMask 0xFFFFFFFF
+#define GCREG_BLOCK4_SRC_ORIGIN_WriteMask 0xFFFFFFFF
+#define GCREG_BLOCK4_SRC_ORIGIN_ResetValue 0x00000000
+
+#define GCREG_BLOCK4_SRC_ORIGIN_Y 31 : 16
+#define GCREG_BLOCK4_SRC_ORIGIN_Y_End 31
+#define GCREG_BLOCK4_SRC_ORIGIN_Y_Start 16
+#define GCREG_BLOCK4_SRC_ORIGIN_Y_Type U16
+
+#define GCREG_BLOCK4_SRC_ORIGIN_X 15 : 0
+#define GCREG_BLOCK4_SRC_ORIGIN_X_End 15
+#define GCREG_BLOCK4_SRC_ORIGIN_X_Start 0
+#define GCREG_BLOCK4_SRC_ORIGIN_X_Type U16
+
+/*******************************************************************************
+** State gcregBlock4SrcSize
+*/
+
+/* Width and height of the source rectangle in pixels. If the source is
+** relative (see SRC_RELATIVE field of gcregBlock4SrcConfig register) or a
+** regular bitblt is being performed without stretching, this register is
+** ignored and the source size is assumed to be the same as the destination.
+*/
+
+#define gcregBlock4SrcSizeRegAddrs 0x4A14
+#define GCREG_BLOCK4_SRC_SIZE_MSB 15
+#define GCREG_BLOCK4_SRC_SIZE_LSB 2
+#define GCREG_BLOCK4_SRC_SIZE_BLK 0
+#define GCREG_BLOCK4_SRC_SIZE_Count 4
+#define GCREG_BLOCK4_SRC_SIZE_FieldMask 0xFFFFFFFF
+#define GCREG_BLOCK4_SRC_SIZE_ReadMask 0xFFFFFFFF
+#define GCREG_BLOCK4_SRC_SIZE_WriteMask 0xFFFFFFFF
+#define GCREG_BLOCK4_SRC_SIZE_ResetValue 0x00000000
+
+#define GCREG_BLOCK4_SRC_SIZE_Y 31 : 16
+#define GCREG_BLOCK4_SRC_SIZE_Y_End 31
+#define GCREG_BLOCK4_SRC_SIZE_Y_Start 16
+#define GCREG_BLOCK4_SRC_SIZE_Y_Type U16
+
+#define GCREG_BLOCK4_SRC_SIZE_X 15 : 0
+#define GCREG_BLOCK4_SRC_SIZE_X_End 15
+#define GCREG_BLOCK4_SRC_SIZE_X_Start 0
+#define GCREG_BLOCK4_SRC_SIZE_X_Type U16
+
+/*******************************************************************************
+** State gcregBlock4SrcColorBg
+*/
+
+/* Select the color where source becomes transparent. It must be programmed
+** in A8R8G8B8 format.
+*/
+
+#define gcregBlock4SrcColorBgRegAddrs 0x4A18
+#define GCREG_BLOCK4_SRC_COLOR_BG_MSB 15
+#define GCREG_BLOCK4_SRC_COLOR_BG_LSB 2
+#define GCREG_BLOCK4_SRC_COLOR_BG_BLK 0
+#define GCREG_BLOCK4_SRC_COLOR_BG_Count 4
+#define GCREG_BLOCK4_SRC_COLOR_BG_FieldMask 0xFFFFFFFF
+#define GCREG_BLOCK4_SRC_COLOR_BG_ReadMask 0xFFFFFFFF
+#define GCREG_BLOCK4_SRC_COLOR_BG_WriteMask 0xFFFFFFFF
+#define GCREG_BLOCK4_SRC_COLOR_BG_ResetValue 0x00000000
+
+#define GCREG_BLOCK4_SRC_COLOR_BG_ALPHA 31 : 24
+#define GCREG_BLOCK4_SRC_COLOR_BG_ALPHA_End 31
+#define GCREG_BLOCK4_SRC_COLOR_BG_ALPHA_Start 24
+#define GCREG_BLOCK4_SRC_COLOR_BG_ALPHA_Type U08
+
+#define GCREG_BLOCK4_SRC_COLOR_BG_RED 23 : 16
+#define GCREG_BLOCK4_SRC_COLOR_BG_RED_End 23
+#define GCREG_BLOCK4_SRC_COLOR_BG_RED_Start 16
+#define GCREG_BLOCK4_SRC_COLOR_BG_RED_Type U08
+
+#define GCREG_BLOCK4_SRC_COLOR_BG_GREEN 15 : 8
+#define GCREG_BLOCK4_SRC_COLOR_BG_GREEN_End 15
+#define GCREG_BLOCK4_SRC_COLOR_BG_GREEN_Start 8
+#define GCREG_BLOCK4_SRC_COLOR_BG_GREEN_Type U08
+
+#define GCREG_BLOCK4_SRC_COLOR_BG_BLUE 7 : 0
+#define GCREG_BLOCK4_SRC_COLOR_BG_BLUE_End 7
+#define GCREG_BLOCK4_SRC_COLOR_BG_BLUE_Start 0
+#define GCREG_BLOCK4_SRC_COLOR_BG_BLUE_Type U08
+
+/*******************************************************************************
+** State gcregBlock4Rop
+*/
+
+/* Raster operation foreground and background codes. Even though ROP is not
+** used in CLEAR, HOR_FILTER_BLT, VER_FILTER_BLT and alpha-eanbled BIT_BLTs,
+** ROP code still has to be programmed, because the engine makes the decision
+** whether source, destination and pattern are involved in the current
+** operation and the correct decision is essential for the engine to complete
+** the operation as expected.
+*/
+
+#define gcregBlock4RopRegAddrs 0x4A1C
+#define GCREG_BLOCK4_ROP_MSB 15
+#define GCREG_BLOCK4_ROP_LSB 2
+#define GCREG_BLOCK4_ROP_BLK 0
+#define GCREG_BLOCK4_ROP_Count 4
+#define GCREG_BLOCK4_ROP_FieldMask 0x0030FFFF
+#define GCREG_BLOCK4_ROP_ReadMask 0x0030FFFF
+#define GCREG_BLOCK4_ROP_WriteMask 0x0030FFFF
+#define GCREG_BLOCK4_ROP_ResetValue 0x00000000
+
+/* ROP type: ROP2, ROP3 or ROP4 */
+#define GCREG_BLOCK4_ROP_TYPE 21 : 20
+#define GCREG_BLOCK4_ROP_TYPE_End 21
+#define GCREG_BLOCK4_ROP_TYPE_Start 20
+#define GCREG_BLOCK4_ROP_TYPE_Type U02
+#define GCREG_BLOCK4_ROP_TYPE_ROP2_PATTERN 0x0
+#define GCREG_BLOCK4_ROP_TYPE_ROP2_SOURCE 0x1
+#define GCREG_BLOCK4_ROP_TYPE_ROP3 0x2
+#define GCREG_BLOCK4_ROP_TYPE_ROP4 0x3
+
+/* Background ROP code is used for transparent pixels. */
+#define GCREG_BLOCK4_ROP_ROP_BG 15 : 8
+#define GCREG_BLOCK4_ROP_ROP_BG_End 15
+#define GCREG_BLOCK4_ROP_ROP_BG_Start 8
+#define GCREG_BLOCK4_ROP_ROP_BG_Type U08
+
+/* Background ROP code is used for opaque pixels. */
+#define GCREG_BLOCK4_ROP_ROP_FG 7 : 0
+#define GCREG_BLOCK4_ROP_ROP_FG_End 7
+#define GCREG_BLOCK4_ROP_ROP_FG_Start 0
+#define GCREG_BLOCK4_ROP_ROP_FG_Type U08
+
+/*******************************************************************************
+** State gcregBlock4AlphaControl
+*/
+
+#define gcregBlock4AlphaControlRegAddrs 0x4A20
+#define GCREG_BLOCK4_ALPHA_CONTROL_MSB 15
+#define GCREG_BLOCK4_ALPHA_CONTROL_LSB 2
+#define GCREG_BLOCK4_ALPHA_CONTROL_BLK 0
+#define GCREG_BLOCK4_ALPHA_CONTROL_Count 4
+#define GCREG_BLOCK4_ALPHA_CONTROL_FieldMask 0x00000001
+#define GCREG_BLOCK4_ALPHA_CONTROL_ReadMask 0x00000001
+#define GCREG_BLOCK4_ALPHA_CONTROL_WriteMask 0x00000001
+#define GCREG_BLOCK4_ALPHA_CONTROL_ResetValue 0x00000000
+
+#define GCREG_BLOCK4_ALPHA_CONTROL_ENABLE 0 : 0
+#define GCREG_BLOCK4_ALPHA_CONTROL_ENABLE_End 0
+#define GCREG_BLOCK4_ALPHA_CONTROL_ENABLE_Start 0
+#define GCREG_BLOCK4_ALPHA_CONTROL_ENABLE_Type U01
+#define GCREG_BLOCK4_ALPHA_CONTROL_ENABLE_OFF 0x0
+#define GCREG_BLOCK4_ALPHA_CONTROL_ENABLE_ON 0x1
+
+/*******************************************************************************
+** State gcregBlock4AlphaModes
+*/
+
+#define gcregBlock4AlphaModesRegAddrs 0x4A24
+#define GCREG_BLOCK4_ALPHA_MODES_MSB 15
+#define GCREG_BLOCK4_ALPHA_MODES_LSB 2
+#define GCREG_BLOCK4_ALPHA_MODES_BLK 0
+#define GCREG_BLOCK4_ALPHA_MODES_Count 4
+#define GCREG_BLOCK4_ALPHA_MODES_FieldMask 0xFF003311
+#define GCREG_BLOCK4_ALPHA_MODES_ReadMask 0xFF003311
+#define GCREG_BLOCK4_ALPHA_MODES_WriteMask 0xFF003311
+#define GCREG_BLOCK4_ALPHA_MODES_ResetValue 0x00000000
+
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_ALPHA_MODE 0 : 0
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_ALPHA_MODE_End 0
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_ALPHA_MODE_Start 0
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_ALPHA_MODE_Type U01
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_ALPHA_MODE_NORMAL 0x0
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_ALPHA_MODE_INVERSED 0x1
+
+#define GCREG_BLOCK4_ALPHA_MODES_DST_ALPHA_MODE 4 : 4
+#define GCREG_BLOCK4_ALPHA_MODES_DST_ALPHA_MODE_End 4
+#define GCREG_BLOCK4_ALPHA_MODES_DST_ALPHA_MODE_Start 4
+#define GCREG_BLOCK4_ALPHA_MODES_DST_ALPHA_MODE_Type U01
+#define GCREG_BLOCK4_ALPHA_MODES_DST_ALPHA_MODE_NORMAL 0x0
+#define GCREG_BLOCK4_ALPHA_MODES_DST_ALPHA_MODE_INVERSED 0x1
+
+#define GCREG_BLOCK4_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE 9 : 8
+#define GCREG_BLOCK4_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE_End 9
+#define GCREG_BLOCK4_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE_Start 8
+#define GCREG_BLOCK4_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE_Type U02
+#define GCREG_BLOCK4_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE_NORMAL 0x0
+#define GCREG_BLOCK4_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE_GLOBAL 0x1
+#define GCREG_BLOCK4_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE_SCALED 0x2
+
+#define GCREG_BLOCK4_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE 13 : 12
+#define GCREG_BLOCK4_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE_End 13
+#define GCREG_BLOCK4_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE_Start 12
+#define GCREG_BLOCK4_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE_Type U02
+#define GCREG_BLOCK4_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE_NORMAL 0x0
+#define GCREG_BLOCK4_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE_GLOBAL 0x1
+#define GCREG_BLOCK4_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE_SCALED 0x2
+
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_BLENDING_MODE 26 : 24
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_BLENDING_MODE_End 26
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_BLENDING_MODE_Start 24
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_BLENDING_MODE_Type U03
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_BLENDING_MODE_ZERO 0x0
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_BLENDING_MODE_ONE 0x1
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_BLENDING_MODE_NORMAL 0x2
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_BLENDING_MODE_INVERSED 0x3
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_BLENDING_MODE_COLOR 0x4
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_BLENDING_MODE_COLOR_INVERSED 0x5
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_BLENDING_MODE_SATURATED_ALPHA 0x6
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_BLENDING_MODE_SATURATED_DEST_ALPHA 0x7
+
+/* Src Blending factor is calculate from Src alpha. */
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_ALPHA_FACTOR 27 : 27
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_ALPHA_FACTOR_End 27
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_ALPHA_FACTOR_Start 27
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_ALPHA_FACTOR_Type U01
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_ALPHA_FACTOR_DISABLED 0x0
+#define GCREG_BLOCK4_ALPHA_MODES_SRC_ALPHA_FACTOR_ENABLED 0x1
+
+#define GCREG_BLOCK4_ALPHA_MODES_DST_BLENDING_MODE 30 : 28
+#define GCREG_BLOCK4_ALPHA_MODES_DST_BLENDING_MODE_End 30
+#define GCREG_BLOCK4_ALPHA_MODES_DST_BLENDING_MODE_Start 28
+#define GCREG_BLOCK4_ALPHA_MODES_DST_BLENDING_MODE_Type U03
+#define GCREG_BLOCK4_ALPHA_MODES_DST_BLENDING_MODE_ZERO 0x0
+#define GCREG_BLOCK4_ALPHA_MODES_DST_BLENDING_MODE_ONE 0x1
+#define GCREG_BLOCK4_ALPHA_MODES_DST_BLENDING_MODE_NORMAL 0x2
+#define GCREG_BLOCK4_ALPHA_MODES_DST_BLENDING_MODE_INVERSED 0x3
+#define GCREG_BLOCK4_ALPHA_MODES_DST_BLENDING_MODE_COLOR 0x4
+#define GCREG_BLOCK4_ALPHA_MODES_DST_BLENDING_MODE_COLOR_INVERSED 0x5
+#define GCREG_BLOCK4_ALPHA_MODES_DST_BLENDING_MODE_SATURATED_ALPHA 0x6
+#define GCREG_BLOCK4_ALPHA_MODES_DST_BLENDING_MODE_SATURATED_DEST_ALPHA 0x7
+
+/* Dst Blending factor is calculate from Dst alpha. */
+#define GCREG_BLOCK4_ALPHA_MODES_DST_ALPHA_FACTOR 31 : 31
+#define GCREG_BLOCK4_ALPHA_MODES_DST_ALPHA_FACTOR_End 31
+#define GCREG_BLOCK4_ALPHA_MODES_DST_ALPHA_FACTOR_Start 31
+#define GCREG_BLOCK4_ALPHA_MODES_DST_ALPHA_FACTOR_Type U01
+#define GCREG_BLOCK4_ALPHA_MODES_DST_ALPHA_FACTOR_DISABLED 0x0
+#define GCREG_BLOCK4_ALPHA_MODES_DST_ALPHA_FACTOR_ENABLED 0x1
+
+/*******************************************************************************
+** State gcregBlock4AddressU
+*/
+
+/* 32-bit aligned base address of the source U plane. */
+
+#define gcregBlock4UPlaneAddressRegAddrs 0x4A28
+#define GCREG_BLOCK4_UPLANE_ADDRESS_MSB 15
+#define GCREG_BLOCK4_UPLANE_ADDRESS_LSB 2
+#define GCREG_BLOCK4_UPLANE_ADDRESS_BLK 0
+#define GCREG_BLOCK4_UPLANE_ADDRESS_Count 4
+#define GCREG_BLOCK4_UPLANE_ADDRESS_FieldMask 0xFFFFFFFF
+#define GCREG_BLOCK4_UPLANE_ADDRESS_ReadMask 0xFFFFFFFC
+#define GCREG_BLOCK4_UPLANE_ADDRESS_WriteMask 0xFFFFFFFC
+#define GCREG_BLOCK4_UPLANE_ADDRESS_ResetValue 0x00000000
+
+#define GCREG_BLOCK4_UPLANE_ADDRESS_ADDRESS 31 : 0
+#define GCREG_BLOCK4_UPLANE_ADDRESS_ADDRESS_End 30
+#define GCREG_BLOCK4_UPLANE_ADDRESS_ADDRESS_Start 0
+#define GCREG_BLOCK4_UPLANE_ADDRESS_ADDRESS_Type U31
+
+/*******************************************************************************
+** State gcregBlock4StrideU
+*/
+
+/* Stride of the source U plane in bytes. */
+
+#define gcregBlock4UPlaneStrideRegAddrs 0x4A2C
+#define GCREG_BLOCK4_UPLANE_STRIDE_MSB 15
+#define GCREG_BLOCK4_UPLANE_STRIDE_LSB 2
+#define GCREG_BLOCK4_UPLANE_STRIDE_BLK 0
+#define GCREG_BLOCK4_UPLANE_STRIDE_Count 4
+#define GCREG_BLOCK4_UPLANE_STRIDE_FieldMask 0x0003FFFF
+#define GCREG_BLOCK4_UPLANE_STRIDE_ReadMask 0x0003FFFC
+#define GCREG_BLOCK4_UPLANE_STRIDE_WriteMask 0x0003FFFC
+#define GCREG_BLOCK4_UPLANE_STRIDE_ResetValue 0x00000000
+
+#define GCREG_BLOCK4_UPLANE_STRIDE_STRIDE 17 : 0
+#define GCREG_BLOCK4_UPLANE_STRIDE_STRIDE_End 17
+#define GCREG_BLOCK4_UPLANE_STRIDE_STRIDE_Start 0
+#define GCREG_BLOCK4_UPLANE_STRIDE_STRIDE_Type U18
+
+/*******************************************************************************
+** State gcregBlock4AddressV
+*/
+
+/* 32-bit aligned base address of the source V plane. */
+
+#define gcregBlock4VPlaneAddressRegAddrs 0x4A30
+#define GCREG_BLOCK4_VPLANE_ADDRESS_MSB 15
+#define GCREG_BLOCK4_VPLANE_ADDRESS_LSB 2
+#define GCREG_BLOCK4_VPLANE_ADDRESS_BLK 0
+#define GCREG_BLOCK4_VPLANE_ADDRESS_Count 4
+#define GCREG_BLOCK4_VPLANE_ADDRESS_FieldMask 0xFFFFFFFF
+#define GCREG_BLOCK4_VPLANE_ADDRESS_ReadMask 0xFFFFFFFC
+#define GCREG_BLOCK4_VPLANE_ADDRESS_WriteMask 0xFFFFFFFC
+#define GCREG_BLOCK4_VPLANE_ADDRESS_ResetValue 0x00000000
+
+#define GCREG_BLOCK4_VPLANE_ADDRESS_ADDRESS 31 : 0
+#define GCREG_BLOCK4_VPLANE_ADDRESS_ADDRESS_End 30
+#define GCREG_BLOCK4_VPLANE_ADDRESS_ADDRESS_Start 0
+#define GCREG_BLOCK4_VPLANE_ADDRESS_ADDRESS_Type U31
+
+/*******************************************************************************
+** State gcregBlock4StrideV
+*/
+
+/* Stride of the source V plane in bytes. */
+
+#define gcregBlock4VPlaneStrideRegAddrs 0x4A34
+#define GCREG_BLOCK4_VPLANE_STRIDE_MSB 15
+#define GCREG_BLOCK4_VPLANE_STRIDE_LSB 2
+#define GCREG_BLOCK4_VPLANE_STRIDE_BLK 0
+#define GCREG_BLOCK4_VPLANE_STRIDE_Count 4
+#define GCREG_BLOCK4_VPLANE_STRIDE_FieldMask 0x0003FFFF
+#define GCREG_BLOCK4_VPLANE_STRIDE_ReadMask 0x0003FFFC
+#define GCREG_BLOCK4_VPLANE_STRIDE_WriteMask 0x0003FFFC
+#define GCREG_BLOCK4_VPLANE_STRIDE_ResetValue 0x00000000
+
+#define GCREG_BLOCK4_VPLANE_STRIDE_STRIDE 17 : 0
+#define GCREG_BLOCK4_VPLANE_STRIDE_STRIDE_End 17
+#define GCREG_BLOCK4_VPLANE_STRIDE_STRIDE_Start 0
+#define GCREG_BLOCK4_VPLANE_STRIDE_STRIDE_Type U18
+
+/*******************************************************************************
+** State gcregBlock4SrcRotationHeight
+*/
+
+/* 180/270 degree rotation configuration for the Source surface. Height field
+** specifies the height of the surface in pixels.
+*/
+
+#define gcregBlock4SrcRotationHeightRegAddrs 0x4A38
+#define GCREG_BLOCK4_SRC_ROTATION_HEIGHT_MSB 15
+#define GCREG_BLOCK4_SRC_ROTATION_HEIGHT_LSB 2
+#define GCREG_BLOCK4_SRC_ROTATION_HEIGHT_BLK 0
+#define GCREG_BLOCK4_SRC_ROTATION_HEIGHT_Count 4
+#define GCREG_BLOCK4_SRC_ROTATION_HEIGHT_FieldMask 0x0000FFFF
+#define GCREG_BLOCK4_SRC_ROTATION_HEIGHT_ReadMask 0x0000FFFF
+#define GCREG_BLOCK4_SRC_ROTATION_HEIGHT_WriteMask 0x0000FFFF
+#define GCREG_BLOCK4_SRC_ROTATION_HEIGHT_ResetValue 0x00000000
+
+#define GCREG_BLOCK4_SRC_ROTATION_HEIGHT_HEIGHT 15 : 0
+#define GCREG_BLOCK4_SRC_ROTATION_HEIGHT_HEIGHT_End 15
+#define GCREG_BLOCK4_SRC_ROTATION_HEIGHT_HEIGHT_Start 0
+#define GCREG_BLOCK4_SRC_ROTATION_HEIGHT_HEIGHT_Type U16
+
+/*******************************************************************************
+** State gcregBlock4RotAngle
+*/
+
+/* 0/90/180/270 degree rotation configuration for the Source surface. Height
+** field specifies the height of the surface in pixels.
+*/
+
+#define gcregBlock4RotAngleRegAddrs 0x4A3C
+#define GCREG_BLOCK4_ROT_ANGLE_MSB 15
+#define GCREG_BLOCK4_ROT_ANGLE_LSB 2
+#define GCREG_BLOCK4_ROT_ANGLE_BLK 0
+#define GCREG_BLOCK4_ROT_ANGLE_Count 4
+#define GCREG_BLOCK4_ROT_ANGLE_FieldMask 0x000BB33F
+#define GCREG_BLOCK4_ROT_ANGLE_ReadMask 0x000BB33F
+#define GCREG_BLOCK4_ROT_ANGLE_WriteMask 0x000BB33F
+#define GCREG_BLOCK4_ROT_ANGLE_ResetValue 0x00000000
+
+#define GCREG_BLOCK4_ROT_ANGLE_SRC 2 : 0
+#define GCREG_BLOCK4_ROT_ANGLE_SRC_End 2
+#define GCREG_BLOCK4_ROT_ANGLE_SRC_Start 0
+#define GCREG_BLOCK4_ROT_ANGLE_SRC_Type U03
+#define GCREG_BLOCK4_ROT_ANGLE_SRC_ROT0 0x0
+#define GCREG_BLOCK4_ROT_ANGLE_SRC_FLIP_X 0x1
+#define GCREG_BLOCK4_ROT_ANGLE_SRC_FLIP_Y 0x2
+#define GCREG_BLOCK4_ROT_ANGLE_SRC_ROT90 0x4
+#define GCREG_BLOCK4_ROT_ANGLE_SRC_ROT180 0x5
+#define GCREG_BLOCK4_ROT_ANGLE_SRC_ROT270 0x6
+
+#define GCREG_BLOCK4_ROT_ANGLE_DST 5 : 3
+#define GCREG_BLOCK4_ROT_ANGLE_DST_End 5
+#define GCREG_BLOCK4_ROT_ANGLE_DST_Start 3
+#define GCREG_BLOCK4_ROT_ANGLE_DST_Type U03
+#define GCREG_BLOCK4_ROT_ANGLE_DST_ROT0 0x0
+#define GCREG_BLOCK4_ROT_ANGLE_DST_FLIP_X 0x1
+#define GCREG_BLOCK4_ROT_ANGLE_DST_FLIP_Y 0x2
+#define GCREG_BLOCK4_ROT_ANGLE_DST_ROT90 0x4
+#define GCREG_BLOCK4_ROT_ANGLE_DST_ROT180 0x5
+#define GCREG_BLOCK4_ROT_ANGLE_DST_ROT270 0x6
+
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_SRC 8 : 8
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_SRC_End 8
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_SRC_Start 8
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_SRC_Type U01
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_SRC_ENABLED 0x0
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_SRC_MASKED 0x1
+
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_DST 9 : 9
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_DST_End 9
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_DST_Start 9
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_DST_Type U01
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_DST_ENABLED 0x0
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_DST_MASKED 0x1
+
+#define GCREG_BLOCK4_ROT_ANGLE_SRC_MIRROR 13 : 12
+#define GCREG_BLOCK4_ROT_ANGLE_SRC_MIRROR_End 13
+#define GCREG_BLOCK4_ROT_ANGLE_SRC_MIRROR_Start 12
+#define GCREG_BLOCK4_ROT_ANGLE_SRC_MIRROR_Type U02
+#define GCREG_BLOCK4_ROT_ANGLE_SRC_MIRROR_NONE 0x0
+#define GCREG_BLOCK4_ROT_ANGLE_SRC_MIRROR_MIRROR_X 0x1
+#define GCREG_BLOCK4_ROT_ANGLE_SRC_MIRROR_MIRROR_Y 0x2
+#define GCREG_BLOCK4_ROT_ANGLE_SRC_MIRROR_MIRROR_XY 0x3
+
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_SRC_MIRROR 15 : 15
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_SRC_MIRROR_End 15
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_SRC_MIRROR_Start 15
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_SRC_MIRROR_Type U01
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_SRC_MIRROR_ENABLED 0x0
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_SRC_MIRROR_MASKED 0x1
+
+#define GCREG_BLOCK4_ROT_ANGLE_DST_MIRROR 17 : 16
+#define GCREG_BLOCK4_ROT_ANGLE_DST_MIRROR_End 17
+#define GCREG_BLOCK4_ROT_ANGLE_DST_MIRROR_Start 16
+#define GCREG_BLOCK4_ROT_ANGLE_DST_MIRROR_Type U02
+#define GCREG_BLOCK4_ROT_ANGLE_DST_MIRROR_NONE 0x0
+#define GCREG_BLOCK4_ROT_ANGLE_DST_MIRROR_MIRROR_X 0x1
+#define GCREG_BLOCK4_ROT_ANGLE_DST_MIRROR_MIRROR_Y 0x2
+#define GCREG_BLOCK4_ROT_ANGLE_DST_MIRROR_MIRROR_XY 0x3
+
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_DST_MIRROR 19 : 19
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_DST_MIRROR_End 19
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_DST_MIRROR_Start 19
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_DST_MIRROR_Type U01
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_DST_MIRROR_ENABLED 0x0
+#define GCREG_BLOCK4_ROT_ANGLE_MASK_DST_MIRROR_MASKED 0x1
+
+/*******************************************************************************
+** State gcregBlock4GlobalSrcColor
+*/
+
+/* Defines the global source color and alpha values. */
+
+#define gcregBlock4GlobalSrcColorRegAddrs 0x4A40
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_MSB 15
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_LSB 2
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_BLK 0
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_Count 4
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_FieldMask 0xFFFFFFFF
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_ReadMask 0xFFFFFFFF
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_WriteMask 0xFFFFFFFF
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_ResetValue 0x00000000
+
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_ALPHA 31 : 24
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_ALPHA_End 31
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_ALPHA_Start 24
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_ALPHA_Type U08
+
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_RED 23 : 16
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_RED_End 23
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_RED_Start 16
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_RED_Type U08
+
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_GREEN 15 : 8
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_GREEN_End 15
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_GREEN_Start 8
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_GREEN_Type U08
+
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_BLUE 7 : 0
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_BLUE_End 7
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_BLUE_Start 0
+#define GCREG_BLOCK4_GLOBAL_SRC_COLOR_BLUE_Type U08
+
+/*******************************************************************************
+** State gcregBlock4GlobalDestColor
+*/
+
+/* Defines the global destination color and alpha values. */
+
+#define gcregBlock4GlobalDestColorRegAddrs 0x4A44
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_MSB 15
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_LSB 2
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_BLK 0
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_Count 4
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_FieldMask 0xFFFFFFFF
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_ReadMask 0xFFFFFFFF
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_WriteMask 0xFFFFFFFF
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_ResetValue 0x00000000
+
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_ALPHA 31 : 24
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_ALPHA_End 31
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_ALPHA_Start 24
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_ALPHA_Type U08
+
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_RED 23 : 16
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_RED_End 23
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_RED_Start 16
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_RED_Type U08
+
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_GREEN 15 : 8
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_GREEN_End 15
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_GREEN_Start 8
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_GREEN_Type U08
+
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_BLUE 7 : 0
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_BLUE_End 7
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_BLUE_Start 0
+#define GCREG_BLOCK4_GLOBAL_DEST_COLOR_BLUE_Type U08
+
+/*******************************************************************************
+** State gcregBlock4ColorMultiplyModes
+*/
+
+/* Color modes to multiply Source or Destination pixel color by alpha
+** channel. Alpha can be from global color source or current pixel.
+*/
+
+#define gcregBlock4ColorMultiplyModesRegAddrs 0x4A48
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_MSB 15
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_LSB 2
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_BLK 0
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_Count 4
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_FieldMask 0x00100311
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_ReadMask 0x00100311
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_WriteMask 0x00100311
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_ResetValue 0x00000000
+
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY 0 : 0
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_End 0
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_Start 0
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_Type U01
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_DISABLE 0x0
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_ENABLE 0x1
+
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_DST_PREMULTIPLY 4 : 4
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_DST_PREMULTIPLY_End 4
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_DST_PREMULTIPLY_Start 4
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_DST_PREMULTIPLY_Type U01
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_DST_PREMULTIPLY_DISABLE 0x0
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_DST_PREMULTIPLY_ENABLE 0x1
+
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY 9 : 8
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_End 9
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_Start 8
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_Type U02
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_DISABLE 0x0
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_ALPHA 0x1
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_COLOR 0x2
+
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY 20 : 20
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_End 20
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_Start 20
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_Type U01
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_DISABLE 0x0
+#define GCREG_BLOCK4_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_ENABLE 0x1
+
+/*******************************************************************************
+** State gcregBlock4Transparency
+*/
+
+#define gcregBlock4TransparencyRegAddrs 0x4A4C
+#define GCREG_BLOCK4_TRANSPARENCY_MSB 15
+#define GCREG_BLOCK4_TRANSPARENCY_LSB 2
+#define GCREG_BLOCK4_TRANSPARENCY_BLK 0
+#define GCREG_BLOCK4_TRANSPARENCY_Count 4
+#define GCREG_BLOCK4_TRANSPARENCY_FieldMask 0xB3331333
+#define GCREG_BLOCK4_TRANSPARENCY_ReadMask 0xB3331333
+#define GCREG_BLOCK4_TRANSPARENCY_WriteMask 0xB3331333
+#define GCREG_BLOCK4_TRANSPARENCY_ResetValue 0x00000000
+
+/* Source transparency mode. */
+#define GCREG_BLOCK4_TRANSPARENCY_SOURCE 1 : 0
+#define GCREG_BLOCK4_TRANSPARENCY_SOURCE_End 1
+#define GCREG_BLOCK4_TRANSPARENCY_SOURCE_Start 0
+#define GCREG_BLOCK4_TRANSPARENCY_SOURCE_Type U02
+#define GCREG_BLOCK4_TRANSPARENCY_SOURCE_OPAQUE 0x0
+#define GCREG_BLOCK4_TRANSPARENCY_SOURCE_MASK 0x1
+#define GCREG_BLOCK4_TRANSPARENCY_SOURCE_KEY 0x2
+
+/* Pattern transparency mode. KEY transparency mode is reserved. */
+#define GCREG_BLOCK4_TRANSPARENCY_PATTERN 5 : 4
+#define GCREG_BLOCK4_TRANSPARENCY_PATTERN_End 5
+#define GCREG_BLOCK4_TRANSPARENCY_PATTERN_Start 4
+#define GCREG_BLOCK4_TRANSPARENCY_PATTERN_Type U02
+#define GCREG_BLOCK4_TRANSPARENCY_PATTERN_OPAQUE 0x0
+#define GCREG_BLOCK4_TRANSPARENCY_PATTERN_MASK 0x1
+#define GCREG_BLOCK4_TRANSPARENCY_PATTERN_KEY 0x2
+
+/* Destination transparency mode. MASK transparency mode is reserved. */
+#define GCREG_BLOCK4_TRANSPARENCY_DESTINATION 9 : 8
+#define GCREG_BLOCK4_TRANSPARENCY_DESTINATION_End 9
+#define GCREG_BLOCK4_TRANSPARENCY_DESTINATION_Start 8
+#define GCREG_BLOCK4_TRANSPARENCY_DESTINATION_Type U02
+#define GCREG_BLOCK4_TRANSPARENCY_DESTINATION_OPAQUE 0x0
+#define GCREG_BLOCK4_TRANSPARENCY_DESTINATION_MASK 0x1
+#define GCREG_BLOCK4_TRANSPARENCY_DESTINATION_KEY 0x2
+
+/* Mask field for Source/Pattern/Destination fields. */
+#define GCREG_BLOCK4_TRANSPARENCY_MASK_TRANSPARENCY 12 : 12
+#define GCREG_BLOCK4_TRANSPARENCY_MASK_TRANSPARENCY_End 12
+#define GCREG_BLOCK4_TRANSPARENCY_MASK_TRANSPARENCY_Start 12
+#define GCREG_BLOCK4_TRANSPARENCY_MASK_TRANSPARENCY_Type U01
+#define GCREG_BLOCK4_TRANSPARENCY_MASK_TRANSPARENCY_ENABLED 0x0
+#define GCREG_BLOCK4_TRANSPARENCY_MASK_TRANSPARENCY_MASKED 0x1
+
+/* Source usage override. */
+#define GCREG_BLOCK4_TRANSPARENCY_USE_SRC_OVERRIDE 17 : 16
+#define GCREG_BLOCK4_TRANSPARENCY_USE_SRC_OVERRIDE_End 17
+#define GCREG_BLOCK4_TRANSPARENCY_USE_SRC_OVERRIDE_Start 16
+#define GCREG_BLOCK4_TRANSPARENCY_USE_SRC_OVERRIDE_Type U02
+#define GCREG_BLOCK4_TRANSPARENCY_USE_SRC_OVERRIDE_DEFAULT 0x0
+#define GCREG_BLOCK4_TRANSPARENCY_USE_SRC_OVERRIDE_USE_ENABLE 0x1
+#define GCREG_BLOCK4_TRANSPARENCY_USE_SRC_OVERRIDE_USE_DISABLE 0x2
+
+/* Pattern usage override. */
+#define GCREG_BLOCK4_TRANSPARENCY_USE_PAT_OVERRIDE 21 : 20
+#define GCREG_BLOCK4_TRANSPARENCY_USE_PAT_OVERRIDE_End 21
+#define GCREG_BLOCK4_TRANSPARENCY_USE_PAT_OVERRIDE_Start 20
+#define GCREG_BLOCK4_TRANSPARENCY_USE_PAT_OVERRIDE_Type U02
+#define GCREG_BLOCK4_TRANSPARENCY_USE_PAT_OVERRIDE_DEFAULT 0x0
+#define GCREG_BLOCK4_TRANSPARENCY_USE_PAT_OVERRIDE_USE_ENABLE 0x1
+#define GCREG_BLOCK4_TRANSPARENCY_USE_PAT_OVERRIDE_USE_DISABLE 0x2
+
+/* Destination usage override. */
+#define GCREG_BLOCK4_TRANSPARENCY_USE_DST_OVERRIDE 25 : 24
+#define GCREG_BLOCK4_TRANSPARENCY_USE_DST_OVERRIDE_End 25
+#define GCREG_BLOCK4_TRANSPARENCY_USE_DST_OVERRIDE_Start 24
+#define GCREG_BLOCK4_TRANSPARENCY_USE_DST_OVERRIDE_Type U02
+#define GCREG_BLOCK4_TRANSPARENCY_USE_DST_OVERRIDE_DEFAULT 0x0
+#define GCREG_BLOCK4_TRANSPARENCY_USE_DST_OVERRIDE_USE_ENABLE 0x1
+#define GCREG_BLOCK4_TRANSPARENCY_USE_DST_OVERRIDE_USE_DISABLE 0x2
+
+/* 2D resource usage override mask field. */
+#define GCREG_BLOCK4_TRANSPARENCY_MASK_RESOURCE_OVERRIDE 28 : 28
+#define GCREG_BLOCK4_TRANSPARENCY_MASK_RESOURCE_OVERRIDE_End 28
+#define GCREG_BLOCK4_TRANSPARENCY_MASK_RESOURCE_OVERRIDE_Start 28
+#define GCREG_BLOCK4_TRANSPARENCY_MASK_RESOURCE_OVERRIDE_Type U01
+#define GCREG_BLOCK4_TRANSPARENCY_MASK_RESOURCE_OVERRIDE_ENABLED 0x0
+#define GCREG_BLOCK4_TRANSPARENCY_MASK_RESOURCE_OVERRIDE_MASKED 0x1
+
+/* DFB Color Key. */
+#define GCREG_BLOCK4_TRANSPARENCY_DFB_COLOR_KEY 29 : 29
+#define GCREG_BLOCK4_TRANSPARENCY_DFB_COLOR_KEY_End 29
+#define GCREG_BLOCK4_TRANSPARENCY_DFB_COLOR_KEY_Start 29
+#define GCREG_BLOCK4_TRANSPARENCY_DFB_COLOR_KEY_Type U01
+#define GCREG_BLOCK4_TRANSPARENCY_DFB_COLOR_KEY_DISABLED 0x0
+#define GCREG_BLOCK4_TRANSPARENCY_DFB_COLOR_KEY_ENABLED 0x1
+
+#define GCREG_BLOCK4_TRANSPARENCY_MASK_DFB_COLOR_KEY 31 : 31
+#define GCREG_BLOCK4_TRANSPARENCY_MASK_DFB_COLOR_KEY_End 31
+#define GCREG_BLOCK4_TRANSPARENCY_MASK_DFB_COLOR_KEY_Start 31
+#define GCREG_BLOCK4_TRANSPARENCY_MASK_DFB_COLOR_KEY_Type U01
+#define GCREG_BLOCK4_TRANSPARENCY_MASK_DFB_COLOR_KEY_ENABLED 0x0
+#define GCREG_BLOCK4_TRANSPARENCY_MASK_DFB_COLOR_KEY_MASKED 0x1
+
+/*******************************************************************************
+** State gcregBlock4Control
+*/
+
+/* General purpose control register. */
+
+#define gcregBlock4PEControlRegAddrs 0x4A50
+#define GCREG_BLOCK4_PE_CONTROL_MSB 15
+#define GCREG_BLOCK4_PE_CONTROL_LSB 2
+#define GCREG_BLOCK4_PE_CONTROL_BLK 0
+#define GCREG_BLOCK4_PE_CONTROL_Count 4
+#define GCREG_BLOCK4_PE_CONTROL_FieldMask 0x00000999
+#define GCREG_BLOCK4_PE_CONTROL_ReadMask 0x00000999
+#define GCREG_BLOCK4_PE_CONTROL_WriteMask 0x00000999
+#define GCREG_BLOCK4_PE_CONTROL_ResetValue 0x00000000
+
+#define GCREG_BLOCK4_PE_CONTROL_YUV 0 : 0
+#define GCREG_BLOCK4_PE_CONTROL_YUV_End 0
+#define GCREG_BLOCK4_PE_CONTROL_YUV_Start 0
+#define GCREG_BLOCK4_PE_CONTROL_YUV_Type U01
+#define GCREG_BLOCK4_PE_CONTROL_YUV_601 0x0
+#define GCREG_BLOCK4_PE_CONTROL_YUV_709 0x1
+
+#define GCREG_BLOCK4_PE_CONTROL_MASK_YUV 3 : 3
+#define GCREG_BLOCK4_PE_CONTROL_MASK_YUV_End 3
+#define GCREG_BLOCK4_PE_CONTROL_MASK_YUV_Start 3
+#define GCREG_BLOCK4_PE_CONTROL_MASK_YUV_Type U01
+#define GCREG_BLOCK4_PE_CONTROL_MASK_YUV_ENABLED 0x0
+#define GCREG_BLOCK4_PE_CONTROL_MASK_YUV_MASKED 0x1
+
+#define GCREG_BLOCK4_PE_CONTROL_UV_SWIZZLE 4 : 4
+#define GCREG_BLOCK4_PE_CONTROL_UV_SWIZZLE_End 4
+#define GCREG_BLOCK4_PE_CONTROL_UV_SWIZZLE_Start 4
+#define GCREG_BLOCK4_PE_CONTROL_UV_SWIZZLE_Type U01
+#define GCREG_BLOCK4_PE_CONTROL_UV_SWIZZLE_UV 0x0
+#define GCREG_BLOCK4_PE_CONTROL_UV_SWIZZLE_VU 0x1
+
+#define GCREG_BLOCK4_PE_CONTROL_MASK_UV_SWIZZLE 7 : 7
+#define GCREG_BLOCK4_PE_CONTROL_MASK_UV_SWIZZLE_End 7
+#define GCREG_BLOCK4_PE_CONTROL_MASK_UV_SWIZZLE_Start 7
+#define GCREG_BLOCK4_PE_CONTROL_MASK_UV_SWIZZLE_Type U01
+#define GCREG_BLOCK4_PE_CONTROL_MASK_UV_SWIZZLE_ENABLED 0x0
+#define GCREG_BLOCK4_PE_CONTROL_MASK_UV_SWIZZLE_MASKED 0x1
+
+/* YUV to RGB convert enable */
+#define GCREG_BLOCK4_PE_CONTROL_YUVRGB 8 : 8
+#define GCREG_BLOCK4_PE_CONTROL_YUVRGB_End 8
+#define GCREG_BLOCK4_PE_CONTROL_YUVRGB_Start 8
+#define GCREG_BLOCK4_PE_CONTROL_YUVRGB_Type U01
+#define GCREG_BLOCK4_PE_CONTROL_YUVRGB_DISABLED 0x0
+#define GCREG_BLOCK4_PE_CONTROL_YUVRGB_ENABLED 0x1
+
+#define GCREG_BLOCK4_PE_CONTROL_MASK_YUVRGB 11 : 11
+#define GCREG_BLOCK4_PE_CONTROL_MASK_YUVRGB_End 11
+#define GCREG_BLOCK4_PE_CONTROL_MASK_YUVRGB_Start 11
+#define GCREG_BLOCK4_PE_CONTROL_MASK_YUVRGB_Type U01
+#define GCREG_BLOCK4_PE_CONTROL_MASK_YUVRGB_ENABLED 0x0
+#define GCREG_BLOCK4_PE_CONTROL_MASK_YUVRGB_MASKED 0x1
+
+/*******************************************************************************
+** State gcregBlock4SrcColorKeyHigh
+*/
+
+/* Defines the source transparency color in source format. */
+
+#define gcregBlock4SrcColorKeyHighRegAddrs 0x4A54
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_MSB 15
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_LSB 2
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_BLK 0
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_Count 4
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_FieldMask 0xFFFFFFFF
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_ReadMask 0xFFFFFFFF
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_WriteMask 0xFFFFFFFF
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_ResetValue 0x00000000
+
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_ALPHA 31 : 24
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_ALPHA_End 31
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_ALPHA_Start 24
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_ALPHA_Type U08
+
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_RED 23 : 16
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_RED_End 23
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_RED_Start 16
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_RED_Type U08
+
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_GREEN 15 : 8
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_GREEN_End 15
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_GREEN_Start 8
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_GREEN_Type U08
+
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_BLUE 7 : 0
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_BLUE_End 7
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_BLUE_Start 0
+#define GCREG_BLOCK4_SRC_COLOR_KEY_HIGH_BLUE_Type U08
+
+/*******************************************************************************
+** State gcregBlock4SrcExConfig
+*/
+
+#define gcregBlock4SrcExConfigRegAddrs 0x4A58
+#define GCREG_BLOCK4_SRC_EX_CONFIG_MSB 15
+#define GCREG_BLOCK4_SRC_EX_CONFIG_LSB 2
+#define GCREG_BLOCK4_SRC_EX_CONFIG_BLK 0
+#define GCREG_BLOCK4_SRC_EX_CONFIG_Count 4
+#define GCREG_BLOCK4_SRC_EX_CONFIG_FieldMask 0x00000109
+#define GCREG_BLOCK4_SRC_EX_CONFIG_ReadMask 0x00000109
+#define GCREG_BLOCK4_SRC_EX_CONFIG_WriteMask 0x00000109
+#define GCREG_BLOCK4_SRC_EX_CONFIG_ResetValue 0x00000000
+
+/* Source multi tiled address computation control. */
+#define GCREG_BLOCK4_SRC_EX_CONFIG_MULTI_TILED 0 : 0
+#define GCREG_BLOCK4_SRC_EX_CONFIG_MULTI_TILED_End 0
+#define GCREG_BLOCK4_SRC_EX_CONFIG_MULTI_TILED_Start 0
+#define GCREG_BLOCK4_SRC_EX_CONFIG_MULTI_TILED_Type U01
+#define GCREG_BLOCK4_SRC_EX_CONFIG_MULTI_TILED_DISABLED 0x0
+#define GCREG_BLOCK4_SRC_EX_CONFIG_MULTI_TILED_ENABLED 0x1
+
+/* Source super tiled address computation control. */
+#define GCREG_BLOCK4_SRC_EX_CONFIG_SUPER_TILED 3 : 3
+#define GCREG_BLOCK4_SRC_EX_CONFIG_SUPER_TILED_End 3
+#define GCREG_BLOCK4_SRC_EX_CONFIG_SUPER_TILED_Start 3
+#define GCREG_BLOCK4_SRC_EX_CONFIG_SUPER_TILED_Type U01
+#define GCREG_BLOCK4_SRC_EX_CONFIG_SUPER_TILED_DISABLED 0x0
+#define GCREG_BLOCK4_SRC_EX_CONFIG_SUPER_TILED_ENABLED 0x1
+
+/* Source super tiled address computation control. */
+#define GCREG_BLOCK4_SRC_EX_CONFIG_MINOR_TILED 8 : 8
+#define GCREG_BLOCK4_SRC_EX_CONFIG_MINOR_TILED_End 8
+#define GCREG_BLOCK4_SRC_EX_CONFIG_MINOR_TILED_Start 8
+#define GCREG_BLOCK4_SRC_EX_CONFIG_MINOR_TILED_Type U01
+#define GCREG_BLOCK4_SRC_EX_CONFIG_MINOR_TILED_DISABLED 0x0
+#define GCREG_BLOCK4_SRC_EX_CONFIG_MINOR_TILED_ENABLED 0x1
+
+/* Source CacheMode. */
+#define GCREG_BLOCK4_SRC_EX_CONFIG_CACHE_MODE 12 : 12
+#define GCREG_BLOCK4_SRC_EX_CONFIG_CACHE_MODE_End 12
+#define GCREG_BLOCK4_SRC_EX_CONFIG_CACHE_MODE_Start 12
+#define GCREG_BLOCK4_SRC_EX_CONFIG_CACHE_MODE_Type U01
+#define GCREG_BLOCK4_SRC_EX_CONFIG_CACHE_MODE_DISABLED 0x0
+#define GCREG_BLOCK4_SRC_EX_CONFIG_CACHE_MODE_ENABLED 0x1
+
+/*******************************************************************************
+** State gcregBlock4SrcExAddress
+*/
+
+/* 32-bit aligned base address of the source extra surface. */
+
+#define gcregBlock4SrcExAddressRegAddrs 0x4A5C
+#define GCREG_BLOCK4_SRC_EX_ADDRESS_MSB 15
+#define GCREG_BLOCK4_SRC_EX_ADDRESS_LSB 2
+#define GCREG_BLOCK4_SRC_EX_ADDRESS_BLK 0
+#define GCREG_BLOCK4_SRC_EX_ADDRESS_Count 4
+#define GCREG_BLOCK4_SRC_EX_ADDRESS_FieldMask 0xFFFFFFFF
+#define GCREG_BLOCK4_SRC_EX_ADDRESS_ReadMask 0xFFFFFFFC
+#define GCREG_BLOCK4_SRC_EX_ADDRESS_WriteMask 0xFFFFFFFC
+#define GCREG_BLOCK4_SRC_EX_ADDRESS_ResetValue 0x00000000
+
+#define GCREG_BLOCK4_SRC_EX_ADDRESS_ADDRESS 31 : 0
+#define GCREG_BLOCK4_SRC_EX_ADDRESS_ADDRESS_End 30
+#define GCREG_BLOCK4_SRC_EX_ADDRESS_ADDRESS_Start 0
+#define GCREG_BLOCK4_SRC_EX_ADDRESS_ADDRESS_Type U31
+
+/*******************************************************************************
+** State gcregBlock8SrcAddressEx
+*/
+
+/* 32-bit aligned base address of the source surface. */
+
+#define gcregBlock8SrcAddressRegAddrs 0x4A80
+#define GCREG_BLOCK8_SRC_ADDRESS_MSB 15
+#define GCREG_BLOCK8_SRC_ADDRESS_LSB 3
+#define GCREG_BLOCK8_SRC_ADDRESS_BLK 0
+#define GCREG_BLOCK8_SRC_ADDRESS_Count 8
+#define GCREG_BLOCK8_SRC_ADDRESS_FieldMask 0xFFFFFFFF
+#define GCREG_BLOCK8_SRC_ADDRESS_ReadMask 0xFFFFFFFC
+#define GCREG_BLOCK8_SRC_ADDRESS_WriteMask 0xFFFFFFFC
+#define GCREG_BLOCK8_SRC_ADDRESS_ResetValue 0x00000000
+
+#define GCREG_BLOCK8_SRC_ADDRESS_ADDRESS 31 : 0
+#define GCREG_BLOCK8_SRC_ADDRESS_ADDRESS_End 30
+#define GCREG_BLOCK8_SRC_ADDRESS_ADDRESS_Start 0
+#define GCREG_BLOCK8_SRC_ADDRESS_ADDRESS_Type U31
+
+/*******************************************************************************
+** State gcregBlock8SrcStride
+*/
+
+/* Stride of the source surface in bytes. To calculate the stride multiply
+** the surface width in pixels by the number of bytes per pixel.
+*/
+
+#define gcregBlock8SrcStrideRegAddrs 0x4A88
+#define GCREG_BLOCK8_SRC_STRIDE_MSB 15
+#define GCREG_BLOCK8_SRC_STRIDE_LSB 3
+#define GCREG_BLOCK8_SRC_STRIDE_BLK 0
+#define GCREG_BLOCK8_SRC_STRIDE_Count 8
+#define GCREG_BLOCK8_SRC_STRIDE_FieldMask 0x0003FFFF
+#define GCREG_BLOCK8_SRC_STRIDE_ReadMask 0x0003FFFC
+#define GCREG_BLOCK8_SRC_STRIDE_WriteMask 0x0003FFFC
+#define GCREG_BLOCK8_SRC_STRIDE_ResetValue 0x00000000
+
+#define GCREG_BLOCK8_SRC_STRIDE_STRIDE 17 : 0
+#define GCREG_BLOCK8_SRC_STRIDE_STRIDE_End 17
+#define GCREG_BLOCK8_SRC_STRIDE_STRIDE_Start 0
+#define GCREG_BLOCK8_SRC_STRIDE_STRIDE_Type U18
+
+/*******************************************************************************
+** State gcregBlock8SrcRotationConfig
+*/
+
+/* 90 degree rotation configuration for the source surface. Width field
+** specifies the width of the surface in pixels.
+*/
+
+#define gcregBlock8SrcRotationConfigRegAddrs 0x4A90
+#define GCREG_BLOCK8_SRC_ROTATION_CONFIG_MSB 15
+#define GCREG_BLOCK8_SRC_ROTATION_CONFIG_LSB 3
+#define GCREG_BLOCK8_SRC_ROTATION_CONFIG_BLK 0
+#define GCREG_BLOCK8_SRC_ROTATION_CONFIG_Count 8
+#define GCREG_BLOCK8_SRC_ROTATION_CONFIG_FieldMask 0x0001FFFF
+#define GCREG_BLOCK8_SRC_ROTATION_CONFIG_ReadMask 0x0001FFFF
+#define GCREG_BLOCK8_SRC_ROTATION_CONFIG_WriteMask 0x0001FFFF
+#define GCREG_BLOCK8_SRC_ROTATION_CONFIG_ResetValue 0x00000000
+
+#define GCREG_BLOCK8_SRC_ROTATION_CONFIG_WIDTH 15 : 0
+#define GCREG_BLOCK8_SRC_ROTATION_CONFIG_WIDTH_End 15
+#define GCREG_BLOCK8_SRC_ROTATION_CONFIG_WIDTH_Start 0
+#define GCREG_BLOCK8_SRC_ROTATION_CONFIG_WIDTH_Type U16
+
+#define GCREG_BLOCK8_SRC_ROTATION_CONFIG_ROTATION 16 : 16
+#define GCREG_BLOCK8_SRC_ROTATION_CONFIG_ROTATION_End 16
+#define GCREG_BLOCK8_SRC_ROTATION_CONFIG_ROTATION_Start 16
+#define GCREG_BLOCK8_SRC_ROTATION_CONFIG_ROTATION_Type U01
+#define GCREG_BLOCK8_SRC_ROTATION_CONFIG_ROTATION_NORMAL 0x0
+#define GCREG_BLOCK8_SRC_ROTATION_CONFIG_ROTATION_ROTATED 0x1
+
+/*******************************************************************************
+** State gcregBlock8SrcConfig
+*/
+
+/* Source surface configuration register. */
+
+#define gcregBlock8SrcConfigRegAddrs 0x4A98
+#define GCREG_BLOCK8_SRC_CONFIG_MSB 15
+#define GCREG_BLOCK8_SRC_CONFIG_LSB 3
+#define GCREG_BLOCK8_SRC_CONFIG_BLK 0
+#define GCREG_BLOCK8_SRC_CONFIG_Count 8
+#define GCREG_BLOCK8_SRC_CONFIG_FieldMask 0xDF30B1C0
+#define GCREG_BLOCK8_SRC_CONFIG_ReadMask 0xDF30B1C0
+#define GCREG_BLOCK8_SRC_CONFIG_WriteMask 0xDF30B1C0
+#define GCREG_BLOCK8_SRC_CONFIG_ResetValue 0x00000000
+
+/* Control source endianess. */
+#define GCREG_BLOCK8_SRC_CONFIG_ENDIAN_CONTROL 31 : 30
+#define GCREG_BLOCK8_SRC_CONFIG_ENDIAN_CONTROL_End 31
+#define GCREG_BLOCK8_SRC_CONFIG_ENDIAN_CONTROL_Start 30
+#define GCREG_BLOCK8_SRC_CONFIG_ENDIAN_CONTROL_Type U02
+#define GCREG_BLOCK8_SRC_CONFIG_ENDIAN_CONTROL_NO_SWAP 0x0
+#define GCREG_BLOCK8_SRC_CONFIG_ENDIAN_CONTROL_SWAP_WORD 0x1
+#define GCREG_BLOCK8_SRC_CONFIG_ENDIAN_CONTROL_SWAP_DWORD 0x2
+
+/* Defines the pixel format of the source surface. */
+#define GCREG_BLOCK8_SRC_CONFIG_SOURCE_FORMAT 28 : 24
+#define GCREG_BLOCK8_SRC_CONFIG_SOURCE_FORMAT_End 28
+#define GCREG_BLOCK8_SRC_CONFIG_SOURCE_FORMAT_Start 24
+#define GCREG_BLOCK8_SRC_CONFIG_SOURCE_FORMAT_Type U05
+#define GCREG_BLOCK8_SRC_CONFIG_SOURCE_FORMAT_X4R4G4B4 0x00
+#define GCREG_BLOCK8_SRC_CONFIG_SOURCE_FORMAT_A4R4G4B4 0x01
+#define GCREG_BLOCK8_SRC_CONFIG_SOURCE_FORMAT_X1R5G5B5 0x02
+#define GCREG_BLOCK8_SRC_CONFIG_SOURCE_FORMAT_A1R5G5B5 0x03
+#define GCREG_BLOCK8_SRC_CONFIG_SOURCE_FORMAT_R5G6B5 0x04
+#define GCREG_BLOCK8_SRC_CONFIG_SOURCE_FORMAT_X8R8G8B8 0x05
+#define GCREG_BLOCK8_SRC_CONFIG_SOURCE_FORMAT_A8R8G8B8 0x06
+#define GCREG_BLOCK8_SRC_CONFIG_SOURCE_FORMAT_YUY2 0x07
+#define GCREG_BLOCK8_SRC_CONFIG_SOURCE_FORMAT_UYVY 0x08
+#define GCREG_BLOCK8_SRC_CONFIG_SOURCE_FORMAT_INDEX8 0x09
+#define GCREG_BLOCK8_SRC_CONFIG_SOURCE_FORMAT_MONOCHROME 0x0A
+#define GCREG_BLOCK8_SRC_CONFIG_SOURCE_FORMAT_YV12 0x0F
+#define GCREG_BLOCK8_SRC_CONFIG_SOURCE_FORMAT_A8 0x10
+#define GCREG_BLOCK8_SRC_CONFIG_SOURCE_FORMAT_NV12 0x11
+#define GCREG_BLOCK8_SRC_CONFIG_SOURCE_FORMAT_NV16 0x12
+#define GCREG_BLOCK8_SRC_CONFIG_SOURCE_FORMAT_RG16 0x13
+
+/* Color channel swizzles. */
+#define GCREG_BLOCK8_SRC_CONFIG_SWIZZLE 21 : 20
+#define GCREG_BLOCK8_SRC_CONFIG_SWIZZLE_End 21
+#define GCREG_BLOCK8_SRC_CONFIG_SWIZZLE_Start 20
+#define GCREG_BLOCK8_SRC_CONFIG_SWIZZLE_Type U02
+#define GCREG_BLOCK8_SRC_CONFIG_SWIZZLE_ARGB 0x0
+#define GCREG_BLOCK8_SRC_CONFIG_SWIZZLE_RGBA 0x1
+#define GCREG_BLOCK8_SRC_CONFIG_SWIZZLE_ABGR 0x2
+#define GCREG_BLOCK8_SRC_CONFIG_SWIZZLE_BGRA 0x3
+
+/* Mono expansion: if 0, transparency color will be 0, otherwise transparency **
+** color will be 1. */
+#define GCREG_BLOCK8_SRC_CONFIG_MONO_TRANSPARENCY 15 : 15
+#define GCREG_BLOCK8_SRC_CONFIG_MONO_TRANSPARENCY_End 15
+#define GCREG_BLOCK8_SRC_CONFIG_MONO_TRANSPARENCY_Start 15
+#define GCREG_BLOCK8_SRC_CONFIG_MONO_TRANSPARENCY_Type U01
+#define GCREG_BLOCK8_SRC_CONFIG_MONO_TRANSPARENCY_BACKGROUND 0x0
+#define GCREG_BLOCK8_SRC_CONFIG_MONO_TRANSPARENCY_FOREGROUND 0x1
+
+/* Mono expansion or masked blit: stream packing in pixels. Determines how **
+** many horizontal pixels are there per each 32-bit chunk. For example, if **
+** set to Packed8, each 32-bit chunk is 8-pixel wide, which also means that **
+** it defines 4 vertical lines of pixels. */
+#define GCREG_BLOCK8_SRC_CONFIG_PACK 13 : 12
+#define GCREG_BLOCK8_SRC_CONFIG_PACK_End 13
+#define GCREG_BLOCK8_SRC_CONFIG_PACK_Start 12
+#define GCREG_BLOCK8_SRC_CONFIG_PACK_Type U02
+#define GCREG_BLOCK8_SRC_CONFIG_PACK_PACKED8 0x0
+#define GCREG_BLOCK8_SRC_CONFIG_PACK_PACKED16 0x1
+#define GCREG_BLOCK8_SRC_CONFIG_PACK_PACKED32 0x2
+#define GCREG_BLOCK8_SRC_CONFIG_PACK_UNPACKED 0x3
+
+/* Source data location: set to STREAM for mono expansion blits or masked **
+** blits. For mono expansion blits the complete bitmap comes from the command **
+** stream. For masked blits the source data comes from the memory and the **
+** mask from the command stream. */
+#define GCREG_BLOCK8_SRC_CONFIG_LOCATION 8 : 8
+#define GCREG_BLOCK8_SRC_CONFIG_LOCATION_End 8
+#define GCREG_BLOCK8_SRC_CONFIG_LOCATION_Start 8
+#define GCREG_BLOCK8_SRC_CONFIG_LOCATION_Type U01
+#define GCREG_BLOCK8_SRC_CONFIG_LOCATION_MEMORY 0x0
+#define GCREG_BLOCK8_SRC_CONFIG_LOCATION_STREAM 0x1
+
+/* Source linear/tiled address computation control. */
+#define GCREG_BLOCK8_SRC_CONFIG_TILED 7 : 7
+#define GCREG_BLOCK8_SRC_CONFIG_TILED_End 7
+#define GCREG_BLOCK8_SRC_CONFIG_TILED_Start 7
+#define GCREG_BLOCK8_SRC_CONFIG_TILED_Type U01
+#define GCREG_BLOCK8_SRC_CONFIG_TILED_DISABLED 0x0
+#define GCREG_BLOCK8_SRC_CONFIG_TILED_ENABLED 0x1
+
+/* If set to ABSOLUTE, the source coordinates are treated as absolute **
+** coordinates inside the source surface. If set to RELATIVE, the source **
+** coordinates are treated as the offsets from the destination coordinates **
+** with the source size equal to the size of the destination. */
+#define GCREG_BLOCK8_SRC_CONFIG_SRC_RELATIVE 6 : 6
+#define GCREG_BLOCK8_SRC_CONFIG_SRC_RELATIVE_End 6
+#define GCREG_BLOCK8_SRC_CONFIG_SRC_RELATIVE_Start 6
+#define GCREG_BLOCK8_SRC_CONFIG_SRC_RELATIVE_Type U01
+#define GCREG_BLOCK8_SRC_CONFIG_SRC_RELATIVE_ABSOLUTE 0x0
+#define GCREG_BLOCK8_SRC_CONFIG_SRC_RELATIVE_RELATIVE 0x1
+
+/*******************************************************************************
+** State gcregBlock8SrcOrigin
+*/
+
+/* Absolute or relative (see SRC_RELATIVE field of gcregBlock8SrcConfig
+** register) X and Y coordinates in pixels of the top left corner of the
+** source rectangle within the source surface.
+*/
+
+#define gcregBlock8SrcOriginRegAddrs 0x4AA0
+#define GCREG_BLOCK8_SRC_ORIGIN_MSB 15
+#define GCREG_BLOCK8_SRC_ORIGIN_LSB 3
+#define GCREG_BLOCK8_SRC_ORIGIN_BLK 0
+#define GCREG_BLOCK8_SRC_ORIGIN_Count 8
+#define GCREG_BLOCK8_SRC_ORIGIN_FieldMask 0xFFFFFFFF
+#define GCREG_BLOCK8_SRC_ORIGIN_ReadMask 0xFFFFFFFF
+#define GCREG_BLOCK8_SRC_ORIGIN_WriteMask 0xFFFFFFFF
+#define GCREG_BLOCK8_SRC_ORIGIN_ResetValue 0x00000000
+
+#define GCREG_BLOCK8_SRC_ORIGIN_Y 31 : 16
+#define GCREG_BLOCK8_SRC_ORIGIN_Y_End 31
+#define GCREG_BLOCK8_SRC_ORIGIN_Y_Start 16
+#define GCREG_BLOCK8_SRC_ORIGIN_Y_Type U16
+
+#define GCREG_BLOCK8_SRC_ORIGIN_X 15 : 0
+#define GCREG_BLOCK8_SRC_ORIGIN_X_End 15
+#define GCREG_BLOCK8_SRC_ORIGIN_X_Start 0
+#define GCREG_BLOCK8_SRC_ORIGIN_X_Type U16
+
+/*******************************************************************************
+** State gcregBlock8SrcSize
+*/
+
+/* Width and height of the source rectangle in pixels. If the source is
+** relative (see SRC_RELATIVE field of gcregBlock8SrcConfig register) or a
+** regular bitblt is being performed without stretching, this register is
+** ignored and the source size is assumed to be the same as the destination.
+*/
+
+#define gcregBlock8SrcSizeRegAddrs 0x4AA8
+#define GCREG_BLOCK8_SRC_SIZE_MSB 15
+#define GCREG_BLOCK8_SRC_SIZE_LSB 3
+#define GCREG_BLOCK8_SRC_SIZE_BLK 0
+#define GCREG_BLOCK8_SRC_SIZE_Count 8
+#define GCREG_BLOCK8_SRC_SIZE_FieldMask 0xFFFFFFFF
+#define GCREG_BLOCK8_SRC_SIZE_ReadMask 0xFFFFFFFF
+#define GCREG_BLOCK8_SRC_SIZE_WriteMask 0xFFFFFFFF
+#define GCREG_BLOCK8_SRC_SIZE_ResetValue 0x00000000
+
+#define GCREG_BLOCK8_SRC_SIZE_Y 31 : 16
+#define GCREG_BLOCK8_SRC_SIZE_Y_End 31
+#define GCREG_BLOCK8_SRC_SIZE_Y_Start 16
+#define GCREG_BLOCK8_SRC_SIZE_Y_Type U16
+
+#define GCREG_BLOCK8_SRC_SIZE_X 15 : 0
+#define GCREG_BLOCK8_SRC_SIZE_X_End 15
+#define GCREG_BLOCK8_SRC_SIZE_X_Start 0
+#define GCREG_BLOCK8_SRC_SIZE_X_Type U16
+
+/*******************************************************************************
+** State gcregBlock8SrcColorBg
+*/
+
+/* Select the color where source becomes transparent. It must be programmed
+** in A8R8G8B8 format.
+*/
+
+#define gcregBlock8SrcColorBgRegAddrs 0x4AB0
+#define GCREG_BLOCK8_SRC_COLOR_BG_MSB 15
+#define GCREG_BLOCK8_SRC_COLOR_BG_LSB 3
+#define GCREG_BLOCK8_SRC_COLOR_BG_BLK 0
+#define GCREG_BLOCK8_SRC_COLOR_BG_Count 8
+#define GCREG_BLOCK8_SRC_COLOR_BG_FieldMask 0xFFFFFFFF
+#define GCREG_BLOCK8_SRC_COLOR_BG_ReadMask 0xFFFFFFFF
+#define GCREG_BLOCK8_SRC_COLOR_BG_WriteMask 0xFFFFFFFF
+#define GCREG_BLOCK8_SRC_COLOR_BG_ResetValue 0x00000000
+
+#define GCREG_BLOCK8_SRC_COLOR_BG_ALPHA 31 : 24
+#define GCREG_BLOCK8_SRC_COLOR_BG_ALPHA_End 31
+#define GCREG_BLOCK8_SRC_COLOR_BG_ALPHA_Start 24
+#define GCREG_BLOCK8_SRC_COLOR_BG_ALPHA_Type U08
+
+#define GCREG_BLOCK8_SRC_COLOR_BG_RED 23 : 16
+#define GCREG_BLOCK8_SRC_COLOR_BG_RED_End 23
+#define GCREG_BLOCK8_SRC_COLOR_BG_RED_Start 16
+#define GCREG_BLOCK8_SRC_COLOR_BG_RED_Type U08
+
+#define GCREG_BLOCK8_SRC_COLOR_BG_GREEN 15 : 8
+#define GCREG_BLOCK8_SRC_COLOR_BG_GREEN_End 15
+#define GCREG_BLOCK8_SRC_COLOR_BG_GREEN_Start 8
+#define GCREG_BLOCK8_SRC_COLOR_BG_GREEN_Type U08
+
+#define GCREG_BLOCK8_SRC_COLOR_BG_BLUE 7 : 0
+#define GCREG_BLOCK8_SRC_COLOR_BG_BLUE_End 7
+#define GCREG_BLOCK8_SRC_COLOR_BG_BLUE_Start 0
+#define GCREG_BLOCK8_SRC_COLOR_BG_BLUE_Type U08
+
+/*******************************************************************************
+** State gcregBlock8Rop
+*/
+
+/* Raster operation foreground and background codes. Even though ROP is not
+** used in CLEAR, HOR_FILTER_BLT, VER_FILTER_BLT and alpha-eanbled BIT_BLTs,
+** ROP code still has to be programmed, because the engine makes the decision
+** whether source, destination and pattern are involved in the current
+** operation and the correct decision is essential for the engine to complete
+** the operation as expected.
+*/
+
+#define gcregBlock8RopRegAddrs 0x4AB8
+#define GCREG_BLOCK8_ROP_MSB 15
+#define GCREG_BLOCK8_ROP_LSB 3
+#define GCREG_BLOCK8_ROP_BLK 0
+#define GCREG_BLOCK8_ROP_Count 8
+#define GCREG_BLOCK8_ROP_FieldMask 0x0030FFFF
+#define GCREG_BLOCK8_ROP_ReadMask 0x0030FFFF
+#define GCREG_BLOCK8_ROP_WriteMask 0x0030FFFF
+#define GCREG_BLOCK8_ROP_ResetValue 0x00000000
+
+/* ROP type: ROP2, ROP3 or ROP4 */
+#define GCREG_BLOCK8_ROP_TYPE 21 : 20
+#define GCREG_BLOCK8_ROP_TYPE_End 21
+#define GCREG_BLOCK8_ROP_TYPE_Start 20
+#define GCREG_BLOCK8_ROP_TYPE_Type U02
+#define GCREG_BLOCK8_ROP_TYPE_ROP2_PATTERN 0x0
+#define GCREG_BLOCK8_ROP_TYPE_ROP2_SOURCE 0x1
+#define GCREG_BLOCK8_ROP_TYPE_ROP3 0x2
+#define GCREG_BLOCK8_ROP_TYPE_ROP4 0x3
+
+/* Background ROP code is used for transparent pixels. */
+#define GCREG_BLOCK8_ROP_ROP_BG 15 : 8
+#define GCREG_BLOCK8_ROP_ROP_BG_End 15
+#define GCREG_BLOCK8_ROP_ROP_BG_Start 8
+#define GCREG_BLOCK8_ROP_ROP_BG_Type U08
+
+/* Background ROP code is used for opaque pixels. */
+#define GCREG_BLOCK8_ROP_ROP_FG 7 : 0
+#define GCREG_BLOCK8_ROP_ROP_FG_End 7
+#define GCREG_BLOCK8_ROP_ROP_FG_Start 0
+#define GCREG_BLOCK8_ROP_ROP_FG_Type U08
+
+/*******************************************************************************
+** State gcregBlock8AlphaControl
+*/
+
+#define gcregBlock8AlphaControlRegAddrs 0x4AC0
+#define GCREG_BLOCK8_ALPHA_CONTROL_MSB 15
+#define GCREG_BLOCK8_ALPHA_CONTROL_LSB 3
+#define GCREG_BLOCK8_ALPHA_CONTROL_BLK 0
+#define GCREG_BLOCK8_ALPHA_CONTROL_Count 8
+#define GCREG_BLOCK8_ALPHA_CONTROL_FieldMask 0x00000001
+#define GCREG_BLOCK8_ALPHA_CONTROL_ReadMask 0x00000001
+#define GCREG_BLOCK8_ALPHA_CONTROL_WriteMask 0x00000001
+#define GCREG_BLOCK8_ALPHA_CONTROL_ResetValue 0x00000000
+
+#define GCREG_BLOCK8_ALPHA_CONTROL_ENABLE 0 : 0
+#define GCREG_BLOCK8_ALPHA_CONTROL_ENABLE_End 0
+#define GCREG_BLOCK8_ALPHA_CONTROL_ENABLE_Start 0
+#define GCREG_BLOCK8_ALPHA_CONTROL_ENABLE_Type U01
+#define GCREG_BLOCK8_ALPHA_CONTROL_ENABLE_OFF 0x0
+#define GCREG_BLOCK8_ALPHA_CONTROL_ENABLE_ON 0x1
+
+/*******************************************************************************
+** State gcregBlock8AlphaModes
+*/
+
+#define gcregBlock8AlphaModesRegAddrs 0x4AC8
+#define GCREG_BLOCK8_ALPHA_MODES_MSB 15
+#define GCREG_BLOCK8_ALPHA_MODES_LSB 3
+#define GCREG_BLOCK8_ALPHA_MODES_BLK 0
+#define GCREG_BLOCK8_ALPHA_MODES_Count 8
+#define GCREG_BLOCK8_ALPHA_MODES_FieldMask 0xFF003311
+#define GCREG_BLOCK8_ALPHA_MODES_ReadMask 0xFF003311
+#define GCREG_BLOCK8_ALPHA_MODES_WriteMask 0xFF003311
+#define GCREG_BLOCK8_ALPHA_MODES_ResetValue 0x00000000
+
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_ALPHA_MODE 0 : 0
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_ALPHA_MODE_End 0
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_ALPHA_MODE_Start 0
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_ALPHA_MODE_Type U01
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_ALPHA_MODE_NORMAL 0x0
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_ALPHA_MODE_INVERSED 0x1
+
+#define GCREG_BLOCK8_ALPHA_MODES_DST_ALPHA_MODE 4 : 4
+#define GCREG_BLOCK8_ALPHA_MODES_DST_ALPHA_MODE_End 4
+#define GCREG_BLOCK8_ALPHA_MODES_DST_ALPHA_MODE_Start 4
+#define GCREG_BLOCK8_ALPHA_MODES_DST_ALPHA_MODE_Type U01
+#define GCREG_BLOCK8_ALPHA_MODES_DST_ALPHA_MODE_NORMAL 0x0
+#define GCREG_BLOCK8_ALPHA_MODES_DST_ALPHA_MODE_INVERSED 0x1
+
+#define GCREG_BLOCK8_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE 9 : 8
+#define GCREG_BLOCK8_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE_End 9
+#define GCREG_BLOCK8_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE_Start 8
+#define GCREG_BLOCK8_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE_Type U02
+#define GCREG_BLOCK8_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE_NORMAL 0x0
+#define GCREG_BLOCK8_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE_GLOBAL 0x1
+#define GCREG_BLOCK8_ALPHA_MODES_GLOBAL_SRC_ALPHA_MODE_SCALED 0x2
+
+#define GCREG_BLOCK8_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE 13 : 12
+#define GCREG_BLOCK8_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE_End 13
+#define GCREG_BLOCK8_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE_Start 12
+#define GCREG_BLOCK8_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE_Type U02
+#define GCREG_BLOCK8_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE_NORMAL 0x0
+#define GCREG_BLOCK8_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE_GLOBAL 0x1
+#define GCREG_BLOCK8_ALPHA_MODES_GLOBAL_DST_ALPHA_MODE_SCALED 0x2
+
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_BLENDING_MODE 26 : 24
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_BLENDING_MODE_End 26
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_BLENDING_MODE_Start 24
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_BLENDING_MODE_Type U03
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_BLENDING_MODE_ZERO 0x0
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_BLENDING_MODE_ONE 0x1
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_BLENDING_MODE_NORMAL 0x2
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_BLENDING_MODE_INVERSED 0x3
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_BLENDING_MODE_COLOR 0x4
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_BLENDING_MODE_COLOR_INVERSED 0x5
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_BLENDING_MODE_SATURATED_ALPHA 0x6
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_BLENDING_MODE_SATURATED_DEST_ALPHA 0x7
+
+/* Src Blending factor is calculate from Src alpha. */
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_ALPHA_FACTOR 27 : 27
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_ALPHA_FACTOR_End 27
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_ALPHA_FACTOR_Start 27
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_ALPHA_FACTOR_Type U01
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_ALPHA_FACTOR_DISABLED 0x0
+#define GCREG_BLOCK8_ALPHA_MODES_SRC_ALPHA_FACTOR_ENABLED 0x1
+
+#define GCREG_BLOCK8_ALPHA_MODES_DST_BLENDING_MODE 30 : 28
+#define GCREG_BLOCK8_ALPHA_MODES_DST_BLENDING_MODE_End 30
+#define GCREG_BLOCK8_ALPHA_MODES_DST_BLENDING_MODE_Start 28
+#define GCREG_BLOCK8_ALPHA_MODES_DST_BLENDING_MODE_Type U03
+#define GCREG_BLOCK8_ALPHA_MODES_DST_BLENDING_MODE_ZERO 0x0
+#define GCREG_BLOCK8_ALPHA_MODES_DST_BLENDING_MODE_ONE 0x1
+#define GCREG_BLOCK8_ALPHA_MODES_DST_BLENDING_MODE_NORMAL 0x2
+#define GCREG_BLOCK8_ALPHA_MODES_DST_BLENDING_MODE_INVERSED 0x3
+#define GCREG_BLOCK8_ALPHA_MODES_DST_BLENDING_MODE_COLOR 0x4
+#define GCREG_BLOCK8_ALPHA_MODES_DST_BLENDING_MODE_COLOR_INVERSED 0x5
+#define GCREG_BLOCK8_ALPHA_MODES_DST_BLENDING_MODE_SATURATED_ALPHA 0x6
+#define GCREG_BLOCK8_ALPHA_MODES_DST_BLENDING_MODE_SATURATED_DEST_ALPHA 0x7
+
+/* Dst Blending factor is calculate from Dst alpha. */
+#define GCREG_BLOCK8_ALPHA_MODES_DST_ALPHA_FACTOR 31 : 31
+#define GCREG_BLOCK8_ALPHA_MODES_DST_ALPHA_FACTOR_End 31
+#define GCREG_BLOCK8_ALPHA_MODES_DST_ALPHA_FACTOR_Start 31
+#define GCREG_BLOCK8_ALPHA_MODES_DST_ALPHA_FACTOR_Type U01
+#define GCREG_BLOCK8_ALPHA_MODES_DST_ALPHA_FACTOR_DISABLED 0x0
+#define GCREG_BLOCK8_ALPHA_MODES_DST_ALPHA_FACTOR_ENABLED 0x1
+
+/*******************************************************************************
+** State gcregBlock8AddressU
+*/
+
+/* 32-bit aligned base address of the source U plane. */
+
+#define gcregBlock8AddressURegAddrs 0x4AD0
+#define GCREG_BLOCK8_UPLANE_ADDRESS_MSB 15
+#define GCREG_BLOCK8_UPLANE_ADDRESS_LSB 3
+#define GCREG_BLOCK8_UPLANE_ADDRESS_BLK 0
+#define GCREG_BLOCK8_UPLANE_ADDRESS_Count 8
+#define GCREG_BLOCK8_UPLANE_ADDRESS_FieldMask 0xFFFFFFFF
+#define GCREG_BLOCK8_UPLANE_ADDRESS_ReadMask 0xFFFFFFFC
+#define GCREG_BLOCK8_UPLANE_ADDRESS_WriteMask 0xFFFFFFFC
+#define GCREG_BLOCK8_UPLANE_ADDRESS_ResetValue 0x00000000
+
+#define GCREG_BLOCK8_UPLANE_ADDRESS_ADDRESS 31 : 0
+#define GCREG_BLOCK8_UPLANE_ADDRESS_ADDRESS_End 30
+#define GCREG_BLOCK8_UPLANE_ADDRESS_ADDRESS_Start 0
+#define GCREG_BLOCK8_UPLANE_ADDRESS_ADDRESS_Type U31
+
+/*******************************************************************************
+** State gcregBlock8StrideU
+*/
+
+/* Stride of the source U plane in bytes. */
+
+#define gcregBlock8StrideURegAddrs 0x4AD8
+#define GCREG_BLOCK8_UPLANE_STRIDE_MSB 15
+#define GCREG_BLOCK8_UPLANE_STRIDE_LSB 3
+#define GCREG_BLOCK8_UPLANE_STRIDE_BLK 0
+#define GCREG_BLOCK8_UPLANE_STRIDE_Count 8
+#define GCREG_BLOCK8_UPLANE_STRIDE_FieldMask 0x0003FFFF
+#define GCREG_BLOCK8_UPLANE_STRIDE_ReadMask 0x0003FFFC
+#define GCREG_BLOCK8_UPLANE_STRIDE_WriteMask 0x0003FFFC
+#define GCREG_BLOCK8_UPLANE_STRIDE_ResetValue 0x00000000
+
+#define GCREG_BLOCK8_UPLANE_STRIDE_STRIDE 17 : 0
+#define GCREG_BLOCK8_UPLANE_STRIDE_STRIDE_End 17
+#define GCREG_BLOCK8_UPLANE_STRIDE_STRIDE_Start 0
+#define GCREG_BLOCK8_UPLANE_STRIDE_STRIDE_Type U18
+
+/*******************************************************************************
+** State gcregBlock8AddressV
+*/
+
+/* 32-bit aligned base address of the source V plane. */
+
+#define gcregBlock8AddressVRegAddrs 0x4AE0
+#define GCREG_BLOCK8_VPLANE_ADDRESS_MSB 15
+#define GCREG_BLOCK8_VPLANE_ADDRESS_LSB 3
+#define GCREG_BLOCK8_VPLANE_ADDRESS_BLK 0
+#define GCREG_BLOCK8_VPLANE_ADDRESS_Count 8
+#define GCREG_BLOCK8_VPLANE_ADDRESS_FieldMask 0xFFFFFFFF
+#define GCREG_BLOCK8_VPLANE_ADDRESS_ReadMask 0xFFFFFFFC
+#define GCREG_BLOCK8_VPLANE_ADDRESS_WriteMask 0xFFFFFFFC
+#define GCREG_BLOCK8_VPLANE_ADDRESS_ResetValue 0x00000000
+
+#define GCREG_BLOCK8_VPLANE_ADDRESS_ADDRESS 31 : 0
+#define GCREG_BLOCK8_VPLANE_ADDRESS_ADDRESS_End 30
+#define GCREG_BLOCK8_VPLANE_ADDRESS_ADDRESS_Start 0
+#define GCREG_BLOCK8_VPLANE_ADDRESS_ADDRESS_Type U31
+
+/*******************************************************************************
+** State gcregBlock8StrideV
+*/
+
+/* Stride of the source V plane in bytes. */
+
+#define gcregBlock8StrideVRegAddrs 0x4AE8
+#define GCREG_BLOCK8_VPLANE_STRIDE_MSB 15
+#define GCREG_BLOCK8_VPLANE_STRIDE_LSB 3
+#define GCREG_BLOCK8_VPLANE_STRIDE_BLK 0
+#define GCREG_BLOCK8_VPLANE_STRIDE_Count 8
+#define GCREG_BLOCK8_VPLANE_STRIDE_FieldMask 0x0003FFFF
+#define GCREG_BLOCK8_VPLANE_STRIDE_ReadMask 0x0003FFFC
+#define GCREG_BLOCK8_VPLANE_STRIDE_WriteMask 0x0003FFFC
+#define GCREG_BLOCK8_VPLANE_STRIDE_ResetValue 0x00000000
+
+#define GCREG_BLOCK8_VPLANE_STRIDE_STRIDE 17 : 0
+#define GCREG_BLOCK8_VPLANE_STRIDE_STRIDE_End 17
+#define GCREG_BLOCK8_VPLANE_STRIDE_STRIDE_Start 0
+#define GCREG_BLOCK8_VPLANE_STRIDE_STRIDE_Type U18
+
+/*******************************************************************************
+** State gcregBlock8SrcRotationHeight
+*/
+
+/* 180/270 degree rotation configuration for the Source surface. Height field
+** specifies the height of the surface in pixels.
+*/
+
+#define gcregBlock8SrcRotationHeightRegAddrs 0x4AF0
+#define GCREG_BLOCK8_SRC_ROTATION_HEIGHT_MSB 15
+#define GCREG_BLOCK8_SRC_ROTATION_HEIGHT_LSB 3
+#define GCREG_BLOCK8_SRC_ROTATION_HEIGHT_BLK 0
+#define GCREG_BLOCK8_SRC_ROTATION_HEIGHT_Count 8
+#define GCREG_BLOCK8_SRC_ROTATION_HEIGHT_FieldMask 0x0000FFFF
+#define GCREG_BLOCK8_SRC_ROTATION_HEIGHT_ReadMask 0x0000FFFF
+#define GCREG_BLOCK8_SRC_ROTATION_HEIGHT_WriteMask 0x0000FFFF
+#define GCREG_BLOCK8_SRC_ROTATION_HEIGHT_ResetValue 0x00000000
+
+#define GCREG_BLOCK8_SRC_ROTATION_HEIGHT_HEIGHT 15 : 0
+#define GCREG_BLOCK8_SRC_ROTATION_HEIGHT_HEIGHT_End 15
+#define GCREG_BLOCK8_SRC_ROTATION_HEIGHT_HEIGHT_Start 0
+#define GCREG_BLOCK8_SRC_ROTATION_HEIGHT_HEIGHT_Type U16
+
+/*******************************************************************************
+** State gcregBlock8RotAngle
+*/
+
+/* 0/90/180/270 degree rotation configuration for the Source surface. Height
+** field specifies the height of the surface in pixels.
+*/
+
+#define gcregBlock8RotAngleRegAddrs 0x4AF8
+#define GCREG_BLOCK8_ROT_ANGLE_MSB 15
+#define GCREG_BLOCK8_ROT_ANGLE_LSB 3
+#define GCREG_BLOCK8_ROT_ANGLE_BLK 0
+#define GCREG_BLOCK8_ROT_ANGLE_Count 8
+#define GCREG_BLOCK8_ROT_ANGLE_FieldMask 0x000BB33F
+#define GCREG_BLOCK8_ROT_ANGLE_ReadMask 0x000BB33F
+#define GCREG_BLOCK8_ROT_ANGLE_WriteMask 0x000BB33F
+#define GCREG_BLOCK8_ROT_ANGLE_ResetValue 0x00000000
+
+#define GCREG_BLOCK8_ROT_ANGLE_SRC 2 : 0
+#define GCREG_BLOCK8_ROT_ANGLE_SRC_End 2
+#define GCREG_BLOCK8_ROT_ANGLE_SRC_Start 0
+#define GCREG_BLOCK8_ROT_ANGLE_SRC_Type U03
+#define GCREG_BLOCK8_ROT_ANGLE_SRC_ROT0 0x0
+#define GCREG_BLOCK8_ROT_ANGLE_SRC_FLIP_X 0x1
+#define GCREG_BLOCK8_ROT_ANGLE_SRC_FLIP_Y 0x2
+#define GCREG_BLOCK8_ROT_ANGLE_SRC_ROT90 0x4
+#define GCREG_BLOCK8_ROT_ANGLE_SRC_ROT180 0x5
+#define GCREG_BLOCK8_ROT_ANGLE_SRC_ROT270 0x6
+
+#define GCREG_BLOCK8_ROT_ANGLE_DST 5 : 3
+#define GCREG_BLOCK8_ROT_ANGLE_DST_End 5
+#define GCREG_BLOCK8_ROT_ANGLE_DST_Start 3
+#define GCREG_BLOCK8_ROT_ANGLE_DST_Type U03
+#define GCREG_BLOCK8_ROT_ANGLE_DST_ROT0 0x0
+#define GCREG_BLOCK8_ROT_ANGLE_DST_FLIP_X 0x1
+#define GCREG_BLOCK8_ROT_ANGLE_DST_FLIP_Y 0x2
+#define GCREG_BLOCK8_ROT_ANGLE_DST_ROT90 0x4
+#define GCREG_BLOCK8_ROT_ANGLE_DST_ROT180 0x5
+#define GCREG_BLOCK8_ROT_ANGLE_DST_ROT270 0x6
+
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_SRC 8 : 8
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_SRC_End 8
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_SRC_Start 8
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_SRC_Type U01
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_SRC_ENABLED 0x0
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_SRC_MASKED 0x1
+
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_DST 9 : 9
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_DST_End 9
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_DST_Start 9
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_DST_Type U01
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_DST_ENABLED 0x0
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_DST_MASKED 0x1
+
+#define GCREG_BLOCK8_ROT_ANGLE_SRC_MIRROR 13 : 12
+#define GCREG_BLOCK8_ROT_ANGLE_SRC_MIRROR_End 13
+#define GCREG_BLOCK8_ROT_ANGLE_SRC_MIRROR_Start 12
+#define GCREG_BLOCK8_ROT_ANGLE_SRC_MIRROR_Type U02
+#define GCREG_BLOCK8_ROT_ANGLE_SRC_MIRROR_NONE 0x0
+#define GCREG_BLOCK8_ROT_ANGLE_SRC_MIRROR_MIRROR_X 0x1
+#define GCREG_BLOCK8_ROT_ANGLE_SRC_MIRROR_MIRROR_Y 0x2
+#define GCREG_BLOCK8_ROT_ANGLE_SRC_MIRROR_MIRROR_XY 0x3
+
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_SRC_MIRROR 15 : 15
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_SRC_MIRROR_End 15
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_SRC_MIRROR_Start 15
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_SRC_MIRROR_Type U01
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_SRC_MIRROR_ENABLED 0x0
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_SRC_MIRROR_MASKED 0x1
+
+#define GCREG_BLOCK8_ROT_ANGLE_DST_MIRROR 17 : 16
+#define GCREG_BLOCK8_ROT_ANGLE_DST_MIRROR_End 17
+#define GCREG_BLOCK8_ROT_ANGLE_DST_MIRROR_Start 16
+#define GCREG_BLOCK8_ROT_ANGLE_DST_MIRROR_Type U02
+#define GCREG_BLOCK8_ROT_ANGLE_DST_MIRROR_NONE 0x0
+#define GCREG_BLOCK8_ROT_ANGLE_DST_MIRROR_MIRROR_X 0x1
+#define GCREG_BLOCK8_ROT_ANGLE_DST_MIRROR_MIRROR_Y 0x2
+#define GCREG_BLOCK8_ROT_ANGLE_DST_MIRROR_MIRROR_XY 0x3
+
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_DST_MIRROR 19 : 19
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_DST_MIRROR_End 19
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_DST_MIRROR_Start 19
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_DST_MIRROR_Type U01
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_DST_MIRROR_ENABLED 0x0
+#define GCREG_BLOCK8_ROT_ANGLE_MASK_DST_MIRROR_MASKED 0x1
+
+/*******************************************************************************
+** State gcregBlock8GlobalSrcColor
+*/
+
+/* Defines the global source color and alpha values. */
+
+#define gcregBlock8GlobalSrcColorRegAddrs 0x4B00
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_MSB 15
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_LSB 3
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_BLK 0
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_Count 8
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_FieldMask 0xFFFFFFFF
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_ReadMask 0xFFFFFFFF
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_WriteMask 0xFFFFFFFF
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_ResetValue 0x00000000
+
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_ALPHA 31 : 24
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_ALPHA_End 31
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_ALPHA_Start 24
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_ALPHA_Type U08
+
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_RED 23 : 16
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_RED_End 23
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_RED_Start 16
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_RED_Type U08
+
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_GREEN 15 : 8
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_GREEN_End 15
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_GREEN_Start 8
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_GREEN_Type U08
+
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_BLUE 7 : 0
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_BLUE_End 7
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_BLUE_Start 0
+#define GCREG_BLOCK8_GLOBAL_SRC_COLOR_BLUE_Type U08
+
+/*******************************************************************************
+** State gcregBlock8GlobalDestColor
+*/
+
+/* Defines the global destination color and alpha values. */
+
+#define gcregBlock8GlobalDestColorRegAddrs 0x4B08
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_MSB 15
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_LSB 3
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_BLK 0
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_Count 8
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_FieldMask 0xFFFFFFFF
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_ReadMask 0xFFFFFFFF
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_WriteMask 0xFFFFFFFF
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_ResetValue 0x00000000
+
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_ALPHA 31 : 24
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_ALPHA_End 31
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_ALPHA_Start 24
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_ALPHA_Type U08
+
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_RED 23 : 16
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_RED_End 23
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_RED_Start 16
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_RED_Type U08
+
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_GREEN 15 : 8
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_GREEN_End 15
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_GREEN_Start 8
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_GREEN_Type U08
+
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_BLUE 7 : 0
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_BLUE_End 7
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_BLUE_Start 0
+#define GCREG_BLOCK8_GLOBAL_DEST_COLOR_BLUE_Type U08
+
+/*******************************************************************************
+** State gcregBlock8ColorMultiplyModes
+*/
+
+/* Color modes to multiply Source or Destination pixel color by alpha
+** channel. Alpha can be from global color source or current pixel.
+*/
+
+#define gcregBlock8ColorMultiplyModesRegAddrs 0x4B10
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_MSB 15
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_LSB 3
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_BLK 0
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_Count 8
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_FieldMask 0x00100311
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_ReadMask 0x00100311
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_WriteMask 0x00100311
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_ResetValue 0x00000000
+
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY 0 : 0
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_End 0
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_Start 0
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_Type U01
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_DISABLE 0x0
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_ENABLE 0x1
+
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_DST_PREMULTIPLY 4 : 4
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_DST_PREMULTIPLY_End 4
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_DST_PREMULTIPLY_Start 4
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_DST_PREMULTIPLY_Type U01
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_DST_PREMULTIPLY_DISABLE 0x0
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_DST_PREMULTIPLY_ENABLE 0x1
+
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY 9 : 8
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_End 9
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_Start 8
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_Type U02
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_DISABLE 0x0
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_ALPHA 0x1
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_COLOR 0x2
+
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY 20 : 20
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_End 20
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_Start 20
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_Type U01
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_DISABLE 0x0
+#define GCREG_BLOCK8_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_ENABLE 0x1
+
+/*******************************************************************************
+** State gcregBlock8Transparency
+*/
+
+#define gcregBlock8TransparencyRegAddrs 0x4B18
+#define GCREG_BLOCK8_TRANSPARENCY_MSB 15
+#define GCREG_BLOCK8_TRANSPARENCY_LSB 3
+#define GCREG_BLOCK8_TRANSPARENCY_BLK 0
+#define GCREG_BLOCK8_TRANSPARENCY_Count 8
+#define GCREG_BLOCK8_TRANSPARENCY_FieldMask 0xB3331333
+#define GCREG_BLOCK8_TRANSPARENCY_ReadMask 0xB3331333
+#define GCREG_BLOCK8_TRANSPARENCY_WriteMask 0xB3331333
+#define GCREG_BLOCK8_TRANSPARENCY_ResetValue 0x00000000
+
+/* Source transparency mode. */
+#define GCREG_BLOCK8_TRANSPARENCY_SOURCE 1 : 0
+#define GCREG_BLOCK8_TRANSPARENCY_SOURCE_End 1
+#define GCREG_BLOCK8_TRANSPARENCY_SOURCE_Start 0
+#define GCREG_BLOCK8_TRANSPARENCY_SOURCE_Type U02
+#define GCREG_BLOCK8_TRANSPARENCY_SOURCE_OPAQUE 0x0
+#define GCREG_BLOCK8_TRANSPARENCY_SOURCE_MASK 0x1
+#define GCREG_BLOCK8_TRANSPARENCY_SOURCE_KEY 0x2
+
+/* Pattern transparency mode. KEY transparency mode is reserved. */
+#define GCREG_BLOCK8_TRANSPARENCY_PATTERN 5 : 4
+#define GCREG_BLOCK8_TRANSPARENCY_PATTERN_End 5
+#define GCREG_BLOCK8_TRANSPARENCY_PATTERN_Start 4
+#define GCREG_BLOCK8_TRANSPARENCY_PATTERN_Type U02
+#define GCREG_BLOCK8_TRANSPARENCY_PATTERN_OPAQUE 0x0
+#define GCREG_BLOCK8_TRANSPARENCY_PATTERN_MASK 0x1
+#define GCREG_BLOCK8_TRANSPARENCY_PATTERN_KEY 0x2
+
+/* Destination transparency mode. MASK transparency mode is reserved. */
+#define GCREG_BLOCK8_TRANSPARENCY_DESTINATION 9 : 8
+#define GCREG_BLOCK8_TRANSPARENCY_DESTINATION_End 9
+#define GCREG_BLOCK8_TRANSPARENCY_DESTINATION_Start 8
+#define GCREG_BLOCK8_TRANSPARENCY_DESTINATION_Type U02
+#define GCREG_BLOCK8_TRANSPARENCY_DESTINATION_OPAQUE 0x0
+#define GCREG_BLOCK8_TRANSPARENCY_DESTINATION_MASK 0x1
+#define GCREG_BLOCK8_TRANSPARENCY_DESTINATION_KEY 0x2
+
+/* Mask field for Source/Pattern/Destination fields. */
+#define GCREG_BLOCK8_TRANSPARENCY_MASK_TRANSPARENCY 12 : 12
+#define GCREG_BLOCK8_TRANSPARENCY_MASK_TRANSPARENCY_End 12
+#define GCREG_BLOCK8_TRANSPARENCY_MASK_TRANSPARENCY_Start 12
+#define GCREG_BLOCK8_TRANSPARENCY_MASK_TRANSPARENCY_Type U01
+#define GCREG_BLOCK8_TRANSPARENCY_MASK_TRANSPARENCY_ENABLED 0x0
+#define GCREG_BLOCK8_TRANSPARENCY_MASK_TRANSPARENCY_MASKED 0x1
+
+/* Source usage override. */
+#define GCREG_BLOCK8_TRANSPARENCY_USE_SRC_OVERRIDE 17 : 16
+#define GCREG_BLOCK8_TRANSPARENCY_USE_SRC_OVERRIDE_End 17
+#define GCREG_BLOCK8_TRANSPARENCY_USE_SRC_OVERRIDE_Start 16
+#define GCREG_BLOCK8_TRANSPARENCY_USE_SRC_OVERRIDE_Type U02
+#define GCREG_BLOCK8_TRANSPARENCY_USE_SRC_OVERRIDE_DEFAULT 0x0
+#define GCREG_BLOCK8_TRANSPARENCY_USE_SRC_OVERRIDE_USE_ENABLE 0x1
+#define GCREG_BLOCK8_TRANSPARENCY_USE_SRC_OVERRIDE_USE_DISABLE 0x2
+
+/* Pattern usage override. */
+#define GCREG_BLOCK8_TRANSPARENCY_USE_PAT_OVERRIDE 21 : 20
+#define GCREG_BLOCK8_TRANSPARENCY_USE_PAT_OVERRIDE_End 21
+#define GCREG_BLOCK8_TRANSPARENCY_USE_PAT_OVERRIDE_Start 20
+#define GCREG_BLOCK8_TRANSPARENCY_USE_PAT_OVERRIDE_Type U02
+#define GCREG_BLOCK8_TRANSPARENCY_USE_PAT_OVERRIDE_DEFAULT 0x0
+#define GCREG_BLOCK8_TRANSPARENCY_USE_PAT_OVERRIDE_USE_ENABLE 0x1
+#define GCREG_BLOCK8_TRANSPARENCY_USE_PAT_OVERRIDE_USE_DISABLE 0x2
+
+/* Destination usage override. */
+#define GCREG_BLOCK8_TRANSPARENCY_USE_DST_OVERRIDE 25 : 24
+#define GCREG_BLOCK8_TRANSPARENCY_USE_DST_OVERRIDE_End 25
+#define GCREG_BLOCK8_TRANSPARENCY_USE_DST_OVERRIDE_Start 24
+#define GCREG_BLOCK8_TRANSPARENCY_USE_DST_OVERRIDE_Type U02
+#define GCREG_BLOCK8_TRANSPARENCY_USE_DST_OVERRIDE_DEFAULT 0x0
+#define GCREG_BLOCK8_TRANSPARENCY_USE_DST_OVERRIDE_USE_ENABLE 0x1
+#define GCREG_BLOCK8_TRANSPARENCY_USE_DST_OVERRIDE_USE_DISABLE 0x2
+
+/* 2D resource usage override mask field. */
+#define GCREG_BLOCK8_TRANSPARENCY_MASK_RESOURCE_OVERRIDE 28 : 28
+#define GCREG_BLOCK8_TRANSPARENCY_MASK_RESOURCE_OVERRIDE_End 28
+#define GCREG_BLOCK8_TRANSPARENCY_MASK_RESOURCE_OVERRIDE_Start 28
+#define GCREG_BLOCK8_TRANSPARENCY_MASK_RESOURCE_OVERRIDE_Type U01
+#define GCREG_BLOCK8_TRANSPARENCY_MASK_RESOURCE_OVERRIDE_ENABLED 0x0
+#define GCREG_BLOCK8_TRANSPARENCY_MASK_RESOURCE_OVERRIDE_MASKED 0x1
+
+/* DFB Color Key. */
+#define GCREG_BLOCK8_TRANSPARENCY_DFB_COLOR_KEY 29 : 29
+#define GCREG_BLOCK8_TRANSPARENCY_DFB_COLOR_KEY_End 29
+#define GCREG_BLOCK8_TRANSPARENCY_DFB_COLOR_KEY_Start 29
+#define GCREG_BLOCK8_TRANSPARENCY_DFB_COLOR_KEY_Type U01
+#define GCREG_BLOCK8_TRANSPARENCY_DFB_COLOR_KEY_DISABLED 0x0
+#define GCREG_BLOCK8_TRANSPARENCY_DFB_COLOR_KEY_ENABLED 0x1
+
+#define GCREG_BLOCK8_TRANSPARENCY_MASK_DFB_COLOR_KEY 31 : 31
+#define GCREG_BLOCK8_TRANSPARENCY_MASK_DFB_COLOR_KEY_End 31
+#define GCREG_BLOCK8_TRANSPARENCY_MASK_DFB_COLOR_KEY_Start 31
+#define GCREG_BLOCK8_TRANSPARENCY_MASK_DFB_COLOR_KEY_Type U01
+#define GCREG_BLOCK8_TRANSPARENCY_MASK_DFB_COLOR_KEY_ENABLED 0x0
+#define GCREG_BLOCK8_TRANSPARENCY_MASK_DFB_COLOR_KEY_MASKED 0x1
+
+/*******************************************************************************
+** State gcregBlock8Control
+*/
+
+/* General purpose control register. */
+
+#define gcregBlock8PEControlRegAddrs 0x4B20
+#define GCREG_BLOCK8_PE_CONTROL_MSB 15
+#define GCREG_BLOCK8_PE_CONTROL_LSB 3
+#define GCREG_BLOCK8_PE_CONTROL_BLK 0
+#define GCREG_BLOCK8_PE_CONTROL_Count 8
+#define GCREG_BLOCK8_PE_CONTROL_FieldMask 0x00000999
+#define GCREG_BLOCK8_PE_CONTROL_ReadMask 0x00000999
+#define GCREG_BLOCK8_PE_CONTROL_WriteMask 0x00000999
+#define GCREG_BLOCK8_PE_CONTROL_ResetValue 0x00000000
+
+#define GCREG_BLOCK8_PE_CONTROL_YUV 0 : 0
+#define GCREG_BLOCK8_PE_CONTROL_YUV_End 0
+#define GCREG_BLOCK8_PE_CONTROL_YUV_Start 0
+#define GCREG_BLOCK8_PE_CONTROL_YUV_Type U01
+#define GCREG_BLOCK8_PE_CONTROL_YUV_601 0x0
+#define GCREG_BLOCK8_PE_CONTROL_YUV_709 0x1
+
+#define GCREG_BLOCK8_PE_CONTROL_MASK_YUV 3 : 3
+#define GCREG_BLOCK8_PE_CONTROL_MASK_YUV_End 3
+#define GCREG_BLOCK8_PE_CONTROL_MASK_YUV_Start 3
+#define GCREG_BLOCK8_PE_CONTROL_MASK_YUV_Type U01
+#define GCREG_BLOCK8_PE_CONTROL_MASK_YUV_ENABLED 0x0
+#define GCREG_BLOCK8_PE_CONTROL_MASK_YUV_MASKED 0x1
+
+#define GCREG_BLOCK8_PE_CONTROL_UV_SWIZZLE 4 : 4
+#define GCREG_BLOCK8_PE_CONTROL_UV_SWIZZLE_End 4
+#define GCREG_BLOCK8_PE_CONTROL_UV_SWIZZLE_Start 4
+#define GCREG_BLOCK8_PE_CONTROL_UV_SWIZZLE_Type U01
+#define GCREG_BLOCK8_PE_CONTROL_UV_SWIZZLE_UV 0x0
+#define GCREG_BLOCK8_PE_CONTROL_UV_SWIZZLE_VU 0x1
+
+#define GCREG_BLOCK8_PE_CONTROL_MASK_UV_SWIZZLE 7 : 7
+#define GCREG_BLOCK8_PE_CONTROL_MASK_UV_SWIZZLE_End 7
+#define GCREG_BLOCK8_PE_CONTROL_MASK_UV_SWIZZLE_Start 7
+#define GCREG_BLOCK8_PE_CONTROL_MASK_UV_SWIZZLE_Type U01
+#define GCREG_BLOCK8_PE_CONTROL_MASK_UV_SWIZZLE_ENABLED 0x0
+#define GCREG_BLOCK8_PE_CONTROL_MASK_UV_SWIZZLE_MASKED 0x1
+
+/* YUV to RGB convert enable */
+#define GCREG_BLOCK8_PE_CONTROL_YUVRGB 8 : 8
+#define GCREG_BLOCK8_PE_CONTROL_YUVRGB_End 8
+#define GCREG_BLOCK8_PE_CONTROL_YUVRGB_Start 8
+#define GCREG_BLOCK8_PE_CONTROL_YUVRGB_Type U01
+#define GCREG_BLOCK8_PE_CONTROL_YUVRGB_DISABLED 0x0
+#define GCREG_BLOCK8_PE_CONTROL_YUVRGB_ENABLED 0x1
+
+#define GCREG_BLOCK8_PE_CONTROL_MASK_YUVRGB 11 : 11
+#define GCREG_BLOCK8_PE_CONTROL_MASK_YUVRGB_End 11
+#define GCREG_BLOCK8_PE_CONTROL_MASK_YUVRGB_Start 11
+#define GCREG_BLOCK8_PE_CONTROL_MASK_YUVRGB_Type U01
+#define GCREG_BLOCK8_PE_CONTROL_MASK_YUVRGB_ENABLED 0x0
+#define GCREG_BLOCK8_PE_CONTROL_MASK_YUVRGB_MASKED 0x1
+
+/*******************************************************************************
+** State gcregBlock8SrcColorKeyHigh
+*/
+
+/* Defines the source transparency color in source format. */
+
+#define gcregBlock8SrcColorKeyHighRegAddrs 0x4B28
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_MSB 15
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_LSB 3
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_BLK 0
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_Count 8
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_FieldMask 0xFFFFFFFF
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_ReadMask 0xFFFFFFFF
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_WriteMask 0xFFFFFFFF
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_ResetValue 0x00000000
+
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_ALPHA 31 : 24
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_ALPHA_End 31
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_ALPHA_Start 24
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_ALPHA_Type U08
+
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_RED 23 : 16
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_RED_End 23
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_RED_Start 16
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_RED_Type U08
+
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_GREEN 15 : 8
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_GREEN_End 15
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_GREEN_Start 8
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_GREEN_Type U08
+
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_BLUE 7 : 0
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_BLUE_End 7
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_BLUE_Start 0
+#define GCREG_BLOCK8_SRC_COLOR_KEY_HIGH_BLUE_Type U08
+
+/*******************************************************************************
+** State gcregBlock8SrcExConfig
+*/
+
+#define gcregBlock8SrcExConfigRegAddrs 0x4B30
+#define GCREG_BLOCK8_SRC_EX_CONFIG_MSB 15
+#define GCREG_BLOCK8_SRC_EX_CONFIG_LSB 3
+#define GCREG_BLOCK8_SRC_EX_CONFIG_BLK 0
+#define GCREG_BLOCK8_SRC_EX_CONFIG_Count 8
+#define GCREG_BLOCK8_SRC_EX_CONFIG_FieldMask 0x00000109
+#define GCREG_BLOCK8_SRC_EX_CONFIG_ReadMask 0x00000109
+#define GCREG_BLOCK8_SRC_EX_CONFIG_WriteMask 0x00000109
+#define GCREG_BLOCK8_SRC_EX_CONFIG_ResetValue 0x00000000
+
+/* Source multi tiled address computation control. */
+#define GCREG_BLOCK8_SRC_EX_CONFIG_MULTI_TILED 0 : 0
+#define GCREG_BLOCK8_SRC_EX_CONFIG_MULTI_TILED_End 0
+#define GCREG_BLOCK8_SRC_EX_CONFIG_MULTI_TILED_Start 0
+#define GCREG_BLOCK8_SRC_EX_CONFIG_MULTI_TILED_Type U01
+#define GCREG_BLOCK8_SRC_EX_CONFIG_MULTI_TILED_DISABLED 0x0
+#define GCREG_BLOCK8_SRC_EX_CONFIG_MULTI_TILED_ENABLED 0x1
+
+/* Source super tiled address computation control. */
+#define GCREG_BLOCK8_SRC_EX_CONFIG_SUPER_TILED 3 : 3
+#define GCREG_BLOCK8_SRC_EX_CONFIG_SUPER_TILED_End 3
+#define GCREG_BLOCK8_SRC_EX_CONFIG_SUPER_TILED_Start 3
+#define GCREG_BLOCK8_SRC_EX_CONFIG_SUPER_TILED_Type U01
+#define GCREG_BLOCK8_SRC_EX_CONFIG_SUPER_TILED_DISABLED 0x0
+#define GCREG_BLOCK8_SRC_EX_CONFIG_SUPER_TILED_ENABLED 0x1
+
+/* Source super tiled address computation control. */
+#define GCREG_BLOCK8_SRC_EX_CONFIG_MINOR_TILED 8 : 8
+#define GCREG_BLOCK8_SRC_EX_CONFIG_MINOR_TILED_End 8
+#define GCREG_BLOCK8_SRC_EX_CONFIG_MINOR_TILED_Start 8
+#define GCREG_BLOCK8_SRC_EX_CONFIG_MINOR_TILED_Type U01
+#define GCREG_BLOCK8_SRC_EX_CONFIG_MINOR_TILED_DISABLED 0x0
+#define GCREG_BLOCK8_SRC_EX_CONFIG_MINOR_TILED_ENABLED 0x1
+
+/* Source CacheMode. */
+#define GCREG_BLOCK8_SRC_EX_CONFIG_CACHE_MODE 12 : 12
+#define GCREG_BLOCK8_SRC_EX_CONFIG_CACHE_MODE_End 12
+#define GCREG_BLOCK8_SRC_EX_CONFIG_CACHE_MODE_Start 12
+#define GCREG_BLOCK8_SRC_EX_CONFIG_CACHE_MODE_Type U01
+#define GCREG_BLOCK8_SRC_EX_CONFIG_CACHE_MODE_DISABLED 0x0
+#define GCREG_BLOCK8_SRC_EX_CONFIG_CACHE_MODE_ENABLED 0x1
+
+/*******************************************************************************
+** State gcregBlock8SrcExAddress
+*/
+
+/* 32-bit aligned base address of the source extra surface. */
+
+#define gcregBlock8SrcExAddressRegAddrs 0x4B38
+#define GCREG_BLOCK8_SRC_EX_ADDRESS_MSB 15
+#define GCREG_BLOCK8_SRC_EX_ADDRESS_LSB 3
+#define GCREG_BLOCK8_SRC_EX_ADDRESS_BLK 0
+#define GCREG_BLOCK8_SRC_EX_ADDRESS_Count 8
+#define GCREG_BLOCK8_SRC_EX_ADDRESS_FieldMask 0xFFFFFFFF
+#define GCREG_BLOCK8_SRC_EX_ADDRESS_ReadMask 0xFFFFFFFC
+#define GCREG_BLOCK8_SRC_EX_ADDRESS_WriteMask 0xFFFFFFFC
+#define GCREG_BLOCK8_SRC_EX_ADDRESS_ResetValue 0x00000000
+
+#define GCREG_BLOCK8_SRC_EX_ADDRESS_ADDRESS 31 : 0
+#define GCREG_BLOCK8_SRC_EX_ADDRESS_ADDRESS_End 30
+#define GCREG_BLOCK8_SRC_EX_ADDRESS_ADDRESS_Start 0
+#define GCREG_BLOCK8_SRC_EX_ADDRESS_ADDRESS_Type U31
+
+/*******************************************************************************
+** Generic defines
+*/
+
+#define GCREG_FORMAT_SUB_SAMPLE_MODE_YUV_MODE422 0x0
+#define GCREG_FORMAT_SUB_SAMPLE_MODE_YUV_MODE420 0x1
+
+#define GCREG_DE_SWIZZLE_ARGB 0x0
+#define GCREG_DE_SWIZZLE_RGBA 0x1
+#define GCREG_DE_SWIZZLE_ABGR 0x2
+#define GCREG_DE_SWIZZLE_BGRA 0x3
+
+#define GCREG_DE_FORMAT_X4R4G4B4 0x00
+#define GCREG_DE_FORMAT_A4R4G4B4 0x01
+#define GCREG_DE_FORMAT_X1R5G5B5 0x02
+#define GCREG_DE_FORMAT_A1R5G5B5 0x03
+#define GCREG_DE_FORMAT_R5G6B5 0x04
+#define GCREG_DE_FORMAT_X8R8G8B8 0x05
+#define GCREG_DE_FORMAT_A8R8G8B8 0x06
+#define GCREG_DE_FORMAT_YUY2 0x07
+#define GCREG_DE_FORMAT_UYVY 0x08
+#define GCREG_DE_FORMAT_INDEX8 0x09
+#define GCREG_DE_FORMAT_MONOCHROME 0x0A
+#define GCREG_DE_FORMAT_YV12 0x0F
+#define GCREG_DE_FORMAT_A8 0x10
+#define GCREG_DE_FORMAT_NV12 0x11
+#define GCREG_DE_FORMAT_NV16 0x12
+#define GCREG_DE_FORMAT_RG16 0x13
+
+/* ~~~~~~~~~~~~~ */
+
+#define GCREG_ALPHA_MODE_NORMAL 0x0
+#define GCREG_ALPHA_MODE_INVERSED 0x1
+
+#define GCREG_GLOBAL_ALPHA_MODE_NORMAL 0x0
+#define GCREG_GLOBAL_ALPHA_MODE_GLOBAL 0x1
+#define GCREG_GLOBAL_ALPHA_MODE_SCALED 0x2
+
+#define GCREG_COLOR_MODE_NORMAL 0x0
+#define GCREG_COLOR_MODE_MULTIPLY 0x1
+
+#define GCREG_BLENDING_MODE_ZERO 0x0
+#define GCREG_BLENDING_MODE_ONE 0x1
+#define GCREG_BLENDING_MODE_NORMAL 0x2
+#define GCREG_BLENDING_MODE_INVERSED 0x3
+#define GCREG_BLENDING_MODE_COLOR 0x4
+#define GCREG_BLENDING_MODE_COLOR_INVERSED 0x5
+#define GCREG_BLENDING_MODE_SATURATED_ALPHA 0x6
+#define GCREG_BLENDING_MODE_SATURATED_DEST_ALPHA 0x7
+
+/* ~~~~~~~~~~~~~ */
+
+#define GCREG_FACTOR_INVERSE_DISABLE 0x0
+#define GCREG_FACTOR_INVERSE_ENABLE 0x1
+
+/* ~~~~~~~~~~~~~ */
+
+#define GCREG_RESOURCE_USAGE_OVERRIDE_DEFAULT 0x0
+#define GCREG_RESOURCE_USAGE_OVERRIDE_USE_ENABLE 0x1
+#define GCREG_RESOURCE_USAGE_OVERRIDE_USE_DISABLE 0x2
+
+/*******************************************************************************
+** Modular operations: pipesel
+*/
+
+static const struct gccmdldstate gcmopipesel_pipesel_ldst =
+ GCLDSTATE(gcregPipeSelectRegAddrs, 1);
+
+struct gcmopipesel {
+ /* gcregPipeSelectRegAddrs */
+ struct gccmdldstate pipesel_ldst;
+
+ /* gcregPipeSelectRegAddrs */
+ union {
+ struct gcregpipeselect reg;
+ unsigned int raw;
+ } pipesel;
+};
+
+/*******************************************************************************
+** Modular operations: signal
+*/
+
+static const struct gccmdldstate gcmosignal_signal_ldst =
+ GCLDSTATE(gcregEventRegAddrs, 1);
+
+struct gcmosignal {
+ /* gcregEventRegAddrs */
+ struct gccmdldstate signal_ldst;
+
+ /* gcregEventRegAddrs */
+ union {
+ struct gcregevent reg;
+ unsigned int raw;
+ } signal;
+};
+
+/*******************************************************************************
+** Modular operations: flush
+*/
+
+static const struct gccmdldstate gcmoflush_flush_ldst =
+ GCLDSTATE(gcregFlushRegAddrs, 1);
+
+struct gcmoflush {
+ /* gcregFlushRegAddrs */
+ struct gccmdldstate flush_ldst;
+
+ /* gcregFlushRegAddrs */
+ union {
+ struct gcregflush reg;
+ unsigned int raw;
+ } flush;
+};
+
+/*******************************************************************************
+** Modular operations: semaphore
+*/
+
+static const struct gccmdldstate gcmosema_sema_ldst =
+ GCLDSTATE(gcregSemaphoreRegAddrs, 1);
+
+struct gcmosema {
+ /* gcregSemaphoreRegAddrs */
+ struct gccmdldstate sema_ldst;
+
+ /* gcregSemaphoreRegAddrs */
+ union {
+ struct gcregsemaphore reg;
+ unsigned int raw;
+ } sema;
+};
+
+/*******************************************************************************
+** Modular operations: mmuinit
+*/
+
+struct gcmoterminator {
+ union {
+ struct gcmosignal done;
+ struct gccmdnop nop;
+ } u1;
+
+ union {
+ struct gccmdwait wait;
+ struct gccmdlink linknext;
+ struct gccmdend end;
+ } u2;
+
+ union {
+ struct gccmdlink linkwait;
+ struct gccmdnop nop;
+ } u3;
+};
+
+/*******************************************************************************
+** Modular operations: mmuinit
+*/
+
+static const struct gccmdldstate gcmommuinit_safe_ldst =
+ GCLDSTATE(gcregMMUSafeAddressRegAddrs, 2);
+
+struct gcmommuinit {
+ /* gcregMMUSafeAddressRegAddrs */
+ struct gccmdldstate safe_ldst;
+
+ /* gcregMMUSafeAddressRegAddrs */
+ unsigned int safe;
+
+ /* gcregMMUConfigurationRegAddrs */
+ unsigned int mtlb;
+
+ /* Alignment filler. */
+ unsigned int _filler;
+};
+
+/*******************************************************************************
+** Modular operations: mmumaster
+*/
+
+static const struct gccmdldstate gcmommumaster_master_ldst =
+ GCLDSTATE(gcregMMUConfigurationRegAddrs, 1);
+
+struct gcmommumaster {
+ /* gcregMMUConfigurationRegAddrs */
+ struct gccmdldstate master_ldst;
+
+ /* gcregMMUConfigurationRegAddrs */
+ unsigned int master;
+};
+
+/*******************************************************************************
+** Modular operations: mmuflush
+*/
+
+static const struct gccmdldstate gcmommuflush_mmuflush_ldst =
+ GCLDSTATE(gcregMMUConfigurationRegAddrs, 1);
+
+struct gcmommuflush {
+ /* PE cache flush. */
+ struct gcmoflush peflush;
+
+ /* Semaphore/stall after PE flush. */
+ struct gcmosema peflushsema;
+ struct gccmdstall peflushstall;
+
+ /* Link to flush FE FIFO. */
+ struct gccmdlink feflush;
+
+ /* MMU flush. */
+ struct gccmdldstate mmuflush_ldst;
+
+ /* gcregMMUConfigurationRegAddrs */
+ union {
+ struct gcregmmuconfiguration reg;
+ unsigned int raw;
+ } mmuflush;
+
+ /* Semaphore/stall after MMU flush. */
+ struct gcmosema mmuflushsema;
+ struct gccmdstall mmuflushstall;
+
+ /* Link to the user buffer. */
+ struct gccmdlink link;
+};
+
+/*******************************************************************************
+** Modular operations: dst
+*/
+
+static const struct gccmdldstate gcmodst_config_ldst =
+ GCLDSTATE(gcregDestAddressRegAddrs, 3);
+
+static const struct gccmdldstate gcmodst_rotationheight_ldst =
+ GCLDSTATE(gcregDstRotationHeightRegAddrs, 1);
+
+static const struct gccmdldstate gcmodst_clip_ldst =
+ GCLDSTATE(gcregClipTopLeftRegAddrs, 2);
+
+struct gcmodst {
+ /* Configuration block. */
+ struct gccmdldstate config_ldst;
+
+ /* gcregDestAddressRegAddrs */
+ unsigned int address;
+
+ /* gcregDestStrideRegAddrs */
+ unsigned int stride;
+
+ /* gcregDestRotationConfigRegAddrs */
+ union {
+ struct gcregdstrotationconfig reg;
+ unsigned int raw;
+ } rotation;
+
+ /* gcregDstRotationHeightRegAddrs */
+ struct gccmdldstate rotationheight_ldst;
+
+ /* gcregDstRotationHeightRegAddrs */
+ union {
+ struct gcregdstrotationheight reg;
+ unsigned int raw;
+ } rotationheight;
+
+ /* Clipping block. */
+ struct gccmdldstate clip_ldst;
+
+ /* gcregClipTopLeftRegAddrs */
+ union {
+ struct gcregcliplt reg;
+ unsigned int raw;
+ } cliplt;
+
+ /* gcregClipBottomRight */
+ union {
+ struct gcregcliprb reg;
+ unsigned int raw;
+ } cliprb;
+
+ /* Alignment filler. */
+ unsigned int _filler;
+};
+
+/*******************************************************************************
+** Modular operations: alphaoff
+*/
+
+static const struct gccmdldstate gcmoalphaoff_control_ldst[4] = {
+ GCLDSTATE(gcregAlphaControlRegAddrs, 1),
+ GCLDSTATE(gcregBlock4AlphaControlRegAddrs + 1, 1),
+ GCLDSTATE(gcregBlock4AlphaControlRegAddrs + 2, 1),
+ GCLDSTATE(gcregBlock4AlphaControlRegAddrs + 3, 1),
+};
+
+struct gcmoalphaoff {
+ /* gcregAlphaControlRegAddrs */
+ struct gccmdldstate control_ldst;
+
+ /* gcregAlphaControlRegAddrs */
+ union {
+ struct gcregalphacontrol reg;
+ unsigned int raw;
+ } control;
+};
+
+/*******************************************************************************
+** Modular operations: alpha
+*/
+
+static const struct gccmdldstate gcmoalpha_config_ldst =
+ GCLDSTATE(gcregAlphaControlRegAddrs, 2);
+
+struct gcmoalpha {
+ /* Alpha control block. */
+ struct gccmdldstate config_ldst;
+
+ /* gcregAlphaControlRegAddrs */
+ union {
+ struct gcregalphacontrol reg;
+ unsigned int raw;
+ } control;
+
+ /* gcregAlphaModesRegAddrs */
+ union {
+ struct gcregalphamodes reg;
+ unsigned int raw;
+ } mode;
+
+ /* Alignment filler. */
+ unsigned int _filler;
+};
+
+static const struct gccmdldstate gcmoxsrcalpha_control_ldst[4] = {
+ GCLDSTATE(gcregAlphaControlRegAddrs, 1),
+ GCLDSTATE(gcregBlock4AlphaControlRegAddrs + 1, 1),
+ GCLDSTATE(gcregBlock4AlphaControlRegAddrs + 2, 1),
+ GCLDSTATE(gcregBlock4AlphaControlRegAddrs + 3, 1),
+};
+
+static const struct gccmdldstate gcmoxsrcalpha_mode_ldst[4] = {
+ GCLDSTATE(gcregAlphaModesRegAddrs, 1),
+ GCLDSTATE(gcregBlock4AlphaModesRegAddrs + 1, 1),
+ GCLDSTATE(gcregBlock4AlphaModesRegAddrs + 2, 1),
+ GCLDSTATE(gcregBlock4AlphaModesRegAddrs + 3, 1),
+};
+
+struct gcmoxsrcalpha {
+ /* gcregBlock4AlphaControlRegAddrs */
+ struct gccmdldstate control_ldst;
+
+ /* gcregBlock4AlphaControlRegAddrs */
+ union {
+ struct gcregalphacontrol reg;
+ unsigned int raw;
+ } control;
+
+ /* gcregBlock4AlphaModesRegAddrs */
+ struct gccmdldstate mode_ldst;
+
+ /* gcregBlock4AlphaModesRegAddrs */
+ union {
+ struct gcregalphamodes reg;
+ unsigned int raw;
+ } mode;
+};
+
+/*******************************************************************************
+** Modular operations: alphaglobal
+*/
+
+static const struct gccmdldstate gcmoglobal_color_ldst =
+ GCLDSTATE(gcregGlobalSrcColorRegAddrs, 2);
+
+struct gcmoglobal {
+ /* Global color block. */
+ struct gccmdldstate color_ldst;
+
+ /* gcregGlobalSrcColorRegAddrs */
+ union {
+ struct gcregglobalsrccolor reg;
+ unsigned int raw;
+ } srcglobal;
+
+ /* gcregGlobalDestColorRegAddrs */
+ union {
+ struct gcregglobaldstcolor reg;
+ unsigned int raw;
+ } dstglobal;
+
+ /* Alignment filler. */
+ unsigned int _filler;
+};
+
+static const struct gccmdldstate gcmoxsrcglobal_srcglobal_ldst[4] = {
+ GCLDSTATE(gcregGlobalSrcColorRegAddrs, 1),
+ GCLDSTATE(gcregBlock4GlobalSrcColorRegAddrs + 1, 1),
+ GCLDSTATE(gcregBlock4GlobalSrcColorRegAddrs + 2, 1),
+ GCLDSTATE(gcregBlock4GlobalSrcColorRegAddrs + 3, 1),
+};
+
+static const struct gccmdldstate gcmoxsrcglobal_dstglobal_ldst[4] = {
+ GCLDSTATE(gcregGlobalDestColorRegAddrs, 1),
+ GCLDSTATE(gcregBlock4GlobalDestColorRegAddrs + 1, 1),
+ GCLDSTATE(gcregBlock4GlobalDestColorRegAddrs + 2, 1),
+ GCLDSTATE(gcregBlock4GlobalDestColorRegAddrs + 3, 1),
+};
+
+struct gcmoxsrcglobal {
+ /* gcregBlock4GlobalSrcColorRegAddrs */
+ struct gccmdldstate srcglobal_ldst;
+
+ /* gcregBlock4GlobalSrcColorRegAddrs */
+ union {
+ struct gcregglobalsrccolor reg;
+ unsigned int raw;
+ } srcglobal;
+
+ /* gcregBlock4GlobalDestColorRegAddrs */
+ struct gccmdldstate dstglobal_ldst;
+
+ /* gcregBlock4GlobalDestColorRegAddrs */
+ union {
+ struct gcregglobaldstcolor reg;
+ unsigned int raw;
+ } dstglobal;
+};
+
+/*******************************************************************************
+** Modular operations: yuv
+*/
+
+static const struct gccmdldstate gcmoyuv_pectrl_ldst =
+ GCLDSTATE(gcregPEControlRegAddrs, 1);
+
+static const struct gccmdldstate gcmoyuv2_plane_ldst =
+ GCLDSTATE(gcregUPlaneAddressRegAddrs, 2);
+
+static const struct gccmdldstate gcmoyuv3_plane_ldst =
+ GCLDSTATE(gcregUPlaneAddressRegAddrs, 4);
+
+struct gcmoyuv1 {
+ /* gcregPEControlRegAddrs */
+ struct gccmdldstate pectrl_ldst;
+
+ /* gcregPEControlRegAddrs */
+ union {
+ struct gcregpecontrol reg;
+ unsigned int raw;
+ } pectrl;
+};
+
+struct gcmoyuv2 {
+ /* gcregPEControlRegAddrs */
+ struct gccmdldstate pectrl_ldst;
+
+ /* gcregPEControlRegAddrs */
+ union {
+ struct gcregpecontrol reg;
+ unsigned int raw;
+ } pectrl;
+
+ /* Plane state block. */
+ struct gccmdldstate plane_ldst;
+
+ /* gcregUPlaneAddressRegAddrs */
+ unsigned int uplaneaddress;
+
+ /* gcregUPlaneStrideRegAddrs */
+ unsigned int uplanestride;
+
+ /* Alignment filler. */
+ unsigned int _filler1;
+};
+
+struct gcmoyuv3 {
+ /* gcregPEControlRegAddrs */
+ struct gccmdldstate pectrl_ldst;
+
+ /* gcregPEControlRegAddrs */
+ union {
+ struct gcregpecontrol reg;
+ unsigned int raw;
+ } pectrl;
+
+ /* Plane state block. */
+ struct gccmdldstate plane_ldst;
+
+ /* gcregUPlaneAddressRegAddrs */
+ unsigned int uplaneaddress;
+
+ /* gcregUPlaneStrideRegAddrs */
+ unsigned int uplanestride;
+
+ /* gcregVPlaneAddressRegAddrs */
+ unsigned int vplaneaddress;
+
+ /* gcregVPlaneStrideRegAddrs */
+ unsigned int vplanestride;
+
+ /* Alignment filler. */
+ unsigned int _filler1;
+};
+
+/*******************************************************************************
+** Modular operations: xsrcyuv
+*/
+
+static const struct gccmdldstate gcmoxsrcyuv_uplaneaddress_ldst[4] = {
+ GCLDSTATE(gcregUPlaneAddressRegAddrs, 1),
+ GCLDSTATE(gcregBlock4UPlaneAddressRegAddrs + 1, 1),
+ GCLDSTATE(gcregBlock4UPlaneAddressRegAddrs + 2, 1),
+ GCLDSTATE(gcregBlock4UPlaneAddressRegAddrs + 3, 1),
+};
+
+static const struct gccmdldstate gcmoxsrcyuv_uplanestride_ldst[4] = {
+ GCLDSTATE(gcregUPlaneStrideRegAddrs, 1),
+ GCLDSTATE(gcregBlock4UPlaneStrideRegAddrs + 1, 1),
+ GCLDSTATE(gcregBlock4UPlaneStrideRegAddrs + 2, 1),
+ GCLDSTATE(gcregBlock4UPlaneStrideRegAddrs + 3, 1),
+};
+
+static const struct gccmdldstate gcmoxsrcyuv_vplaneaddress_ldst[4] = {
+ GCLDSTATE(gcregVPlaneAddressRegAddrs, 1),
+ GCLDSTATE(gcregBlock4VPlaneAddressRegAddrs + 1, 1),
+ GCLDSTATE(gcregBlock4VPlaneAddressRegAddrs + 2, 1),
+ GCLDSTATE(gcregBlock4VPlaneAddressRegAddrs + 3, 1),
+};
+
+static const struct gccmdldstate gcmoxsrcyuv_vplanestride_ldst[4] = {
+ GCLDSTATE(gcregVPlaneStrideRegAddrs, 1),
+ GCLDSTATE(gcregBlock4VPlaneStrideRegAddrs + 1, 1),
+ GCLDSTATE(gcregBlock4VPlaneStrideRegAddrs + 2, 1),
+ GCLDSTATE(gcregBlock4VPlaneStrideRegAddrs + 3, 1),
+};
+
+static const struct gccmdldstate gcmoxsrcyuv_pectrl_ldst[4] = {
+ GCLDSTATE(gcregPEControlRegAddrs, 1),
+ GCLDSTATE(gcregBlock4PEControlRegAddrs + 1, 1),
+ GCLDSTATE(gcregBlock4PEControlRegAddrs + 2, 1),
+ GCLDSTATE(gcregBlock4PEControlRegAddrs + 3, 1),
+};
+
+struct gcmoxsrcyuv1 {
+ /* gcregBlock4PEControlRegAddrs */
+ struct gccmdldstate pectrl_ldst;
+
+ /* gcregBlock4PEControlRegAddrs */
+ union {
+ struct gcregpecontrol reg;
+ unsigned int raw;
+ } pectrl;
+};
+
+struct gcmoxsrcyuv2 {
+ /* gcregBlock4PEControlRegAddrs */
+ struct gccmdldstate pectrl_ldst;
+
+ /* gcregBlock4PEControlRegAddrs */
+ union {
+ struct gcregpecontrol reg;
+ unsigned int raw;
+ } pectrl;
+
+ /* gcregBlock4UPlaneAddressRegAddrs */
+ struct gccmdldstate uplaneaddress_ldst;
+
+ /* gcregBlock4UPlaneAddressRegAddrs */
+ unsigned int uplaneaddress;
+
+ /* gcregBlock4UPlaneStrideRegAddrs */
+ struct gccmdldstate uplanestride_ldst;
+
+ /* gcregBlock4UPlaneStrideRegAddrs */
+ unsigned int uplanestride;
+};
+
+struct gcmoxsrcyuv3 {
+ /* gcregBlock4PEControlRegAddrs */
+ struct gccmdldstate pectrl_ldst;
+
+ /* gcregBlock4PEControlRegAddrs */
+ union {
+ struct gcregpecontrol reg;
+ unsigned int raw;
+ } pectrl;
+
+ /* gcregBlock4UPlaneAddressRegAddrs */
+ struct gccmdldstate uplaneaddress_ldst;
+
+ /* gcregBlock4UPlaneAddressRegAddrs */
+ unsigned int uplaneaddress;
+
+ /* gcregBlock4UPlaneStrideRegAddrs */
+ struct gccmdldstate uplanestride_ldst;
+
+ /* gcregBlock4UPlaneStrideRegAddrs */
+ unsigned int uplanestride;
+
+ /* gcregBlock4VPlaneAddressRegAddrs */
+ struct gccmdldstate vplaneaddress_ldst;
+
+ /* gcregBlock4VPlaneAddressRegAddrs */
+ unsigned int vplaneaddress;
+
+ /* gcregBlock4VPlaneStrideRegAddrs */
+ struct gccmdldstate vplanestride_ldst;
+
+ /* gcregBlock4VPlaneStrideRegAddrs */
+ unsigned int vplanestride;
+};
+
+/*******************************************************************************
+** Modular operations: src
+*/
+
+static const struct gccmdldstate gcmosrc0_config_ldst =
+ GCLDSTATE(gcregSrcAddressRegAddrs, 6);
+
+static const struct gccmdldstate gcmosrc0_rotation_ldst =
+ GCLDSTATE(gcregSrcRotationHeightRegAddrs, 2);
+
+static const struct gccmdldstate gcmosrc0_rop_ldst =
+ GCLDSTATE(gcregRopRegAddrs, 1);
+
+static const struct gccmdldstate gcmosrc0_mult_ldst =
+ GCLDSTATE(gcregColorMultiplyModesRegAddrs, 1);
+
+struct gcmosrc0 {
+ /* Configuration block. */
+ struct gccmdldstate config_ldst;
+
+ /* gcregSrcAddressRegAddrs */
+ unsigned int address;
+
+ /* gcregSrcStrideRegAddrs */
+ unsigned int stride;
+
+ /* gcregSrcRotationConfigRegAddrs */
+ union {
+ struct gcregsrcrotationconfig reg;
+ unsigned int raw;
+ } rotation;
+
+ /* gcregSrcConfigRegAddrs */
+ union {
+ struct gcregsrcconfig reg;
+ unsigned int raw;
+ } config;
+
+ /* gcregSrcOriginRegAddrs */
+ union {
+ struct gcregsrcorigin reg;
+ unsigned int raw;
+ } origin;
+
+ /* gcregSrcSizeRegAddrs */
+ union {
+ struct gcregsrcsize reg;
+ unsigned int raw;
+ } size;
+
+ /* Alignment filler. */
+ unsigned int _filler1;
+
+ /* Rotation block. */
+ struct gccmdldstate rotation_ldst;
+
+ /* gcregSrcRotationHeightRegAddrs */
+ union {
+ struct gcregsrcrotationheight reg;
+ unsigned int raw;
+ } rotationheight;
+
+ /* gcregRotAngleRegAddrs */
+ union {
+ struct gcregrotangle reg;
+ unsigned int raw;
+ } rotationangle;
+
+ /* Alignment filler. */
+ unsigned int _filler2;
+
+ /* gcregRopRegAddrs */
+ struct gccmdldstate rop_ldst;
+
+ /* gcregRopRegAddrs */
+ union {
+ struct gcregrop reg;
+ unsigned int raw;
+ } rop;
+
+ /* gcregColorMultiplyModesRegAddrs */
+ struct gccmdldstate mult_ldst;
+
+ /* gcregColorMultiplyModesRegAddrs */
+ union {
+ struct gcregcolormultiplymodes reg;
+ unsigned int raw;
+ } mult;
+};
+
+static const struct gccmdldstate gcmosrc_address_ldst[4] = {
+ GCLDSTATE(gcregSrcAddressRegAddrs, 1),
+ GCLDSTATE(gcregBlock4SrcAddressRegAddrs + 1, 1),
+ GCLDSTATE(gcregBlock4SrcAddressRegAddrs + 2, 1),
+ GCLDSTATE(gcregBlock4SrcAddressRegAddrs + 3, 1),
+};
+
+static const struct gccmdldstate gcmosrc_stride_ldst[4] = {
+ GCLDSTATE(gcregSrcStrideRegAddrs, 1),
+ GCLDSTATE(gcregBlock4SrcStrideRegAddrs + 1, 1),
+ GCLDSTATE(gcregBlock4SrcStrideRegAddrs + 2, 1),
+ GCLDSTATE(gcregBlock4SrcStrideRegAddrs + 3, 1),
+};
+
+static const struct gccmdldstate gcmosrc_rotation_ldst[4] = {
+ GCLDSTATE(gcregSrcRotationConfigRegAddrs, 1),
+ GCLDSTATE(gcregBlock4SrcRotationConfigRegAddrs + 1, 1),
+ GCLDSTATE(gcregBlock4SrcRotationConfigRegAddrs + 2, 1),
+ GCLDSTATE(gcregBlock4SrcRotationConfigRegAddrs + 3, 1),
+};
+
+static const struct gccmdldstate gcmosrc_config_ldst[4] = {
+ GCLDSTATE(gcregSrcConfigRegAddrs, 1),
+ GCLDSTATE(gcregBlock4SrcConfigRegAddrs + 1, 1),
+ GCLDSTATE(gcregBlock4SrcConfigRegAddrs + 2, 1),
+ GCLDSTATE(gcregBlock4SrcConfigRegAddrs + 3, 1),
+};
+
+static const struct gccmdldstate gcmosrc_origin_ldst[4] = {
+ GCLDSTATE(gcregSrcOriginRegAddrs, 1),
+ GCLDSTATE(gcregBlock4SrcOriginRegAddrs + 1, 1),
+ GCLDSTATE(gcregBlock4SrcOriginRegAddrs + 2, 1),
+ GCLDSTATE(gcregBlock4SrcOriginRegAddrs + 3, 1),
+};
+
+static const struct gccmdldstate gcmosrc_size_ldst[4] = {
+ GCLDSTATE(gcregSrcSizeRegAddrs, 1),
+ GCLDSTATE(gcregBlock4SrcSizeRegAddrs + 1, 1),
+ GCLDSTATE(gcregBlock4SrcSizeRegAddrs + 2, 1),
+ GCLDSTATE(gcregBlock4SrcSizeRegAddrs + 3, 1),
+};
+
+static const struct gccmdldstate gcmosrc_rotationheight_ldst[4] = {
+ GCLDSTATE(gcregSrcRotationHeightRegAddrs, 1),
+ GCLDSTATE(gcregBlock4SrcRotationHeightRegAddrs + 1, 1),
+ GCLDSTATE(gcregBlock4SrcRotationHeightRegAddrs + 2, 1),
+ GCLDSTATE(gcregBlock4SrcRotationHeightRegAddrs + 3, 1),
+};
+
+static const struct gccmdldstate gcmosrc_rotationangle_ldst[4] = {
+ GCLDSTATE(gcregRotAngleRegAddrs, 1),
+ GCLDSTATE(gcregBlock4RotAngleRegAddrs + 1, 1),
+ GCLDSTATE(gcregBlock4RotAngleRegAddrs + 2, 1),
+ GCLDSTATE(gcregBlock4RotAngleRegAddrs + 3, 1),
+};
+
+static const struct gccmdldstate gcmosrc_rop_ldst[4] = {
+ GCLDSTATE(gcregRopRegAddrs, 1),
+ GCLDSTATE(gcregBlock4RopRegAddrs + 1, 1),
+ GCLDSTATE(gcregBlock4RopRegAddrs + 2, 1),
+ GCLDSTATE(gcregBlock4RopRegAddrs + 3, 1),
+};
+
+static const struct gccmdldstate gcmosrc_mult_ldst[4] = {
+ GCLDSTATE(gcregColorMultiplyModesRegAddrs, 1),
+ GCLDSTATE(gcregBlock4ColorMultiplyModesRegAddrs + 1, 1),
+ GCLDSTATE(gcregBlock4ColorMultiplyModesRegAddrs + 2, 1),
+ GCLDSTATE(gcregBlock4ColorMultiplyModesRegAddrs + 3, 1),
+};
+
+struct gcmosrc {
+ /* gcregBlock4SrcAddressRegAddrs */
+ struct gccmdldstate address_ldst;
+
+ /* gcregBlock4SrcAddressRegAddrs */
+ unsigned int address;
+
+ /* gcregBlock4SrcStrideRegAddrs */
+ struct gccmdldstate stride_ldst;
+
+ /* gcregBlock4SrcStrideRegAddrs */
+ unsigned int stride;
+
+ /* gcregBlock4SrcRotationConfigRegAddrs */
+ struct gccmdldstate rotation_ldst;
+
+ /* gcregBlock4SrcRotationConfigRegAddrs */
+ union {
+ struct gcregsrcrotationconfig reg;
+ unsigned int raw;
+ } rotation;
+
+ /* gcregBlock4SrcConfigRegAddrs */
+ struct gccmdldstate config_ldst;
+
+ /* gcregBlock4SrcConfigRegAddrs */
+ union {
+ struct gcregsrcconfig reg;
+ unsigned int raw;
+ } config;
+
+ /* gcregBlock4SrcOriginRegAddrs */
+ struct gccmdldstate origin_ldst;
+
+ /* gcregBlock4SrcOriginRegAddrs */
+ union {
+ struct gcregsrcorigin reg;
+ unsigned int raw;
+ } origin;
+
+ /* gcregBlock4SrcSizeRegAddrs */
+ struct gccmdldstate size_ldst;
+
+ /* gcregBlock4SrcSizeRegAddrs */
+ union {
+ struct gcregsrcsize reg;
+ unsigned int raw;
+ } size;
+
+ /* gcregBlock4SrcRotationHeightRegAddrs */
+ struct gccmdldstate rotationheight_ldst;
+
+ /* gcregBlock4SrcRotationHeightRegAddrs */
+ union {
+ struct gcregsrcrotationheight reg;
+ unsigned int raw;
+ } rotationheight;
+
+ /* gcregBlock4RotAngleRegAddrs */
+ struct gccmdldstate rotationangle_ldst;
+
+ /* gcregBlock4RotAngleRegAddrs */
+ union {
+ struct gcregrotangle reg;
+ unsigned int raw;
+ } rotationangle;
+
+ /* gcregBlock4RopRegAddrs */
+ struct gccmdldstate rop_ldst;
+
+ /* gcregBlock4RopRegAddrs */
+ union {
+ struct gcregrop reg;
+ unsigned int raw;
+ } rop;
+
+ /* gcregBlock4ColorMultiplyModesRegAddrs */
+ struct gccmdldstate mult_ldst;
+
+ /* gcregBlock4ColorMultiplyModesRegAddrs */
+ union {
+ struct gcregcolormultiplymodes reg;
+ unsigned int raw;
+ } mult;
+};
+
+static const struct gccmdldstate gcmovrsrc_config_ldst =
+ GCLDSTATE(gcregSrcAddressRegAddrs, 4);
+
+static const struct gccmdldstate gcmovrsrc_pos_ldst =
+ GCLDSTATE(gcregVRSourceImageLowRegAddrs, 4);
+
+static const struct gccmdldstate gcmovrsrc_rotation_ldst =
+ GCLDSTATE(gcregSrcRotationHeightRegAddrs, 2);
+
+static const struct gccmdldstate gcmovrsrc_rop_ldst =
+ GCLDSTATE(gcregRopRegAddrs, 1);
+
+static const struct gccmdldstate gcmovrsrc_mult_ldst =
+ GCLDSTATE(gcregColorMultiplyModesRegAddrs, 1);
+
+struct gcmovrsrc {
+ /* Configuration block. */
+ struct gccmdldstate config_ldst;
+
+ /* gcregSrcAddressRegAddrs */
+ unsigned int address;
+
+ /* gcregSrcStrideRegAddrs */
+ unsigned int stride;
+
+ /* gcregSrcRotationConfigRegAddrs */
+ union {
+ struct gcregsrcrotationconfig reg;
+ unsigned int raw;
+ } rotation;
+
+ /* gcregSrcConfigRegAddrs */
+ union {
+ struct gcregsrcconfig reg;
+ unsigned int raw;
+ } config;
+
+ /* Alignment filler. */
+ unsigned int _filler1;
+
+ /* Source position block. */
+ struct gccmdldstate pos_ldst;
+
+ /* gcregVRSourceImageLowRegAddrs */
+ union {
+ struct gcregvrsourceimagelow reg;
+ unsigned int raw;
+ } lt;
+
+ /* gcregVRSourceImageHighRegAddrs */
+ union {
+ struct gcregvrsourceimagehigh reg;
+ unsigned int raw;
+ } rb;
+
+ /* gcregVRSourceOriginLowRegAddrs */
+ unsigned int x;
+
+ /* gcregVRSourceOriginHighRegAddrs */
+ unsigned int y;
+
+ /* Alignment filler. */
+ unsigned int _filler2;
+
+ /* Rotation block. */
+ struct gccmdldstate rotation_ldst;
+
+ /* gcregSrcRotationHeightRegAddrs */
+ union {
+ struct gcregsrcrotationheight reg;
+ unsigned int raw;
+ } rotationheight;
+
+ /* gcregRotAngleRegAddrs */
+ union {
+ struct gcregrotangle reg;
+ unsigned int raw;
+ } rotationangle;
+
+ /* Alignment filler. */
+ unsigned int _filler3;
+
+ /* gcregRopRegAddrs */
+ struct gccmdldstate rop_ldst;
+
+ /* gcregRopRegAddrs */
+ union {
+ struct gcregrop reg;
+ unsigned int raw;
+ } rop;
+
+ /* gcregColorMultiplyModesRegAddrs */
+ struct gccmdldstate mult_ldst;
+
+ /* gcregColorMultiplyModesRegAddrs */
+ union {
+ struct gcregcolormultiplymodes reg;
+ unsigned int raw;
+ } mult;
+};
+
+/*******************************************************************************
+** Modular operations: bltconfig
+*/
+
+static const struct gccmdldstate gcmobltconfig_multisource_ldst =
+ GCLDSTATE(gcregDEMultiSourceRegAddrs, 1);
+
+static const struct gccmdldstate gcmobltconfig_dstconfig_ldst =
+ GCLDSTATE(gcregDestConfigRegAddrs, 1);
+
+struct gcmobltconfig {
+ /* gcregDEMultiSourceRegAddrs */
+ struct gccmdldstate multisource_ldst;
+
+ /* gcregDEMultiSourceRegAddrs */
+ union {
+ struct gcregmultisource reg;
+ unsigned int raw;
+ } multisource;
+
+ /* gcregDestConfigRegAddrs */
+ struct gccmdldstate dstconfig_ldst;
+
+ /* gcregDestConfigRegAddrs */
+ union {
+ struct gcregdstconfig reg;
+ unsigned int raw;
+ } dstconfig;
+};
+
+/*******************************************************************************
+** Modular operations: startde
+*/
+
+struct gcmostartde {
+ /* Start DE command. */
+ struct gccmdstartde startde;
+ struct gccmdstartderect rect;
+};
+
+/*******************************************************************************
+** Modular operations: fillsrc
+*/
+
+static const struct gccmdldstate gcmofillsrc_rotation_ldst =
+ GCLDSTATE(gcregSrcRotationConfigRegAddrs, 2);
+
+static const struct gccmdldstate gcmofillsrc_rotationheight_ldst =
+ GCLDSTATE(gcregSrcRotationHeightRegAddrs, 2);
+
+static const struct gccmdldstate gcmofillsrc_alphacontrol_ldst =
+ GCLDSTATE(gcregAlphaControlRegAddrs, 1);
+
+struct gcmofillsrc {
+ /* gcregSrcRotationConfigRegAddrs */
+ struct gccmdldstate rotation_ldst;
+
+ /* gcregSrcRotationConfigRegAddrs */
+ union {
+ struct gcregsrcrotationconfig reg;
+ unsigned int raw;
+ } rotation;
+
+ /* gcregSrcConfigRegAddrs */
+ union {
+ struct gcregsrcconfig reg;
+ unsigned int raw;
+ } config;
+
+ /* Alignment filler. */
+ unsigned int _filler1;
+
+ /* gcregSrcRotationHeightRegAddrs */
+ struct gccmdldstate rotationheight_ldst;
+
+ /* gcregSrcRotationHeightRegAddrs */
+ union {
+ struct gcregsrcrotationheight reg;
+ unsigned int raw;
+ } rotationheight;
+
+ /* gcregRotAngleRegAddrs */
+ union {
+ struct gcregrotangle reg;
+ unsigned int raw;
+ } rotationangle;
+
+ /* Alignment filler. */
+ unsigned int _filler2;
+
+ /* gcregAlphaControlRegAddrs */
+ struct gccmdldstate alphacontrol_ldst;
+
+ /* gcregAlphaControlRegAddrs */
+ union {
+ struct gcregalphacontrol reg;
+ unsigned int raw;
+ } alphacontrol;
+};
+
+/*******************************************************************************
+** Modular operations: fill
+*/
+
+static const struct gccmdldstate gcmofill_clearcolor_ldst =
+ GCLDSTATE(gcregClearPixelValue32RegAddrs, 1);
+
+static const struct gccmdldstate gcmofill_dstconfig_ldst =
+ GCLDSTATE(gcregDestConfigRegAddrs, 1);
+
+static const struct gccmdldstate gcmofill_rop_ldst =
+ GCLDSTATE(gcregRopRegAddrs, 1);
+
+struct gcmofill {
+ struct gcmofillsrc src;
+
+ /* gcregClearPixelValue32RegAddrs */
+ struct gccmdldstate clearcolor_ldst;
+
+ /* gcregClearPixelValue32RegAddrs */
+ union {
+ struct gcregclearcolor reg;
+ unsigned int raw;
+ } clearcolor;
+
+ /* gcregDestConfigRegAddrs */
+ struct gccmdldstate dstconfig_ldst;
+
+ /* gcregDestConfigRegAddrs */
+ union {
+ struct gcregdstconfig reg;
+ unsigned int raw;
+ } dstconfig;
+
+ /* gcregRopRegAddrs */
+ struct gccmdldstate rop_ldst;
+
+ /* gcregRopRegAddrs */
+ union {
+ struct gcregrop reg;
+ unsigned int raw;
+ } rop;
+
+ /* Start DE command. */
+ struct gccmdstartde startde;
+ struct gccmdstartderect rect;
+};
+
+/*******************************************************************************
+** Modular operations: filterkernel
+*/
+
+static const struct gccmdldstate gcmofilterkernel_shared_ldst =
+ GCLDSTATE(gcregFilterKernelRegAddrs, 77);
+
+static const struct gccmdldstate gcmofilterkernel_horizontal_ldst =
+ GCLDSTATE(gcregHoriFilterKernelRegAddrs, 77);
+
+static const struct gccmdldstate gcmofilterkernel_vertical_ldst =
+ GCLDSTATE(gcregVertiFilterKernelRegAddrs, 77);
+
+struct gcmofilterkernel {
+ /* Kernel array block. */
+ struct gccmdldstate kernelarray_ldst;
+
+ /* Array of kernel coefficients. */
+ struct gcregfilterkernel kernelarray;
+};
+
+/*******************************************************************************
+** Modular operations: vrdst
+*/
+
+static const struct gccmdldstate gcmovrdst_config_ldst =
+ GCLDSTATE(gcregDestAddressRegAddrs, 4);
+
+static const struct gccmdldstate gcmovrdst_rotationheight_ldst =
+ GCLDSTATE(gcregDstRotationHeightRegAddrs, 1);
+
+struct gcmovrdst {
+ /* Configuration block. */
+ struct gccmdldstate config_ldst;
+
+ /* gcregDestAddressRegAddrs */
+ unsigned int address;
+
+ /* gcregDestStrideRegAddrs */
+ unsigned int stride;
+
+ /* gcregDestRotationConfigRegAddrs */
+ union {
+ struct gcregdstrotationconfig reg;
+ unsigned int raw;
+ } rotation;
+
+ /* gcregDestConfigRegAddrs */
+ union {
+ struct gcregdstconfig reg;
+ unsigned int raw;
+ } config;
+
+ /* Alignment filler. */
+ unsigned int _filler;
+
+ /* gcregDstRotationHeightRegAddrs */
+ struct gccmdldstate rotationheight_ldst;
+
+ /* gcregDstRotationHeightRegAddrs */
+ union {
+ struct gcregdstrotationheight reg;
+ unsigned int raw;
+ } rotationheight;
+};
+
+/*******************************************************************************
+** Modular operations: vrconfigex
+*/
+
+static const struct gccmdldstate gcmovrconfigex_config_ldst =
+ GCLDSTATE(gcregVRConfigExRegAddrs, 1);
+
+struct gcmovrconfigex {
+ /* gcregVRConfigExRegAddrs */
+ struct gccmdldstate config_ldst;
+
+ /* gcregVRConfigExRegAddrs */
+ union {
+ struct gcregvrconfigex reg;
+ unsigned int raw;
+ } config;
+};
+
+/*******************************************************************************
+** Modular operations: startvr
+*/
+
+static const struct gccmdldstate gcmostartvr_scale_ldst =
+ GCLDSTATE(gcregStretchFactorLowRegAddrs, 2);
+
+static const struct gccmdldstate gcmostartvr_rect_ldst =
+ GCLDSTATE(gcregVRTargetWindowLowRegAddrs, 2);
+
+static const struct gccmdldstate gcmostartvr_config_ldst =
+ GCLDSTATE(gcregVRConfigRegAddrs, 1);
+
+struct gcmostartvr {
+ /* Scale factor block. */
+ struct gccmdldstate scale_ldst;
+
+ /* gcregStretchFactorLowRegAddrs */
+ unsigned int scalex;
+
+ /* gcregStretchFactorHighRegAddrs */
+ unsigned int scaley;
+
+ /* Alignment filler. */
+ unsigned int _filler1;
+
+ /* Target rectangle. */
+ struct gccmdldstate rect_ldst;
+
+ /* gcregVRTargetWindowLowRegAddrs */
+ struct gcregvrtargetwindowlow lt;
+
+ /* gcregVRTargetWindowHighRegAddrs */
+ struct gcregvrtargetwindowhigh rb;
+
+ /* Alignment filler. */
+ unsigned int _filler2;
+
+ /* Start video raster commad. */
+ struct gccmdldstate config_ldst;
+
+ /* gcregVRConfigRegAddrs */
+ struct gcregvrconfig config;
+};
+
+#endif
diff --git a/bltsville/gcbv/mirror/include/gcx.h b/bltsville/gcbv/mirror/include/gcx.h
new file mode 100644
index 0000000..285762f
--- /dev/null
+++ b/bltsville/gcbv/mirror/include/gcx.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright(c) 2012,
+ * Texas Instruments, Inc. and Vivante Corporation.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Vivante Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCX_H
+#define GCX_H
+
+#include <pthread.h>
+#include "gcerror.h"
+#include "gcreg.h"
+#include "gcdbglog.h"
+
+#ifndef countof
+#define countof(a) \
+( \
+ sizeof(a) / sizeof(a[0]) \
+)
+#endif
+
+#define GC_PTR2INT(p) \
+( \
+ (unsigned int) (p) \
+)
+
+#define GC_ALIGN(n, align) \
+( \
+ ((n) + ((align) - 1)) & ~((align) - 1) \
+)
+
+#define GCLOCK_TIMEOUT_SEC 10
+#define GCLOCK_TIMEOUT_JIF (msecs_to_jiffies(GCLOCK_TIMEOUT_SEC * 1000))
+
+#define GCLOCK_TYPE \
+ pthread_mutex_t
+
+#define GCDEFINE_LOCK(name) \
+ pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER
+
+#define GCLOCK_INIT(lock) \
+ if (pthread_mutex_init(lock, NULL)) { \
+ GCERR("failed to init mutex.\n"); \
+ }
+
+#define GCLOCK_DESTROY(lock) \
+ if (pthread_mutex_destroy(lock)) { \
+ GCERR("failed to destroy mutex.\n"); \
+ }
+
+#define GCLOCK(lock) \
+ if (pthread_mutex_lock(lock)) { \
+ GCERR("failed to lock mutex.\n"); \
+ }
+
+#define GCUNLOCK(lock) \
+ if (pthread_mutex_unlock(lock)) { \
+ GCERR("failed to unlock mutex.\n"); \
+ }
+
+#endif
diff --git a/bltsville/gcbv/version.h b/bltsville/gcbv/version.h
new file mode 100644
index 0000000..431cb96
--- /dev/null
+++ b/bltsville/gcbv/version.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012,
+ * Texas Instruments, Inc. and Vivante Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Texas Instruments, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL TEXAS INSTRUMENTS, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define VER_FILEVERSION 2,2,2,0
+#define VER_FILEVERSION_STR "2.2.2.0\0"
+#define VER_PRODUCTVERSION 2,2,2,0
+#define VER_PRODUCTVERSION_STR "2.2\0"
diff --git a/bltsville/ocd/README b/bltsville/ocd/README
new file mode 100644
index 0000000..20a1485
--- /dev/null
+++ b/bltsville/ocd/README
@@ -0,0 +1 @@
+git://github.com/graphics/ocd.git
diff --git a/bltsville/ocd/include/ocd.h b/bltsville/ocd/include/ocd.h
new file mode 100755
index 0000000..14e6fc6
--- /dev/null
+++ b/bltsville/ocd/include/ocd.h
@@ -0,0 +1,801 @@
+/*
+ * ocd.h
+ *
+ * Open Color format Definitions
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This file defines the Open Color format Definitions (OCD), an open,
+ * extensible, color format definition.
+ *
+ * This work is licensed under the Creative Commons Attribution-NoDerivs 3.0
+ * Unported License. To view a copy of this license, visit
+ * http://creativecommons.org/licenses/by-nd/3.0/ or send a letter to
+ * Creative Commons, 444 Castro Street, Suite 900, Mountain View, California,
+ * 94041, USA.
+ */
+
+#ifndef OCD_H
+#define OCD_H
+
+/*
+ * ocdformat - specifies one of the supported color formats
+ *
+ * ocdformat consists of 8 bits indicating the vendor ID, followed by 24 bits
+ * specified by the vendor.
+ *
+ * VENDOR_ALL is a common ID with formats defined below.
+ */
+
+/****** Bits 31-24 are the vendor ID. The other 24 are vendor defined. ******/
+#define OCDFMTDEF_VENDOR_SHIFT 24
+#define OCDFMTDEF_VENDOR_MASK (0xFF << OCDFMTDEF_VENDOR_SHIFT)
+
+#define OCDFMTDEF_VENDOR_ALL \
+ (0x00 << OCDFMTDEF_VENDOR_SHIFT) /* Common format */
+#define OCDFMTDEF_VENDOR_TI \
+ (0x01 << OCDFMTDEF_VENDOR_SHIFT) /* Texas Instruments, Inc. */
+/* 0xF0-0xFF reserved */
+
+/***** OCDFMTDEF_VENDOR_ALL *****/
+/* The formats in this group are created using combinations of the values
+ listed below. */
+
+/*
+ * 33222222 222 21 1 1 1 11 111 1
+ * 10987654 321 09 8 7 6 54 321 0 9 876 543210
+ * [------] [-] [] | | | [] [-] | | [-] [----]
+ * | | | | | | | | | | | |
+ * | | | | | | | | | | | color bits minus 1
+ * | | | | | | | | | | |
+ * | | | | | | | | | | container
+ * | | | | | | | | | |
+ * | | | | | | | | | left justified
+ * | | | | | | | | |
+ * | | | | | | | | reversed
+ * | | | | | | | |
+ * | | | | | | | layout
+ * | | | | | | |
+ * | | | | | | subsampling
+ * | | | | | |
+ * | | | | | subsample position \
+ * | | | | | |
+ * | | | | non-premult/fill empty 0 > alpha components
+ * | | | | |
+ * | | | alpha /
+ * | | |
+ * | | standard
+ * | |
+ * | color space
+ * |
+ * vendor ID (VENDOR_ALL = 0x00)
+ */
+
+/**** Bits 23-21 define the color space. ****/
+#define OCDFMTDEF_CS_SHIFT 21
+#define OCDFMTDEF_CS_MASK (7 << OCDFMTDEF_CS_SHIFT)
+
+#define OCDFMTDEF_CS_MONO \
+ (0 << OCDFMTDEF_CS_SHIFT) /* Monochrome (luma only) */
+#define OCDFMTDEF_CS_LUT \
+ (1 << OCDFMTDEF_CS_SHIFT) /* Look-up table (using palette) */
+#define OCDFMTDEF_CS_RGB \
+ (2 << OCDFMTDEF_CS_SHIFT) /* Red, green, blue */
+#define OCDFMTDEF_CS_YCbCr \
+ (3 << OCDFMTDEF_CS_SHIFT) /* YCbCr (YUV) (luma & chroma) */
+#define OCDFMTDEF_CS_ALPHA \
+ (4 << OCDFMTDEF_CS_SHIFT) /* Alpha only (transparency) */
+/* 5 reserved */
+/* 6 reserved */
+/* 7 reserved */
+
+/**** Bits 20-19 define the standard ****/
+#define OCDFMTDEF_STD_SHIFT 19
+#define OCDFMTDEF_STD_MASK (3 << OCDFMTDEF_STD_SHIFT)
+
+#define OCDFMTDEF_STD_ITUR_601_YCbCr \
+ (0 << OCDFMTDEF_STD_SHIFT) /* ITU-R BT.601 - YCbCr only */
+/* 0 default for non-YCbCr */
+#define OCDFMTDEF_STD_ITUR_709_YCbCr \
+ (1 << OCDFMTDEF_STD_SHIFT) /* ITU-R BT.709 - YCbCr only */
+/* 1 reserved for non-YCbCr */
+/* 2 reserved */
+#define OCDFMTDEF_FULLSCALE_YCbCr \
+ (3 << OCDFMTDEF_STD_SHIFT) /* RGB 0 to 255 =>
+ YCbCr 0 to 255, -128 to 127 */
+/* 3 reserved for non-YCbCr */
+
+/**** Bits 18-16 are component modifiers for non-alpha c/s only ****/
+#define OCDFMTDEF_ALPHA_SHIFT 18
+#define OCDFMTDEF_ALPHA \
+ (1 << OCDFMTDEF_ALPHA_SHIFT) /* An alpha component is added to the
+ format */
+#define OCDFMTDEF_NON_PREMULT_SHIFT 17
+#define OCDFMTDEF_NON_PREMULT \
+ (1 << OCDFMTDEF_NON_PREMULT_SHIFT) /* Component(s) is(are) not
+ premultiplied by the alpha
+ (default is
+ premultiplied) */
+#define OCDFMTDEF_FILL_EMPTY_0_SHIFT \
+ OCDFMTDEF_NON_PREMULT_SHIFT
+#define OCDFMTDEF_FILL_EMPTY_0 \
+ OCDFMTDEF_NON_PREMULT /* Empty bits are hard-wired to 0
+ (default is 1) */
+#define OCDFMTDEF_SUBSAMPLE_HORZ_ALIGNMENT_SHIFT 16
+#define OCDFMTDEF_SUBSAMPLE_HORZ_ALIGNED \
+ (0 << OCDFMTDEF_SUBSAMPLE_HORZ_ALIGNMENT_SHIFT) /* Subsamples aligned
+ w/1st non-subsample
+ (e.g. MPEG-2) */
+#define OCDFMTDEF_SUBSAMPLE_HORZ_CENTERED \
+ (1 << OCDFMTDEF_SUBSAMPLE_HORZ_ALIGNMENT_SHIFT) /* Subsamples are
+ between
+ non-subsamples
+ (e.g. MPEG-1) */
+
+/*** Bits 18-16 are used differently for alpha c/s ***/
+/* Bit 18 is reserved */
+/*** Bits 17-16 define the number of alpha components for alpha c/s ***/
+#define OCDFMTDEF_ALPHA_COMPONENTS_SHIFT 16
+#define OCDFMTDEF_ALPHA_COMPONENTS_MASK \
+ (3 << OCDFMTDEF_ALPHA_COMPONENTS_SHIFT)
+
+#define OCDFMTDEF_ALPHA_COMPONENTS_1 (0 << OCDFMTDEF_ALPHA_COMPONENTS_SHIFT)
+#define OCDFMTDEF_ALPHA_COMPONENTS_2 (1 << OCDFMTDEF_ALPHA_COMPONENTS_SHIFT)
+#define OCDFMTDEF_ALPHA_COMPONENTS_3 (2 << OCDFMTDEF_ALPHA_COMPONENTS_SHIFT)
+#define OCDFMTDEF_ALPHA_COMPONENTS_4 (3 << OCDFMTDEF_ALPHA_COMPONENTS_SHIFT)
+
+/**** Bits 15-14 define subsampling ****/
+#define OCDFMTDEF_SUBSAMPLE_SHIFT 14
+#define OCDFMTDEF_SUBSAMPLE_MASK (3 << OCDFMTDEF_SUBSAMPLE_SHIFT)
+
+#define OCDFMTDEF_SUBSAMPLE_NONE \
+ (0 << OCDFMTDEF_SUBSAMPLE_SHIFT) /* No subsampling;
+ each pixel has each component */
+#define OCDFMTDEF_SUBSAMPLE_422_YCbCr \
+ (1 << OCDFMTDEF_SUBSAMPLE_SHIFT) /* 4:2:2 subsampling;
+ each horizontal pair of pixels
+ has one Y (luma) component each,
+ but shares one Cb and Cr (chroma)
+ component. */
+/* 1 reserved for non-YCbCr */
+#define OCDFMTDEF_SUBSAMPLE_420_YCbCr \
+ (2 << OCDFMTDEF_SUBSAMPLE_SHIFT) /* 4:2:0 subsampling;
+ each square of four pixels has
+ one Y (luma) component each, but
+ shares one Cb and Cr (chroma)
+ component. */
+/* 2 reserved for non-YCbCr */
+#define OCDFMTDEF_SUBSAMPLE_411_YCbCr \
+ (3 << OCDFMTDEF_SUBSAMPLE_SHIFT) /* 4:1:1 subsampling;
+ each horizontal four pixels have
+ one Y (luma) component each, but
+ shares one Cb and Cr (chroma)
+ component. */
+/* 3 reserved for non-YCbCr */
+
+/**** Bits 13-11 define the memory layout
+ (combined with _REVERSED and _LEFT_JUSTIFIED) ****/
+#define OCDFMTDEF_LAYOUT_SHIFT 11
+#define OCDFMTDEF_LAYOUT_MASK (7 << OCDFMTDEF_LAYOUT_SHIFT)
+
+#define OCDFMTDEF_PACKED \
+ (0 << OCDFMTDEF_LAYOUT_SHIFT) /* Components interleaved together */
+#define OCDFMTDEF_DISTRIBUTED \
+ (1 << OCDFMTDEF_LAYOUT_SHIFT) /* Components are distributed evenly
+ across the container; e.g. a 64-bit
+ container with four 8-bit components
+ are distributed with 8 bits between
+ them: __C0__C1__C2__C3 */
+#define OCDFMTDEF_2_PLANE_YCbCr \
+ (2 << OCDFMTDEF_LAYOUT_SHIFT) /* Y component is separated from Cb & Cr
+ components. After the Y plane, an
+ interleaved CbCr plane follows. */
+/* 2 reserved for non-YCbCr */
+#define OCDFMTDEF_3_PLANE_STACKED \
+ (3 << OCDFMTDEF_LAYOUT_SHIFT) /* Y, Cb, and Cr components are
+ separated. After the Y plane is a Cb
+ plane, and then a Cr plane. */
+/* 3 reserved for non-YCbCr and non-RGB */
+/* 4 reserved */
+/* 5 reserved */
+/* 6 reserved */
+#define OCDFMTDEF_3_PLANE_SIDE_BY_SIDE_YCbCr \
+ (7 << OCDFMTDEF_LAYOUT_SHIFT) /* Y, Cb, and Cr components are
+ separated. After the Y plane the Cb
+ and Cr planes are separated but
+ side-by-side in memory (interleaved
+ on a line-by-line basis). */
+/* 7 reserved for non-YCbCr */
+
+/**** Bits 10-9 are layout modifiers. ****/
+#define OCDFMTDEF_REVERSED_SHIFT 10
+#define OCDFMTDEF_REVERSED \
+ (1 << OCDFMTDEF_REVERSED_SHIFT) /* Order of components reversed
+ (default is RGB or CbCr) */
+#define OCDFMTDEF_LEFT_JUSTIFIED_SHIFT 9
+#define OCDFMTDEF_LEFT_JUSTIFIED \
+ (1 << OCDFMTDEF_LEFT_JUSTIFIED_SHIFT) /* Components are shifted
+ left (default is shifted
+ right); for 3-plane YCbCr,
+ this indicates wasted space
+ to the right of the Cb & Cr
+ planes (stride matches Y
+ plane). */
+
+/**** Bits 6-8 specify the container type. ****/
+#define OCDFMTDEF_CONTAINER_SHIFT 6
+#define OCDFMTDEF_CONTAINER_MASK (7 << OCDFMTDEF_CONTAINER_SHIFT)
+
+#define OCDFMTDEF_CONTAINER_8BIT (0 << OCDFMTDEF_CONTAINER_SHIFT)
+#define OCDFMTDEF_CONTAINER_16BIT (1 << OCDFMTDEF_CONTAINER_SHIFT)
+#define OCDFMTDEF_CONTAINER_24BIT (2 << OCDFMTDEF_CONTAINER_SHIFT)
+#define OCDFMTDEF_CONTAINER_32BIT (3 << OCDFMTDEF_CONTAINER_SHIFT)
+/* 4 (0x008000) reserved */
+#define OCDFMTDEF_CONTAINER_48BIT (5 << OCDFMTDEF_CONTAINER_SHIFT)
+/* 6 (0x00C000) reserved */
+#define OCDFMTDEF_CONTAINER_64BIT (7 << OCDFMTDEF_CONTAINER_SHIFT)
+
+/**** Bits 0-5 contain the total number of component bits minus one. ****/
+/* To calculate the number of bits for each RGBA component, use the following
+ * formula:
+ *
+ * green bits = int((color bits + 2) / 3)
+ * blue bits = int((color bits - green bits) / 2)
+ * red bits = color bits - green bits - blue bits
+ * alpha bits (when present) = container size - color bits
+ *
+ * Ex. 1: RGB16 -> 16 bits
+ * green bits = int((16 + 2) / 3) = 6
+ * blue bits = int((16 - 6) / 2) = 5
+ * red bits = 16 - 6 - 5 = 5
+ * alpha bits = n/a
+ * Ex. 2: ARGB16 -> 16 bits
+ * green bits = int((16 + 2) / 3) = 6
+ * blue bits = int((16 - 6) / 2) = 5
+ * red bits = 16 - 6 - 5 = 5
+ * alpha bits = 24 - 16 = 8
+ * Ex. 3: RGB32 -> 32 bits
+ * green bits = int((32 + 2) / 3) = 11
+ * blue bits = int((32 - 11) / 2) = 10
+ * red bits = 32 - 11 - 10 = 11
+ * alpha bits = n/a
+ *
+ * For planar formats, the container indicates the total number of bits on the
+ * subsampled boundary, while the component bits are the average number of
+ * bits per pixel.
+ *
+ * Ex. 1: YV12 -> YCbCr 4:2:0 w/8-bit samples -> 4x8 + 2x8 = 48 bit container
+ * 48 bits / 4 pixels = 12 bpp
+ * Ex. 2: NV16 -> YCbCr 4:2:2 w/8-bit samples -> 2x8 + 2x8 = 32 bit container
+ * 24 bits / 2 pixels = 16 bpp
+ */
+#define OCDFMTDEF_COMPONENTSIZEMINUS1_SHIFT 0
+#define OCDFMTDEF_COMPONENTSIZEMINUS1_MASK \
+ (0x3F << OCDFMTDEF_COMPONENTSIZEMINUS1_SHIFT)
+
+
+/*
+ * The formats below are constructed from the definitions above. However, not
+ * all formats possible are specified (and named) below. The other formats
+ * which can be uniquely formed using the above definitions are legitimate
+ * formats, and may be used as well.
+ */
+enum ocdformat {
+ OCDFMT_UNKNOWN = -1,
+ OCDFMT_NONE = OCDFMT_UNKNOWN,
+
+ /*** Alpha only ***/
+ /** Packed **/
+ OCDFMT_ALPHA1 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_ALPHA |
+ OCDFMTDEF_ALPHA_COMPONENTS_1 |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (1 - 1),
+ OCDFMT_ALPHA2 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_ALPHA |
+ OCDFMTDEF_ALPHA_COMPONENTS_1 |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (2 - 1),
+ OCDFMT_ALPHA4 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_ALPHA |
+ OCDFMTDEF_ALPHA_COMPONENTS_1 |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (4 - 1),
+ OCDFMT_ALPHA8 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_ALPHA |
+ OCDFMTDEF_ALPHA_COMPONENTS_1 |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (8 - 1),
+ /* Sub-pixel */
+ OCDFMT_ALPHA4x1 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_ALPHA |
+ OCDFMTDEF_ALPHA_COMPONENTS_4 |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (4 - 1),
+ OCDFMT_ALPHA3x8 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_ALPHA |
+ OCDFMTDEF_ALPHA_COMPONENTS_3 |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_24BIT |
+ (24 - 1),
+ OCDFMT_ALPHA4x8 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_ALPHA |
+ OCDFMTDEF_ALPHA_COMPONENTS_4 |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_32BIT |
+ (32 - 1),
+
+ /*** Monochrome ***/
+ /** Packed **/
+ OCDFMT_MONO1 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_MONO |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (1 - 1),
+ OCDFMT_MONO2 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_MONO |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (2 - 1),
+ OCDFMT_MONO4 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_MONO |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (4 - 1),
+ OCDFMT_MONO8 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_MONO |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (8 - 1),
+
+ /*** Palettized (look-up-table) ***/
+ /** Packed **/
+ OCDFMT_LUT1 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_LUT |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (1 - 1),
+ OCDFMT_LUT2 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_LUT |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (2 - 1),
+ OCDFMT_LUT4 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_LUT |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (4 - 1),
+ OCDFMT_LUT8 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_LUT |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (8 - 1),
+
+ /*** RGB ***/
+ /** Packed **/
+ /* No subsampling */
+ OCDFMT_RGB12 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_RGB |
+ OCDFMTDEF_SUBSAMPLE_NONE |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_16BIT |
+ (12 - 1), /* (15):4:4:4 */
+ OCDFMT_xRGB12 = OCDFMT_RGB12,
+ OCDFMT_1RGB12 = OCDFMT_xRGB12,
+ OCDFMT_0RGB12 = OCDFMT_xRGB12 |
+ OCDFMTDEF_FILL_EMPTY_0, /* (0):4:4:4 */
+
+ OCDFMT_BGR12 = OCDFMT_RGB12 |
+ OCDFMTDEF_REVERSED, /* (15):4:4:4 */
+ OCDFMT_xBGR12 = OCDFMT_BGR12,
+ OCDFMT_1BGR12 = OCDFMT_xBGR12,
+ OCDFMT_0BGR12 = OCDFMT_xBGR12 |
+ OCDFMTDEF_FILL_EMPTY_0, /* (0):4:4:4 */
+
+ OCDFMT_RGBx12 = OCDFMT_xRGB12 |
+ OCDFMTDEF_LEFT_JUSTIFIED, /* 4:4:4:(15) */
+ OCDFMT_RGB112 = OCDFMT_RGBx12,
+ OCDFMT_RGB012 = OCDFMT_RGBx12 |
+ OCDFMTDEF_FILL_EMPTY_0, /* 4:4:4:(0) */
+
+ OCDFMT_BGRx12 = OCDFMT_xRGB12 |
+ OCDFMTDEF_LEFT_JUSTIFIED |
+ OCDFMTDEF_REVERSED, /* 4:4:4:(15) */
+ OCDFMT_BGR112 = OCDFMT_BGRx12,
+ OCDFMT_BGR012 = OCDFMT_BGRx12 |
+ OCDFMTDEF_FILL_EMPTY_0, /* 4:4:4:(0) */
+
+ OCDFMT_RGB15 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_RGB |
+ OCDFMTDEF_SUBSAMPLE_NONE |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_16BIT |
+ (15 - 1), /* (1):5:5:5 */
+ OCDFMT_xRGB15 = OCDFMT_RGB15,
+ OCDFMT_1RGB15 = OCDFMT_xRGB15,
+ OCDFMT_0RGB15 = OCDFMT_xRGB15 |
+ OCDFMTDEF_FILL_EMPTY_0, /* (0):5:5:5 */
+
+ OCDFMT_BGR15 = OCDFMT_RGB15 |
+ OCDFMTDEF_REVERSED, /* (1):5:5:5 */
+ OCDFMT_xBGR15 = OCDFMT_BGR15,
+ OCDFMT_1BGR15 = OCDFMT_xBGR15,
+ OCDFMT_0BGR15 = OCDFMT_xBGR15 |
+ OCDFMTDEF_FILL_EMPTY_0, /* (0):5:5:5 */
+
+ OCDFMT_RGBx15 = OCDFMT_RGB15 |
+ OCDFMTDEF_LEFT_JUSTIFIED, /* 5:5:5:(1) */
+ OCDFMT_RGB115 = OCDFMT_RGBx15,
+ OCDFMT_RGB015 = OCDFMT_RGBx15 |
+ OCDFMTDEF_FILL_EMPTY_0, /* 5:5:5:(0) */
+
+ OCDFMT_BGRx15 = OCDFMT_RGB15 |
+ OCDFMTDEF_LEFT_JUSTIFIED |
+ OCDFMTDEF_REVERSED, /* 5:5:5:(1) */
+ OCDFMT_BGR115 = OCDFMT_BGRx15,
+ OCDFMT_BGR015 = OCDFMT_BGRx15 |
+ OCDFMTDEF_FILL_EMPTY_0, /* 5:5:5:(0) */
+
+ OCDFMT_RGB16 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_RGB |
+ OCDFMTDEF_SUBSAMPLE_NONE |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_16BIT |
+ (16 - 1), /* 5:6:5 */
+ OCDFMT_BGR16 = OCDFMT_RGB16 |
+ OCDFMTDEF_REVERSED, /* 5:6:5 */
+
+ OCDFMT_RGB24 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_RGB |
+ OCDFMTDEF_SUBSAMPLE_NONE |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_24BIT |
+ (24 - 1), /* 8:8:8 */
+ OCDFMT_BGR24 = OCDFMT_RGB24 |
+ OCDFMTDEF_REVERSED, /* 8:8:8 */
+
+ OCDFMT_xRGB16 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_RGB |
+ OCDFMTDEF_SUBSAMPLE_NONE |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_24BIT |
+ (16 - 1), /* (255):5:6:5 */
+ OCDFMT_1RGB16 = OCDFMT_xRGB16,
+ OCDFMT_0RGB16 = OCDFMT_xRGB16 |
+ OCDFMTDEF_FILL_EMPTY_0, /* (0):5:6:5 */
+
+ OCDFMT_xBGR16 = OCDFMT_xRGB16 |
+ OCDFMTDEF_REVERSED, /* (255):5:6:5 */
+ OCDFMT_1BGR16 = OCDFMT_xBGR16,
+ OCDFMT_0BGR16 = OCDFMT_xBGR16 |
+ OCDFMTDEF_FILL_EMPTY_0, /* (0):5:6:5 */
+
+ OCDFMT_RGBx16 = OCDFMT_xRGB16 |
+ OCDFMTDEF_LEFT_JUSTIFIED, /* 5:6:5:(255) */
+ OCDFMT_RGB116 = OCDFMT_RGBx16,
+ OCDFMT_RGB016 = OCDFMT_RGBx16 |
+ OCDFMTDEF_FILL_EMPTY_0, /* 5:6:5:(0) */
+
+ OCDFMT_BGRx16 = OCDFMT_xRGB16 |
+ OCDFMTDEF_LEFT_JUSTIFIED |
+ OCDFMTDEF_REVERSED, /* 5:6:5:(255) */
+ OCDFMT_BGR116 = OCDFMT_BGRx16,
+ OCDFMT_BGR016 = OCDFMT_BGRx16 |
+ OCDFMTDEF_FILL_EMPTY_0, /* 5:6:5:(0) */
+
+ OCDFMT_xRGB24 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_RGB |
+ OCDFMTDEF_SUBSAMPLE_NONE |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_32BIT |
+ (24 - 1), /* (255):8:8:8 */
+ OCDFMT_1RGB24 = OCDFMT_xRGB24,
+ OCDFMT_0RGB24 = OCDFMT_xRGB24 |
+ OCDFMTDEF_FILL_EMPTY_0, /* (0):8:8:8 */
+
+ OCDFMT_xBGR24 = OCDFMT_xRGB24 |
+ OCDFMTDEF_REVERSED, /* (255):8:8:8 */
+ OCDFMT_1BGR24 = OCDFMT_xBGR24,
+ OCDFMT_0BGR24 = OCDFMT_xBGR24 |
+ OCDFMTDEF_FILL_EMPTY_0, /* (0):8:8:8 */
+
+ OCDFMT_RGBx24 = OCDFMT_xRGB24 |
+ OCDFMTDEF_LEFT_JUSTIFIED, /* 8:8:8:(255) */
+ OCDFMT_RGB124 = OCDFMT_RGBx24,
+ OCDFMT_RGB024 = OCDFMT_RGBx24 |
+ OCDFMTDEF_FILL_EMPTY_0, /* 8:8:8:(0) */
+
+ OCDFMT_BGRx24 = OCDFMT_xRGB24 |
+ OCDFMTDEF_LEFT_JUSTIFIED |
+ OCDFMTDEF_REVERSED, /* 8:8:8:(255) */
+ OCDFMT_BGR124 = OCDFMT_BGRx24,
+ OCDFMT_BGR024 = OCDFMT_BGRx24 |
+ OCDFMTDEF_FILL_EMPTY_0, /* 8:8:8:(0) */
+
+ /* Premultiplied ARGB */
+ OCDFMT_ARGB12 = OCDFMT_xRGB12 |
+ OCDFMTDEF_ALPHA, /* 4:4:4:4 */
+ OCDFMT_ABGR12 = OCDFMT_xBGR12 |
+ OCDFMTDEF_ALPHA, /* 4:4:4:4 */
+ OCDFMT_RGBA12 = OCDFMT_RGBx12 |
+ OCDFMTDEF_ALPHA, /* 4:4:4:4 */
+ OCDFMT_BGRA12 = OCDFMT_BGRx12 |
+ OCDFMTDEF_ALPHA, /* 4:4:4:4 */
+
+ OCDFMT_ARGB16 = OCDFMT_xRGB16 |
+ OCDFMTDEF_ALPHA, /* 8:5:6:5 */
+ OCDFMT_ABGR16 = OCDFMT_ARGB16 |
+ OCDFMTDEF_REVERSED, /* 8:5:6:5 */
+ OCDFMT_RGBA16 = OCDFMT_ARGB16 |
+ OCDFMTDEF_LEFT_JUSTIFIED, /* 5:6:5:8 */
+ OCDFMT_BGRA16 = OCDFMT_ARGB16 |
+ OCDFMTDEF_LEFT_JUSTIFIED |
+ OCDFMTDEF_REVERSED, /* 5:6:5:8 */
+
+ OCDFMT_ARGB24 = OCDFMT_xRGB24 |
+ OCDFMTDEF_ALPHA, /* 8:8:8:8 */
+ OCDFMT_ABGR24 = OCDFMT_xBGR24 |
+ OCDFMTDEF_ALPHA, /* 8:8:8:8 */
+ OCDFMT_RGBA24 = OCDFMT_RGBx24 |
+ OCDFMTDEF_ALPHA, /* 8:8:8:8 */
+ OCDFMT_BGRA24 = OCDFMT_BGRx24 |
+ OCDFMTDEF_ALPHA, /* 8:8:8:8 */
+
+ /* Non-premultiplied ARGB */
+ OCDFMT_nARGB12 = OCDFMT_ARGB12 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_ARGB12_NON_PREMULT = OCDFMT_nARGB12,
+
+ OCDFMT_nABGR12 = OCDFMT_ABGR12 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_ABGR12_NON_PREMULT = OCDFMT_nABGR12,
+
+ OCDFMT_nRGBA12 = OCDFMT_RGBA12 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_RGBA12_NON_PREMULT = OCDFMT_nRGBA12,
+
+ OCDFMT_nBGRA12 = OCDFMT_BGRA12 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_BGRA12_NON_PREMULT = OCDFMT_nBGRA12,
+
+ OCDFMT_ARGB15 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_RGB |
+ OCDFMTDEF_ALPHA |
+ OCDFMTDEF_NON_PREMULT |
+ OCDFMTDEF_SUBSAMPLE_NONE |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_16BIT |
+ (15 - 1), /* 1:5:5:5 - "normal"
+ format is not
+ premultiplied */
+ OCDFMT_nARGB15 = OCDFMT_ARGB15,
+ OCDFMT_ARGB15_NON_PREMULT = OCDFMT_nARGB15,
+
+ OCDFMT_ABGR15 = OCDFMT_ARGB15 |
+ OCDFMTDEF_REVERSED, /* 1:5:5:5 - "normal"
+ format is not
+ premultiplied */
+ OCDFMT_nABGR15 = OCDFMT_ABGR15,
+ OCDFMT_ABGR15_NON_PREMULT = OCDFMT_nABGR15,
+
+ OCDFMT_RGBA15 = OCDFMT_ARGB15 |
+ OCDFMTDEF_LEFT_JUSTIFIED, /* 5:5:5:1 - "normal"
+ format is not
+ premultiplied */
+ OCDFMT_nRGBA15 = OCDFMT_RGBA15,
+ OCDFMT_RGBA15_NON_PREMULT = OCDFMT_nRGBA15,
+
+ OCDFMT_BGRA15 = OCDFMT_ARGB15 |
+ OCDFMTDEF_LEFT_JUSTIFIED |
+ OCDFMTDEF_REVERSED, /* 5:5:5:1 - "normal"
+ format is not
+ premultiplied */
+ OCDFMT_nBGRA15 = OCDFMT_BGRA15,
+ OCDFMT_BGRA15_NON_PREMULT = OCDFMT_nRGBA15,
+
+ OCDFMT_nARGB16 = OCDFMT_ARGB16 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_ARGB16_NON_PREMULT = OCDFMT_nARGB16,
+
+ OCDFMT_nABGR16 = OCDFMT_ABGR16 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_ABGR16_NON_PREMULT = OCDFMT_nABGR16,
+
+ OCDFMT_nRGBA16 = OCDFMT_RGBA16 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_RGBA16_NON_PREMULT = OCDFMT_nRGBA16,
+
+ OCDFMT_nBGRA16 = OCDFMT_BGRA16 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_BGRA16_NON_PREMULT = OCDFMT_nBGRA16,
+
+ OCDFMT_nARGB24 = OCDFMT_ARGB24 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_ARGB24_NON_PREMULT = OCDFMT_nARGB24,
+
+ OCDFMT_nABGR24 = OCDFMT_ABGR24 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_ABGR24_NON_PREMULT = OCDFMT_nABGR24,
+
+ OCDFMT_nRGBA24 = OCDFMT_RGBA24 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_RGBA24_NON_PREMULT = OCDFMT_nRGBA24,
+
+ OCDFMT_nBGRA24 = OCDFMT_BGRA24 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_BGRA24_NON_PREMULT = OCDFMT_nBGRA24,
+
+ /*** YCbCr ***/
+ /** Packed **/
+ /* YCbCr 4:2:2 */
+ OCDFMT_UYVY = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_422_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_HORZ_ALIGNED |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_32BIT |
+ (16 - 1),
+ OCDFMT_UYVY_601 = OCDFMT_UYVY |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_UYVY_709 = OCDFMT_UYVY |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+ OCDFMT_Y422 = OCDFMT_UYVY,
+ OCDFMT_Y422_601 = OCDFMT_UYVY_601,
+ OCDFMT_Y422_709 = OCDFMT_UYVY_709,
+
+ OCDFMT_VYUY = OCDFMT_UYVY |
+ OCDFMTDEF_REVERSED,
+ OCDFMT_VYUY_601 = OCDFMT_VYUY |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_VYUY_709 = OCDFMT_VYUY |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ OCDFMT_YUYV = OCDFMT_UYVY |
+ OCDFMTDEF_LEFT_JUSTIFIED,
+ OCDFMT_YUYV_601 = OCDFMT_YUYV |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_YUYV_709 = OCDFMT_YUYV |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+ OCDFMT_YUY2 = OCDFMT_YUYV,
+ OCDFMT_YUY2_601 = OCDFMT_YUYV_601,
+ OCDFMT_YUY2_709 = OCDFMT_YUYV_709,
+
+ OCDFMT_YVYU = OCDFMT_VYUY |
+ OCDFMTDEF_LEFT_JUSTIFIED,
+ OCDFMT_YVYU_601 = OCDFMT_YVYU |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_YVYU_709 = OCDFMT_YVYU |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ /** 3-plane **/
+ /* YCbCr 4:2:2 */
+ OCDFMT_YV16 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_422_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_HORZ_ALIGNED |
+ OCDFMTDEF_3_PLANE_STACKED |
+ OCDFMTDEF_CONTAINER_32BIT |
+ (16 - 1),
+ OCDFMT_YV16_601 = OCDFMT_YV16 |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_YV16_709 = OCDFMT_YV16 |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ /* YCbCr 4:2:0 */
+ OCDFMT_IYUV = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_420_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_HORZ_ALIGNED |
+ OCDFMTDEF_3_PLANE_STACKED |
+ OCDFMTDEF_CONTAINER_48BIT |
+ (12 - 1),
+ OCDFMT_IYUV_601 = OCDFMT_IYUV |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_IYUV_709 = OCDFMT_IYUV |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+ OCDFMT_I420 = OCDFMT_IYUV,
+ OCDFMT_I420_601 = OCDFMT_IYUV_601,
+ OCDFMT_I420_709 = OCDFMT_IYUV_709,
+
+ OCDFMT_YV12 = OCDFMT_IYUV |
+ OCDFMTDEF_REVERSED,
+ OCDFMT_YV12_601 = OCDFMT_YV12 |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_YV12_709 = OCDFMT_YV12 |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ OCDFMT_IMC3 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_420_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_HORZ_ALIGNED |
+ OCDFMTDEF_3_PLANE_STACKED |
+ OCDFMTDEF_LEFT_JUSTIFIED | /* Indicates wasted
+ space to the
+ right */
+ OCDFMTDEF_CONTAINER_48BIT |
+ (12 - 1),
+ OCDFMT_IMC3_601 = OCDFMT_IMC3 |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_IMC3_709 = OCDFMT_IMC3 |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ OCDFMT_IMC1 = OCDFMT_IMC3 |
+ OCDFMTDEF_REVERSED,
+ OCDFMT_IMC1_601 = OCDFMT_IMC1 |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_IMC1_709 = OCDFMT_IMC1 |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ OCDFMT_IMC4 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_YCbCr |
+ OCDFMTDEF_STD_ITUR_601_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_420_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_HORZ_ALIGNED |
+ OCDFMTDEF_3_PLANE_SIDE_BY_SIDE_YCbCr |
+ OCDFMTDEF_CONTAINER_48BIT |
+ (12 - 1),
+ OCDFMT_IMC4_601 = OCDFMT_IMC4 |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_IMC4_709 = OCDFMT_IMC4 |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ OCDFMT_IMC2 = OCDFMT_IMC4 |
+ OCDFMTDEF_REVERSED,
+ OCDFMT_IMC2_601 = OCDFMT_IMC2 |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_IMC2_709 = OCDFMT_IMC2 |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ /** 2-plane **/
+ /* YCbCr 4:2:2 */
+ OCDFMT_NV16 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_422_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_HORZ_ALIGNED |
+ OCDFMTDEF_2_PLANE_YCbCr |
+ OCDFMTDEF_CONTAINER_32BIT |
+ (16 - 1),
+ OCDFMT_NV16_601 = OCDFMT_NV16 |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_NV16_709 = OCDFMT_NV16 |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ OCDFMT_NV61 = OCDFMT_NV16 |
+ OCDFMTDEF_REVERSED,
+ OCDFMT_NV61_601 = OCDFMT_NV61 |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_NV61_709 = OCDFMT_NV61 |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ /* YCbCr 4:2:0 */
+ OCDFMT_NV12 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_YCbCr |
+ OCDFMTDEF_STD_ITUR_601_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_420_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_HORZ_ALIGNED |
+ OCDFMTDEF_2_PLANE_YCbCr |
+ OCDFMTDEF_CONTAINER_48BIT |
+ (12 - 1),
+ OCDFMT_NV12_601 = OCDFMT_NV12 |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_NV12_709 = OCDFMT_NV12 |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ OCDFMT_NV21 = OCDFMT_NV12 |
+ OCDFMTDEF_REVERSED,
+ OCDFMT_NV21_601 = OCDFMT_NV21 |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_NV21_709 = OCDFMT_NV21 |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+#ifdef OCD_EXTERNAL_INCLUDE
+#include OCD_EXTERNAL_INCLUDE
+#endif
+};
+
+#endif /* OCD_H */
diff --git a/bltsville/ocd/index.html b/bltsville/ocd/index.html
new file mode 100755
index 0000000..52eaa11
--- /dev/null
+++ b/bltsville/ocd/index.html
@@ -0,0 +1,617 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
+
+<head>
+<meta http-equiv="Content-Language" content="en-us" />
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Need OCD?</title>
+<style type="text/css">
+.Header1 {
+ margin: 0px 0 0 0;
+ font-size: xx-large;
+ font-weight: bold;
+ text-align: left;
+ line-height: normal;
+ background-color: #E0E0E0;
+}
+.Header2 {
+ font-size: xx-large;
+ font-weight: bold;
+ margin: 0px;
+ line-height: 100%;
+}
+.Header3 {
+ font-size: x-large;
+ font-weight: bold;
+ text-align: left;
+ line-height: 100%;
+ margin: 0px;
+}
+.note {
+ font-family: Arial, Helvetica, sans-serif;
+ font-weight: bold;
+ margin-left: 40px;
+}
+.description { font-size: 1.2em; margin-bottom: 30px; margin-top: 30px; font-style: italic;}
+.download { float: right; }
+.inline_code {
+ font-family: "Courier New", Courier, monospace;
+ font-size: small;
+}
+.cmd_line {
+ background: #000;
+ color: #fff;
+ padding: 10px;
+ font-family: "Courier New", Courier, monospace;
+ font-size: small;
+}
+.code_block {
+ margin-left: 40px;
+ font-family: "Courier New", Courier, monospace;
+ font-size: small;
+}
+.filename {
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: small;
+}
+.Code_Header {
+ font-size: xx-large;
+ font-weight: bold;
+ text-align: left;
+ font-family: "Courier New", Courier, monospace;
+}
+.Code_Header_2 {
+ font-size: x-large;
+ font-weight: bold;
+ text-align: left;
+ font-family: "Courier New", Courier, monospace;
+}
+.Code_Header_3 {
+ font-size: large;
+ font-weight: bold;
+ text-align: left;
+ font-family: "Courier New", Courier, monospace;
+}
+.indent {
+ margin-left: 40px;
+}
+.ctr_thinbord {
+ text-align: center;
+ border: 1px solid #000000;
+}
+.style4 {
+ border-width: 0px;
+ margin-left: 40px;
+}
+.style5 {
+ margin-left: 80px;
+ font-family: "Courier New", Courier, monospace;
+ font-size: small;
+}
+</style>
+</head>
+
+<body>
+
+<table style="width: 100%; line-height: 100%;">
+ <tr>
+ <td style="width: 484px">
+<img alt="" src="ocdlogo.jpg"/></td>
+ <td>
+ <p>OCD is a set of Open Color format Definitions.</p>
+<p>Color formats are used in everything from BLTers to video codecs, and from cameras to displays.&nbsp; But although
+there are plenty of common formats, the definition of the code specifying them is never the same. </p>
+ <p>OCD attempts to solve this problem.&nbsp; It provides logical color format codes, and
+ is extensible.</p>
+<hr />
+ <table style="width: 100%">
+ <tr>
+ <td>
+<div class="download"><img alt="CC BY-ND" longdesc="Creative Commons Attribution-NoDerivs 3.0 Unported License" src="http://i.creativecommons.org/l/by-nd/3.0/88x31.png" width="88" height="31" /></div>
+<p class="Header2">License</p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+<div>
+<p class="style17">The definitions are designed and maintained by Texas Instruments, Inc., but anyone is free to use them with no
+cost or obligation.</p>
+<p>This project is licensed under the <a href="http://creativecommons.org/licenses/by-nd/3.0/">Creative Commons
+Attribution-NoDerivs 3.0 Unported License</a>.</p>
+</div>
+ </td>
+ </tr>
+ </table>
+<hr />
+ <table style="width: 100%">
+ <tr>
+ <td>
+ <p class="Header2">Source</p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <div class="download">
+ <a href="http://github.com/graphics/ocd/zipball/master">
+ <img width="90" alt="download zip" src="http://github.com/images/modules/download/zip.png" border="0"/></a>
+ <a href="http://github.com/graphics/ocd/tarball/master">
+ <img width="90" alt ="download tar" src="http://github.com/images/modules/download/tar.png" border="0"/></a>
+ </div>
+<div>
+ Get the source code on GitHub at <a href="http://github.com/graphics/ocd">graphics/ocd</a>, or download this
+ project in either
+ <a href="http://github.com/graphics/ocd/zipball/master">zip</a> or
+ <a href="http://github.com/graphics/ocd/tarball/master">tar</a> formats.</div>
+ <p>You can also clone the project with <a href="http://git-scm.com">Git</a> by running:</p>
+ <pre><a class="cmd_line">$ git clone git://github.com/graphics/ocd</a></pre>
+ </td>
+ </tr>
+ <tr><td><hr />
+ <table style="width: 100%">
+ <tr>
+ <td class="Header2">Wiki</td>
+ </tr>
+ <tr>
+ <td><a href="https://github.com/graphics/ocd/wiki">https://github.com/graphics/ocd/wiki</a></td>
+ </tr>
+ </table>
+ </td></tr>
+ </table>
+ </td>
+ </tr>
+</table>
+<hr />
+<p class="Header1">Header File</p>
+<p><span class="filename">ocd.h</span> contains the Open Color format Definitions.</p>
+<p class="Header1">How does it work?</p>
+<p>OCD was designed to allow a single 32-bit word (int) to specify the
+color format.&nbsp; The color format is specified as an enumeration.&nbsp; The
+enumeration values are constructed using bitfields.</p>
+<p>OCD breaks off a chunk of those 32 bits to specify a vendor ID.&nbsp; With
+this, OCD can allow vendors with very unique formats to obtain their own vendor
+ID and specify any of 16 million formats of their own.&nbsp; Minimum sharing
+here, but maximum flexibility.</p>
+<p class="Code_Header_2">OCDFMTDEF_VENDOR_ALL</p>
+<p>The power of OCD lies in the shared vendor ID.&nbsp; The
+<span class="inline_code">OCDFMTDEF_VENDOR_ALL</span> vendor ID indicates that the common set of definitions is
+being used.&nbsp; And this set of definitions is designed to specify pretty much
+any reasonably common color format in use today.</p>
+<p>When <span class="inline_code">OCDFMTDEF_VENDOR_ALL</span> is chosen, the remaining 24 bits of the format are
+sub-divided into bitfields used to describe the format.</p>
+<p class="Header2">Predefined Names</p>
+<p>A set of enumeration values are already provided with predefined names.&nbsp;
+It is easiest for clients to use these predefined values.&nbsp; They already cover most of
+the formats likely to be encountered.</p>
+<p class="note">NOTE:&nbsp; The naming conventions of the predefined formats are based on their byte
+ordering, so they are not endian-dependent.&nbsp; The exceptions are the 16-bit
+packed formats, which are little-endian.</p>
+<p>Some examples:</p>
+<p class="indent"><span class="inline_code">OCDFMT_RGB24</span> is a format
+where each pixel consists of 3 bytes (24 bits).&nbsp; The first byte in memory
+(at address A, read as a byte) is the red component.&nbsp; The second byte in
+memory (at address A+1, read as a byte) is the green component.&nbsp; The third
+byte in memory (at address A+2, read as a byte) is the blue component.</p>
+<p class="indent">OCDFMT_xRGB24 is a format where each pixel consists of 4 bytes
+(32 bits), but only 3 of these (24 bits) contain color information.&nbsp; The
+remaining 8 bits are ignored on a read, or filled with 0s on a write.</p>
+<p>If the format of interest is not already specified, it is still likely that
+the format is supported by the VENDOR_ALL design.&nbsp; Using the bitfields below, new combinations can be constructed.&nbsp; These
+combinations are already legal, but they just have not been given names.&nbsp;
+Users of OCD can define their own names in a separate header file and include it
+using the OCD_EXTERNAL_INCLUDE mechanism:</p>
+<p class="indent">file: <span class="filename">myocdfmts.h</span></p>
+<p class="style5">MYOCDFMT_ALPHAMONO8 = OCDFMT_MONO8 |<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+OCDFMTDEF_ALPHA,</p>
+<p class="indent">file:&nbsp; <span class="filename">mysource.c</span></p>
+<p class="style5">#define OCD_EXTERNAL_INCLUDE &quot;myocdfmts.h&quot;<br />
+#include &lt;ocd.h&gt;</p>
+<p class="Header2">VENDOR_ALL Bitfields</p>
+<p>The following bitfields only apply to the <span class="inline_code">
+OCDFMTDEF_VENDOR_ALL</span> color formats. </p>
+<p class="Header3">Color Space</p>
+<p>The first field specifies the color space.&nbsp; Currently there are five
+color spaces defined, but there is room for three more if the need arises:</p>
+<ul>
+ <li>Monochrome - <span class="inline_code">OCDFMTDEF_CS_MONO</span></li>
+ <li>Look-Up Table - <span class="inline_code">OCDFMTDEF_CS_LUT</span></li>
+ <li>RGB -<span class="inline_code"> OCDFMTDEF_CS_RGB</span></li>
+ <li>YCbCr (a.k.a. YUV) - <span class="inline_code">
+ OCDFMTDEF_CS_YCbCr</span></li>
+ <li>Alpha - <span class="inline_code">OCDFMTDEF_CS_ALPHA</span></li>
+</ul>
+<p>Once the color space has been selected, the remaining bits depend on that
+choice:</p>
+<p class="Code_Header_3">OCDFMTDEF_CS_MONO</p>
+<table class="style4">
+ <tr>
+ <td class="ctr_thinbord">31:24</td>
+ <td class="ctr_thinbord">23:21</td>
+ <td class="ctr_thinbord">20:19</td>
+ <td class="ctr_thinbord">18</td>
+ <td class="ctr_thinbord">17</td>
+ <td class="ctr_thinbord">16</td>
+ <td class="ctr_thinbord">15:14</td>
+ <td class="ctr_thinbord">13:11</td>
+ <td class="ctr_thinbord">10</td>
+ <td class="ctr_thinbord">9</td>
+ <td class="ctr_thinbord">8:6</td>
+ <td class="ctr_thinbord">5:0</td>
+ </tr>
+ <tr>
+ <td class="ctr_thinbord">00000000</td>
+ <td class="ctr_thinbord">000</td>
+ <td class="ctr_thinbord">reserved<br />
+ (00)</td>
+ <td class="ctr_thinbord">alpha</td>
+ <td class="ctr_thinbord">non-premult/<br />
+ fill empty 0</td>
+ <td class="ctr_thinbord">reserved<br />
+ (0)</td>
+ <td class="ctr_thinbord">reserved<br />
+ (0)</td>
+ <td class="ctr_thinbord">reserved<br />
+ (0)</td>
+ <td class="ctr_thinbord">reversed</td>
+ <td class="ctr_thinbord">reserved<br />
+ (0)</td>
+ <td class="ctr_thinbord">container<br />
+ size</td>
+ <td class="ctr_thinbord">color<br />
+ bits-1</td>
+ </tr>
+</table>
+<p class="Code_Header_3">OCDFMTDEF_CS_LUT</p>
+<table class="style4">
+ <tr>
+ <td class="ctr_thinbord">31:24</td>
+ <td class="ctr_thinbord">23:21</td>
+ <td class="ctr_thinbord">20:19</td>
+ <td class="ctr_thinbord">18</td>
+ <td class="ctr_thinbord">17</td>
+ <td class="ctr_thinbord">16</td>
+ <td class="ctr_thinbord">15:14</td>
+ <td class="ctr_thinbord">13:11</td>
+ <td class="ctr_thinbord">10</td>
+ <td class="ctr_thinbord">9</td>
+ <td class="ctr_thinbord">8:6</td>
+ <td class="ctr_thinbord">5:0</td>
+ </tr>
+ <tr>
+ <td class="ctr_thinbord">00000000</td>
+ <td class="ctr_thinbord">001</td>
+ <td class="ctr_thinbord">reserved<br />
+ (00)</td>
+ <td class="ctr_thinbord">reserved<br />
+ (0)</td>
+ <td class="ctr_thinbord">reserved<br />
+ (0)</td>
+ <td class="ctr_thinbord">reserved<br />
+ (0)</td>
+ <td class="ctr_thinbord">reserved<br />
+ (0)</td>
+ <td class="ctr_thinbord">reserved<br />
+ (0)</td>
+ <td class="ctr_thinbord">reversed</td>
+ <td class="ctr_thinbord">reserved<br />
+ (0)</td>
+ <td class="ctr_thinbord">container<br />
+ size</td>
+ <td class="ctr_thinbord">color<br />
+ bits-1</td>
+ </tr>
+</table>
+<p class="Code_Header_3">OCDFMTDEF_CS_RGB</p>
+<table class="style4">
+ <tr>
+ <td class="ctr_thinbord">31:24</td>
+ <td class="ctr_thinbord">23:21</td>
+ <td class="ctr_thinbord">20:19</td>
+ <td class="ctr_thinbord">18</td>
+ <td class="ctr_thinbord">17</td>
+ <td class="ctr_thinbord">16</td>
+ <td class="ctr_thinbord">15:14</td>
+ <td class="ctr_thinbord">13:11</td>
+ <td class="ctr_thinbord">10</td>
+ <td class="ctr_thinbord">9</td>
+ <td class="ctr_thinbord">8:6</td>
+ <td class="ctr_thinbord">5:0</td>
+ </tr>
+ <tr>
+ <td class="ctr_thinbord">00000000</td>
+ <td class="ctr_thinbord">010</td>
+ <td class="ctr_thinbord">reserved<br />
+ (00)</td>
+ <td class="ctr_thinbord">alpha</td>
+ <td class="ctr_thinbord">non-premult/<br />
+ fill empty 0</td>
+ <td class="ctr_thinbord">reserved<br />
+ (0)</td>
+ <td class="ctr_thinbord">reserved<br />
+ (00)</td>
+ <td class="ctr_thinbord">layout</td>
+ <td class="ctr_thinbord">reversed</td>
+ <td class="ctr_thinbord">left<br />
+ justified</td>
+ <td class="ctr_thinbord">container<br />
+ size</td>
+ <td class="ctr_thinbord">color<br />
+ bits-1</td>
+ </tr>
+</table>
+<p class="Code_Header_3">OCDFMTDEF_CS_YCbCr</p>
+<table class="style4">
+ <tr>
+ <td class="ctr_thinbord">31:24</td>
+ <td class="ctr_thinbord">23:21</td>
+ <td class="ctr_thinbord">20:19</td>
+ <td class="ctr_thinbord">18</td>
+ <td class="ctr_thinbord">17</td>
+ <td class="ctr_thinbord">16</td>
+ <td class="ctr_thinbord">15:14</td>
+ <td class="ctr_thinbord">13:11</td>
+ <td class="ctr_thinbord">10</td>
+ <td class="ctr_thinbord">9</td>
+ <td class="ctr_thinbord">8:6</td>
+ <td class="ctr_thinbord">5:0</td>
+ </tr>
+ <tr>
+ <td class="ctr_thinbord">00000000</td>
+ <td class="ctr_thinbord">011</td>
+ <td class="ctr_thinbord">standard</td>
+ <td class="ctr_thinbord">alpha</td>
+ <td class="ctr_thinbord">non-premult/<br />
+ fill empty 0</td>
+ <td class="ctr_thinbord">subsample<br />
+ position</td>
+ <td class="ctr_thinbord">subsampling</td>
+ <td class="ctr_thinbord">layout</td>
+ <td class="ctr_thinbord">reversed</td>
+ <td class="ctr_thinbord">left<br />
+ justified</td>
+ <td class="ctr_thinbord">container<br />
+ size</td>
+ <td class="ctr_thinbord">color<br />
+ bits-1</td>
+ </tr>
+</table>
+<p class="Code_Header_3">OCDFMTDEF_CS_ALPHA</p>
+<table class="style4">
+ <tr>
+ <td class="ctr_thinbord">31:24</td>
+ <td class="ctr_thinbord">23:21</td>
+ <td class="ctr_thinbord">20:19</td>
+ <td class="ctr_thinbord">18</td>
+ <td class="ctr_thinbord">17</td>
+ <td class="ctr_thinbord">16</td>
+ <td class="ctr_thinbord">15:14</td>
+ <td class="ctr_thinbord">13:11</td>
+ <td class="ctr_thinbord">10</td>
+ <td class="ctr_thinbord">9</td>
+ <td class="ctr_thinbord">8:6</td>
+ <td class="ctr_thinbord">5:0</td>
+ </tr>
+ <tr>
+ <td class="ctr_thinbord">00000000</td>
+ <td class="ctr_thinbord">100</td>
+ <td class="ctr_thinbord">reserved<br />
+ (00)</td>
+ <td class="ctr_thinbord">reserved<br />
+ (0)</td>
+ <td class="ctr_thinbord">reserved<br />
+ (0)</td>
+ <td class="ctr_thinbord">reserved<br />
+ (0)</td>
+ <td class="ctr_thinbord">reserved<br />
+ (00)</td>
+ <td class="ctr_thinbord">reserved<br />
+ (00)</td>
+ <td class="ctr_thinbord">reversed</td>
+ <td class="ctr_thinbord">reserved<br />
+ (0)</td>
+ <td class="ctr_thinbord">container<br />
+ size</td>
+ <td class="ctr_thinbord">alpha<br />
+ bits-1</td>
+ </tr>
+</table>
+<p>&nbsp;</p>
+<p class="Header3">Standard (YCbCr)</p>
+<p>This field specifies the standard being used for this color space.</p>
+<p>Currently, this field is only defined for the YCbCr color space:</p>
+<ul>
+ <li><a href="http://www.itu.int/rec/R-REC-BT.601/en">ITU-R BT.601</a> - <span class="inline_code">
+ OCDFMTDEF_STD_ITUR_601_YCbCr</span></li>
+ <li><a href="http://www.itu.int/rec/R-REC-BT.709/en">ITU-R BT.709</a> - <span class="inline_code">
+ OCDFMTDEF_STD_ITUR_709_YCbCr</span></li>
+ <li><a href="http://www.w3.org/Graphics/JPEG/jfif3.pdf">Full Scale</a> - <span class="inline_code">
+ OCDFMTDEF_FULLSCALE_YCbCr</span></li>
+</ul>
+<p>We believe that this field will be used to add linear format support in the
+very near future.</p>
+<p class="Header3">Fill Empty 0 (Mono, RGB, YCbCr)</p>
+<p>When there is no alpha included with a format, but the color components don&#39;t
+fill up the container, the remainder of the bits must be filled with something
+when written.&nbsp; When the <span class="inline_code">OCDFMTDEF_FILL_EMPTY_0</span>
+flag is not set, they are filled with 1.&nbsp; This is done in case they are
+later used as an alpha value, which will already represent an opaque pixel
+(whether the pixel is premultiplied or not).&nbsp; When the flag is set, they are
+filled with 0, to accommodate those environments where they are required to be
+cleared when unused.</p>
+<p class="Header3">Alpha (Mono, RGB, YCbCr)</p>
+<p>The <span class="inline_code">OCDFMTDEF_ALPHA</span> bit indicates that the
+format includes an alpha channel along with the main color components.</p>
+<p class="Header3">Non-Premult (Mono, RGB, YCbCr)</p>
+<p>Formats with alpha can have their color components pre-multiplied by the
+alpha component or not.&nbsp; When the <span class="inline_code">
+OCDFMTDEF_NON_PREMULT</span> bit is set, the color components are not
+premultiplied by the accompanying alpha.&nbsp; When the bit is not set, the
+color components are already multiplied by the alpha.</p>
+<p class="Header3">Subsampling (YCbCr)</p>
+<p>Some formats can be subsampled.&nbsp; At this point, only subsampled YCbCr is
+supported.</p>
+<ul>
+ <li>No subsampling - <span class="inline_code">
+ OCDFMTDEF_SUBSAMPLE_NONE</span></li>
+ <li>4:2:2 subsampling - <span class="inline_code">
+ OCDFMTDEF_SUBSAMPLE_422_YCbCr</span></li>
+ <li>4:2:0 subsampling - <span class="inline_code">
+ OCDFMTDEF_SUBSAMPLE_420_YCbCr</span></li>
+ <li>4:1:1 subsampling - <span class="inline_code">
+ OCDFMTDEF_SUBSAMPLE_411_YCbCr</span></li>
+</ul>
+<p class="Header3">Subsample Position (YCbCr)</p>
+<p>Subsampling can have different equivalent positions relative to the pixels.&nbsp;
+Vertical subsampling positions are consistent, so the following are supported to
+control the horizontal subsampling position:</p>
+<ul>
+ <li><span class="inline_code">OCDFMTDEF_SUBSAMPLE_HORZ_ALIGNED </span>- subsamples are aligned with first pixel (e.g. MPEG-2
+ spec)</li>
+ <li><span class="inline_code">OCDFMTDEF_SUBSAMPLE_HORZ_CENTERED
+ </span>- subsamples are centered between the pixels (e.g. MPEG-1
+ spec)</li>
+</ul>
+<p>NOTE:&nbsp; It is encouraged that users of OCD be generous when handling
+subsampling positions.&nbsp; Allowing misaligned subsampling is preferable to
+complete failure.</p>
+<p class="Header3">Alpha Components (Alpha)</p>
+<p>To support applying alpha values to the individual components of other color
+spaces, the alpha color space can have more than one alpha value per pixel.&nbsp;
+This field specifies how many:</p>
+<ul>
+ <li><span class="inline_code">OCDFMTDEF_ALPHA_COMPONENTS_1 </span>- pixel contains 1 alpha value (default)</li>
+ <li><span class="inline_code">OCDFMTDEF_ALPHA_COMPONENTS_2
+ </span>- pixel contains 2 alpha values</li>
+ <li><span class="inline_code">OCDFMTDEF_ALPHA_COMPONENTS_3
+ </span>- pixel contains 3 alpha values; suitable for RGB
+ manipulation (e.g. FreeType/ClearType)</li>
+ <li><span class="inline_code">OCDFMTDEF_ALPHA_COMPONENTS_4
+ </span>-- pixel contains 4 alpha values</li>
+</ul>
+<p class="Header3">Layout (RGB, YCbCr)</p>
+<p>The layout values, in conjunction with the reversed and left-justified
+modifiers, specify how the pixel components are placed into memory.&nbsp; All
+non-RGB/YCbCr formats are packed.</p>
+<ul>
+ <li><span class="inline_code">OCDFMTDEF_PACKED </span>- pixel
+ components are sequential in memory, defaulting to RGB or CbCr
+ order, right justified</li>
+ <li><span class="inline_code">OCDFMTDEF_DISTRIBUTED </span>-
+ pixel components that don&#39;t fill the container are evenly
+ distributed within the container (e.g. 32 bits of ARGB in a
+ 64-bit container is distributed 8 bits every 16 bits: xAxRxGxB)</li>
+ <li><span class="inline_code">OCDFMTDEF_2_PLANE_YCbCr </span>-
+ for subsampled formats only, Y plane is followed by subsampled
+ interleaved CbCr plane</li>
+ <li><span class="inline_code">OCDFMTDEF_3_PLANE_STACKED </span>-
+ pixel components are divided into planes that are sequential in
+ memory</li>
+ <li><span class="inline_code">
+ OCDFMTDEF_3_PLANE_SIDE_BY_SIDE_YCbCr </span>- for subsampled
+ formats only pixel components are divided into planes, with the
+ non-subsampled component followed by the subsampled components
+ stored side-by-side (lines interleaved) </li>
+</ul>
+<p class="Header3">Reversed (RGB, YCbCr)</p>
+<p><span class="inline_code">OCDFMTDEF_REVERSED</span> indicates that the order
+of the color components is the opposite of the defaults.&nbsp; For RGB formats,
+this means BGR.&nbsp; For YCbCr formats, this means CrCb.</p>
+<p class="Header3">Left-Justified (RGB, YCbCr)</p>
+<p><span class="inline_code">OCDFMTDEF_LEFT_JUSTIFIED</span> indicates that the
+color components are shifted to the left, as opposed to the default of shifting
+to the right.</p>
+<p>Some examples for <span class="inline_code">OCDFMTDEF_REVERSED</span> and
+<span class="inline_code">OCDFMTDEF_LEFT_JUSTIFIED</span>:</p>
+<ul>
+ <li>Packed RGB:&nbsp; x,R,G,B is the default byte order<ul>
+ <li>x,B,G,R is the format if
+ <span class="inline_code">OCDFMTDEF_REVERSED</span>
+ is set</li>
+ <li>R,G,B,x is the format if
+ <span class="inline_code">
+ OCDFMTDEF_LEFT_JUSTIFIED</span> is set</li>
+ <li>B,G,R,x is the format if
+ <span class="inline_code">OCDFMTDEF_REVERSED</span>
+ and <span class="inline_code">
+ OCDFMTDEF_LEFT_JUSTIFIED</span> are set</li>
+ </ul>
+ </li>
+ <li>Packed YCbCr 4:2:2:&nbsp; U,Y,V,Y is the default byte order<ul>
+ <li>V,Y,U,Y is the format if
+ <span class="inline_code">OCDFMTDEF_REVERSED</span>
+ is set</li>
+ <li>Y,U,Y,V is the format if
+ <span class="inline_code">
+ OCDFMTDEF_LEFT_JUSTIFIED</span> is set</li>
+ <li>Y,V,Y,U is the format if
+ <span class="inline_code">OCDFMTDEF_REVERSED</span>
+ and <span class="inline_code">
+ OCDFMTDEF_LEFT_JUSTIFIED</span> are set</li>
+ </ul>
+ </li>
+ <li>3-Plane YCbCr 4:2:2 or 4:2:0:&nbsp; The default is the Y
+ plane, followed by the Cb plane and then the Cr plane.&nbsp; The
+ Cb and Cr planes have half of the stride of the Y plane.<ul>
+ <li>If <span class="inline_code">
+ OCDFMTDEF_REVERSED</span> is set, the Cb and Cr
+ planes are reversed.</li>
+ <li><span class="inline_code">
+ OCDFMTDEF_LEFT_JUSTIFIED</span> has a special
+ case for this layout.&nbsp; When set, it
+ indicates that the Cb and Cr planes have the
+ same stride as the Y plane, and the Cb and Cr
+ data is shifted to the left.</li>
+ <li>If both <span class="inline_code">
+ OCDFMTDEF_LEFT_REVERSED</span> and
+ <span class="inline_code">
+ OCDFMTDEF_LEFT_JUSTIFIED</span> are set, the Cb
+ and Cr planes are reversed and double width.</li>
+ </ul>
+ </li>
+ <li>2-Plane YCbCr 4:2:2 or 4:2:0:&nbsp; The default is the Y
+ plane, followed by the CbCr interleaved plane, with the same
+ stride as the Y plane.<ul>
+ <li><span class="inline_code">OCDFMTDEF_REVERSED</span>
+ swaps the Cb and Cr components.</li>
+ </ul>
+ </li>
+</ul>
+<p class="Header3">Container (All)</p>
+<p>The container field indicates the total size of all the bits of the color
+components of a color format.&nbsp; This does not include the alpha component,
+if it is present.</p>
+<ul>
+ <li><span class="inline_code">OCDFMTDEF_CONTAINER_8BIT</span> -
+ Indicates the container is 8 bits.&nbsp; When the pixel
+ component size is 4 bits or less, multiple pixels are stored in
+ the container.</li>
+ <li><span class="inline_code">OCDFMTDEF_CONTAINER_16BIT</span> -
+ Indicates the container is 16 bits.&nbsp; When the pixel
+ component size is less than 16 bits, the remaining bits are
+ available to be used as an alpha channel.</li>
+ <li><span class="inline_code">OCDFMTDEF_CONTAINER_24BIT</span> -
+ Indicates the container is 24 bits.&nbsp; When the pixel
+ component size is less than 24 bits, the remaining bits are
+ available to be used as an alpha channel.</li>
+ <li><span class="inline_code">OCDFMTDEF_CONTAINER_32BIT</span> -
+ Indicates the container is 32 bits.&nbsp; When the pixel
+ component size is less than 32 bits, the remaining bits are
+ available to be used as an alpha channel.</li>
+ <li><span class="inline_code">OCDFMTDEF_CONTAINER_48BIT</span> -
+ Indicates the container is 48 bits.&nbsp; When the pixel
+ component size is less than 48 bits, the remaining bits are
+ available to be used as an alpha channel.</li>
+ <li><span class="inline_code">OCDFMTDEF_CONTAINER_64BIT</span> -
+ Indicates the container is 64 bits.&nbsp; When the pixel
+ component size is less than 64 bits, the remaining bits are
+ available to be used as an alpha channel.</li>
+</ul>
+<p class="Header3">Component Size (All)</p>
+<p>The component size field specifies the total number of bits in the color
+components, not including the alpha component.&nbsp; (It is specified in the
+code with one subtracted.)</p>
+<p class="note">NOTE:&nbsp; The alpha only color space uses this to specify the total number
+of alpha bits.</p>
+</body>
+
+</html>
diff --git a/bltsville/ocd/ocdlogo.jpg b/bltsville/ocd/ocdlogo.jpg
new file mode 100755
index 0000000..0537386
--- /dev/null
+++ b/bltsville/ocd/ocdlogo.jpg
Binary files differ
diff --git a/bltsville/ticpu/Android.mk b/bltsville/ticpu/Android.mk
new file mode 100755
index 0000000..1b855c8
--- /dev/null
+++ b/bltsville/ticpu/Android.mk
@@ -0,0 +1,53 @@
+#
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+#Copying libbltsville_ticpu.BV_CPUVERSION.so
+include $(CLEAR_VARS)
+BV_CPUVERSION :=$(shell ls $(COMMON_PATH)/bltsville/ticpu/lib/android/libbltsville_*.*.so|\
+ sed 's/device\/samsung\/omap4-common\/bltsville\/ticpu\/lib\/android\/libbltsville_ticpu.//')
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_MODULE := libbltsville_ticpu.$(BV_CPUVERSION)
+LOCAL_SRC_FILES := lib/android/libbltsville_ticpu.$(BV_CPUVERSION)
+LOCAL_MODULE_PATH:= $(TARGET_OUT_VENDOR)/lib
+include $(BUILD_PREBUILT)
+
+#Creating SymLinks
+#libbltsville_ticpu.so -> libbltsville_ticpu.BV_CPUVERSION.so
+#libbltsville_cpu.so -> libbltsville_ticpu.so
+SYMLINKS := $(TARGET_OUT_VENDOR)/lib/libbltsville_ticpu.so
+$(SYMLINKS): TICPU_BINARY := ./libbltsville_ticpu.$(BV_CPUVERSION)
+$(SYMLINKS): $(LOCAL_INSTALLED_MODULE) $(LOCAL_PATH)/Android.mk
+ @echo "Symlink: $@ -> $(TICPU_BINARY)"
+ @mkdir -p $(dir $@)
+ @rm -rf $@
+ $(hide) ln -fs $(TICPU_BINARY) $@
+ @cp -afr $(COMMON_PATH)/bltsville/ticpu/lib/android/libbltsville_ticpu_license.txt $(TARGET_OUT_VENDOR)/lib
+ALL_DEFAULT_INSTALLED_MODULES += $(SYMLINKS)
+
+SYMLINKS1 := $(TARGET_OUT_VENDOR)/lib/libbltsville_cpu.so
+$(SYMLINKS1): LINK_BINARY := ./libbltsville_ticpu.so
+$(SYMLINKS1): $(LOCAL_INSTALLED_MODULE) $(LOCAL_PATH)/Android.mk
+ @echo "Symlink: $@ -> $(LINK_BINARY)"
+ @mkdir -p $(dir $@)
+ @rm -rf $@
+ $(hide) ln -fs $(LINK_BINARY) $@
+ALL_DEFAULT_INSTALLED_MODULES += $(SYMLINKS1)
+
+# for mm
+all_modules: $(SYMLINKS) $(SYMLINKS1)
diff --git a/bltsville/ticpu/doc/android/BLTsville-Android-Release-Notes.html b/bltsville/ticpu/doc/android/BLTsville-Android-Release-Notes.html
new file mode 100755
index 0000000..21461b9
--- /dev/null
+++ b/bltsville/ticpu/doc/android/BLTsville-Android-Release-Notes.html
@@ -0,0 +1,15129 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
+<head>
+<title>
+</title>
+<meta http-equiv="Content-Language" content="en-us"/>
+<meta http-equiv="Content-Type" content='' "text/html; charset='utf-8'"/>
+<title>
+Welcome to BLTsville </title>
+<style type="text/css">
+.Title {
+ font-size: xx-large;
+ font-weight: bold;
+}
+.Subtitle {
+ font-size: x-large;
+ font-weight: bold;
+}
+.Section {
+ font-size: large;
+ font-weight: bold;
+}
+.Header {
+ font-weight: bold;
+}
+.ctr_small {
+ text-align: center;
+ font-size: small;
+}
+.rt {
+ text-align: right;
+}
+.Code {
+ font-family: "Courier New", Courier, monospace;
+}
+.list {
+ margin-left: 80px;
+}
+.note {
+ font-size: large;
+ font-weight: bold;
+ font-style: italic;
+ font-family: Arial, Helvetica, sans-serif;
+}
+.indent {
+ margin-left: 40px;
+}
+</style>
+</head>
+<body>
+<span class="Title">BLTsville for Android</span>
+<p class="Subtitle">
+ CPU Implementation - Version 2.1.0.0
+</p>
+<hr/>
+<p>
+ Copyright © 2012 Texas Instruments, Inc.
+</p>
+<p>
+ By using this software you agree that you have read, understood, and agree to be bound by the terms in the accompanying <a href="../license">
+ license</a> file, and to comply with all applicable laws and regulations regarding use of this software.&nbsp; If you do not agree to these terms, you do not have permission to use this software.
+</p>
+<hr/>
+<p class="Section">
+ What is BLTsville?
+</p>
+<p>
+ BLTsville is an open, non-implementation specific API for performing 2-D operations.&nbsp; It can control software and hardware implementations alike.&nbsp; Details are at <a href="http://bltsville.github.com">
+ http://bltsville.github.com</a>.
+</p>
+<hr/>
+<p class="Section">
+ What is this?
+</p>
+<p>
+ This is a CPU-based implementation which uses optimized ARM and Neon code to perform the 2-D operations.&nbsp; It can be distributed for use any Texas Instruments device.&nbsp; See the <a href="../license">license file</a> for details.
+</p>
+<hr/>
+<p>
+ <span class="Section">Known issues:</span>
+</p>
+<table>
+<tr>
+ <td>
+ <ul>
+ <li>Blend types <span class="Code">BVBLEND_SRC1</span> and <span class="Code">BVBLEND_SRC2</span> are functionally equivalent to ROPs of <span class="Code">0xCCCC</span> and <span class="Code">0xF0F0</span>, respectively.&nbsp; But these two ways of specifying the same operation currently take two different code paths, so:</li>
+ </ul>
+ <ol class="list">
+ <li>When a conversion is supported by both paths, the performance of them will differ.&nbsp; In general, the ROP path will be faster.</li>
+ <li>When a conversion is not supported in the ROP path, it may be supported in the blend path.</li>
+ <li>When a conversion is supported in the blend path, it may not be supported in the ROP path.</li>
+ </ol>
+ </td>
+</tr>
+</table>
+<p class="Section">
+ Bugfixes/Additions:
+</p>
+<table>
+<tr>
+ <td>
+ <p>
+ 2.1.0.0</p>
+ <ul>
+ <li>Updated headers to 2.1.0.0 (forwards and backwards compatible with clients).</li>
+ <li>Changed test for surface equality to use <span class="Code">bvbuffdesc</span> and <span class="Code">
+ bvsurfgeom</span> pointers (as per spec) instead of members.</li>
+ <li>Corrected inconsistent initial scaling phase when clipping.</li>
+ <li>Added error returns for rectangles in subsampled surfaces that split subsamples.</li>
+ <li>Corrected incorrect validation during scaling which could return error for properly clipped rectangles.</li>
+ <li>Loosened validation of <span class="Code">bvbuffmap</span> structures in <span class="Code">
+ bvbuffdesc.map</span> to avoid other implementation errors causing problems.</li>
+ <li>Improved <span class="Code">errdesc</span> messages to help with debugging.</li>
+ <li>Corrected color component error when using an RGBx24 solid color with a blend.</li>
+ </ul>
+ <p>
+ 2.0.0.10</p>
+ <ul>
+ <li>Fixed segfault when doing vertical scaling, but not horizontal.</li>
+ </ul>
+ <p>
+ 2.0.0.9</p>
+ <ul>
+ <li>Improved structure validation checks.</li>
+ <li>Fixed two issues that could cause access of <span class="Code">bvbltparams</span> members associated with unused surfaces.</li>
+ <li>Added validation of <span class="Code">dithermode</span> when doing fills (dithering not currently supported for fills).</li>
+ <li>Added support for <span class="Code">BVDITHER_GOOD_ON</span>, <span class="Code">BVDITHER_BETTER_ON</span>, and <span class="Code">BVDITHER_BEST_ON</span>.</li>
+ <li>Fixed issue with rotated surfaces and fills.</li>
+ <li>Added 4 new conversions:<ul>
+ <li>RGBx24 to UYVY</li>
+ <li>UYVY to RGBx24</li>
+ <li>NV12 to RGBx24</li>
+ <li>NV12 to BGRx24</li>
+ </ul>
+ </li>
+ <li>Added scaled RGBA24 SRC1OVER blend into RGB16 (source2 and destination must be the same).</li>
+ <li>Added scaled RGBA24 SRC1OVER blend into RGB16 with dithering (source2 and destination must be the same).</li>
+ <li>Changed method of non-interpolated upscaling for better pixel distribution.</li>
+ <li>Fixed incorrect color in RGBx24 to RGB16 dithering for images without a multiple of 8 width.</li>
+ </ul>
+ <p>
+ 2.0.0.8</p>
+ <ul>
+ <li>Fixed occasional failure to initialize that caused return of BVERR_RSRC.</li>
+ </ul>
+ <p>
+ 2.0.0.7</p>
+ <ul>
+ <li>Fixed typedef of bv_unmap member of bvbuffmap structure (bvinternal.h issue).</li>
+ <li>Fixed access-after-free bug in bv_unmap().</li>
+ <li>Changed method of handling over-read on last source line during scaling.</li>
+ </ul>
+ <p>
+ 2.0.0.6</p>
+ <ul>
+ <li>Added more dither validation.</li>
+ <li>Extended non-interpolated scaling to all supported 32-bit formats.</li>
+ <li>Added ordered 2x2/4x4 dither for RGBx24 to RGB16.</li>
+ <li>Fixed issue with NV12 rectangle offset that caused incorrect colors on right edge of images.</li>
+ <li>Added support for ALPHA8 as mask (instead of MONO8).</li>
+ </ul>
+ <p>
+ 2.0.0.5</p>
+ <ul>
+ <li>Fix for clipping regression of negative coordinates and clips result in NULL rectangles.</li>
+ <li>Fixed YUV to RGB conversion overflow if the YUV is out of (ITU-R Bt.601) range.</li>
+ <li>Fixed scaling and dithering for multi-threaded clients.</li>
+ </ul>
+ <p>
+ 2.0.0.4
+ </p>
+ <ul>
+ <li>Fix for clipping of scaled images.</li>
+ <li>Fix for random alpha value when converting from RGB16 to RGB124.</li>
+ <li>Fix for incorrect alpha used for right edge of scaled blend of RGBA24 to RGB124.</li>
+ <li>Fix for occasionally incorrect blend in scaled blend of RGBA24 to RGB124.</li>
+ <li>Fix to recognize global alpha supplied with SRC1 blend and return unsupported error.</li>
+ </ul>
+ <p>
+ 2.0.0.3
+ </p>
+ <ul>
+ <li>Fixed YV12 to NV12 bug which used wrong dimensions for source U and V planes.</li>
+ <li>Fixed clipping for blends.</li>
+ <li>Speed improvement for non-interpolated scale of RGB16 to RGB124.</li>
+ <li>Added SRC1OVER blend of non-interpolated scaled RGBA24 source 1 into RGBA24 or RGB124 destination (source 2 == destination).</li>
+ <li>Fixed error clipping images scaled vertically but not horizontally.</li>
+ <li>Added debug output (from errors) to logcat.</li>
+ </ul>
+ <p>
+ 2.0.0.2
+ </p>
+ <ul>
+ <li>Clipping added for all supported ROP operations
+ <ul>
+ <li>Solid Fill</li>
+ <li>Copy/Conversion</li>
+ <li>Rotation</li>
+ </ul>
+ </li>
+ <li>Fix for UYVY/VYUY 180° rotation</li>
+ <li>Fix for rotation normalization (calculating difference between surface orientations)</li>
+ <li>Removed double-rotation in some cases</li>
+ <li>Added check for NULL and inverted rectangles</li>
+ <li>8 new NV12 operations:
+ <ul>
+ <li>NV12 to RGB24</li>
+ <li>NV12 to BGR24</li>
+ <li>RGB16 to NV12</li>
+ <li>BGR16 to NV12</li>
+ <li>RGB24 to NV12</li>
+ <li>BGR24 to NV12</li>
+ <li>RGBx24 to NV12</li>
+ <li>BGRx24 to NV12</li>
+ </ul>
+ </li>
+ </ul>
+ <p>
+ 2.0.0.1
+ </p>
+ <ul>
+ <li>Fixed bad calculations when clipping.</li>
+ <li>Fixed clipping of negative rectangles when scaling.</li>
+ <li>Added rejection of scaled/clipped rectangles outside of surfaces.</li>
+ <li>Fixed error blending when local and global alphas are both used.</li>
+ </ul>
+ <p>
+ 2.0.0.0
+ </p>
+ <p class="indent">
+ Initial release
+ </p>
+ </td>
+</tr>
+</table>
+<p class="Section">
+ Contents:
+</p>
+<table border="1" cellpadding="2" cellspacing="2">
+<tr>
+ <td>
+ .../lib/android/libbltsville_cpu.so
+ </td>
+ <td>
+ Client entry point for CPU-based implementations. Softlink to libbltsville_ticpu.so.
+ </td>
+</tr>
+<tr>
+ <td>
+ .../lib/android/libbltsville_ticpu.so
+ </td>
+ <td>
+ Client entry point for special cases.&nbsp; Softlink to libbltsville_ticpu.2.0.0.10.so.&nbsp; (Most clients should not use this entry.)
+ </td>
+</tr>
+<tr>
+ <td>
+ .../lib/android/libbltsville_ticpu.2.0.0.10.so
+ </td>
+ <td>
+ Version 2.0.0.10 of the TI BLTsville CPU-based library of 2-D functions for Android.&nbsp; (Do not directly load this file.)
+ </td>
+</tr>
+</table>
+<p>
+ <span class="Header">To Install:</span>
+</p>
+<ol>
+ <li>
+ Copy .../lib/android/* to /system/vendor/lib on the target device. </li>
+</ol>
+<div>
+ <span class="note">NOTE: Two of the files are symbolic links, which require care when copying to avoid being replaced with a copy of the target library.</span>
+</div>
+<ul>
+ <li>
+ It may be necessary to reconstruct the links on the target platform using:&nbsp; <span class="Code">ln -s &lt;tgt&gt; &lt;lnk&gt;</span>
+ </li>
+</ul>
+<p class="note">
+ NOTE: The license file must be installed on the target system with the binaries.
+</p>
+<p class="Section">
+ Functions supported:
+</p>
+<table border="1" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="25" class="Header">
+ Solid Fill (1x1 Source 1)
+ </td>
+</tr>
+<tr>
+ <td colspan="25">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ LUT8
+ </td>
+ <td>
+ RGB16
+ </td>
+ <td>
+ BGR24
+ </td>
+ <td>
+ RGB24
+ </td>
+ <td>
+ BGR024
+ </td>
+ <td>
+ RGB024
+ </td>
+ <td>
+ BGR124
+ </td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ BGRA24
+ </td>
+ <td>
+ RGBA24
+ </td>
+ <td>
+ 0BGR24
+ </td>
+ <td>
+ 0RGB24
+ </td>
+ <td>
+ 1BGR24
+ </td>
+ <td>
+ 1RGB24
+ </td>
+ <td>
+ ABGR24
+ </td>
+ <td>
+ ARGB24
+ </td>
+ <td>
+ nBGRA24
+ </td>
+ <td>
+ nRGBA24
+ </td>
+ <td>
+ nABGR24
+ </td>
+ <td>
+ nARGB24
+ </td>
+ <td>
+ UYVY/Y422
+ </td>
+ <td>
+ YUYV/YUY2
+ </td>
+ <td>
+ IYUV/I420
+ </td>
+ <td>
+ NV12
+ </td>
+ <td>
+ YV12
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table style="background-color:#EBEBEB" border="1">
+<tr>
+ <td colspan="26" class="Header">
+ Color Space Conversion
+ </td>
+</tr>
+<tr>
+ <td>
+ Source&nbsp;1
+ </td>
+ <td colspan="25">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ LUT8
+ </td>
+ <td>
+ RGB16
+ </td>
+ <td>
+ BGR24
+ </td>
+ <td>
+ RGB24
+ </td>
+ <td>
+ BGR024
+ </td>
+ <td>
+ RGB024
+ </td>
+ <td>
+ BGR124
+ </td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ BGRA24
+ </td>
+ <td>
+ RGBA24
+ </td>
+ <td>
+ 0BGR24
+ </td>
+ <td>
+ 0RGB24
+ </td>
+ <td>
+ 1BGR24
+ </td>
+ <td>
+ 1RGB24
+ </td>
+ <td>
+ ABGR24
+ </td>
+ <td>
+ ARGB24
+ </td>
+ <td>
+ nBGRA24
+ </td>
+ <td>
+ nRGBA24
+ </td>
+ <td>
+ nABGR24
+ </td>
+ <td>
+ nARGB24
+ </td>
+ <td>
+ UYVY/Y422
+ </td>
+ <td>
+ YUYV/YUY2
+ </td>
+ <td>
+ IYUV/I420
+ </td>
+ <td>
+ NV12
+ </td>
+ <td>
+ YV12
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ LUT8
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR16
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ xBGR24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ xRGB24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ ABGR24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ ARGB24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nABGR24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nARGB24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ YUYV/YUY2
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ IYUV/I420
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ NV12
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ YV12
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table border="1" cellpadding="2" cellspacing="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="2" class="Header">
+ Color Space Conversion<br/>
+ (with Dither)
+ </td>
+</tr>
+<tr>
+ <td>
+ Source 1
+ </td>
+ <td rowspan="1">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;&nbsp;
+ </td>
+ <td>
+ RGB16
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24</td>
+ <td>
+ <img src="check.png" alt="+"/></td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table border="1" cellpadding="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="13" class="Header">
+ Scaling: Non-interpolated<br/>
+ (NEAREST_NEIGHBOR)
+ </td>
+</tr>
+<tr>
+ <td>
+ Source 1
+ </td>
+ <td colspan="12">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;&nbsp;
+ </td>
+ <td>
+ BGR124
+ </td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ 1BGR24
+ </td>
+ <td>
+ 1RGB24
+ </td>
+ <td>
+ BGRA24</td>
+ <td>
+ RGBA24</td>
+ <td>
+ ABGR24</td>
+ <td>
+ ARGB24</td>
+ <td>
+ nBGRA24</td>
+ <td>
+ nRGBA24</td>
+ <td>
+ nABGR24</td>
+ <td>
+ nARGB24</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ xBGR24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ xRGB24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ <img src="check.png" alt="+"/></td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ <img src="check.png" alt="+"/></td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ ABGR24</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ <img src="check.png" alt="+"/></td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ ARGB24</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ <img src="check.png" alt="+"/></td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ <img src="check.png" alt="+"/></td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ <img src="check.png" alt="+"/></td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nABGR24</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ <img src="check.png" alt="+"/></td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nARGB24</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ <img src="check.png" alt="+"/></td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table border="1" cellpadding="2" cellspacing="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="7" class="Header">
+ Rotation
+ </td>
+</tr>
+<tr>
+ <td>
+ Angle
+ </td>
+ <td colspan="6">
+ Format
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;&nbsp;
+ </td>
+ <td>
+ LUT8
+ </td>
+ <td>
+ RGB16
+ </td>
+ <td>
+ UYVY/Y422
+ </td>
+ <td>
+ YUYV/YUY2
+ </td>
+ <td>
+ IYUV/I420
+ </td>
+ <td>
+ NV12
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ 90 Degrees
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ 180 Degrees
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ 270 Degrees
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+</tr>
+</table>
+<p>
+ * = Rotation has width/height limitations.. See the chart below
+</p>
+<table border="1" cellpadding="2" cellspacing="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="7" class="Header">
+ Rotation Limitations
+ </td>
+</tr>
+<tr>
+ <td>
+ Angle
+ </td>
+ <td colspan="6">
+ Format
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;&nbsp;
+ </td>
+ <td>
+ LUT8
+ </td>
+ <td>
+ RGB16
+ </td>
+ <td>
+ UYVY/Y422
+ </td>
+ <td>
+ YUYV/YUY2
+ </td>
+ <td>
+ IYUV/I420
+ </td>
+ <td>
+ NV12
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ 90 Degrees
+ </td>
+ <td>
+ Multiple of 4 x 8&nbsp;
+ </td>
+ <td>
+ Multiple of 8 x 8
+ </td>
+ <td>
+ Multiple of 2 x 8
+ </td>
+ <td>
+ Multiple of 2 x 8
+ </td>
+ <td>
+ Multiple of 8 x 16
+ </td>
+ <td>
+ Multiple of 16 x 16
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ 180 Degrees
+ </td>
+ <td>
+ Multiple of 16 x 1
+ </td>
+ <td>
+ Multiple of 8 x 1
+ </td>
+ <td>
+ Multiple of 8 x 1
+ </td>
+ <td>
+ Multiple of 8 x 1
+ </td>
+ <td>
+ Multiple of 32 x 2
+ </td>
+ <td>
+ Multiple of 16 x 2
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ 270 Degrees
+ </td>
+ <td>
+ Multiple of 4 x 8
+ </td>
+ <td>
+ Multiple of 8 x 8
+ </td>
+ <td>
+ Multiple of 2 x 8
+ </td>
+ <td>
+ Multiple of 2 x 8
+ </td>
+ <td>
+ Multiple of 8 x 16
+ </td>
+ <td>
+ Multiple of 16 x 16
+ </td>
+</tr>
+</table>
+<p>
+ (Rotation does not support scaling.)
+</p>
+<p>
+ &nbsp;
+</p>
+<p>
+ (Blends do not support clipping or scaling.)<br/>
+ (Source 1 or Source 2 can be a 1x1 rectangle for solid color.)<br/>
+ (Color space conversion is performed as indicated.)
+</p>
+<table border="1" cellpadding="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="9" class="Header">
+ Blend: CLEAR
+ </td>
+</tr>
+<tr>
+ <td colspan="9">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ RGB16
+ </td>
+ <td>
+ BGR24
+ </td>
+ <td>
+ RGB24
+ </td>
+ <td>
+ BGR024
+ </td>
+ <td>
+ RGB024
+ </td>
+ <td>
+ BGR124
+ </td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ BGRA24
+ </td>
+ <td>
+ RGBA24
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>&nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table border="1" cellpadding="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="10" class="Header">
+ Blend: SRC1
+ </td>
+</tr>
+<tr>
+ <td>
+ Source 1
+ </td>
+ <td colspan="9">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;&nbsp;
+ </td>
+ <td>
+ RGB16
+ </td>
+ <td>
+ BGR24
+ </td>
+ <td>
+ RGB24
+ </td>
+ <td>
+ BGR024
+ </td>
+ <td>
+ RGB024
+ </td>
+ <td>
+ BGR124
+ </td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ BGRA24
+ </td>
+ <td>
+ RGBA24
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table border="1" cellpadding="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="10" class="Header">
+ Blend: SRC2
+ </td>
+</tr>
+<tr>
+ <td>
+ Source 2
+ </td>
+ <td colspan="9">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;&nbsp;
+ </td>
+ <td>
+ RGB16
+ </td>
+ <td>
+ BGR24
+ </td>
+ <td>
+ RGB24
+ </td>
+ <td>
+ BGR024
+ </td>
+ <td>
+ RGB024
+ </td>
+ <td>
+ BGR124
+ </td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ BGRA24
+ </td>
+ <td>
+ RGBA24
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table border="1" cellpadding="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="11" class="Header">
+ Blend: SRC1OVER<br/>
+ (uses only Source 1 and Source 2 alphas, if present)
+ </td>
+</tr>
+<tr>
+ <td>
+ Source 1
+ </td>
+ <td>
+ Source 2
+ </td>
+ <td colspan="9" rowspan="1">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ RGB16
+ </td>
+ <td>
+ BGR24
+ </td>
+ <td>
+ RGB24
+ </td>
+ <td>
+ BGR024
+ </td>
+ <td>
+ RGB024
+ </td>
+ <td>
+ BGR124
+ </td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ BGRA24
+ </td>
+ <td>
+ RGBA24
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td colspan="1" rowspan="10" class="rt">
+ BGRA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td colspan="1" rowspan="10" class="rt">
+ RGBA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td colspan="1" rowspan="10" class="rt">
+ nBGRA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td colspan="1" rowspan="10" class="rt">
+ nRGBA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table border="1" cellpadding="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="11" class="Header">
+ Blend: SRC1OVER | GLOBAL<br/>
+ (uses global alpha as well as source 1 and source 2 alphas, if present)
+ </td>
+</tr>
+<tr>
+ <td>
+ Source 1
+ </td>
+ <td>
+ Source 2
+ </td>
+ <td colspan="9" rowspan="1">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ RGB16
+ </td>
+ <td>
+ BGR24
+ </td>
+ <td>
+ RGB24
+ </td>
+ <td>
+ BGR024
+ </td>
+ <td>
+ RGB024
+ </td>
+ <td>
+ BGR124
+ </td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ BGRA24
+ </td>
+ <td>
+ RGBA24
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGB16
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ BGR24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGB24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ BGRx24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGBx24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ BGRA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGBA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ nBGRA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ nRGBA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ UYVY/Y422
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table border="1" cellpadding="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="11" class="Header">
+ Blend: SRC1OVER<br/>
+ (uses mask alpha&nbsp;as well as source 1 and source 2 alphas, if present)<br/>
+ (only mask format of ALPHA8 is supported)<br/>
+ </td>
+</tr>
+<tr>
+ <td>
+ Source 1
+ </td>
+ <td>
+ Source 2
+ </td>
+ <td colspan="9" rowspan="1">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ RGB16
+ </td>
+ <td>
+ BGR24
+ </td>
+ <td>
+ RGB24
+ </td>
+ <td>
+ BGR024
+ </td>
+ <td>
+ RGB024
+ </td>
+ <td>
+ BGR124
+ </td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ BGRA24
+ </td>
+ <td>
+ RGBA24
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGB16
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ BGR24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGB24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ BGRx24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGBx24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ BGRA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGBA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ nBGRA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ nRGBA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ UYVY/Y422
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table border="1" cellpadding="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="11" class="Header">
+ Blend: SRC1OVER<br/>
+ (uses global alpha, mask alpha, as well as source 1 and source 2 alphas, when present)<br/>
+ (only mask format of ALPHA8 is supported)
+ </td>
+</tr>
+<tr>
+ <td>
+ Source 1
+ </td>
+ <td>
+ Source 2
+ </td>
+ <td colspan="9" rowspan="1">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ RGB16
+ </td>
+ <td>
+ BGR24
+ </td>
+ <td>
+ RGB24
+ </td>
+ <td>
+ BGR024
+ </td>
+ <td>
+ RGB024
+ </td>
+ <td>
+ BGR124
+ </td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ BGRA24
+ </td>
+ <td>
+ RGBA24
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGB16
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ BGR24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGB24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ BGRx24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGBx24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ BGRA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGBA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ nBGRA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ nRGBA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ UYVY/Y422
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table border="1" cellpadding="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="5" class="Header">
+ Non-Interpolated Scale (Nearest Neighbor) + Blend: SRC1OVER<br/>
+ (uses only Source 1 and Source 2/Destination alphas, if present)
+ </td>
+</tr>
+<tr>
+ <td>
+ Source 1
+ </td>
+ <td>
+ Source 2
+ </td>
+ <td colspan="3" rowspan="1">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ RGB16</td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ RGBA24
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td colspan="1" rowspan="9" class="rt">
+ RGBA24
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB16</td>
+ <td>
+ <img src="check.png" alt="+"/>*,**</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ &nbsp;</td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+</tr>
+</table>
+<p>
+ * Source 2 and Destination must be the same surface (and have the same geometry) and share the same rectangle.<br />
+ ** With and without ordered dither.</p>
+</body>
+</html> \ No newline at end of file
diff --git a/bltsville/ticpu/doc/android/check.png b/bltsville/ticpu/doc/android/check.png
new file mode 100755
index 0000000..5577b45
--- /dev/null
+++ b/bltsville/ticpu/doc/android/check.png
Binary files differ
diff --git a/bltsville/ticpu/doc/linux/BLTsville-Linux-Release-Notes.html b/bltsville/ticpu/doc/linux/BLTsville-Linux-Release-Notes.html
new file mode 100755
index 0000000..32478ba
--- /dev/null
+++ b/bltsville/ticpu/doc/linux/BLTsville-Linux-Release-Notes.html
@@ -0,0 +1,15127 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
+<head>
+<title>
+</title>
+<meta http-equiv="Content-Language" content="en-us"/>
+<meta http-equiv="Content-Type" content='' "text/html; charset='utf-8'"/>
+<title>
+Welcome to BLTsville </title>
+<style type="text/css">
+.Title {
+ font-size: xx-large;
+ font-weight: bold;
+}
+.Subtitle {
+ font-size: x-large;
+ font-weight: bold;
+}
+.Section {
+ font-size: large;
+ font-weight: bold;
+}
+.Header {
+ font-weight: bold;
+}
+.ctr_small {
+ text-align: center;
+ font-size: small;
+}
+.rt {
+ text-align: right;
+}
+.Code {
+ font-family: "Courier New", Courier, monospace;
+}
+.list {
+ margin-left: 80px;
+}
+.note {
+ font-size: large;
+ font-weight: bold;
+ font-style: italic;
+ font-family: Arial, Helvetica, sans-serif;
+}
+.indent {
+ margin-left: 40px;
+}
+</style>
+</head>
+<body>
+<span class="Title">BLTsville for Linux</span>
+<p class="Subtitle">
+ CPU Implementation - Version 2.1.0.0</p>
+<hr/>
+<p>
+ Copyright © 2012 Texas Instruments, Inc.
+</p>
+<p>
+ By using this software you agree that you have read, understood, and agree to be bound by the terms in the accompanying <a href="../license">
+ license</a> file, and to comply with all applicable laws and regulations regarding use of this software.&nbsp; If you do not agree to these terms, you do not have permission to use this software.
+</p>
+<hr/>
+<p class="Section">
+ What is BLTsville?
+</p>
+<p>
+ BLTsville is an open, non-implementation specific API for performing 2-D operations.&nbsp; It can control software and hardware implementations alike.&nbsp; Details are at <a href="http://bltsville.github.com">
+ http://bltsville.github.com</a>.
+</p>
+<hr/>
+<p class="Section">
+ What is this?
+</p>
+<p>
+ This is a CPU-based implementation which uses optimized ARM and Neon code to perform the 2-D operations.&nbsp; It can be distributed for use any Texas Instruments device.&nbsp; See the <a href="../license">license file</a> for details.
+</p>
+<hr/>
+<p>
+ <span class="Section">Known issues:</span>
+</p>
+<table>
+<tr>
+ <td>
+ <ul>
+ <li>Blend types <span class="Code">BVBLEND_SRC1</span> and <span class="Code">BVBLEND_SRC2</span> are functionally equivalent to ROPs of <span class="Code">0xCCCC</span> and <span class="Code">0xF0F0</span>, respectively.&nbsp; But these two ways of specifying the same operation currently take two different code paths, so:</li>
+ </ul>
+ <ol class="list">
+ <li>When a conversion is supported by both paths, the performance of them will differ.&nbsp; In general, the ROP path will be faster.</li>
+ <li>When a conversion is not supported in the ROP path, it may be supported in the blend path.</li>
+ <li>When a conversion is supported in the blend path, it may not be supported in the ROP path.</li>
+ </ol>
+ </td>
+</tr>
+</table>
+<p class="Section">
+ Bugfixes/Additions:
+</p>
+<table>
+<tr>
+ <td>
+ <p>
+ 2.1.0.0</p>
+ <ul>
+ <li>Updated headers to 2.1.0.0 (forwards and backwards compatible with clients).</li>
+ <li>Changed test for surface equality to use <span class="Code">bvbuffdesc</span> and <span class="Code">
+ bvsurfgeom</span> pointers (as per spec) instead of members.</li>
+ <li>Corrected inconsistent initial scaling phase when clipping.</li>
+ <li>Added error returns for rectangles in subsampled surfaces that split subsamples.</li>
+ <li>Corrected incorrect validation during scaling which could return error for properly clipped rectangles.</li>
+ <li>Loosened validation of <span class="Code">bvbuffmap</span> structures in <span class="Code">
+ bvbuffdesc.map</span> to avoid other implementation errors causing problems.</li>
+ <li>Improved <span class="Code">errdesc</span> messages to help with debugging.</li>
+ <li>Corrected color component error when using an RGBx24 solid color with a blend.</li>
+ </ul>
+ <p>
+ 2.0.0.10</p>
+ <ul>
+ <li>Fixed segfault when doing vertical scaling, but not horizontal.</li>
+ </ul>
+ <p>
+ 2.0.0.9</p>
+ <ul>
+ <li>Improved structure validation checks.</li>
+ <li>Fixed two issues that could cause access of <span class="Code">bvbltparams</span> members associated with unused surfaces.</li>
+ <li>Added validation of <span class="Code">dithermode</span> when doing fills (dithering not currently supported for fills).</li>
+ <li>Added support for <span class="Code">BVDITHER_GOOD_ON</span>, <span class="Code">BVDITHER_BETTER_ON</span>, and <span class="Code">BVDITHER_BEST_ON</span>.</li>
+ <li>Fixed issue with rotated surfaces and fills.</li>
+ <li>Added 4 new conversions:<ul>
+ <li>RGBx24 to UYVY</li>
+ <li>UYVY to RGBx24</li>
+ <li>NV12 to RGBx24</li>
+ <li>NV12 to BGRx24</li>
+ </ul>
+ </li>
+ <li>Added scaled RGBA24 SRC1OVER blend into RGB16 (source2 and destination must be the same).</li>
+ <li>Added scaled RGBA24 SRC1OVER blend into RGB16 with dithering (source2 and destination must be the same).</li>
+ <li>Changed method of non-interpolated upscaling for better pixel distribution.</li>
+ <li>Fixed incorrect color in RGBx24 to RGB16 dithering for images without a multiple of 8 width.</li>
+ </ul>
+ <p>
+ 2.0.0.8</p>
+ <ul>
+ <li>Fixed occasional failure to initialize that caused return of BVERR_RSRC.</li>
+ </ul>
+ <p>
+ 2.0.0.7</p>
+ <ul>
+ <li>Fixed typedef of bv_unmap member of bvbuffmap structure (bvinternal.h issue).</li>
+ <li>Fixed access-after-free bug in bv_unmap().</li>
+ <li>Changed method of handling over-read on last source line during scaling.</li>
+ </ul>
+ <p>
+ 2.0.0.6</p>
+ <ul>
+ <li>Added more dither validation.</li>
+ <li>Extended non-interpolated scaling to all supported 32-bit formats.</li>
+ <li>Added ordered 2x2/4x4 dither for RGBx24 to RGB16.</li>
+ <li>Fixed issue with NV12 rectangle offset that caused incorrect colors on right edge of images.</li>
+ <li>Added support for ALPHA8 as mask (instead of MONO8).</li>
+ </ul>
+ <p>
+ 2.0.0.5</p>
+ <ul>
+ <li>Fix for clipping regression of negative coordinates and clips result in NULL rectangles.</li>
+ <li>Fixed YUV to RGB conversion overflow if the YUV is out of (ITU-R Bt.601) range.</li>
+ <li>Fixed scaling and dithering for multi-threaded clients.</li>
+ </ul>
+ <p>
+ 2.0.0.4
+ </p>
+ <ul>
+ <li>Fix for clipping of scaled images.</li>
+ <li>Fix for random alpha value when converting from RGB16 to RGB124.</li>
+ <li>Fix for incorrect alpha used for right edge of scaled blend of RGBA24 to RGB124.</li>
+ <li>Fix for occasionally incorrect blend in scaled blend of RGBA24 to RGB124.</li>
+ <li>Fix to recognize global alpha supplied with SRC1 blend and return unsupported error.</li>
+ </ul>
+ <p>
+ 2.0.0.3
+ </p>
+ <ul>
+ <li>Fixed YV12 to NV12 bug which used wrong dimensions for source U and V planes.</li>
+ <li>Fixed clipping for blends.</li>
+ <li>Speed improvement for non-interpolated scale of RGB16 to RGB124.</li>
+ <li>Added SRC1OVER blend of non-interpolated scaled RGBA24 source 1 into RGBA24 or RGB124 destination (source 2 == destination).</li>
+ <li>Fixed error clipping images scaled vertically but not horizontally.</li>
+ </ul>
+ <p>
+ 2.0.0.2
+ </p>
+ <ul>
+ <li>Clipping added for all supported ROP operations
+ <ul>
+ <li>Solid Fill</li>
+ <li>Copy/Conversion</li>
+ <li>Rotation</li>
+ </ul>
+ </li>
+ <li>Fix for UYVY/VYUY 180° rotation</li>
+ <li>Fix for rotation normalization (calculating difference between surface orientations)</li>
+ <li>Removed double-rotation in some cases</li>
+ <li>Added check for NULL and inverted rectangles</li>
+ <li>8 new NV12 operations:
+ <ul>
+ <li>NV12 to RGB24</li>
+ <li>NV12 to BGR24</li>
+ <li>RGB16 to NV12</li>
+ <li>BGR16 to NV12</li>
+ <li>RGB24 to NV12</li>
+ <li>BGR24 to NV12</li>
+ <li>RGBx24 to NV12</li>
+ <li>BGRx24 to NV12</li>
+ </ul>
+ </li>
+ </ul>
+ <p>
+ 2.0.0.1
+ </p>
+ <ul>
+ <li>Fixed bad calculations when clipping.</li>
+ <li>Fixed clipping of negative rectangles when scaling.</li>
+ <li>Added rejection of scaled/clipped rectangles outside of surfaces.</li>
+ <li>Fixed error blending when local and global alphas are both used.</li>
+ </ul>
+ <p>
+ 2.0.0.0
+ </p>
+ <p class="indent">
+ Initial release
+ </p>
+ </td>
+</tr>
+</table>
+<p class="Section">
+ Contents:
+</p>
+<table border="1" cellpadding="2" cellspacing="2">
+<tr>
+ <td>
+ .../lib/linux/libbltsville_cpu.so
+ </td>
+ <td>
+ Client entry point for CPU-based implementations. Softlink to libbltsville_ticpu.so.
+ </td>
+</tr>
+<tr>
+ <td>
+ .../lib/linux/libbltsville_ticpu.so
+ </td>
+ <td>
+ Client entry point for special cases.&nbsp; Softlink to libbltsville_ticpu.so.2.0.0.10.&nbsp; (Most clients should not use this entry.)
+ </td>
+</tr>
+<tr>
+ <td>
+ .../lib/linux/libbltsville_ticpu.so.2.0.0.10
+ </td>
+ <td>
+ Version 2.0.0.10 of the TI BLTsville CPU-based library of 2-D functions for Linux.&nbsp; (Do not directly load this file.)
+ </td>
+</tr>
+</table>
+<p>
+ <span class="Header">To Install:</span>
+</p>
+<ol>
+ <li>
+ Copy .../lib/linux/* to /lib on the target device. </li>
+</ol>
+<div>
+ <span class="note">NOTE: Two of the files are symbolic links, which require care when copying to avoid being replaced with a copy of the target library.</span>
+</div>
+<ul>
+ <li>
+ It may be necessary to reconstruct the links on the target platform using:&nbsp; <span class="Code">ln -s &lt;tgt&gt; &lt;lnk&gt;</span>
+ </li>
+</ul>
+<p class="note">
+ NOTE: The license file must be installed on the target system with the binaries.
+</p>
+<p class="Section">
+ Functions supported:
+</p>
+<table border="1" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="25" class="Header">
+ Solid Fill (1x1 Source 1)
+ </td>
+</tr>
+<tr>
+ <td colspan="25">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ LUT8
+ </td>
+ <td>
+ RGB16
+ </td>
+ <td>
+ BGR24
+ </td>
+ <td>
+ RGB24
+ </td>
+ <td>
+ BGR024
+ </td>
+ <td>
+ RGB024
+ </td>
+ <td>
+ BGR124
+ </td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ BGRA24
+ </td>
+ <td>
+ RGBA24
+ </td>
+ <td>
+ 0BGR24
+ </td>
+ <td>
+ 0RGB24
+ </td>
+ <td>
+ 1BGR24
+ </td>
+ <td>
+ 1RGB24
+ </td>
+ <td>
+ ABGR24
+ </td>
+ <td>
+ ARGB24
+ </td>
+ <td>
+ nBGRA24
+ </td>
+ <td>
+ nRGBA24
+ </td>
+ <td>
+ nABGR24
+ </td>
+ <td>
+ nARGB24
+ </td>
+ <td>
+ UYVY/Y422
+ </td>
+ <td>
+ YUYV/YUY2
+ </td>
+ <td>
+ IYUV/I420
+ </td>
+ <td>
+ NV12
+ </td>
+ <td>
+ YV12
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table style="background-color:#EBEBEB" border="1">
+<tr>
+ <td colspan="26" class="Header">
+ Color Space Conversion
+ </td>
+</tr>
+<tr>
+ <td>
+ Source&nbsp;1
+ </td>
+ <td colspan="25">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ LUT8
+ </td>
+ <td>
+ RGB16
+ </td>
+ <td>
+ BGR24
+ </td>
+ <td>
+ RGB24
+ </td>
+ <td>
+ BGR024
+ </td>
+ <td>
+ RGB024
+ </td>
+ <td>
+ BGR124
+ </td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ BGRA24
+ </td>
+ <td>
+ RGBA24
+ </td>
+ <td>
+ 0BGR24
+ </td>
+ <td>
+ 0RGB24
+ </td>
+ <td>
+ 1BGR24
+ </td>
+ <td>
+ 1RGB24
+ </td>
+ <td>
+ ABGR24
+ </td>
+ <td>
+ ARGB24
+ </td>
+ <td>
+ nBGRA24
+ </td>
+ <td>
+ nRGBA24
+ </td>
+ <td>
+ nABGR24
+ </td>
+ <td>
+ nARGB24
+ </td>
+ <td>
+ UYVY/Y422
+ </td>
+ <td>
+ YUYV/YUY2
+ </td>
+ <td>
+ IYUV/I420
+ </td>
+ <td>
+ NV12
+ </td>
+ <td>
+ YV12
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ LUT8
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR16
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ xBGR24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ xRGB24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ ABGR24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ ARGB24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nABGR24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nARGB24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ YUYV/YUY2
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ IYUV/I420
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ NV12
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ YV12
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table border="1" cellpadding="2" cellspacing="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="2" class="Header">
+ Color Space Conversion<br/>
+ (with Dither)
+ </td>
+</tr>
+<tr>
+ <td>
+ Source 1
+ </td>
+ <td rowspan="1">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;&nbsp;
+ </td>
+ <td>
+ RGB16
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24</td>
+ <td>
+ <img src="check.png" alt="+"/></td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table border="1" cellpadding="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="13" class="Header">
+ Scaling: Non-interpolated<br/>
+ (NEAREST_NEIGHBOR)
+ </td>
+</tr>
+<tr>
+ <td>
+ Source 1
+ </td>
+ <td colspan="12">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;&nbsp;
+ </td>
+ <td>
+ BGR124
+ </td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ 1BGR24
+ </td>
+ <td>
+ 1RGB24
+ </td>
+ <td>
+ BGRA24</td>
+ <td>
+ RGBA24</td>
+ <td>
+ ABGR24</td>
+ <td>
+ ARGB24</td>
+ <td>
+ nBGRA24</td>
+ <td>
+ nRGBA24</td>
+ <td>
+ nABGR24</td>
+ <td>
+ nARGB24</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ xBGR24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ xRGB24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ <img src="check.png" alt="+"/></td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ <img src="check.png" alt="+"/></td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ ABGR24</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ <img src="check.png" alt="+"/></td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ ARGB24</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ <img src="check.png" alt="+"/></td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ <img src="check.png" alt="+"/></td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ <img src="check.png" alt="+"/></td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nABGR24</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ <img src="check.png" alt="+"/></td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nARGB24</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ <img src="check.png" alt="+"/></td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table border="1" cellpadding="2" cellspacing="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="7" class="Header">
+ Rotation
+ </td>
+</tr>
+<tr>
+ <td>
+ Angle
+ </td>
+ <td colspan="6">
+ Format
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;&nbsp;
+ </td>
+ <td>
+ LUT8
+ </td>
+ <td>
+ RGB16
+ </td>
+ <td>
+ UYVY/Y422
+ </td>
+ <td>
+ YUYV/YUY2
+ </td>
+ <td>
+ IYUV/I420
+ </td>
+ <td>
+ NV12
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ 90 Degrees
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ 180 Degrees
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ 270 Degrees
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+</tr>
+</table>
+<p>
+ * = Rotation has width/height limitations.. See the chart below
+</p>
+<table border="1" cellpadding="2" cellspacing="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="7" class="Header">
+ Rotation Limitations
+ </td>
+</tr>
+<tr>
+ <td>
+ Angle
+ </td>
+ <td colspan="6">
+ Format
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;&nbsp;
+ </td>
+ <td>
+ LUT8
+ </td>
+ <td>
+ RGB16
+ </td>
+ <td>
+ UYVY/Y422
+ </td>
+ <td>
+ YUYV/YUY2
+ </td>
+ <td>
+ IYUV/I420
+ </td>
+ <td>
+ NV12
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ 90 Degrees
+ </td>
+ <td>
+ Multiple of 4 x 8&nbsp;
+ </td>
+ <td>
+ Multiple of 8 x 8
+ </td>
+ <td>
+ Multiple of 2 x 8
+ </td>
+ <td>
+ Multiple of 2 x 8
+ </td>
+ <td>
+ Multiple of 8 x 16
+ </td>
+ <td>
+ Multiple of 16 x 16
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ 180 Degrees
+ </td>
+ <td>
+ Multiple of 16 x 1
+ </td>
+ <td>
+ Multiple of 8 x 1
+ </td>
+ <td>
+ Multiple of 8 x 1
+ </td>
+ <td>
+ Multiple of 8 x 1
+ </td>
+ <td>
+ Multiple of 32 x 2
+ </td>
+ <td>
+ Multiple of 16 x 2
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ 270 Degrees
+ </td>
+ <td>
+ Multiple of 4 x 8
+ </td>
+ <td>
+ Multiple of 8 x 8
+ </td>
+ <td>
+ Multiple of 2 x 8
+ </td>
+ <td>
+ Multiple of 2 x 8
+ </td>
+ <td>
+ Multiple of 8 x 16
+ </td>
+ <td>
+ Multiple of 16 x 16
+ </td>
+</tr>
+</table>
+<p>
+ (Rotation does not support scaling.)
+</p>
+<p>
+ &nbsp;
+</p>
+<p>
+ (Blends do not support clipping or scaling.)<br/>
+ (Source 1 or Source 2 can be a 1x1 rectangle for solid color.)<br/>
+ (Color space conversion is performed as indicated.)
+</p>
+<table border="1" cellpadding="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="9" class="Header">
+ Blend: CLEAR
+ </td>
+</tr>
+<tr>
+ <td colspan="9">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ RGB16
+ </td>
+ <td>
+ BGR24
+ </td>
+ <td>
+ RGB24
+ </td>
+ <td>
+ BGR024
+ </td>
+ <td>
+ RGB024
+ </td>
+ <td>
+ BGR124
+ </td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ BGRA24
+ </td>
+ <td>
+ RGBA24
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>&nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table border="1" cellpadding="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="10" class="Header">
+ Blend: SRC1
+ </td>
+</tr>
+<tr>
+ <td>
+ Source 1
+ </td>
+ <td colspan="9">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;&nbsp;
+ </td>
+ <td>
+ RGB16
+ </td>
+ <td>
+ BGR24
+ </td>
+ <td>
+ RGB24
+ </td>
+ <td>
+ BGR024
+ </td>
+ <td>
+ RGB024
+ </td>
+ <td>
+ BGR124
+ </td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ BGRA24
+ </td>
+ <td>
+ RGBA24
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table border="1" cellpadding="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="10" class="Header">
+ Blend: SRC2
+ </td>
+</tr>
+<tr>
+ <td>
+ Source 2
+ </td>
+ <td colspan="9">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;&nbsp;
+ </td>
+ <td>
+ RGB16
+ </td>
+ <td>
+ BGR24
+ </td>
+ <td>
+ RGB24
+ </td>
+ <td>
+ BGR024
+ </td>
+ <td>
+ RGB024
+ </td>
+ <td>
+ BGR124
+ </td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ BGRA24
+ </td>
+ <td>
+ RGBA24
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table border="1" cellpadding="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="11" class="Header">
+ Blend: SRC1OVER<br/>
+ (uses only Source 1 and Source 2 alphas, if present)
+ </td>
+</tr>
+<tr>
+ <td>
+ Source 1
+ </td>
+ <td>
+ Source 2
+ </td>
+ <td colspan="9" rowspan="1">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ RGB16
+ </td>
+ <td>
+ BGR24
+ </td>
+ <td>
+ RGB24
+ </td>
+ <td>
+ BGR024
+ </td>
+ <td>
+ RGB024
+ </td>
+ <td>
+ BGR124
+ </td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ BGRA24
+ </td>
+ <td>
+ RGBA24
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td colspan="1" rowspan="10" class="rt">
+ BGRA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td colspan="1" rowspan="10" class="rt">
+ RGBA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td colspan="1" rowspan="10" class="rt">
+ nBGRA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td colspan="1" rowspan="10" class="rt">
+ nRGBA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table border="1" cellpadding="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="11" class="Header">
+ Blend: SRC1OVER | GLOBAL<br/>
+ (uses global alpha as well as source 1 and source 2 alphas, if present)
+ </td>
+</tr>
+<tr>
+ <td>
+ Source 1
+ </td>
+ <td>
+ Source 2
+ </td>
+ <td colspan="9" rowspan="1">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ RGB16
+ </td>
+ <td>
+ BGR24
+ </td>
+ <td>
+ RGB24
+ </td>
+ <td>
+ BGR024
+ </td>
+ <td>
+ RGB024
+ </td>
+ <td>
+ BGR124
+ </td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ BGRA24
+ </td>
+ <td>
+ RGBA24
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGB16
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ BGR24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGB24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ BGRx24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGBx24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ BGRA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGBA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ nBGRA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ nRGBA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ UYVY/Y422
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table border="1" cellpadding="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="11" class="Header">
+ Blend: SRC1OVER<br/>
+ (uses mask alpha&nbsp;as well as source 1 and source 2 alphas, if present)<br/>
+ (only mask format of ALPHA8 is supported)<br/>
+ </td>
+</tr>
+<tr>
+ <td>
+ Source 1
+ </td>
+ <td>
+ Source 2
+ </td>
+ <td colspan="9" rowspan="1">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ RGB16
+ </td>
+ <td>
+ BGR24
+ </td>
+ <td>
+ RGB24
+ </td>
+ <td>
+ BGR024
+ </td>
+ <td>
+ RGB024
+ </td>
+ <td>
+ BGR124
+ </td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ BGRA24
+ </td>
+ <td>
+ RGBA24
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGB16
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ BGR24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGB24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ BGRx24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGBx24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ BGRA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGBA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ nBGRA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ nRGBA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ UYVY/Y422
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table border="1" cellpadding="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="11" class="Header">
+ Blend: SRC1OVER<br/>
+ (uses global alpha, mask alpha, as well as source 1 and source 2 alphas, when present)<br/>
+ (only mask format of ALPHA8 is supported)
+ </td>
+</tr>
+<tr>
+ <td>
+ Source 1
+ </td>
+ <td>
+ Source 2
+ </td>
+ <td colspan="9" rowspan="1">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ RGB16
+ </td>
+ <td>
+ BGR24
+ </td>
+ <td>
+ RGB24
+ </td>
+ <td>
+ BGR024
+ </td>
+ <td>
+ RGB024
+ </td>
+ <td>
+ BGR124
+ </td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ BGRA24
+ </td>
+ <td>
+ RGBA24
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGB16
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ BGR24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGB24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ BGRx24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGBx24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ BGRA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ RGBA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ nBGRA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ nRGBA24
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td rowspan="10" class="rt">
+ UYVY/Y422
+ </td>
+ <td class="rt">
+ RGB16
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGR24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ BGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nBGRA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ nRGBA24
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ UYVY/Y422
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>
+ </td>
+</tr>
+</table>
+<p>
+ &nbsp;
+</p>
+<table border="1" cellpadding="2" style="background-color:#EBEBEB">
+<tr>
+ <td colspan="5" class="Header">
+ Non-Interpolated Scale (Nearest Neighbor) + Blend: SRC1OVER<br/>
+ (uses only Source 1 and Source 2/Destination alphas, if present)
+ </td>
+</tr>
+<tr>
+ <td>
+ Source 1
+ </td>
+ <td>
+ Source 2
+ </td>
+ <td colspan="3" rowspan="1">
+ Destination
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ RGB16</td>
+ <td>
+ RGB124
+ </td>
+ <td>
+ RGBA24
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td colspan="1" rowspan="9" class="rt">
+ RGBA24
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGB16</td>
+ <td>
+ <img src="check.png" alt="+"/>*,**</td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;</td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBx24
+ </td>
+ <td>
+ &nbsp;</td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+ <td>
+ &nbsp;
+ </td>
+</tr>
+<tr class="ctr_small">
+ <td class="rt">
+ RGBA24
+ </td>
+ <td>
+ &nbsp;</td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <img src="check.png" alt="+"/>*
+ </td>
+</tr>
+</table>
+<p>
+ * Source 2 and Destination must be the same surface (and have the same geometry) and share the same rectangle.<br />
+ ** With and without ordered dither.</p>
+</body>
+</html> \ No newline at end of file
diff --git a/bltsville/ticpu/doc/linux/check.png b/bltsville/ticpu/doc/linux/check.png
new file mode 100755
index 0000000..5577b45
--- /dev/null
+++ b/bltsville/ticpu/doc/linux/check.png
Binary files differ
diff --git a/bltsville/ticpu/lib/android/libbltsville_cpu.so b/bltsville/ticpu/lib/android/libbltsville_cpu.so
new file mode 120000
index 0000000..bd98087
--- /dev/null
+++ b/bltsville/ticpu/lib/android/libbltsville_cpu.so
@@ -0,0 +1 @@
+./libbltsville_ticpu.so \ No newline at end of file
diff --git a/bltsville/ticpu/lib/android/libbltsville_ticpu.2.1.0.0.so b/bltsville/ticpu/lib/android/libbltsville_ticpu.2.1.0.0.so
new file mode 100755
index 0000000..00ca919
--- /dev/null
+++ b/bltsville/ticpu/lib/android/libbltsville_ticpu.2.1.0.0.so
Binary files differ
diff --git a/bltsville/ticpu/lib/android/libbltsville_ticpu.so b/bltsville/ticpu/lib/android/libbltsville_ticpu.so
new file mode 120000
index 0000000..7a8974c
--- /dev/null
+++ b/bltsville/ticpu/lib/android/libbltsville_ticpu.so
@@ -0,0 +1 @@
+./libbltsville_ticpu.2.1.0.0.so \ No newline at end of file
diff --git a/bltsville/ticpu/lib/android/libbltsville_ticpu_license.txt b/bltsville/ticpu/lib/android/libbltsville_ticpu_license.txt
new file mode 100755
index 0000000..a96c003
--- /dev/null
+++ b/bltsville/ticpu/lib/android/libbltsville_ticpu_license.txt
@@ -0,0 +1,172 @@
+Texas Instruments Incorporated
+Technology and Software Publicly Available
+Software License Agreement
+
+Copyright (c) 2012 Texas Instruments Incorporated
+
+Important: Please read the following license agreement carefully. This
+is a legally binding agreement. Do not use or redistribute the Licensed
+Materials unless: (1) you are authorized to accept and agree to the terms
+of this software license agreement and (2) you intend to enter into and to
+be bound by the terms of this agreement.
+
+This Software License Agreement ("License") is a legal agreement between you
+(either an individual or entity) and Texas Instruments Incorporated ("TI"),
+12500 TI Boulevard, Dallas, Texas 75243. The "Licensed Materials" subject
+to this License include, in whole or in part, the software programs that
+accompany this License. By installing, copying or otherwise using the
+Licensed Materials you agree to abide by the terms of this License. If you
+choose not to accept or agree with these terms, you must immediately cease
+any use, copying or redistribution and destroy the Licensed Materials.
+
+NOTE: The Licensed Materials may be bundled with open source software and
+separate license terms may apply. For clarification, this License does not
+license, limit your rights under, nor does it grant you rights that
+supersede, the license terms of any applicable open source license agreement.
+
+1. Object Code License. TI hereby grants to you a limited, non-exclusive
+license to reproduce and use the Licensed Materials provided to you in object
+code format and to distribute an unlimited number of object or executable
+copies of such Licensed Materials provided that Licensed Materials are used
+solely and exclusively on devices manufactured by or for TI. Redistributions
+must reproduce the copyright notices and all the terms of this License in the
+documentation and/or other materials provided with the Licensed Materials.
+Licensed Materials may not be distributed under terms different than this
+License.
+
+2. Termination. This license is effective until terminated. Without
+prejudice to any other rights, TI may terminate your right to use the
+Licensed Materials under this License if you fail to comply with the terms
+of this License. In such event, you shall destroy all copies of the Licensed
+Materials, including all portions and derivatives thereof.
+
+3. Intellectual Property Rights.
+
+a. The Licensed Materials being provided to you hereunder are being made
+publicly available by TI, even though they contain copyrighted material of TI
+and its licensors, if applicable. In no event may you alter, remove or
+destroy any copyright notice included in the Licensed Materials. To the
+extent that any of the Licensed Materials are provided in binary or object
+code only, you may not unlock, decompile, reverse engineer, disassemble or
+otherwise translate such binary or object code to human-perceivable form.
+The source code of such reverse engineered code may contain TI trade secret
+and other proprietary information. Further, nothing shall obligate TI to
+provide you with source code for the Licensed Materials licensed to you in
+binary or object code only under this License. TI reserves all rights not
+specifically granted under this License.
+
+b. Certain Licensed Materials may
+(i) require patent licenses from third parties claiming patent rights
+covering implementation of the Licensed Materials or
+(ii) be based on industry recognized standards or software programs
+published by industry recognized standards bodies and certain third parties
+may claim to own patents or copyrights that cover implementation of those
+standards. You acknowledge and agree that this License does not convey a
+license to any such third party patents and copyrights.
+
+c. YOU ACKNOWLEDGE AND AGREE THAT TI SHALL NOT BE LIABLE FOR AND SHALL NOT
+DEFEND OR INDEMNIFY YOU AGAINST ANY THIRD PARTY INFRINGEMENT CLAIM THAT
+RELATES TO OR IS BASED ON YOUR MANUFACTURE, USE, OR DISTRIBUTION OF THE
+LICENSED MATERIALS OR YOUR MANUFACTURE, USE, OFFER FOR SALE, SALE,
+IMPORTATION OR DISTRIBUTION OF YOUR PRODUCTS THAT INCLUDE OR INCORPORATE
+THE LICENSED MATERIALS.
+
+d. You acknowledge and agree that you are responsible for any fees or
+royalties that may be payable to any third party based on such third party's
+interests in the Licensed Materials described in Section 3(b) above (the
+"Third Party Payment Obligations"). You agree to indemnify TI against any
+Third Party Payment Obligations and will defend any claim, suit or
+proceeding brought against TI insofar as such claim, suit or proceeding is
+based on your failure to pay any Third Party Payment Obligations.
+
+4. Warranties and Limitations. THE LICENSED MATERIALS ARE PROVIDED "AS IS".
+TI AND ITS LICENSORS MAKE NO WARRANTY OR REPRESENTATION, EXPRESS, IMPLIED
+OR STATUTORY, INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTIBILITY, FITNESS
+FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS OF
+RESPONSES, RESULTS AND LACK OF NEGLIGENCE. TI DISCLAIMS ANY WARRANTY OF
+TITLE, QUIET ENJOYMENT, QUIET POSESSION, AND NON-INFRINGEMENT OF ANY THIRD
+PARTY INTELLECTUAL PROPERTY RIGHTS WITH REGARD TO THE LICENSED MATERIALS OR
+USE OF THOSE MATERIALS.
+
+YOU ACKNOWLEDGE AND AGREE THAT THE LICENSED MATERIALS MAY NOT BE INTENDED FOR
+PRODUCTION APPLICATIONS AND MAY CONTAIN IRREGULARITIES AND DEFECTS NOT FOUND
+IN PRODUCTION SOFTWARE. FURTHERMORE, YOU ACKNOWLEDGE AND AGREE THAT THE
+LICENSED MATERIALS HAVE NOT BEEN TESTED OR CERTIFIED BY ANY GOVERNMENT AGENCY
+OR INDUSTRY REGULATORY ORGANIZATION OR ANY OTHER THIRD PARTY ORGANIZATION.
+YOU AGREE THAT PRIOR TO USING, INCORPORATING OR DISTRIBUTING THE LICENSED
+MATERIALS IN OR WITH ANY COMMERCIAL PRODUCT THAT YOU WILL THOROUGHLY TEST THE
+PRODUCT AND THE FUNCTIONALITY OF THE LICENSED MATERIALS IN OR WITH THAT
+PRODUCT AND BE SOLELY RESPONSIBLE FOR ANY PROBLEMS OR FAILURES.
+
+IN NO EVENT SHALL TI OR ITS LICENSORS BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, PUNITIVE OR CONSEQUENTIAL DAMAGES, HOWEVER CAUSED ON ANY THEORY OF
+LIABILITY, ARISING IN ANY WAY OUT OF THIS LICENSE, OR YOUR USE OF THE
+LICENSED MATERIALS, WHETHER OR NOT TI HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES. EXCLUDED DAMAGES INCLUDE, BUT ARE NOT LIMITED TO, COST OF
+REMOVAL OR REINSTALLATION, OUTSIDE COMPUTER TIME, LABOR COSTS, LOSS OR
+CORRUPTION OF DATA, LOSS OF GOODWILL, LOSS OF PROFITS, LOSS OF SAVINGS, OR
+LOSS OF USE OR INTERRUPTION OF BUSINESS OR ANY OTHER ECONOMIC LOSS. IN NO
+EVENT WILL TI'S AGGREGATE LIABILITY UNDER THIS LICENSE OR ARISING OUT OF YOUR
+USE OF THE LICENSED MATERIALS EXCEED FIVE HUNDRED U.S. DOLLARS (US$500).
+
+Because some jurisdictions do not allow the exclusion or limitation of
+incidental or consequential damages or limitation on how long an implied
+warranty lasts, the above limitations or exclusions may not apply to you.
+
+5. Export Control. The software programs and any on-line documentation as
+well as any updates or upgrades to such software programs or documentation may
+be subject to the export or import regulations of certain countries. You agree
+to comply with all such regulations and acknowledge that you have the
+responsibility to obtain any licenses or other authorizations that may be
+required to export, re-export or import the Licensed Materials.
+
+6. Governing Law, Jurisdiction and Severability. This License will be
+governed by and interpreted in accordance with the laws of the State of
+Texas, without reference to that state's conflict of laws principles. This
+License shall not be governed by the United Nations Convention on Contracts
+for the International Sale of Goods, nor shall it be governed by the Uniform
+Computer Information Transactions Act (UCITA). Any dispute arising out of or
+related to this License will be brought in, and each party consents to the
+exclusive jurisdiction and venue in the state and federal courts sitting in
+Dallas Country, Texas. Each party waives all defenses of lack of personal
+jurisdiction and forum non-conveniens and agrees that process may be served on
+either party in a manner authorized by applicable law or court rule. If for
+any reason a court of competent jurisdiction finds any provision of the
+License to be unenforceable, that provision will be enforced to the maximum
+extent possible to effectuate the intent of the parties and the remainder
+of the License shall continue in full force and effect.
+
+7. PRC Provisions. If you are located in the People's Republic of China
+("PRC") or if the Licensed Materials will be sent to the PRC, the following
+provisions shall apply and shall supersede any other provisions in this
+License concerning the same subject matter as the following provisions:
+
+ a. Registration Requirements. You shall be solely responsible for performing
+ all acts and obtaining all approvals that may be required in connection with
+ this License by the government of the PRC, including but not limited to
+ registering pursuant to, and otherwise complying with, the PRC Measures on
+ the Administration of Software Products, Management Regulations on Technology
+ Import-Export, and Technology Import and Export Contract Registration
+ Management Rules. Upon receipt of such approvals from the government
+ authorities, you shall forward evidence of all such approvals to TI for its
+ records. In the event that you fail to obtain any such approval or
+ registration, you shall be solely responsible for any and all losses, damages
+ or costs resulting therefrom, and shall indemnify TI for all such losses,
+ damages or costs.
+
+ b. Governing Language. This License is written and executed in the English
+ language. If a translation of this License is required for any purpose,
+ including but not limited to registration of the License pursuant to any
+ governmental laws, regulations or rules, you shall be solely responsible for
+ creating such translation. Any translation of this License into a language
+ other than English is intended solely in order to comply with such laws or
+ for reference purposes, and the English language version shall be
+ authoritative and controlling.
+
+8. Entire Agreement. This License is the entire agreement between you and TI
+and supersedes any prior agreement between the parties related to the subject
+matter of this License. No amendment or modification of this License will be
+effective unless in writing and signed by a duly authorized representative of
+TI. You hereby warrant and represent that you have obtained all
+authorizations and other applicable consents required empowering you to enter
+into this License.
diff --git a/bltsville/ticpu/lib/linux/libbltsville_cpu.so b/bltsville/ticpu/lib/linux/libbltsville_cpu.so
new file mode 120000
index 0000000..bd98087
--- /dev/null
+++ b/bltsville/ticpu/lib/linux/libbltsville_cpu.so
@@ -0,0 +1 @@
+./libbltsville_ticpu.so \ No newline at end of file
diff --git a/bltsville/ticpu/lib/linux/libbltsville_ticpu.so b/bltsville/ticpu/lib/linux/libbltsville_ticpu.so
new file mode 120000
index 0000000..d6f50f9
--- /dev/null
+++ b/bltsville/ticpu/lib/linux/libbltsville_ticpu.so
@@ -0,0 +1 @@
+./libbltsville_ticpu.so.2.1.0.0 \ No newline at end of file
diff --git a/bltsville/ticpu/lib/linux/libbltsville_ticpu.so.2.1.0.0 b/bltsville/ticpu/lib/linux/libbltsville_ticpu.so.2.1.0.0
new file mode 100755
index 0000000..31866f7
--- /dev/null
+++ b/bltsville/ticpu/lib/linux/libbltsville_ticpu.so.2.1.0.0
Binary files differ
diff --git a/bltsville/ticpu/lib/linux/libbltsville_ticpu_license.txt b/bltsville/ticpu/lib/linux/libbltsville_ticpu_license.txt
new file mode 100755
index 0000000..a96c003
--- /dev/null
+++ b/bltsville/ticpu/lib/linux/libbltsville_ticpu_license.txt
@@ -0,0 +1,172 @@
+Texas Instruments Incorporated
+Technology and Software Publicly Available
+Software License Agreement
+
+Copyright (c) 2012 Texas Instruments Incorporated
+
+Important: Please read the following license agreement carefully. This
+is a legally binding agreement. Do not use or redistribute the Licensed
+Materials unless: (1) you are authorized to accept and agree to the terms
+of this software license agreement and (2) you intend to enter into and to
+be bound by the terms of this agreement.
+
+This Software License Agreement ("License") is a legal agreement between you
+(either an individual or entity) and Texas Instruments Incorporated ("TI"),
+12500 TI Boulevard, Dallas, Texas 75243. The "Licensed Materials" subject
+to this License include, in whole or in part, the software programs that
+accompany this License. By installing, copying or otherwise using the
+Licensed Materials you agree to abide by the terms of this License. If you
+choose not to accept or agree with these terms, you must immediately cease
+any use, copying or redistribution and destroy the Licensed Materials.
+
+NOTE: The Licensed Materials may be bundled with open source software and
+separate license terms may apply. For clarification, this License does not
+license, limit your rights under, nor does it grant you rights that
+supersede, the license terms of any applicable open source license agreement.
+
+1. Object Code License. TI hereby grants to you a limited, non-exclusive
+license to reproduce and use the Licensed Materials provided to you in object
+code format and to distribute an unlimited number of object or executable
+copies of such Licensed Materials provided that Licensed Materials are used
+solely and exclusively on devices manufactured by or for TI. Redistributions
+must reproduce the copyright notices and all the terms of this License in the
+documentation and/or other materials provided with the Licensed Materials.
+Licensed Materials may not be distributed under terms different than this
+License.
+
+2. Termination. This license is effective until terminated. Without
+prejudice to any other rights, TI may terminate your right to use the
+Licensed Materials under this License if you fail to comply with the terms
+of this License. In such event, you shall destroy all copies of the Licensed
+Materials, including all portions and derivatives thereof.
+
+3. Intellectual Property Rights.
+
+a. The Licensed Materials being provided to you hereunder are being made
+publicly available by TI, even though they contain copyrighted material of TI
+and its licensors, if applicable. In no event may you alter, remove or
+destroy any copyright notice included in the Licensed Materials. To the
+extent that any of the Licensed Materials are provided in binary or object
+code only, you may not unlock, decompile, reverse engineer, disassemble or
+otherwise translate such binary or object code to human-perceivable form.
+The source code of such reverse engineered code may contain TI trade secret
+and other proprietary information. Further, nothing shall obligate TI to
+provide you with source code for the Licensed Materials licensed to you in
+binary or object code only under this License. TI reserves all rights not
+specifically granted under this License.
+
+b. Certain Licensed Materials may
+(i) require patent licenses from third parties claiming patent rights
+covering implementation of the Licensed Materials or
+(ii) be based on industry recognized standards or software programs
+published by industry recognized standards bodies and certain third parties
+may claim to own patents or copyrights that cover implementation of those
+standards. You acknowledge and agree that this License does not convey a
+license to any such third party patents and copyrights.
+
+c. YOU ACKNOWLEDGE AND AGREE THAT TI SHALL NOT BE LIABLE FOR AND SHALL NOT
+DEFEND OR INDEMNIFY YOU AGAINST ANY THIRD PARTY INFRINGEMENT CLAIM THAT
+RELATES TO OR IS BASED ON YOUR MANUFACTURE, USE, OR DISTRIBUTION OF THE
+LICENSED MATERIALS OR YOUR MANUFACTURE, USE, OFFER FOR SALE, SALE,
+IMPORTATION OR DISTRIBUTION OF YOUR PRODUCTS THAT INCLUDE OR INCORPORATE
+THE LICENSED MATERIALS.
+
+d. You acknowledge and agree that you are responsible for any fees or
+royalties that may be payable to any third party based on such third party's
+interests in the Licensed Materials described in Section 3(b) above (the
+"Third Party Payment Obligations"). You agree to indemnify TI against any
+Third Party Payment Obligations and will defend any claim, suit or
+proceeding brought against TI insofar as such claim, suit or proceeding is
+based on your failure to pay any Third Party Payment Obligations.
+
+4. Warranties and Limitations. THE LICENSED MATERIALS ARE PROVIDED "AS IS".
+TI AND ITS LICENSORS MAKE NO WARRANTY OR REPRESENTATION, EXPRESS, IMPLIED
+OR STATUTORY, INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTIBILITY, FITNESS
+FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS OF
+RESPONSES, RESULTS AND LACK OF NEGLIGENCE. TI DISCLAIMS ANY WARRANTY OF
+TITLE, QUIET ENJOYMENT, QUIET POSESSION, AND NON-INFRINGEMENT OF ANY THIRD
+PARTY INTELLECTUAL PROPERTY RIGHTS WITH REGARD TO THE LICENSED MATERIALS OR
+USE OF THOSE MATERIALS.
+
+YOU ACKNOWLEDGE AND AGREE THAT THE LICENSED MATERIALS MAY NOT BE INTENDED FOR
+PRODUCTION APPLICATIONS AND MAY CONTAIN IRREGULARITIES AND DEFECTS NOT FOUND
+IN PRODUCTION SOFTWARE. FURTHERMORE, YOU ACKNOWLEDGE AND AGREE THAT THE
+LICENSED MATERIALS HAVE NOT BEEN TESTED OR CERTIFIED BY ANY GOVERNMENT AGENCY
+OR INDUSTRY REGULATORY ORGANIZATION OR ANY OTHER THIRD PARTY ORGANIZATION.
+YOU AGREE THAT PRIOR TO USING, INCORPORATING OR DISTRIBUTING THE LICENSED
+MATERIALS IN OR WITH ANY COMMERCIAL PRODUCT THAT YOU WILL THOROUGHLY TEST THE
+PRODUCT AND THE FUNCTIONALITY OF THE LICENSED MATERIALS IN OR WITH THAT
+PRODUCT AND BE SOLELY RESPONSIBLE FOR ANY PROBLEMS OR FAILURES.
+
+IN NO EVENT SHALL TI OR ITS LICENSORS BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, PUNITIVE OR CONSEQUENTIAL DAMAGES, HOWEVER CAUSED ON ANY THEORY OF
+LIABILITY, ARISING IN ANY WAY OUT OF THIS LICENSE, OR YOUR USE OF THE
+LICENSED MATERIALS, WHETHER OR NOT TI HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES. EXCLUDED DAMAGES INCLUDE, BUT ARE NOT LIMITED TO, COST OF
+REMOVAL OR REINSTALLATION, OUTSIDE COMPUTER TIME, LABOR COSTS, LOSS OR
+CORRUPTION OF DATA, LOSS OF GOODWILL, LOSS OF PROFITS, LOSS OF SAVINGS, OR
+LOSS OF USE OR INTERRUPTION OF BUSINESS OR ANY OTHER ECONOMIC LOSS. IN NO
+EVENT WILL TI'S AGGREGATE LIABILITY UNDER THIS LICENSE OR ARISING OUT OF YOUR
+USE OF THE LICENSED MATERIALS EXCEED FIVE HUNDRED U.S. DOLLARS (US$500).
+
+Because some jurisdictions do not allow the exclusion or limitation of
+incidental or consequential damages or limitation on how long an implied
+warranty lasts, the above limitations or exclusions may not apply to you.
+
+5. Export Control. The software programs and any on-line documentation as
+well as any updates or upgrades to such software programs or documentation may
+be subject to the export or import regulations of certain countries. You agree
+to comply with all such regulations and acknowledge that you have the
+responsibility to obtain any licenses or other authorizations that may be
+required to export, re-export or import the Licensed Materials.
+
+6. Governing Law, Jurisdiction and Severability. This License will be
+governed by and interpreted in accordance with the laws of the State of
+Texas, without reference to that state's conflict of laws principles. This
+License shall not be governed by the United Nations Convention on Contracts
+for the International Sale of Goods, nor shall it be governed by the Uniform
+Computer Information Transactions Act (UCITA). Any dispute arising out of or
+related to this License will be brought in, and each party consents to the
+exclusive jurisdiction and venue in the state and federal courts sitting in
+Dallas Country, Texas. Each party waives all defenses of lack of personal
+jurisdiction and forum non-conveniens and agrees that process may be served on
+either party in a manner authorized by applicable law or court rule. If for
+any reason a court of competent jurisdiction finds any provision of the
+License to be unenforceable, that provision will be enforced to the maximum
+extent possible to effectuate the intent of the parties and the remainder
+of the License shall continue in full force and effect.
+
+7. PRC Provisions. If you are located in the People's Republic of China
+("PRC") or if the Licensed Materials will be sent to the PRC, the following
+provisions shall apply and shall supersede any other provisions in this
+License concerning the same subject matter as the following provisions:
+
+ a. Registration Requirements. You shall be solely responsible for performing
+ all acts and obtaining all approvals that may be required in connection with
+ this License by the government of the PRC, including but not limited to
+ registering pursuant to, and otherwise complying with, the PRC Measures on
+ the Administration of Software Products, Management Regulations on Technology
+ Import-Export, and Technology Import and Export Contract Registration
+ Management Rules. Upon receipt of such approvals from the government
+ authorities, you shall forward evidence of all such approvals to TI for its
+ records. In the event that you fail to obtain any such approval or
+ registration, you shall be solely responsible for any and all losses, damages
+ or costs resulting therefrom, and shall indemnify TI for all such losses,
+ damages or costs.
+
+ b. Governing Language. This License is written and executed in the English
+ language. If a translation of this License is required for any purpose,
+ including but not limited to registration of the License pursuant to any
+ governmental laws, regulations or rules, you shall be solely responsible for
+ creating such translation. Any translation of this License into a language
+ other than English is intended solely in order to comply with such laws or
+ for reference purposes, and the English language version shall be
+ authoritative and controlling.
+
+8. Entire Agreement. This License is the entire agreement between you and TI
+and supersedes any prior agreement between the parties related to the subject
+matter of this License. No amendment or modification of this License will be
+effective unless in writing and signed by a duly authorized representative of
+TI. You hereby warrant and represent that you have obtained all
+authorizations and other applicable consents required empowering you to enter
+into this License.
diff --git a/bltsville/ticpu/license b/bltsville/ticpu/license
new file mode 100755
index 0000000..998bb60
--- /dev/null
+++ b/bltsville/ticpu/license
@@ -0,0 +1,173 @@
+Texas Instruments Incorporated
+Technology and Software Publicly Available
+Software License Agreement
+
+Copyright © 2011 Texas Instruments Incorporated
+Copyright Imagination Technology, Ltd.
+
+Important: Please read the following license agreement carefully. This
+is a legally binding agreement. Do not use or redistribute the Licensed
+Materials unless: (1) you are authorized to accept and agree to the terms
+of this software license agreement and (2) you intend to enter into and to
+be bound by the terms of this agreement.
+
+This Software License Agreement ("License") is a legal agreement between you
+(either an individual or entity) and Texas Instruments Incorporated ("TI"),
+12500 TI Boulevard, Dallas, Texas 75243. The "Licensed Materials" subject
+to this License include, in whole or in part, the software programs that
+accompany this License. By installing, copying or otherwise using the
+Licensed Materials you agree to abide by the terms of this License. If you
+choose not to accept or agree with these terms, you must immediately cease
+any use, copying or redistribution and destroy the Licensed Materials.
+
+NOTE: The Licensed Materials may be bundled with open source software and
+separate license terms may apply. For clarification, this License does not
+license, limit your rights under, nor does it grant you rights that
+supersede, the license terms of any applicable open source license agreement.
+
+1. Object Code License. TI hereby grants to you a limited, non-exclusive
+license to reproduce and use the Licensed Materials provided to you in object
+code format and to distribute an unlimited number of object or executable
+copies of such Licensed Materials provided that Licensed Materials are used
+solely and exclusively on devices manufactured by or for TI. Redistributions
+must reproduce the copyright notices and all the terms of this License in the
+documentation and/or other materials provided with the Licensed Materials.
+Licensed Materials may not be distributed under terms different than this
+License.
+
+2. Termination. This license is effective until terminated. Without
+prejudice to any other rights, TI may terminate your right to use the
+Licensed Materials under this License if you fail to comply with the terms
+of this License. In such event, you shall destroy all copies of the Licensed
+Materials, including all portions and derivatives thereof.
+
+3. Intellectual Property Rights.
+
+a. The Licensed Materials being provided to you hereunder are being made
+publicly available by TI, even though they contain copyrighted material of TI
+and its licensors, if applicable. In no event may you alter, remove or
+destroy any copyright notice included in the Licensed Materials. To the
+extent that any of the Licensed Materials are provided in binary or object
+code only, you may not unlock, decompile, reverse engineer, disassemble or
+otherwise translate such binary or object code to human-perceivable form.
+The source code of such reverse engineered code may contain TI trade secret
+and other proprietary information. Further, nothing shall obligate TI to
+provide you with source code for the Licensed Materials licensed to you in
+binary or object code only under this License. TI reserves all rights not
+specifically granted under this License.
+
+b. Certain Licensed Materials may
+(i) require patent licenses from third parties claiming patent rights
+covering implementation of the Licensed Materials or
+(ii) be based on industry recognized standards or software programs
+published by industry recognized standards bodies and certain third parties
+may claim to own patents or copyrights that cover implementation of those
+standards. You acknowledge and agree that this License does not convey a
+license to any such third party patents and copyrights.
+
+c. YOU ACKNOWLEDGE AND AGREE THAT TI SHALL NOT BE LIABLE FOR AND SHALL NOT
+DEFEND OR INDEMNIFY YOU AGAINST ANY THIRD PARTY INFRINGEMENT CLAIM THAT
+RELATES TO OR IS BASED ON YOUR MANUFACTURE, USE, OR DISTRIBUTION OF THE
+LICENSED MATERIALS OR YOUR MANUFACTURE, USE, OFFER FOR SALE, SALE,
+IMPORTATION OR DISTRIBUTION OF YOUR PRODUCTS THAT INCLUDE OR INCORPORATE
+THE LICENSED MATERIALS.
+
+d. You acknowledge and agree that you are responsible for any fees or
+royalties that may be payable to any third party based on such third party's
+interests in the Licensed Materials described in Section 3(b) above (the
+"Third Party Payment Obligations"). You agree to indemnify TI against any
+Third Party Payment Obligations and will defend any claim, suit or
+proceeding brought against TI insofar as such claim, suit or proceeding is
+based on your failure to pay any Third Party Payment Obligations.
+
+4. Warranties and Limitations. THE LICENSED MATERIALS ARE PROVIDED "AS IS".
+TI AND ITS LICENSORS MAKE NO WARRANTY OR REPRESENTATION, EXPRESS, IMPLIED
+OR STATUTORY, INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTIBILITY, FITNESS
+FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS OF
+RESPONSES, RESULTS AND LACK OF NEGLIGENCE. TI DISCLAIMS ANY WARRANTY OF
+TITLE, QUIET ENJOYMENT, QUIET POSESSION, AND NON-INFRINGEMENT OF ANY THIRD
+PARTY INTELLECTUAL PROPERTY RIGHTS WITH REGARD TO THE LICENSED MATERIALS OR
+USE OF THOSE MATERIALS.
+
+YOU ACKNOWLEDGE AND AGREE THAT THE LICENSED MATERIALS MAY NOT BE INTENDED FOR
+PRODUCTION APPLICATIONS AND MAY CONTAIN IRREGULARITIES AND DEFECTS NOT FOUND
+IN PRODUCTION SOFTWARE. FURTHERMORE, YOU ACKNOWLEDGE AND AGREE THAT THE
+LICENSED MATERIALS HAVE NOT BEEN TESTED OR CERTIFIED BY ANY GOVERNMENT AGENCY
+OR INDUSTRY REGULATORY ORGANIZATION OR ANY OTHER THIRD PARTY ORGANIZATION.
+YOU AGREE THAT PRIOR TO USING, INCORPORATING OR DISTRIBUTING THE LICENSED
+MATERIALS IN OR WITH ANY COMMERCIAL PRODUCT THAT YOU WILL THOROUGHLY TEST THE
+PRODUCT AND THE FUNCTIONALITY OF THE LICENSED MATERIALS IN OR WITH THAT
+PRODUCT AND BE SOLELY RESPONSIBLE FOR ANY PROBLEMS OR FAILURES.
+
+IN NO EVENT SHALL TI OR ITS LICENSORS BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, PUNITIVE OR CONSEQUENTIAL DAMAGES, HOWEVER CAUSED ON ANY THEORY OF
+LIABILITY, ARISING IN ANY WAY OUT OF THIS LICENSE, OR YOUR USE OF THE
+LICENSED MATERIALS, WHETHER OR NOT TI HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES. EXCLUDED DAMAGES INCLUDE, BUT ARE NOT LIMITED TO, COST OF
+REMOVAL OR REINSTALLATION, OUTSIDE COMPUTER TIME, LABOR COSTS, LOSS OR
+CORRUPTION OF DATA, LOSS OF GOODWILL, LOSS OF PROFITS, LOSS OF SAVINGS, OR
+LOSS OF USE OR INTERRUPTION OF BUSINESS OR ANY OTHER ECONOMIC LOSS. IN NO
+EVENT WILL TI'S AGGREGATE LIABILITY UNDER THIS LICENSE OR ARISING OUT OF YOUR
+USE OF THE LICENSED MATERIALS EXCEED FIVE HUNDRED U.S. DOLLARS (US$500).
+
+Because some jurisdictions do not allow the exclusion or limitation of
+incidental or consequential damages or limitation on how long an implied
+warranty lasts, the above limitations or exclusions may not apply to you.
+
+5. Export Control. The software programs and any on-line documentation as
+well as any updates or upgrades to such software programs or documentation may
+be subject to the export or import regulations of certain countries. You agree
+to comply with all such regulations and acknowledge that you have the
+responsibility to obtain any licenses or other authorizations that may be
+required to export, re-export or import the Licensed Materials.
+
+6. Governing Law, Jurisdiction and Severability. This License will be
+governed by and interpreted in accordance with the laws of the State of
+Texas, without reference to that state's conflict of laws principles. This
+License shall not be governed by the United Nations Convention on Contracts
+for the International Sale of Goods, nor shall it be governed by the Uniform
+Computer Information Transactions Act (UCITA). Any dispute arising out of or
+related to this License will be brought in, and each party consents to the
+exclusive jurisdiction and venue in the state and federal courts sitting in
+Dallas Country, Texas. Each party waives all defenses of lack of personal
+jurisdiction and forum non-conveniens and agrees that process may be served on
+either party in a manner authorized by applicable law or court rule. If for
+any reason a court of competent jurisdiction finds any provision of the
+License to be unenforceable, that provision will be enforced to the maximum
+extent possible to effectuate the intent of the parties and the remainder
+of the License shall continue in full force and effect.
+
+7. PRC Provisions. If you are located in the People's Republic of China
+("PRC") or if the Licensed Materials will be sent to the PRC, the following
+provisions shall apply and shall supersede any other provisions in this
+License concerning the same subject matter as the following provisions:
+
+ a. Registration Requirements. You shall be solely responsible for performing
+ all acts and obtaining all approvals that may be required in connection with
+ this License by the government of the PRC, including but not limited to
+ registering pursuant to, and otherwise complying with, the PRC Measures on
+ the Administration of Software Products, Management Regulations on Technology
+ Import-Export, and Technology Import and Export Contract Registration
+ Management Rules. Upon receipt of such approvals from the government
+ authorities, you shall forward evidence of all such approvals to TI for its
+ records. In the event that you fail to obtain any such approval or
+ registration, you shall be solely responsible for any and all losses, damages
+ or costs resulting therefrom, and shall indemnify TI for all such losses,
+ damages or costs.
+
+ b. Governing Language. This License is written and executed in the English
+ language. If a translation of this License is required for any purpose,
+ including but not limited to registration of the License pursuant to any
+ governmental laws, regulations or rules, you shall be solely responsible for
+ creating such translation. Any translation of this License into a language
+ other than English is intended solely in order to comply with such laws or
+ for reference purposes, and the English language version shall be
+ authoritative and controlling.
+
+8. Entire Agreement. This License is the entire agreement between you and TI
+and supersedes any prior agreement between the parties related to the subject
+matter of this License. No amendment or modification of this License will be
+effective unless in writing and signed by a duly authorized representative of
+TI. You hereby warrant and represent that you have obtained all
+authorizations and other applicable consents required empowering you to enter
+into this License.
diff --git a/common.mk b/common.mk
new file mode 100644
index 0000000..3fe7fe6
--- /dev/null
+++ b/common.mk
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2013 The CyanogenMod Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+COMMON_PATH := device/samsung/omap4-common
+
+DEVICE_PACKAGE_OVERLAYS += $(COMMON_PATH)/overlay
+
+# Omap4 Packages
+PRODUCT_PACKAGES += \
+ libedid \
+ libion_ti \
+ libstagefrighthw \
+ smc_pa_ctrl \
+ tf_daemon
+
+PRODUCT_PACKAGES += \
+ audio.a2dp.default \
+ audio.usb.default \
+ libtinyalsa \
+ libaudioutils \
+ libnetcmdiface \
+ tinyplay \
+ tinycap \
+ tinymix
+
+# Filesystem management tools
+PRODUCT_PACKAGES += \
+ static_busybox \
+ make_ext4fs \
+ setup_fs
+
+PRODUCT_PROPERTY_OVERRIDES += \
+ com.ti.omap_enhancement=true \
+ omap.enhancement=true \
+
+# Set default USB interface
+PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
+ persist.sys.usb.config=mtp
+
+$(call inherit-product, hardware/ti/omap4xxx/omap4.mk)
+
+# Include non-opensource parts if available
+$(call inherit-product-if-exists, vendor/samsung/omap4-common/common-vendor.mk)
diff --git a/edid/Android.mk b/edid/Android.mk
new file mode 100644
index 0000000..d1bace0
--- /dev/null
+++ b/edid/Android.mk
@@ -0,0 +1,45 @@
+# Copyright (C) Texas Instruments - http://www.ti.com/
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# AOSP specific
+ifneq ($(TARGET_PRODUCT),full_$(TARGET_BOOTLOADER_BOARD_NAME))
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ lib/edid_parser.c
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libedid
+
+include $(BUILD_SHARED_LIBRARY)
+
+# ====================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ cmd/parse_hdmi_edid.c
+
+LOCAL_SHARED_LIBRARIES:= \
+ libutils \
+ libedid
+
+LOCAL_MODULE:= parse_hdmi_edid
+LOCAL_MODULE_TAGS:= optional
+
+include $(BUILD_EXECUTABLE)
+
+endif
diff --git a/edid/cmd/parse_hdmi_edid.c b/edid/cmd/parse_hdmi_edid.c
new file mode 100644
index 0000000..9f84505
--- /dev/null
+++ b/edid/cmd/parse_hdmi_edid.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) Texas Instruments - http://www.ti.com/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <fcntl.h>
+
+#define LOG_TAG "EDID"
+#include <utils/Log.h>
+
+#include <inc/edid_parser.h>
+
+static const char kHdmiEdidPathName[] = "/sys/devices/platform/omapdss/display1/edid";
+
+static void print_s3d_format_info(struct edid_t *edid, const struct hdmi_s3d_format_info_t *info)
+{
+ unsigned int i;
+ if(info == NULL) {
+ return;
+ }
+
+ switch(info->format) {
+ case HDMI_FRAME_PACKING:
+ fprintf(stdout, "--Frame Packing");
+ break;
+ case HDMI_FIELD_ALTERNATIVE:
+ fprintf(stdout, "--Filed Alternative");
+ break;
+ case HDMI_LINE_ALTERNATIVE:
+ fprintf(stdout, "--Line Alternative");
+ break;
+ case HDMI_SIDE_BY_SIDE_FULL:
+ fprintf(stdout, "--Side by Side FULL");
+ break;
+ case HDMI_L_DEPTH:
+ fprintf(stdout, "--L + Depth");
+ break;
+ case HDMI_L_DEPTH_GFX_GFX_DEPTH:
+ fprintf(stdout, "--L + Depth + Graphics + Graphics + Depth");
+ break;
+ case HDMI_TOPBOTTOM:
+ fprintf(stdout, "--Top Bottom");
+ break;
+ case HDMI_SIDE_BY_SIDE_HALF:
+ fprintf(stdout, "--Side by Side HALF");
+ break;
+ default:
+ fprintf(stdout, "--Unkown format");
+ break;
+ }
+ fprintf(stdout, "\n");
+
+ for (i = 0; i < info->num_valid_vic; i++) {
+ const struct svd_t * svd = edid_get_svd_descriptor(edid, info->vic_info[i].vic_pos);
+ fprintf(stdout, "----Mode:%s sub-sampling: ", svd->info.name);
+ switch(info->vic_info[i].subsampling) {
+ case HDMI_SS_HORZANDQUINCUNX:
+ fprintf(stdout, "Horizontal and Quincunx");
+ break;
+ case HDMI_SS_HORIZONTAL:
+ fprintf(stdout, "Horizontal");
+ break;
+ case HDMI_SS_QUINCUNX_ALL:
+ fprintf(stdout, "Quincunx");
+ break;
+ case HDMI_SS_QUINCUNX_OLOR:
+ fprintf(stdout, "Quincunx Odd-Left/Odd-Right");
+ break;
+ case HDMI_SS_QUINCUNX_OLER:
+ fprintf(stdout, "Quincunx Odd-Left/Even-Right");
+ break;
+ case HDMI_SS_QUINCUNX_ELOR:
+ fprintf(stdout, "Quincunx Even-Left/Odd-Right");
+ break;
+ case HDMI_SS_QUINCUNX_ELER:
+ fprintf(stdout, "Quincunx Even-Left/Even-Right");
+ break;
+ case HDMI_SS_VERTICAL:
+ fprintf(stdout, "Vertical");
+ break;
+ case HDMI_SS_NONE:
+ fprintf(stdout, "None");
+ break;
+ default:
+ break;
+ }
+ fprintf(stdout, "\n");
+ }
+
+}
+int main()
+{
+ unsigned int i;
+ struct svd_t *svd_list;
+ unsigned int num_svds;
+
+ int fd = open(kHdmiEdidPathName, O_RDONLY);
+
+ if (!fd) {
+ return 1;
+ }
+
+ uint8_t edid_data[EDID_SIZE];
+ size_t bytes_read = read(fd, edid_data, EDID_SIZE);
+ close(fd);
+
+ if (bytes_read < EDID_SIZE) {
+ fprintf(stderr, "Could not read EDID data\n");
+ return 1;
+ }
+
+ struct edid_t *edid = NULL;
+ if(edid_parser_init(&edid, edid_data)) {
+ fprintf(stderr, "Could not init parser\n");
+ return 1;
+ }
+
+ edid_get_svd_list(edid, &svd_list, &num_svds);
+
+ fprintf(stdout, "EDID Info\n");
+ fprintf(stdout, "[Short Video Descriptors]\n");
+ for (i = 0; i < num_svds; i++) {
+ fprintf(stdout, "----%d: %s [code:%d, native:%d] [xres:%d, yres:%d Hz:%d]\n",
+ i, svd_list[i].info.name, svd_list[i].code, svd_list[i].native,
+ svd_list[i].info.xres, svd_list[i].info.yres, svd_list[i].info.hz);
+ }
+
+ fprintf(stdout, "\n[S3D Optional Formats]\n");
+ print_s3d_format_info(edid, edid_get_s3d_format_info(edid, HDMI_FRAME_PACKING));
+ print_s3d_format_info(edid, edid_get_s3d_format_info(edid, HDMI_FIELD_ALTERNATIVE));
+ print_s3d_format_info(edid, edid_get_s3d_format_info(edid, HDMI_LINE_ALTERNATIVE));
+ print_s3d_format_info(edid, edid_get_s3d_format_info(edid, HDMI_SIDE_BY_SIDE_FULL));
+ print_s3d_format_info(edid, edid_get_s3d_format_info(edid, HDMI_L_DEPTH));
+ print_s3d_format_info(edid, edid_get_s3d_format_info(edid, HDMI_L_DEPTH_GFX_GFX_DEPTH));
+ print_s3d_format_info(edid, edid_get_s3d_format_info(edid, HDMI_TOPBOTTOM));
+ print_s3d_format_info(edid, edid_get_s3d_format_info(edid, HDMI_SIDE_BY_SIDE_HALF));
+
+ edid_parser_deinit(edid);
+
+ return 0;
+}
diff --git a/edid/inc/edid_parser.h b/edid/inc/edid_parser.h
new file mode 100644
index 0000000..9dba5f4
--- /dev/null
+++ b/edid/inc/edid_parser.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) Texas Instruments - http://www.ti.com/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _EDID_PARSER_
+#define _EDID_PARSER_
+
+#define EDID_SIZE 256
+#define MAX_VIC_CODES_PER_3D_FORMAT 16
+
+struct edid_t;
+
+enum datablock_id {
+ DATABLOCK_AUDIO = 1,
+ DATABLOCK_VIDEO = 2,
+ DATABLOCK_VENDOR = 3,
+ DATABLOCK_SPEAKERS = 4,
+};
+
+enum hdmi_3d_format {
+ HDMI_FRAME_PACKING = 0,
+ HDMI_FIELD_ALTERNATIVE = 1,
+ HDMI_LINE_ALTERNATIVE = 2,
+ HDMI_SIDE_BY_SIDE_FULL = 3,
+ HDMI_L_DEPTH = 4,
+ HDMI_L_DEPTH_GFX_GFX_DEPTH = 5,
+ HDMI_TOPBOTTOM = 6,
+ HDMI_SIDE_BY_SIDE_HALF = 8,
+};
+
+enum hdmi_3d_format_bits {
+ HDMI_FRAME_PACKING_BIT = 1 << HDMI_FRAME_PACKING,
+ HDMI_FIELD_ALTERNATIVE_BIT = 1 << HDMI_FIELD_ALTERNATIVE,
+ HDMI_LINE_ALTERNATIVE_BIT = 1 << HDMI_LINE_ALTERNATIVE,
+ HDMI_SIDE_BY_SIDE_FULL_BIT = 1 << HDMI_SIDE_BY_SIDE_FULL,
+ HDMI_L_DEPTH_BIT = 1 << HDMI_L_DEPTH ,
+ HDMI_L_DEPTH_GFX_GFX_DEPTH_BIT = 1 << HDMI_L_DEPTH_GFX_GFX_DEPTH,
+ HDMI_TOPBOTTOM_BIT = 1 << HDMI_TOPBOTTOM,
+ HDMI_SIDE_BY_SIDE_HALF_BIT = 1 << HDMI_SIDE_BY_SIDE_HALF,
+ HDMI_SIDE_BY_SIDE_HALF_QUINCUNX_BIT = 1 << 15,
+};
+
+//ALL = both horizontal and quincunx modes are supported
+//HDMI_SS_QUINCUNX_ALL = all quincunx subsampling modes are supported
+//OL = Odd left viewHorizontal sub
+//OR = Odd right view
+//ER = Even left view
+//EL = Even right view
+enum hdmi_3d_subsampling {
+ HDMI_SS_HORZANDQUINCUNX = 0,
+ HDMI_SS_HORIZONTAL = 1,
+ HDMI_SS_QUINCUNX_ALL = 6,
+ HDMI_SS_QUINCUNX_OLOR = 7,
+ HDMI_SS_QUINCUNX_OLER = 8,
+ HDMI_SS_QUINCUNX_ELOR = 9,
+ HDMI_SS_QUINCUNX_ELER = 10,
+ HDMI_SS_VERTICAL = 0xF0000,
+ HDMI_SS_NONE = 0xF0001,
+};
+
+enum hdmi_scan_type {
+ HDMI_SCAN_PROGRESSIVE,
+ HDMI_SCAN_INTERLACED,
+};
+
+struct svd_info_t {
+ uint32_t xres;
+ uint32_t yres;
+ uint32_t hz;
+ enum hdmi_scan_type scan_type;
+ char name[9];
+};
+
+struct svd_t {
+ uint8_t code;
+ bool native;
+ struct svd_info_t info;
+};
+
+struct hdmi_s3d_format_vic_info_t {
+ uint8_t vic_pos;
+ enum hdmi_3d_subsampling subsampling;
+};
+
+struct hdmi_s3d_format_info_t {
+ enum hdmi_3d_format format;
+ unsigned int num_valid_vic;
+ struct hdmi_s3d_format_vic_info_t vic_info[MAX_VIC_CODES_PER_3D_FORMAT];
+};
+
+int edid_parser_init(struct edid_t **edid, const uint8_t *raw_edid_data);
+void edid_parser_deinit(struct edid_t *edid);
+
+bool edid_s3d_capable(struct edid_t *edid);
+bool edid_supports_s3d_format(struct edid_t *edid, enum hdmi_3d_format format);
+const struct hdmi_s3d_format_info_t * edid_get_s3d_format_info(struct edid_t *edid, enum hdmi_3d_format format);
+
+void edid_get_svd_list(struct edid_t *edid, struct svd_t **list, unsigned int *num_elements);
+const struct svd_t *edid_get_svd_descriptor(struct edid_t *edid, uint8_t vic_pos);
+
+#endif //_EDID_PARSER_ \ No newline at end of file
diff --git a/edid/lib/edid_parser.c b/edid/lib/edid_parser.c
new file mode 100644
index 0000000..e08822c
--- /dev/null
+++ b/edid/lib/edid_parser.c
@@ -0,0 +1,410 @@
+/*
+ * Copyright (C) Texas Instruments - http://www.ti.com/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <inc/edid_parser.h>
+#include "edid_parser_priv.h"
+
+const struct svd_info_t svd_table[] =
+{
+ {0, 0, 0, HDMI_SCAN_PROGRESSIVE, "reserved"},
+ {640, 480, 60, HDMI_SCAN_PROGRESSIVE, "DMT0659"},
+ {720, 480, 60, HDMI_SCAN_PROGRESSIVE, "480p"},
+ {720, 480, 60, HDMI_SCAN_PROGRESSIVE, "480pH"},
+ {1280, 720, 60, HDMI_SCAN_PROGRESSIVE, "720p"},
+ {1920, 1080, 60, HDMI_SCAN_INTERLACED, "1080i"},
+ {720, 480, 60, HDMI_SCAN_INTERLACED, "480i"},
+ {720, 480, 60, HDMI_SCAN_INTERLACED, "480iH"},
+ {720, 240, 60, HDMI_SCAN_PROGRESSIVE, "240p"},
+ {1280, 720, 60, HDMI_SCAN_PROGRESSIVE, "240pH"},
+ {720, 480, 60, HDMI_SCAN_INTERLACED, "480i4x"},
+ {720, 480, 60, HDMI_SCAN_INTERLACED, "480i4xH"},
+ {720, 240, 60, HDMI_SCAN_PROGRESSIVE, "240p4x"},
+ {720, 240, 60, HDMI_SCAN_PROGRESSIVE, "240p4xH"},
+ {720, 480, 60, HDMI_SCAN_PROGRESSIVE, "480p2x"},
+ {720, 480, 60, HDMI_SCAN_PROGRESSIVE, "480p2xH"},
+ {1920, 1080, 60, HDMI_SCAN_PROGRESSIVE, "1080p"},
+ {720, 576, 50, HDMI_SCAN_PROGRESSIVE, "576p"},
+ {720, 576, 50, HDMI_SCAN_PROGRESSIVE, "576pH"},
+ {1280, 720, 50, HDMI_SCAN_PROGRESSIVE, "720p50"},
+ {1920, 1080, 50, HDMI_SCAN_INTERLACED, "1080i25"},
+ {720, 576, 50, HDMI_SCAN_INTERLACED, "576i"},
+ {720, 576, 50, HDMI_SCAN_INTERLACED, "576iH"},
+ {720, 288, 50, HDMI_SCAN_PROGRESSIVE, "288p"},
+ {720, 288, 50, HDMI_SCAN_PROGRESSIVE, "288pH"},
+ {720, 576, 50, HDMI_SCAN_INTERLACED, "576i4x"},
+ {720, 576, 50, HDMI_SCAN_INTERLACED, "576i4xH"},
+ {720, 288, 50, HDMI_SCAN_PROGRESSIVE, "288p4x"},
+ {720, 288, 50, HDMI_SCAN_PROGRESSIVE, "288p4xH"},
+ {720, 576, 50, HDMI_SCAN_PROGRESSIVE, "576p2x"},
+ {720, 576, 50, HDMI_SCAN_PROGRESSIVE, "576p2xH"},
+ {1920, 1080, 50, HDMI_SCAN_PROGRESSIVE, "1080p50"},
+ {1920, 1080, 24, HDMI_SCAN_PROGRESSIVE, "1080p24"},
+ {1920, 1080, 25, HDMI_SCAN_PROGRESSIVE, "1080p25"},
+ {1920, 1080, 30, HDMI_SCAN_PROGRESSIVE, "1080p30"},
+ {720, 480, 60, HDMI_SCAN_PROGRESSIVE, "480p4x"},
+ {720, 480, 60, HDMI_SCAN_PROGRESSIVE, "480p4xH"},
+ {720, 576, 50, HDMI_SCAN_PROGRESSIVE, "576p4x"},
+ {720, 576, 50, HDMI_SCAN_PROGRESSIVE, "576p4xH"},
+ {1920, 1080, 50, HDMI_SCAN_INTERLACED, "1080i25"},
+ {1920, 1080, 100, HDMI_SCAN_INTERLACED, "1080i50"},
+ {1280, 720, 100, HDMI_SCAN_PROGRESSIVE, "720p100"},
+ {720, 576, 100, HDMI_SCAN_PROGRESSIVE, "576p100"},
+ {720, 576, 100, HDMI_SCAN_PROGRESSIVE, "576p100H"},
+ {720, 576, 100, HDMI_SCAN_INTERLACED, "576i50"},
+ {720, 576, 100, HDMI_SCAN_INTERLACED, "576i50H"},
+ {1920, 1080, 120, HDMI_SCAN_INTERLACED, "1080i60"},
+ {1280, 720, 120, HDMI_SCAN_PROGRESSIVE, "720p120"},
+ {720, 480, 120, HDMI_SCAN_PROGRESSIVE, "480p120"},
+ {720, 480, 120, HDMI_SCAN_PROGRESSIVE, "480p120H"},
+ {720, 480, 120, HDMI_SCAN_INTERLACED, "480i60"},
+ {720, 480, 120, HDMI_SCAN_INTERLACED, "480i60H"},
+ {720, 576, 200, HDMI_SCAN_PROGRESSIVE, "576p200"},
+ {720, 576, 200, HDMI_SCAN_PROGRESSIVE, "576p200H"},
+ {720, 576, 200, HDMI_SCAN_INTERLACED, "576i100"},
+ {720, 576, 200, HDMI_SCAN_INTERLACED, "576i100H"},
+ {720, 480, 240, HDMI_SCAN_PROGRESSIVE, "480p240"},
+ {720, 480, 240, HDMI_SCAN_PROGRESSIVE, "480p240H"},
+ {720, 480, 240, HDMI_SCAN_INTERLACED, "480i120"},
+ {720, 480, 240, HDMI_SCAN_INTERLACED, "480i120H"},
+ {1280, 720, 24, HDMI_SCAN_PROGRESSIVE, "720p24"},
+ {1280, 720, 25, HDMI_SCAN_PROGRESSIVE, "720p25"},
+ {1280, 720, 30, HDMI_SCAN_PROGRESSIVE, "720p30"},
+ {1920, 1080, 120, HDMI_SCAN_PROGRESSIVE, "1080p120"}
+};
+
+const int NUM_SVD_ENTRIES = sizeof(svd_table)/sizeof(svd_table[0]);
+
+static unsigned int count_set_bits(uint16_t value)
+{
+ unsigned int count;
+ for (count = 0; value; count++)
+ value &= value - 1;
+ return count;
+}
+
+static void set_s3d_format_bits(const uint8_t *edid_data, int off, int hdmi_3d_len, uint16_t *s3d_struct_bits)
+{
+ //These are 3D formats signaled through 2D VIC order and 3D_structure-3D_Detail
+ while (hdmi_3d_len > 0) {
+ unsigned int val = edid_data[off++] & 0x0F;
+ *s3d_struct_bits |= 1 << val;
+ //3D Detail_x is included for 3D_Structure_x range 0x8-0xF
+ if ( val >= HDMI_SIDE_BY_SIDE_HALF) {
+ hdmi_3d_len--;
+ off++;
+ }
+ hdmi_3d_len--;
+ }
+}
+
+static void update_s3d_format(struct edid_t *edid, enum hdmi_3d_format format,
+ uint8_t vic_pos, enum hdmi_3d_subsampling subsamp)
+{
+ unsigned int format_ix, vic_pos_ix;
+ if (vic_pos > edid->num_svds) {
+ return;
+ }
+
+ for (format_ix = 0; format_ix < edid->num_s3d_formats; format_ix++) {
+ if (edid->s3d_format_list[format_ix].format == format) {
+ break;
+ }
+ }
+
+ if (format_ix >= edid->num_s3d_formats) {
+ return;
+ }
+
+ //In case this has already been signaled, we'll update the subsampling mode
+ for (vic_pos_ix = 0; vic_pos_ix < edid->s3d_format_list[format_ix].num_valid_vic; vic_pos_ix++) {
+ if (edid->s3d_format_list[format_ix].vic_info[vic_pos_ix].vic_pos == vic_pos) {
+ break;
+ }
+ }
+
+ if (vic_pos_ix >= edid->s3d_format_list[format_ix].num_valid_vic) {
+ vic_pos_ix = edid->s3d_format_list[format_ix].num_valid_vic;
+ edid->s3d_format_list[format_ix].num_valid_vic += 1;
+ }
+
+ edid->s3d_format_list[format_ix].vic_info[vic_pos_ix].vic_pos = vic_pos;
+ edid->s3d_format_list[format_ix].vic_info[vic_pos_ix].subsampling = subsamp;
+}
+
+/* This function was originally written by Mythri pk */
+static int edid_get_datablock_offset(const uint8_t *edid_data, enum datablock_id type, unsigned int *off)
+{
+ uint8_t val;
+ uint8_t ext_length;
+ uint8_t offset;
+
+ //CEA extension signaled? If not, then no datablocks are contained
+ if (edid_data[0x7e] == 0x00) {
+ return 1;
+ }
+
+ //18-byte descriptors only? Otherwise, there are datablocks present
+ ext_length = edid_data[0x82];
+ if (ext_length == 0x4) {
+ return 1;
+ }
+
+ //Start of first extended data block
+ offset = 0x84;
+ while (offset < (0x80 + ext_length)) {
+ val = edid_data[offset];
+ //Upper 3 bits indicate block type
+ if ((val >> 5) == type) {
+ *off = offset;
+ return 0;
+ } else {
+ //lower 5 bits indicate block length
+ offset += (val & 0x1F) + 1;
+ }
+ }
+ return 1;
+}
+
+static void edid_parse_s3d_support(struct edid_t *edid, const uint8_t *edid_data)
+{
+ unsigned int off;
+ unsigned int i, count;
+ uint8_t val;
+ uint8_t s3d_multi_present;
+ uint8_t hdmi_3d_len;
+ uint16_t s3d_struct_all = 0;
+ uint16_t s3d_struct_bits = 0;
+ uint16_t hdmi_vic_pos_bits = 0;
+
+ //memset(edid->s3d_formats, 0, sizeof(edid->s3d_formats));
+
+ //S3D HDMI information is signaled in the Vendor Specific datablock
+ if(edid_get_datablock_offset(edid_data, DATABLOCK_VENDOR, &off))
+ return;
+
+ //Skip header and other non-S3D related fields
+ off += 8;
+ val = edid_data[off++];
+
+ //HDMI_Video_present?
+ if (!(val & 0x20)) {
+ return;
+ }
+
+ //Latency_Fields_Present? Skip
+ if (val & 0x80) {
+ off += 2;
+ }
+
+ //I_Latency_Fields_Present? Skip
+ if (val & 0x40) {
+ off += 2;
+ }
+
+ val = edid_data[off++];
+ //3D_Present?
+ if (!(val & 0x80)) {
+ return;
+ }
+
+ edid->s3d_capable = true;
+
+ s3d_multi_present = (val & 0x60) >> 5;
+
+ //Skip HDMI_XX_LEN
+ val = edid_data[off++];
+ off += (val & 0xE0) >> 5;
+ hdmi_3d_len = (val & 0x1F);
+
+ //3D capabilities signaled through bitmasks
+ //s3d_struct_all has all the 3D formats supported (per bit)
+ //hdmi_vic_mask has which of the corresponding VIC codes the 3D formats apply to
+ //if s3d_multi_present = 1, then the 3D formats apply to all the first 16 VIC codes
+ if (s3d_multi_present == 1 || s3d_multi_present == 2) {
+ s3d_struct_all = (edid_data[off] << 8) | edid_data[off+1];
+ hdmi_vic_pos_bits = 0xFFFF;
+ hdmi_3d_len -= 2;
+ off += 2;
+ }
+
+ if (s3d_multi_present == 2) {
+ hdmi_vic_pos_bits = (edid_data[off] << 8) | edid_data[off+1];
+ hdmi_3d_len -= 2;
+ off += 2;
+ }
+
+ //Bit 15 signals same format as Bit 8 - HDMI_SIDE_BY_SIDE_HALF, they only differ in subsampling options
+ s3d_struct_bits = s3d_struct_all & 0x7FFF;
+ set_s3d_format_bits(edid_data, off, hdmi_3d_len, &s3d_struct_bits);
+
+ edid->num_s3d_formats = count_set_bits(s3d_struct_bits);
+ edid->s3d_format_list = (struct hdmi_s3d_format_info_t *) malloc(edid->num_s3d_formats * sizeof(struct hdmi_s3d_format_info_t));
+
+ count = 0;
+ for (i = 0; i <= HDMI_SIDE_BY_SIDE_HALF; i++) {
+ if (s3d_struct_bits & (1 << i)) {
+ edid->s3d_format_list[count++].format = (enum hdmi_3d_format)i;
+ }
+ }
+
+ for (i = 0; i < edid->num_s3d_formats; i++) {
+ unsigned int j;
+ enum hdmi_3d_subsampling subsampling;
+ if (edid->s3d_format_list[i].format == HDMI_SIDE_BY_SIDE_HALF) {
+ uint16_t bitmask = HDMI_SIDE_BY_SIDE_HALF_QUINCUNX_BIT | HDMI_SIDE_BY_SIDE_HALF_BIT;
+ if ( (s3d_struct_all & bitmask) == bitmask) {
+ subsampling = HDMI_SS_HORZANDQUINCUNX;
+ } else if ((s3d_struct_all & bitmask) == HDMI_SIDE_BY_SIDE_HALF_QUINCUNX_BIT) {
+ subsampling = HDMI_SS_QUINCUNX_ALL;
+ } else if ((s3d_struct_all & bitmask) == HDMI_SIDE_BY_SIDE_HALF_BIT) {
+ subsampling = HDMI_SS_HORIZONTAL;
+ }
+ } else if (edid->s3d_format_list[i].format == HDMI_TOPBOTTOM) {
+ subsampling = HDMI_SS_VERTICAL;
+ } else {
+ subsampling = HDMI_SS_NONE;
+ }
+ count = 0;
+ for (j = 0; j < 16; j++) {
+ if ((s3d_struct_all & (1 << edid->s3d_format_list[i].format)) &&
+ (hdmi_vic_pos_bits & (1 << j))) {
+ edid->s3d_format_list[i].vic_info[count].subsampling = subsampling;
+ edid->s3d_format_list[i].vic_info[count++].vic_pos = j;
+ }
+ }
+ edid->s3d_format_list[i].num_valid_vic = count;
+ }
+
+ //In this case, the 3D formats signaled only apply to the VIC codes signaled per bit
+ //i.e. bit0 = VIC code 0 from the Short video descriptors list
+ while (hdmi_3d_len > 0) {
+ //Upper 4 bits indicate vic position, lower 4 bits are the 3D structure value
+ enum hdmi_3d_subsampling subsampling = HDMI_SS_NONE;
+ uint8_t vic_pos = (edid_data[off] & 0xF0) >> 4;
+ enum hdmi_3d_format format = (enum hdmi_3d_format) (edid_data[off++] & 0x0F);
+ if (format >= HDMI_SIDE_BY_SIDE_HALF) {
+ subsampling = (enum hdmi_3d_subsampling)((edid_data[off++] & 0xF0) >> 4);
+ hdmi_3d_len--;
+ }
+ if (format == HDMI_TOPBOTTOM) {
+ subsampling = HDMI_SS_VERTICAL;
+ }
+ update_s3d_format(edid, format, vic_pos, subsampling);
+ hdmi_3d_len--;
+ }
+}
+
+static void edid_fill_svd_info(uint8_t code, struct svd_info_t *info)
+{
+ if(code > NUM_SVD_ENTRIES)
+ code = 0;
+ memcpy(info, &svd_table[code], sizeof(struct svd_info_t));
+}
+
+static void edid_parse_svds(struct edid_t *edid, const uint8_t *raw_edid_data)
+{
+ unsigned int offset;
+ unsigned int i;
+ if (edid_get_datablock_offset(raw_edid_data, DATABLOCK_VIDEO, &offset)) {
+ edid->num_svds = 0;
+ edid->svd_list = NULL;
+ return ;
+ }
+
+ edid->num_svds = raw_edid_data[offset] & 0x1F;
+ edid->svd_list = (struct svd_t *) malloc(edid->num_svds * sizeof(struct svd_t));
+ for (i = 0; i < edid->num_svds; i++) {
+ struct svd_t *svd = &edid->svd_list[i];
+ svd->code = raw_edid_data[offset + i] & 0x7F;
+ svd->native = (raw_edid_data[offset + i] & 0x80) == 0x80;
+ edid_fill_svd_info(svd->code, &svd->info);
+ }
+}
+
+/*=======================================================*/
+int edid_parser_init(struct edid_t **edid_handle, const uint8_t *raw_edid_data)
+{
+ if(edid_handle == NULL) {
+ return -1;
+ }
+
+ struct edid_t *edid = (struct edid_t *) malloc(sizeof(struct edid_t));
+ if (edid == NULL) {
+ return -1;
+ }
+
+ memset(edid, 0, sizeof(struct edid_t));
+ edid_parse_svds(edid, raw_edid_data);
+ edid_parse_s3d_support(edid, raw_edid_data);
+
+ *edid_handle = edid;
+ return 0;
+}
+
+void edid_parser_deinit(struct edid_t *edid)
+{
+ free(edid->s3d_format_list);
+ free(edid->svd_list);
+ free(edid);
+}
+
+bool edid_s3d_capable(struct edid_t *edid)
+{
+ return edid->s3d_capable;
+}
+
+bool edid_supports_s3d_format(struct edid_t *edid, enum hdmi_3d_format format)
+{
+ unsigned int i;
+ for (i = 0; i < edid->num_s3d_formats; i++) {
+ if (edid->s3d_format_list[i].format == format) {
+ return true;
+ }
+ }
+ return false;
+}
+
+const struct hdmi_s3d_format_info_t * edid_get_s3d_format_info(struct edid_t *edid, enum hdmi_3d_format format)
+{
+ unsigned int i;
+ for (i = 0; i < edid->num_s3d_formats; i++) {
+ if (edid->s3d_format_list[i].format == format) {
+ return &edid->s3d_format_list[i];
+ }
+ }
+ return NULL;
+}
+
+void edid_get_svd_list(struct edid_t *edid, struct svd_t **list, unsigned int *num_elements)
+{
+ if(list == NULL || num_elements == NULL)
+ return;
+
+ *list = edid->svd_list;
+ *num_elements = edid->num_svds;
+}
+
+const struct svd_t *edid_get_svd_descriptor(struct edid_t *edid, uint8_t vic_pos)
+{
+ if(vic_pos > edid->num_svds)
+ return NULL;
+ return &edid->svd_list[vic_pos];
+}
diff --git a/edid/lib/edid_parser_priv.h b/edid/lib/edid_parser_priv.h
new file mode 100644
index 0000000..69ba513
--- /dev/null
+++ b/edid/lib/edid_parser_priv.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) Texas Instruments - http://www.ti.com/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+struct hdmi_s3d_format_t {
+ bool supported;
+ struct hdmi_s3d_format_info_t f;
+};
+
+struct edid_t {
+ bool s3d_capable;
+
+ unsigned int num_s3d_formats;
+ struct hdmi_s3d_format_info_t *s3d_format_list;
+
+ unsigned int num_svds;
+ struct svd_t *svd_list;
+};
diff --git a/extract-files.sh b/extract-files.sh
new file mode 100755
index 0000000..3731cab
--- /dev/null
+++ b/extract-files.sh
@@ -0,0 +1,142 @@
+#!/bin/sh
+
+# Copyright (C) 2013 The CyanogenMod Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+VENDOR=samsung
+COMMON=omap4-common
+COMMONOUTDIR=vendor/$VENDOR/$COMMON
+COMMONBASE=../../../$COMMONOUTDIR/proprietary
+COMMONMAKEFILE=../../../$COMMONOUTDIR/common-vendor-blobs.mk
+COMMONPROPS=../$COMMON/proprietary-files.txt
+
+mkdir -p ../../../vendor/$VENDOR/$COMMON/proprietary
+
+adb root
+adb wait-for-device
+
+echo "Pulling common files..."
+for FILE in `cat $COMMONPROPS | grep -v ^# | grep -v ^$`; do
+ DIR=`dirname $FILE`
+ if [ ! -d $COMMONBASE/$DIR ]; then
+ mkdir -p $COMMONBASE/$DIR
+ fi
+ adb pull /$FILE $COMMONBASE/$FILE
+done
+
+
+(cat << EOF) | sed s/__COMMON__/$COMMON/g | sed s/__VENDOR__/$VENDOR/g > $COMMONMAKEFILE
+# Copyright (C) 2013 The CyanogenMod Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := vendor/samsung/__COMMON__
+
+PRODUCT_COPY_FILES += \\
+EOF
+
+LINEEND=" \\"
+COUNT=`cat $COMMONPROPS | grep -v ^# | grep -v ^$ | wc -l | awk {'print $1'}`
+for FILE in `cat $COMMONPROPS | grep -v ^# | grep -v ^$`; do
+ COUNT=`expr $COUNT - 1`
+ if [ $COUNT = "0" ]; then
+ LINEEND=""
+ fi
+ echo " \$(LOCAL_PATH)/proprietary/$FILE:$FILE$LINEEND" >> $COMMONMAKEFILE
+done
+
+(cat << EOF) | sed s/__COMMON__/$COMMON/g | sed s/__VENDOR__/$VENDOR/g > $COMMONBASE/Android.mk
+# Copyright (C) 2013 The CyanogenMod Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+ifneq (\$(filter i9100g p3100 p3110 p5100 p5110,\$(TARGET_DEVICE)),)
+
+LOCAL_PATH := \$(call my-dir)
+
+# Creating Gralloc SymLink
+GRALLOC_SYMLINK := \$(TARGET_OUT_VENDOR)/lib/hw/gralloc.\$(TARGET_BOARD_PLATFORM).so
+\$(GRALLOC_SYMLINK): GRALLOC_FILE := gralloc.omap\$(TARGET_BOARD_OMAP_CPU).so
+\$(GRALLOC_SYMLINK): \$(LOCAL_INSTALLED_MODULE) \$(LOCAL_PATH)/Android.mk
+ @echo "Symlink: \$@ -> \$(GRALLOC_FILE)"
+ @rm -rf \$@
+ \$(hide) ln -fs \$(GRALLOC_FILE) \$@
+
+ALL_DEFAULT_INSTALLED_MODULES += \$(GRALLOC_SYMLINK)
+
+# for mm/mmm
+all_modules: \$(GRALLOC_SYMLINK)
+
+endif
+
+EOF
+
+(cat << EOF) | sed s/__COMMON__/$COMMON/g | sed s/__VENDOR__/$VENDOR/g > ../../../$COMMONOUTDIR/common-vendor.mk
+# Copyright (C) 2013 The CyanogenMod Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Pick up overlay for features that depend on non-open-source files
+DEVICE_PACKAGE_OVERLAYS += vendor/__VENDOR__/__COMMON__/overlay
+
+\$(call inherit-product, vendor/__VENDOR__/__COMMON__/common-vendor-blobs.mk)
+EOF
+
+(cat << EOF) | sed s/__COMMON__/$COMMON/g | sed s/__VENDOR__/$VENDOR/g > ../../../$COMMONOUTDIR/BoardConfigVendor.mk
+# Copyright (C) 2013 The CyanogenMod Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+EOF
+
diff --git a/hwc/Android.mk b/hwc/Android.mk
new file mode 100644
index 0000000..dc0c713
--- /dev/null
+++ b/hwc/Android.mk
@@ -0,0 +1,31 @@
+LOCAL_PATH := $(call my-dir)
+
+# HAL module implementation, not prelinked and stored in
+# hw/<HWCOMPOSE_HARDWARE_MODULE_ID>.<ro.product.board>.so
+include $(CLEAR_VARS)
+LOCAL_PRELINK_MODULE := false
+LOCAL_ARM_MODE := arm
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/../vendor/lib/hw
+LOCAL_SHARED_LIBRARIES := liblog libEGL libcutils libutils libhardware libhardware_legacy libz \
+ libion_ti
+LOCAL_SRC_FILES := hwc.c rgz_2d.c dock_image.c sw_vsync.c
+LOCAL_STATIC_LIBRARIES := libpng
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE := hwcomposer.$(TARGET_BOOTLOADER_BOARD_NAME)
+LOCAL_CFLAGS := -DLOG_TAG=\"ti_hwc\"
+LOCAL_C_INCLUDES += external/libpng external/zlib
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/../edid/inc \
+ $(LOCAL_PATH)/../include
+LOCAL_SHARED_LIBRARIES += libedid
+
+ifeq ($(BOARD_USE_SYSFS_VSYNC_NOTIFICATION),true)
+LOCAL_CFLAGS += -DSYSFS_VSYNC_NOTIFICATION
+endif
+
+# LOG_NDEBUG=0 means verbose logging enabled
+# LOCAL_CFLAGS += -DLOG_NDEBUG=0
+include $(BUILD_SHARED_LIBRARY)
diff --git a/hwc/dock_image.c b/hwc/dock_image.c
new file mode 100644
index 0000000..b74a17e
--- /dev/null
+++ b/hwc/dock_image.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) Texas Instruments - http://www.ti.com/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include <png.h>
+
+#include <linux/fb.h>
+
+#include "hwc_dev.h"
+#include "dock_image.h"
+
+static struct dock_image_state {
+ void *buffer; /* start of fb for hdmi */
+ uint32_t buffer_size; /* size of fb for hdmi */
+
+ uint32_t max_width;
+ uint32_t max_height;
+
+ image_info_t image;
+} dock_image;
+
+static void free_png_image(image_info_t *img)
+{
+ memset(img, 0, sizeof(*img));
+}
+
+static int load_png_image(char *path, image_info_t *img)
+{
+ void *ptr = NULL;
+ png_bytepp row_pointers = NULL;
+
+ FILE *fd = fopen(path, "rb");
+ if (!fd) {
+ ALOGE("failed to open PNG file %s: (%d)", path, errno);
+ return -EINVAL;
+ }
+
+ const int SIZE_PNG_HEADER = 8;
+ uint8_t header[SIZE_PNG_HEADER];
+ fread(header, 1, SIZE_PNG_HEADER, fd);
+ if (png_sig_cmp(header, 0, SIZE_PNG_HEADER)) {
+ ALOGE("%s is not a PNG file", path);
+ goto fail;
+ }
+
+ png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!png_ptr)
+ goto fail_alloc;
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr)
+ goto fail_alloc;
+
+ if (setjmp(png_jmpbuf(png_ptr)))
+ goto fail_alloc;
+
+ png_init_io(png_ptr, fd);
+ png_set_sig_bytes(png_ptr, SIZE_PNG_HEADER);
+ png_set_user_limits(png_ptr, dock_image.max_width, dock_image.max_height);
+ png_read_info(png_ptr, info_ptr);
+
+ uint8_t bit_depth = png_get_bit_depth(png_ptr, info_ptr);
+ uint32_t width = png_get_image_width(png_ptr, info_ptr);
+ uint32_t height = png_get_image_height(png_ptr, info_ptr);
+ uint8_t color_type = png_get_color_type(png_ptr, info_ptr);
+
+ switch (color_type) {
+ case PNG_COLOR_TYPE_PALETTE:
+ png_set_palette_to_rgb(png_ptr);
+ png_set_filler(png_ptr, 128, PNG_FILLER_AFTER);
+ break;
+ case PNG_COLOR_TYPE_GRAY:
+ if (bit_depth < 8) {
+ png_set_expand_gray_1_2_4_to_8(png_ptr);
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+ png_set_tRNS_to_alpha(png_ptr);
+ } else {
+ png_set_filler(png_ptr, 128, PNG_FILLER_AFTER);
+ }
+ /* fall through */
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ png_set_gray_to_rgb(png_ptr);
+ break;
+ case PNG_COLOR_TYPE_RGB:
+ png_set_filler(png_ptr, 128, PNG_FILLER_AFTER);
+ /* fall through */
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ png_set_bgr(png_ptr);
+ break;
+ default:
+ ALOGE("unsupported PNG color: %x", color_type);
+ goto fail_alloc;
+ }
+
+ if (bit_depth == 16)
+ png_set_strip_16(png_ptr);
+
+ const uint32_t bpp = 4;
+ img->size = ALIGN(width * height * bpp, 4096);
+ if ((uint32_t)img->size > dock_image.buffer_size) {
+ ALOGE("image does not fit into framebuffer area (%d > %d)", img->size, dock_image.buffer_size);
+ goto fail_alloc;
+ }
+ img->ptr = dock_image.buffer;
+
+ row_pointers = calloc(height, sizeof(*row_pointers));
+ if (!row_pointers) {
+ ALOGE("failed to allocate row pointers");
+ goto fail_alloc;
+ }
+ uint32_t i;
+ for (i = 0; i < height; i++)
+ row_pointers[i] = img->ptr + i * width * bpp;
+ png_set_rows(png_ptr, info_ptr, row_pointers);
+ png_read_update_info(png_ptr, info_ptr);
+ img->rowbytes = png_get_rowbytes(png_ptr, info_ptr);
+
+ png_read_image(png_ptr, row_pointers);
+ png_read_end(png_ptr, NULL);
+ free(row_pointers);
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ fclose(fd);
+ img->width = width;
+ img->height = height;
+ return 0;
+
+fail_alloc:
+ free_png_image(img);
+ free(row_pointers);
+ if (!png_ptr || !info_ptr)
+ ALOGE("failed to allocate PNG structures");
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+fail:
+ fclose(fd);
+ return -EINVAL;
+}
+
+int init_dock_image(omap_hwc_device_t *hwc_dev, uint32_t max_width, uint32_t max_height)
+{
+ int err = 0;
+
+ struct fb_fix_screeninfo fix;
+ if (ioctl(hwc_dev->fb_fd, FBIOGET_FSCREENINFO, &fix)) {
+ ALOGE("failed to get fb info (%d)", errno);
+ err = -errno;
+ goto done;
+ }
+
+ dock_image.buffer_size = fix.smem_len;
+ dock_image.buffer = mmap(NULL, fix.smem_len, PROT_WRITE, MAP_SHARED, hwc_dev->fb_fd, 0);
+ if (dock_image.buffer == MAP_FAILED) {
+ ALOGE("failed to map fb memory");
+ err = -errno;
+ goto done;
+ }
+
+ dock_image.max_width = max_width;
+ dock_image.max_height = max_height;
+
+ done:
+ return err;
+}
+
+void load_dock_image()
+{
+ if (!dock_image.image.rowbytes) {
+ char value[PROPERTY_VALUE_MAX];
+ property_get("persist.hwc.dock_image", value, "/vendor/res/images/dock/dock.png");
+ load_png_image(value, &dock_image.image);
+ }
+}
+
+image_info_t *get_dock_image()
+{
+ return &dock_image.image;
+}
+
diff --git a/hwc/dock_image.h b/hwc/dock_image.h
new file mode 100644
index 0000000..44a3271
--- /dev/null
+++ b/hwc/dock_image.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) Texas Instruments - http://www.ti.com/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __DOCK_IMAGE__
+#define __DOCK_IMAGE__
+
+#include <stdint.h>
+
+/* ARGB image */
+struct image_info {
+ int width;
+ int height;
+ int rowbytes;
+ int size;
+ uint8_t *ptr;
+};
+typedef struct image_info image_info_t;
+
+typedef struct omap_hwc_device omap_hwc_device_t;
+
+int init_dock_image(omap_hwc_device_t *hwc_dev, uint32_t max_width, uint32_t max_height);
+void load_dock_image();
+image_info_t *get_dock_image();
+
+#endif
diff --git a/hwc/hal_public.h b/hwc/hal_public.h
new file mode 100644
index 0000000..a7dfb08
--- /dev/null
+++ b/hwc/hal_public.h
@@ -0,0 +1,188 @@
+/* Copyright (c) Imagination Technologies Ltd.
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef HAL_PUBLIC_H
+#define HAL_PUBLIC_H
+
+/* Authors of third party hardware composer (HWC) modules will need to include
+ * this header to access functionality in the gralloc and framebuffer HALs.
+ */
+
+#include <hardware/gralloc.h>
+
+#define ALIGN(x,a) (((x) + (a) - 1L) & ~((a) - 1L))
+#define HW_ALIGN 32
+
+/* This can be tuned down as appropriate for the SOC.
+ *
+ * IMG formats are usually a single sub-alloc.
+ * Some OEM video formats are two sub-allocs (Y, UV planes).
+ * Future OEM video formats might be three sub-allocs (Y, U, V planes).
+ */
+#define MAX_SUB_ALLOCS 3
+
+typedef struct
+{
+ native_handle_t base;
+
+ /* These fields can be sent cross process. They are also valid
+ * to duplicate within the same process.
+ *
+ * A table is stored within psPrivateData on gralloc_module_t (this
+ * is obviously per-process) which maps stamps to a mapped
+ * PVRSRV_CLIENT_MEM_INFO in that process. Each map entry has a lock
+ * count associated with it, satisfying the requirements of the
+ * Android API. This also prevents us from leaking maps/allocations.
+ *
+ * This table has entries inserted either by alloc()
+ * (alloc_device_t) or map() (gralloc_module_t). Entries are removed
+ * by free() (alloc_device_t) and unmap() (gralloc_module_t).
+ *
+ * As a special case for framebuffer_device_t, framebuffer_open()
+ * will add and framebuffer_close() will remove from this table.
+ */
+
+#define IMG_NATIVE_HANDLE_NUMFDS MAX_SUB_ALLOCS
+ /* The `fd' field is used to "export" a meminfo to another process.
+ * Therefore, it is allocated by alloc_device_t, and consumed by
+ * gralloc_module_t. The framebuffer_device_t does not need a handle,
+ * and the special value IMG_FRAMEBUFFER_FD is used instead.
+ */
+ int fd[MAX_SUB_ALLOCS];
+
+#define IMG_NATIVE_HANDLE_NUMINTS ((sizeof(unsigned long long) / sizeof(int)) + 5)
+ /* A KERNEL unique identifier for any exported kernel meminfo. Each
+ * exported kernel meminfo will have a unique stamp, but note that in
+ * userspace, several meminfos across multiple processes could have
+ * the same stamp. As the native_handle can be dup(2)'d, there could be
+ * multiple handles with the same stamp but different file descriptors.
+ */
+ unsigned long long ui64Stamp;
+
+ /* This is used for buffer usage validation when locking a buffer,
+ * and also in WSEGL (for the composition bypass feature).
+ */
+ int usage;
+
+ /* In order to do efficient cache flushes we need the buffer dimensions
+ * and format. These are available on the ANativeWindowBuffer,
+ * but the platform doesn't pass them down to the graphics HAL.
+ *
+ * These fields are also used in the composition bypass. In this
+ * capacity, these are the "real" values for the backing allocation.
+ */
+ int iWidth;
+ int iHeight;
+ int iFormat;
+ unsigned int uiBpp;
+}
+__attribute__((aligned(sizeof(int)),packed)) IMG_native_handle_t;
+
+typedef struct
+{
+ framebuffer_device_t base;
+
+ /* The HWC was loaded. post() is no longer responsible for presents */
+ int bBypassPost;
+
+ /* HWC path for present posts */
+ int (*Post2)(framebuffer_device_t *fb, buffer_handle_t *buffers,
+ int num_buffers, void *data, int data_length);
+}
+IMG_framebuffer_device_public_t;
+
+typedef struct IMG_gralloc_module_public_t
+{
+ gralloc_module_t base;
+
+ /* If the framebuffer has been opened, this will point to the
+ * framebuffer device data required by the allocator, WSEGL
+ * modules and composerhal.
+ */
+ IMG_framebuffer_device_public_t *psFrameBufferDevice;
+
+ int (*GetPhyAddrs)(struct IMG_gralloc_module_public_t const* module,
+ buffer_handle_t handle,
+ unsigned int auiPhyAddr[MAX_SUB_ALLOCS]);
+
+ /* Custom-blit components in lieu of overlay hardware */
+ int (*Blit)(struct IMG_gralloc_module_public_t const *module,
+ buffer_handle_t src,
+ void *dest[MAX_SUB_ALLOCS], int format);
+
+ int (*Blit2)(struct IMG_gralloc_module_public_t const *module,
+ buffer_handle_t src, buffer_handle_t dest,
+ int w, int h, int x, int y);
+}
+IMG_gralloc_module_public_t;
+
+typedef struct
+{
+ int l, t, w, h;
+}
+IMG_write_lock_rect_t;
+
+typedef struct IMG_buffer_format_public_t
+{
+ /* Buffer formats are returned as a linked list */
+ struct IMG_buffer_format_public_t *psNext;
+
+ /* HAL_PIXEL_FORMAT_... enumerant */
+ int iHalPixelFormat;
+
+ /* WSEGL_PIXELFORMAT_... enumerant */
+ int iWSEGLPixelFormat;
+
+ /* Friendly name for format */
+ const char *const szName;
+
+ /* Bits (not bytes) per pixel */
+ unsigned int uiBpp;
+
+ /* GPU output format (creates EGLConfig for format) */
+ int bGPURenderable;
+}
+IMG_buffer_format_public_t;
+
+/*
+ * These are vendor specific pixel formats, by (informal) convention IMGTec
+ * formats start from the top of the range, TI formats start from the bottom
+ */
+#define HAL_PIXEL_FORMAT_BGRX_8888 0x1FF
+#define HAL_PIXEL_FORMAT_TI_NV12 0x100
+#define HAL_PIXEL_FORMAT_TI_UNUSED 0x101 /* Free for use */
+#define HAL_PIXEL_FORMAT_TI_NV12_1D 0x102
+
+#ifndef GRALLOC_USAGE_SYSTEM_HEAP
+#define GRALLOC_USAGE_SYSTEM_HEAP GRALLOC_USAGE_PRIVATE_0
+#else
+#error GRALLOC_USAGE_SYSTEM_HEAP should only be defined by hal_public.h
+#endif
+
+#ifndef GRALLOC_USAGE_PHYS_CONTIG
+#define GRALLOC_USAGE_PHYS_CONTIG GRALLOC_USAGE_PRIVATE_1
+#else
+#error GRALLOC_USAGE_PHYS_CONTIG should only be defined by hal_public.h
+#endif
+#endif /* HAL_PUBLIC_H */
+
diff --git a/hwc/hwc.c b/hwc/hwc.c
new file mode 100644
index 0000000..855942b
--- /dev/null
+++ b/hwc/hwc.c
@@ -0,0 +1,2747 @@
+/*
+ * Copyright (C) Texas Instruments - http://www.ti.com/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <sys/ioctl.h>
+#include <sys/resource.h>
+
+#ifdef SYSFS_VSYNC_NOTIFICATION
+#include <sys/prctl.h>
+#endif
+
+#include <cutils/properties.h>
+#include <cutils/log.h>
+#include <cutils/native_handle.h>
+#define HWC_REMOVE_DEPRECATED_VERSIONS 1
+#include <hardware/hardware.h>
+#include <hardware/hwcomposer.h>
+#include <hardware_legacy/uevent.h>
+#include <system/graphics.h>
+#include <utils/Timers.h>
+#include <EGL/egl.h>
+#include <edid_parser.h>
+#ifdef OMAP_ENHANCEMENT_S3D
+#include <ui/S3DFormat.h>
+#endif
+
+#include <linux/fb.h>
+#include <linux/omapfb.h>
+#include <ion_ti/ion.h>
+
+#include "hwc_dev.h"
+#include "dock_image.h"
+#include "sw_vsync.h"
+
+#define min(a, b) ( { typeof(a) __a = (a), __b = (b); __a < __b ? __a : __b; } )
+#define max(a, b) ( { typeof(a) __a = (a), __b = (b); __a > __b ? __a : __b; } )
+#define swap(a, b) do { typeof(a) __a = (a); (a) = (b); (b) = __a; } while (0)
+
+#define WIDTH(rect) ((rect).right - (rect).left)
+#define HEIGHT(rect) ((rect).bottom - (rect).top)
+
+#define DIV_ROUND_UP(a, b) (((a) + (b) - 1) / (b))
+
+#define MAX_HWC_LAYERS 32
+#define MAX_HW_OVERLAYS 4
+#define NUM_NONSCALING_OVERLAYS 1
+#define NUM_EXT_DISPLAY_BACK_BUFFERS 2
+#define ASPECT_RATIO_TOLERANCE 0.02f
+
+/* used by property settings */
+enum {
+ EXT_ROTATION = 3, /* rotation while mirroring */
+ EXT_HFLIP = (1 << 2), /* flip l-r on output (after rotation) */
+};
+
+#define HAL_FMT(f) ((f) == HAL_PIXEL_FORMAT_TI_NV12 ? "NV12" : \
+ (f) == HAL_PIXEL_FORMAT_TI_NV12_1D ? "NV12" : \
+ (f) == HAL_PIXEL_FORMAT_YV12 ? "YV12" : \
+ (f) == HAL_PIXEL_FORMAT_BGRX_8888 ? "xRGB32" : \
+ (f) == HAL_PIXEL_FORMAT_RGBX_8888 ? "xBGR32" : \
+ (f) == HAL_PIXEL_FORMAT_BGRA_8888 ? "ARGB32" : \
+ (f) == HAL_PIXEL_FORMAT_RGBA_8888 ? "ABGR32" : \
+ (f) == HAL_PIXEL_FORMAT_RGB_565 ? "RGB565" : "??")
+
+#define DSS_FMT(f) ((f) == OMAP_DSS_COLOR_NV12 ? "NV12" : \
+ (f) == OMAP_DSS_COLOR_RGB24U ? "xRGB32" : \
+ (f) == OMAP_DSS_COLOR_ARGB32 ? "ARGB32" : \
+ (f) == OMAP_DSS_COLOR_RGB16 ? "RGB565" : "??")
+
+static bool debug = false;
+static bool debugpost2 = false;
+static bool debugblt = false;
+static rgz_t grgz;
+static rgz_ext_layer_list_t grgz_ext_layer_list;
+static struct bvsurfgeom gscrngeom;
+
+static void showfps(void)
+{
+ static int framecount = 0;
+ static int lastframecount = 0;
+ static nsecs_t lastfpstime = 0;
+ static float fps = 0;
+ char value[PROPERTY_VALUE_MAX];
+
+ property_get("debug.hwc.showfps", value, "0");
+ if (!atoi(value)) {
+ return;
+ }
+
+ framecount++;
+ if (!(framecount & 0x7)) {
+ nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t diff = now - lastfpstime;
+ fps = ((framecount - lastframecount) * (float)(s2ns(1))) / diff;
+ lastfpstime = now;
+ lastframecount = framecount;
+ ALOGI("%d Frames, %f FPS", framecount, fps);
+ }
+}
+
+static void dump_layer(hwc_layer_1_t const* l)
+{
+ ALOGD("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, {%d,%d,%d,%d}, {%d,%d,%d,%d}",
+ l->compositionType, l->flags, l->handle, l->transform, l->blending,
+ l->sourceCrop.left,
+ l->sourceCrop.top,
+ l->sourceCrop.right,
+ l->sourceCrop.bottom,
+ l->displayFrame.left,
+ l->displayFrame.top,
+ l->displayFrame.right,
+ l->displayFrame.bottom);
+}
+
+static void dump_dsscomp(struct dsscomp_setup_dispc_data *d)
+{
+ uint32_t i;
+
+ ALOGD("[%08x] set: %c%c%c %d ovls\n",
+ d->sync_id,
+ (d->mode & DSSCOMP_SETUP_MODE_APPLY) ? 'A' : '-',
+ (d->mode & DSSCOMP_SETUP_MODE_DISPLAY) ? 'D' : '-',
+ (d->mode & DSSCOMP_SETUP_MODE_CAPTURE) ? 'C' : '-',
+ d->num_ovls);
+
+ for (i = 0; i < d->num_mgrs; i++) {
+ struct dss2_mgr_info *mi = &d->mgrs[i];
+ ALOGD(" (dis%d alpha=%d col=%08x ilace=%d)\n",
+ mi->ix,
+ mi->alpha_blending, mi->default_color,
+ mi->interlaced);
+ }
+
+ for (i = 0; i < d->num_ovls; i++) {
+ struct dss2_ovl_info *oi = &d->ovls[i];
+ struct dss2_ovl_cfg *c = &oi->cfg;
+ if (c->zonly)
+ ALOGD("ovl%d(%s z%d)\n",
+ c->ix, c->enabled ? "ON" : "off", c->zorder);
+ else
+ ALOGD("ovl%d(%s z%d %s%s *%d%% %d*%d:%d,%d+%d,%d rot%d%s => %d,%d+%d,%d %p/%p|%d)\n",
+ c->ix, c->enabled ? "ON" : "off", c->zorder, DSS_FMT(c->color_mode),
+ c->pre_mult_alpha ? " premult" : "",
+ (c->global_alpha * 100 + 128) / 255,
+ c->width, c->height, c->crop.x, c->crop.y,
+ c->crop.w, c->crop.h,
+ c->rotation, c->mirror ? "+mir" : "",
+ c->win.x, c->win.y, c->win.w, c->win.h,
+ (void *) oi->ba, (void *) oi->uv, c->stride);
+ }
+}
+
+struct dump_buf {
+ char *buf;
+ int buf_len;
+ int len;
+};
+
+static void dump_printf(struct dump_buf *buf, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ buf->len += vsnprintf(buf->buf + buf->len, buf->buf_len - buf->len, fmt, ap);
+ va_end(ap);
+}
+
+static void dump_set_info(omap_hwc_device_t *hwc_dev, hwc_display_contents_1_t* list)
+{
+ struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data;
+ char logbuf[1024];
+ struct dump_buf log = {
+ .buf = logbuf,
+ .buf_len = sizeof(logbuf),
+ };
+ uint32_t i;
+
+ dump_printf(&log, "set H{");
+ for (i = 0; list && i < list->numHwLayers; i++) {
+ if (i)
+ dump_printf(&log, " ");
+ hwc_layer_1_t *layer = &list->hwLayers[i];
+ IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
+ if (hwc_dev->post2_blit_buffers) {
+ if ((i + 1) < hwc_dev->post2_layers)
+ dump_printf(&log, "%p:%s,", handle, "DSS");
+ else
+ dump_printf(&log, "%p:%s,", handle, "BV2D");
+ }
+ else
+ dump_printf(&log, "%p:%s,", handle, layer->compositionType == HWC_OVERLAY ? "DSS" : "SGX");
+ if ((layer->flags & HWC_SKIP_LAYER) || !handle) {
+ dump_printf(&log, "SKIP");
+ continue;
+ }
+ if (layer->flags & HWC_HINT_CLEAR_FB)
+ dump_printf(&log, "CLR,");
+ dump_printf(&log, "%d*%d(%s)", handle->iWidth, handle->iHeight, HAL_FMT(handle->iFormat));
+ if (layer->transform)
+ dump_printf(&log, "~%d", layer->transform);
+ }
+ dump_printf(&log, "} D{");
+ for (i = 0; i < dsscomp->num_ovls; i++) {
+ if (i)
+ dump_printf(&log, " ");
+ dump_printf(&log, "%d=", dsscomp->ovls[i].cfg.ix);
+ if (dsscomp->ovls[i].cfg.enabled)
+ dump_printf(&log, "%08x:%d*%d,%s",
+ dsscomp->ovls[i].ba,
+ dsscomp->ovls[i].cfg.width,
+ dsscomp->ovls[i].cfg.height,
+ DSS_FMT(dsscomp->ovls[i].cfg.color_mode));
+ else
+ dump_printf(&log, "-");
+ }
+ dump_printf(&log, "} L{");
+ for (i = 0; i < hwc_dev->post2_layers; i++) {
+ if (i)
+ dump_printf(&log, " ");
+ dump_printf(&log, "%p", hwc_dev->buffers[i]);
+ }
+ if (hwc_dev->post2_blit_buffers) {
+ dump_printf(&log, "} B{");
+ for (i = hwc_dev->post2_layers;
+ i < hwc_dev->post2_blit_buffers + hwc_dev->post2_layers; i++) {
+ dump_printf(&log, "%p ", hwc_dev->buffers[i]);
+ }
+ }
+ dump_printf(&log, "}%s\n", hwc_dev->use_sgx ? " swap" : "");
+
+ ALOGD("%s", log.buf);
+}
+
+static int sync_id = 0;
+
+static bool is_valid_format(uint32_t format)
+{
+ switch(format) {
+ case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ case HAL_PIXEL_FORMAT_BGRX_8888:
+ case HAL_PIXEL_FORMAT_TI_NV12:
+ case HAL_PIXEL_FORMAT_TI_NV12_1D:
+ return true;
+
+ default:
+ return false;
+ }
+}
+#ifdef OMAP_ENHANCEMENT_S3D
+static uint32_t get_s3d_layout_type(hwc_layer_1_t *layer)
+{
+ return (layer->flags & S3DLayoutTypeMask) >> S3DLayoutTypeShift;
+}
+
+static uint32_t get_s3d_layout_order(hwc_layer_1_t *layer)
+{
+ return (layer->flags & S3DLayoutOrderMask) >> S3DLayoutOrderShift;
+}
+#endif
+
+static bool scaled(hwc_layer_1_t *layer)
+{
+ int w = WIDTH(layer->sourceCrop);
+ int h = HEIGHT(layer->sourceCrop);
+
+ if (layer->transform & HWC_TRANSFORM_ROT_90)
+ swap(w, h);
+
+ bool res = WIDTH(layer->displayFrame) != w || HEIGHT(layer->displayFrame) != h;
+#ifdef OMAP_ENHANCEMENT_S3D
+ /* An S3D layer also needs scaling due to subsampling */
+ res = res || (get_s3d_layout_type(layer) != eMono);
+#endif
+
+ return res;
+}
+
+static bool is_protected(hwc_layer_1_t *layer)
+{
+ IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
+
+ return (handle->usage & GRALLOC_USAGE_PROTECTED) != 0;
+}
+
+#define is_BLENDED(layer) ((layer)->blending != HWC_BLENDING_NONE)
+
+static bool is_RGB(IMG_native_handle_t *handle)
+{
+ switch(handle->iFormat)
+ {
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ case HAL_PIXEL_FORMAT_BGRX_8888:
+ case HAL_PIXEL_FORMAT_RGB_565:
+ return true;
+ default:
+ return false;
+ }
+}
+static uint32_t get_format_bpp(uint32_t format)
+{
+ switch(format) {
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ case HAL_PIXEL_FORMAT_BGRX_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ return 32;
+ case HAL_PIXEL_FORMAT_RGB_565:
+ return 16;
+ case HAL_PIXEL_FORMAT_TI_NV12:
+ case HAL_PIXEL_FORMAT_TI_NV12_1D:
+ return 8;
+ default:
+ return 0;
+ }
+}
+
+static bool is_BGR_format(uint32_t format)
+{
+ switch (format) {
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool is_BGR(IMG_native_handle_t *handle)
+{
+ return is_BGR_format(handle->iFormat);
+}
+
+static bool is_NV12(IMG_native_handle_t *handle)
+{
+ switch(handle->iFormat)
+ {
+ case HAL_PIXEL_FORMAT_TI_NV12:
+ case HAL_PIXEL_FORMAT_TI_NV12_1D:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool is_upscaled_NV12(omap_hwc_device_t *hwc_dev, hwc_layer_1_t *layer)
+{
+ if (!layer)
+ return false;
+
+ IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
+ if (!is_NV12(handle))
+ return false;
+
+ int w = WIDTH(layer->sourceCrop);
+ int h = HEIGHT(layer->sourceCrop);
+
+ if (layer->transform & HWC_TRANSFORM_ROT_90)
+ swap(w, h);
+
+ return (WIDTH(layer->displayFrame) >= w * hwc_dev->upscaled_nv12_limit ||
+ HEIGHT(layer->displayFrame) >= h * hwc_dev->upscaled_nv12_limit);
+}
+
+static bool dockable(hwc_layer_1_t *layer)
+{
+ IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
+
+ return (handle->usage & GRALLOC_USAGE_EXTERNAL_DISP) != 0;
+}
+
+static uint32_t mem1d(IMG_native_handle_t *handle)
+{
+ if (handle == NULL || is_NV12(handle))
+ return 0;
+
+ int bpp = handle->iFormat == HAL_PIXEL_FORMAT_RGB_565 ? 2 : 4;
+ int stride = ALIGN(handle->iWidth, HW_ALIGN) * bpp;
+ return stride * handle->iHeight;
+}
+
+static void setup_layer_base(struct dss2_ovl_cfg *oc, int index, uint32_t format,
+ bool blended, int width, int height)
+{
+ /* YUV2RGB conversion */
+ const struct omap_dss_cconv_coefs ctbl_bt601_5 = {
+ 298, 409, 0, 298, -208, -100, 298, 0, 517, 0,
+ };
+
+ /* convert color format */
+ switch (format) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ oc->color_mode = OMAP_DSS_COLOR_ARGB32;
+ if (blended)
+ break;
+
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_BGRX_8888:
+ oc->color_mode = OMAP_DSS_COLOR_RGB24U;
+ break;
+
+ case HAL_PIXEL_FORMAT_RGB_565:
+ oc->color_mode = OMAP_DSS_COLOR_RGB16;
+ break;
+
+ case HAL_PIXEL_FORMAT_TI_NV12:
+ case HAL_PIXEL_FORMAT_TI_NV12_1D:
+ oc->color_mode = OMAP_DSS_COLOR_NV12;
+ oc->cconv = ctbl_bt601_5;
+ break;
+
+ default:
+ /* Should have been filtered out */
+ ALOGV("Unsupported pixel format");
+ return;
+ }
+
+ oc->width = width;
+ oc->height = height;
+ oc->stride = ALIGN(width, HW_ALIGN) * get_format_bpp(format) / 8;
+
+ oc->enabled = 1;
+ oc->global_alpha = 255;
+ oc->zorder = index;
+ oc->ix = 0;
+
+ /* defaults for SGX framebuffer renders */
+ oc->crop.w = oc->win.w = width;
+ oc->crop.h = oc->win.h = height;
+
+ /* for now interlacing and vc1 info is not supplied */
+ oc->ilace = OMAP_DSS_ILACE_NONE;
+ oc->vc1.enable = 0;
+}
+
+static void setup_layer(omap_hwc_device_t *hwc_dev, struct dss2_ovl_info *ovl,
+ hwc_layer_1_t *layer, int index, uint32_t format, int width, int height)
+{
+ struct dss2_ovl_cfg *oc = &ovl->cfg;
+
+ //dump_layer(layer);
+
+ setup_layer_base(oc, index, format, is_BLENDED(layer), width, height);
+
+ /* convert transformation - assuming 0-set config */
+ if (layer->transform & HWC_TRANSFORM_FLIP_H)
+ oc->mirror = 1;
+ if (layer->transform & HWC_TRANSFORM_FLIP_V) {
+ oc->rotation = 2;
+ oc->mirror = !oc->mirror;
+ }
+ if (layer->transform & HWC_TRANSFORM_ROT_90) {
+ oc->rotation += oc->mirror ? -1 : 1;
+ oc->rotation &= 3;
+ }
+
+ oc->pre_mult_alpha = layer->blending == HWC_BLENDING_PREMULT;
+
+ /* display position */
+ oc->win.x = layer->displayFrame.left;
+ oc->win.y = layer->displayFrame.top;
+ oc->win.w = WIDTH(layer->displayFrame);
+ oc->win.h = HEIGHT(layer->displayFrame);
+
+ /* crop */
+ oc->crop.x = layer->sourceCrop.left;
+ oc->crop.y = layer->sourceCrop.top;
+ oc->crop.w = WIDTH(layer->sourceCrop);
+ oc->crop.h = HEIGHT(layer->sourceCrop);
+}
+
+const float m_unit[2][3] = { { 1., 0., 0. }, { 0., 1., 0. } };
+
+static inline void m_translate(float m[2][3], float dx, float dy)
+{
+ m[0][2] += dx;
+ m[1][2] += dy;
+}
+
+static inline void m_scale1(float m[3], int from, int to)
+{
+ m[0] = m[0] * to / from;
+ m[1] = m[1] * to / from;
+ m[2] = m[2] * to / from;
+}
+
+static inline void m_scale(float m[2][3], int x_from, int x_to, int y_from, int y_to)
+{
+ m_scale1(m[0], x_from, x_to);
+ m_scale1(m[1], y_from, y_to);
+}
+
+static void m_rotate(float m[2][3], int quarter_turns)
+{
+ if (quarter_turns & 2)
+ m_scale(m, 1, -1, 1, -1);
+ if (quarter_turns & 1) {
+ float q;
+ q = m[0][0]; m[0][0] = -m[1][0]; m[1][0] = q;
+ q = m[0][1]; m[0][1] = -m[1][1]; m[1][1] = q;
+ q = m[0][2]; m[0][2] = -m[1][2]; m[1][2] = q;
+ }
+}
+
+static inline int m_round(float x)
+{
+ /* int truncates towards 0 */
+ return (int) (x < 0 ? x - 0.5 : x + 0.5);
+}
+
+/*
+ * assuming xpy (xratio:yratio) original pixel ratio, calculate the adjusted width
+ * and height for a screen of xres/yres and physical size of width/height.
+ * The adjusted size is the largest that fits into the screen.
+ */
+static void get_max_dimensions(uint32_t orig_xres, uint32_t orig_yres,
+ float xpy,
+ uint32_t scr_xres, uint32_t scr_yres,
+ uint32_t scr_width, uint32_t scr_height,
+ uint32_t *adj_xres, uint32_t *adj_yres)
+{
+ /* assume full screen (largest size)*/
+ *adj_xres = scr_xres;
+ *adj_yres = scr_yres;
+
+ /* assume 1:1 pixel ratios if none supplied */
+ if (!scr_width || !scr_height) {
+ scr_width = scr_xres;
+ scr_height = scr_yres;
+ }
+
+ /* trim to keep aspect ratio */
+ float x_factor = orig_xres * xpy * scr_height;
+ float y_factor = orig_yres * scr_width;
+
+ /* allow for tolerance so we avoid scaling if framebuffer is standard size */
+ if (x_factor < y_factor * (1.f - ASPECT_RATIO_TOLERANCE))
+ *adj_xres = (uint32_t) (x_factor * *adj_xres / y_factor + 0.5);
+ else if (x_factor * (1.f - ASPECT_RATIO_TOLERANCE) > y_factor)
+ *adj_yres = (uint32_t) (y_factor * *adj_yres / x_factor + 0.5);
+}
+
+static void set_ext_matrix(omap_hwc_ext_t *ext, struct hwc_rect region)
+{
+ int orig_w = WIDTH(region);
+ int orig_h = HEIGHT(region);
+ float xpy = ext->lcd_xpy;
+
+ /* reorientation matrix is:
+ m = (center-from-target-center) * (scale-to-target) * (mirror) * (rotate) * (center-to-original-center) */
+
+ memcpy(ext->m, m_unit, sizeof(m_unit));
+ m_translate(ext->m, -(orig_w / 2.0f) - region.left, -(orig_h / 2.0f) - region.top);
+ m_rotate(ext->m, ext->current.rotation);
+ if (ext->current.hflip)
+ m_scale(ext->m, 1, -1, 1, 1);
+
+ if (ext->current.rotation & 1) {
+ swap(orig_w, orig_h);
+ xpy = 1. / xpy;
+ }
+
+ /* get target size */
+ uint32_t adj_xres, adj_yres;
+ get_max_dimensions(orig_w, orig_h, xpy,
+ ext->xres, ext->yres, ext->width, ext->height,
+ &adj_xres, &adj_yres);
+
+ m_scale(ext->m, orig_w, adj_xres, orig_h, adj_yres);
+ m_translate(ext->m, ext->xres >> 1, ext->yres >> 1);
+}
+
+static int
+crop_to_rect(struct dss2_ovl_cfg *cfg, struct hwc_rect vis_rect)
+{
+ struct {
+ int xy[2];
+ int wh[2];
+ } crop, win;
+ struct {
+ int lt[2];
+ int rb[2];
+ } vis;
+ win.xy[0] = cfg->win.x; win.xy[1] = cfg->win.y;
+ win.wh[0] = cfg->win.w; win.wh[1] = cfg->win.h;
+ crop.xy[0] = cfg->crop.x; crop.xy[1] = cfg->crop.y;
+ crop.wh[0] = cfg->crop.w; crop.wh[1] = cfg->crop.h;
+ vis.lt[0] = vis_rect.left; vis.lt[1] = vis_rect.top;
+ vis.rb[0] = vis_rect.right; vis.rb[1] = vis_rect.bottom;
+
+ int c;
+ bool swap = cfg->rotation & 1;
+
+ /* align crop window with display coordinates */
+ if (swap)
+ crop.xy[1] -= (crop.wh[1] = -crop.wh[1]);
+ if (cfg->rotation & 2)
+ crop.xy[!swap] -= (crop.wh[!swap] = -crop.wh[!swap]);
+ if ((!cfg->mirror) ^ !(cfg->rotation & 2))
+ crop.xy[swap] -= (crop.wh[swap] = -crop.wh[swap]);
+
+ for (c = 0; c < 2; c++) {
+ /* see if complete buffer is outside the vis or it is
+ fully cropped or scaled to 0 */
+ if (win.wh[c] <= 0 || vis.rb[c] <= vis.lt[c] ||
+ win.xy[c] + win.wh[c] <= vis.lt[c] ||
+ win.xy[c] >= vis.rb[c] ||
+ !crop.wh[c ^ swap])
+ return -ENOENT;
+
+ /* crop left/top */
+ if (win.xy[c] < vis.lt[c]) {
+ /* correction term */
+ int a = (vis.lt[c] - win.xy[c]) * crop.wh[c ^ swap] / win.wh[c];
+ crop.xy[c ^ swap] += a;
+ crop.wh[c ^ swap] -= a;
+ win.wh[c] -= vis.lt[c] - win.xy[c];
+ win.xy[c] = vis.lt[c];
+ }
+ /* crop right/bottom */
+ if (win.xy[c] + win.wh[c] > vis.rb[c]) {
+ crop.wh[c ^ swap] = crop.wh[c ^ swap] * (vis.rb[c] - win.xy[c]) / win.wh[c];
+ win.wh[c] = vis.rb[c] - win.xy[c];
+ }
+
+ if (!crop.wh[c ^ swap] || !win.wh[c])
+ return -ENOENT;
+ }
+
+ /* realign crop window to buffer coordinates */
+ if (cfg->rotation & 2)
+ crop.xy[!swap] -= (crop.wh[!swap] = -crop.wh[!swap]);
+ if ((!cfg->mirror) ^ !(cfg->rotation & 2))
+ crop.xy[swap] -= (crop.wh[swap] = -crop.wh[swap]);
+ if (swap)
+ crop.xy[1] -= (crop.wh[1] = -crop.wh[1]);
+
+ cfg->win.x = win.xy[0]; cfg->win.y = win.xy[1];
+ cfg->win.w = win.wh[0]; cfg->win.h = win.wh[1];
+ cfg->crop.x = crop.xy[0]; cfg->crop.y = crop.xy[1];
+ cfg->crop.w = crop.wh[0]; cfg->crop.h = crop.wh[1];
+
+ return 0;
+}
+
+static void apply_transform(float transform[2][3],struct dss2_ovl_cfg *oc)
+{
+ float x, y, w, h;
+
+ /* display position */
+ x = transform[0][0] * oc->win.x + transform[0][1] * oc->win.y + transform[0][2];
+ y = transform[1][0] * oc->win.x + transform[1][1] * oc->win.y + transform[1][2];
+ w = transform[0][0] * oc->win.w + transform[0][1] * oc->win.h;
+ h = transform[1][0] * oc->win.w + transform[1][1] * oc->win.h;
+ oc->win.x = m_round(w > 0 ? x : x + w);
+ oc->win.y = m_round(h > 0 ? y : y + h);
+ oc->win.w = m_round(w > 0 ? w : -w);
+ oc->win.h = m_round(h > 0 ? h : -h);
+}
+
+static void adjust_ext_layer(omap_hwc_ext_t *ext, struct dss2_ovl_info *ovl)
+{
+ struct dss2_ovl_cfg *oc = &ovl->cfg;
+
+ /* crop to clone region if mirroring */
+ if (!ext->current.docking &&
+ crop_to_rect(&ovl->cfg, ext->mirror_region) != 0) {
+ ovl->cfg.enabled = 0;
+ return;
+ }
+
+ apply_transform(ext->m, oc);
+
+ /* combining transformations: F^a*R^b*F^i*R^j = F^(a+b)*R^(j+b*(-1)^i), because F*R = R^(-1)*F */
+ oc->rotation += (oc->mirror ? -1 : 1) * ext->current.rotation;
+ oc->rotation &= 3;
+ if (ext->current.hflip)
+ oc->mirror = !oc->mirror;
+}
+
+static struct dsscomp_platform_info limits;
+
+static void adjust_primary_display_layer(omap_hwc_device_t *hwc_dev, struct dss2_ovl_info *ovl)
+{
+ struct dss2_ovl_cfg *oc = &ovl->cfg;
+
+ if (crop_to_rect(&ovl->cfg, hwc_dev->primary_region) != 0) {
+ ovl->cfg.enabled = 0;
+ return;
+ }
+
+ apply_transform(hwc_dev->primary_m, oc);
+
+ /* combining transformations: F^a*R^b*F^i*R^j = F^(a+b)*R^(j+b*(-1)^i), because F*R = R^(-1)*F */
+ oc->rotation += (oc->mirror ? -1 : 1) * hwc_dev->primary_rotation;
+ oc->rotation &= 3;
+}
+
+static bool can_scale(uint32_t src_w, uint32_t src_h, uint32_t dst_w, uint32_t dst_h, bool is_2d,
+ struct dsscomp_display_info *dis, struct dsscomp_platform_info *limits,
+ uint32_t pclk, IMG_native_handle_t *handle)
+{
+ uint32_t fclk = limits->fclk / 1000;
+ uint32_t min_src_w = DIV_ROUND_UP(src_w, is_2d ? limits->max_xdecim_2d : limits->max_xdecim_1d);
+ uint32_t min_src_h = DIV_ROUND_UP(src_h, is_2d ? limits->max_ydecim_2d : limits->max_ydecim_1d);
+
+ /* ERRATAs */
+ /* cannot render 1-width layers on DSI video mode panels - we just disallow all 1-width LCD layers */
+ if (dis->channel != OMAP_DSS_CHANNEL_DIGIT && dst_w < limits->min_width)
+ return false;
+
+ /* NOTE: no support for checking YUV422 layers that are tricky to scale */
+
+ /* FIXME: limit vertical downscale well below theoretical limit as we saw display artifacts */
+ if (dst_h < src_h / 4)
+ return false;
+
+ /* max downscale */
+ if (dst_h * limits->max_downscale < min_src_h)
+ return false;
+
+ /* for manual panels pclk is 0, and there are no pclk based scaling limits */
+ if (!pclk)
+ return !(dst_w < src_w / limits->max_downscale / (is_2d ? limits->max_xdecim_2d : limits->max_xdecim_1d));
+
+ /* :HACK: limit horizontal downscale well below theoretical limit as we saw display artifacts */
+ if (dst_w * 4 < src_w)
+ return false;
+
+ if (handle)
+ if (get_format_bpp(handle->iFormat) == 32 && src_w > 1280 && dst_w * 3 < src_w)
+ return false;
+
+ /* max horizontal downscale is 4, or the fclk/pixclk */
+ if (fclk > pclk * limits->max_downscale)
+ fclk = pclk * limits->max_downscale;
+ /* for small parts, we need to use integer fclk/pixclk */
+ if (src_w < limits->integer_scale_ratio_limit)
+ fclk = fclk / pclk * pclk;
+ if ((uint32_t) dst_w * fclk < min_src_w * pclk)
+ return false;
+
+ return true;
+}
+
+static bool can_scale_layer(omap_hwc_device_t *hwc_dev, hwc_layer_1_t *layer, IMG_native_handle_t *handle)
+{
+ int src_w = WIDTH(layer->sourceCrop);
+ int src_h = HEIGHT(layer->sourceCrop);
+ int dst_w = WIDTH(layer->displayFrame);
+ int dst_h = HEIGHT(layer->displayFrame);
+
+ /* account for 90-degree rotation */
+ if (layer->transform & HWC_TRANSFORM_ROT_90)
+ swap(src_w, src_h);
+
+ /* NOTE: layers should be able to be scaled externally since
+ framebuffer is able to be scaled on selected external resolution */
+ return can_scale(src_w, src_h, dst_w, dst_h, is_NV12(handle), &hwc_dev->fb_dis, &limits,
+ hwc_dev->fb_dis.timings.pixel_clock, handle);
+}
+
+static bool is_valid_layer(omap_hwc_device_t *hwc_dev, hwc_layer_1_t *layer, IMG_native_handle_t *handle)
+{
+ /* Skip layers are handled by SF */
+ if ((layer->flags & HWC_SKIP_LAYER) || !handle)
+ return false;
+
+ if (!is_valid_format(handle->iFormat))
+ return false;
+
+ /* 1D buffers: no transform, must fit in TILER slot */
+ if (!is_NV12(handle)) {
+ if (layer->transform)
+ return false;
+ if (mem1d(handle) > limits.tiler1d_slot_size)
+ return false;
+ }
+
+ return can_scale_layer(hwc_dev, layer, handle);
+}
+
+static uint32_t add_scaling_score(uint32_t score,
+ uint32_t xres, uint32_t yres, uint32_t refresh,
+ uint32_t ext_xres, uint32_t ext_yres,
+ uint32_t mode_xres, uint32_t mode_yres, uint32_t mode_refresh)
+{
+ uint32_t area = xres * yres;
+ uint32_t ext_area = ext_xres * ext_yres;
+ uint32_t mode_area = mode_xres * mode_yres;
+
+ /* prefer to upscale (1% tolerance) [0..1] (insert after 1st bit) */
+ int upscale = (ext_xres >= xres * 99 / 100 && ext_yres >= yres * 99 / 100);
+ score = (((score & ~1) | upscale) << 1) | (score & 1);
+
+ /* pick minimum scaling [0..16] */
+ if (ext_area > area)
+ score = (score << 5) | (16 * area / ext_area);
+ else
+ score = (score << 5) | (16 * ext_area / area);
+
+ /* pick smallest leftover area [0..16] */
+ score = (score << 5) | ((16 * ext_area + (mode_area >> 1)) / mode_area);
+
+ /* adjust mode refresh rate */
+ mode_refresh += mode_refresh % 6 == 5;
+
+ /* prefer same or higher frame rate */
+ upscale = (mode_refresh >= refresh);
+ score = (score << 1) | upscale;
+
+ /* pick closest frame rate */
+ if (mode_refresh > refresh)
+ score = (score << 8) | (240 * refresh / mode_refresh);
+ else
+ score = (score << 8) | (240 * mode_refresh / refresh);
+
+ return score;
+}
+
+static int set_best_hdmi_mode(omap_hwc_device_t *hwc_dev, uint32_t xres, uint32_t yres, float xpy)
+{
+ int dis_ix = hwc_dev->on_tv ? 0 : 1;
+ struct _qdis {
+ struct dsscomp_display_info dis;
+ struct dsscomp_videomode modedb[32];
+ } d = { .dis = { .ix = dis_ix } };
+ omap_hwc_ext_t *ext = &hwc_dev->ext;
+
+ d.dis.modedb_len = sizeof(d.modedb) / sizeof(*d.modedb);
+ int ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_QUERY_DISPLAY, &d);
+ if (ret)
+ return ret;
+
+ if (d.dis.timings.x_res * d.dis.timings.y_res == 0 ||
+ xres * yres == 0)
+ return -EINVAL;
+
+ uint32_t i, best = ~0, best_score = 0;
+ ext->width = d.dis.width_in_mm;
+ ext->height = d.dis.height_in_mm;
+ ext->xres = d.dis.timings.x_res;
+ ext->yres = d.dis.timings.y_res;
+
+ /* use VGA external resolution as default */
+ if (!ext->xres || !ext->yres) {
+ ext->xres = 640;
+ ext->yres = 480;
+ }
+
+ uint32_t ext_fb_xres, ext_fb_yres;
+ for (i = 0; i < d.dis.modedb_len; i++) {
+ uint32_t score = 0;
+ uint32_t mode_xres = d.modedb[i].xres;
+ uint32_t mode_yres = d.modedb[i].yres;
+ uint32_t ext_width = d.dis.width_in_mm;
+ uint32_t ext_height = d.dis.height_in_mm;
+
+ if (d.modedb[i].vmode & FB_VMODE_INTERLACED)
+ mode_yres /= 2;
+
+ if (d.modedb[i].flag & FB_FLAG_RATIO_4_3) {
+ ext_width = 4;
+ ext_height = 3;
+ } else if (d.modedb[i].flag & FB_FLAG_RATIO_16_9) {
+ ext_width = 16;
+ ext_height = 9;
+ }
+
+ if (!mode_xres || !mode_yres)
+ continue;
+
+ get_max_dimensions(xres, yres, xpy, mode_xres, mode_yres,
+ ext_width, ext_height, &ext_fb_xres, &ext_fb_yres);
+
+ /* we need to ensure that even TILER2D buffers can be scaled */
+ if (!d.modedb[i].pixclock ||
+ (d.modedb[i].vmode & ~FB_VMODE_INTERLACED) ||
+ !can_scale(xres, yres, ext_fb_xres, ext_fb_yres,
+ 1, &d.dis, &limits,
+ 1000000000 / d.modedb[i].pixclock, NULL))
+ continue;
+
+ /* prefer CEA modes */
+ if (d.modedb[i].flag & (FB_FLAG_RATIO_4_3 | FB_FLAG_RATIO_16_9))
+ score = 1;
+
+ /* prefer the same mode as we use for mirroring to avoid mode change */
+ score = (score << 1) | (i == ~ext->mirror_mode && ext->avoid_mode_change);
+
+ score = add_scaling_score(score, xres, yres, 60, ext_fb_xres, ext_fb_yres,
+ mode_xres, mode_yres, d.modedb[i].refresh ? : 1);
+
+ ALOGD("#%d: %dx%d %dHz", i, mode_xres, mode_yres, d.modedb[i].refresh);
+ if (debug)
+ ALOGD(" score=0x%x adj.res=%dx%d", score, ext_fb_xres, ext_fb_yres);
+ if (best_score < score) {
+ ext->width = ext_width;
+ ext->height = ext_height;
+ ext->xres = mode_xres;
+ ext->yres = mode_yres;
+ best = i;
+ best_score = score;
+ }
+ }
+ if (~best) {
+ struct dsscomp_setup_display_data sdis = { .ix = dis_ix };
+ sdis.mode = d.dis.modedb[best];
+ ALOGD("picking #%d", best);
+ /* only reconfigure on change */
+ if (ext->last_mode != ~best)
+ ioctl(hwc_dev->dsscomp_fd, DSSCIOC_SETUP_DISPLAY, &sdis);
+ ext->last_mode = ~best;
+ } else {
+ uint32_t ext_width = d.dis.width_in_mm;
+ uint32_t ext_height = d.dis.height_in_mm;
+ uint32_t ext_fb_xres, ext_fb_yres;
+
+ get_max_dimensions(xres, yres, xpy, d.dis.timings.x_res, d.dis.timings.y_res,
+ ext_width, ext_height, &ext_fb_xres, &ext_fb_yres);
+ if (!d.dis.timings.pixel_clock ||
+ !can_scale(xres, yres, ext_fb_xres, ext_fb_yres,
+ 1, &d.dis, &limits,
+ d.dis.timings.pixel_clock, NULL)) {
+ ALOGW("DSS scaler cannot support HDMI cloning");
+ return -1;
+ }
+ }
+ ext->last_xres_used = xres;
+ ext->last_yres_used = yres;
+ ext->last_xpy = xpy;
+ if (d.dis.channel == OMAP_DSS_CHANNEL_DIGIT)
+ ext->on_tv = 1;
+ return 0;
+}
+
+static void gather_layer_statistics(omap_hwc_device_t *hwc_dev, hwc_display_contents_1_t *list)
+{
+ uint32_t i;
+ counts_t *num = &hwc_dev->counts;
+
+ memset(num, 0, sizeof(*num));
+
+ num->composited_layers = list ? list->numHwLayers : 0;
+
+ /* Figure out how many layers we can support via DSS */
+ for (i = 0; list && i < list->numHwLayers; i++) {
+ hwc_layer_1_t *layer = &list->hwLayers[i];
+ IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
+#ifdef OMAP_ENHANCEMENT_S3D
+ uint32_t s3d_layout_type = get_s3d_layout_type(layer);
+#endif
+
+ layer->compositionType = HWC_FRAMEBUFFER;
+
+ if (is_valid_layer(hwc_dev, layer, handle)) {
+#ifdef OMAP_ENHANCEMENT_S3D
+ if (s3d_layout_type != eMono) {
+ /* For now we can only handle 1 S3D layer, skip any additional ones */
+ if (num->s3d > 0 || !hwc_dev->ext.dock.enabled || !hwc_dev->ext.s3d_capable) {
+ layer->flags |= HWC_SKIP_LAYER;
+ continue;
+ } else if (num->s3d == 0) {
+ /* For now, S3D layer is made a dockable layer to trigger docking logic. */
+ if (!dockable(layer)) {
+ num->dockable++;
+ }
+ num->s3d++;
+ hwc_dev->s3d_input_type = s3d_layout_type;
+ hwc_dev->s3d_input_order = get_s3d_layout_order(layer);
+ }
+ }
+#endif
+ num->possible_overlay_layers++;
+
+ /* NV12 layers can only be rendered on scaling overlays */
+ if (scaled(layer) || is_NV12(handle) || hwc_dev->primary_transform)
+ num->scaled_layers++;
+
+ if (is_BGR(handle))
+ num->BGR++;
+ else if (is_RGB(handle))
+ num->RGB++;
+ else if (is_NV12(handle))
+ num->NV12++;
+
+ if (dockable(layer))
+ num->dockable++;
+
+ if (is_protected(layer))
+ num->protected++;
+
+ num->mem += mem1d(handle);
+ }
+ }
+}
+
+static void decide_supported_cloning(omap_hwc_device_t *hwc_dev)
+{
+ omap_hwc_ext_t *ext = &hwc_dev->ext;
+ counts_t *num = &hwc_dev->counts;
+ int nonscaling_ovls = NUM_NONSCALING_OVERLAYS;
+ num->max_hw_overlays = MAX_HW_OVERLAYS;
+
+ /*
+ * We cannot atomically switch overlays from one display to another. First, they
+ * have to be disabled, and the disabling has to take effect on the current display.
+ * We keep track of the available number of overlays here.
+ */
+ if (ext->dock.enabled && !(ext->mirror.enabled && !(num->dockable || ext->force_dock))) {
+ /* some overlays may already be used by the external display, so we account for this */
+
+ /* reserve just a video pipeline for HDMI if docking */
+ hwc_dev->ext_ovls = (num->dockable || ext->force_dock) ? 1 : 0;
+#ifdef OMAP_ENHANCEMENT_S3D
+ if (num->s3d && (hwc_dev->ext.s3d_type != hwc_dev->s3d_input_type)) {
+ /* S3D layers are dockable, and they need two overlays */
+ hwc_dev->ext_ovls += 1;
+ }
+#endif
+ num->max_hw_overlays -= max(hwc_dev->ext_ovls, hwc_dev->last_ext_ovls);
+
+ /* use mirroring transform if we are auto-switching to docking mode while mirroring*/
+ if (ext->mirror.enabled) {
+ ext->current = ext->mirror;
+ ext->current.docking = 1;
+ } else {
+ ext->current = ext->dock;
+ }
+ } else if (ext->mirror.enabled) {
+ /*
+ * otherwise, manage just from half the pipelines. NOTE: there is
+ * no danger of having used too many overlays for external display here.
+ */
+ num->max_hw_overlays >>= 1;
+ nonscaling_ovls >>= 1;
+ hwc_dev->ext_ovls = MAX_HW_OVERLAYS - num->max_hw_overlays;
+ ext->current = ext->mirror;
+ } else {
+ num->max_hw_overlays -= hwc_dev->last_ext_ovls;
+ hwc_dev->ext_ovls = 0;
+ ext->current.enabled = 0;
+ }
+
+ /*
+ * :TRICKY: We may not have enough overlays on the external display. We "reserve" them
+ * here to figure out if mirroring is supported, but may not do mirroring for the first
+ * frame while the overlays required for it are cleared.
+ */
+ hwc_dev->ext_ovls_wanted = hwc_dev->ext_ovls;
+ hwc_dev->ext_ovls = min(MAX_HW_OVERLAYS - hwc_dev->last_int_ovls, hwc_dev->ext_ovls);
+
+ /* if mirroring, we are limited by both internal and external overlays. However,
+ ext_ovls is always <= MAX_HW_OVERLAYS / 2 <= max_hw_overlays */
+ if (!num->protected && hwc_dev->ext_ovls && ext->current.enabled && !ext->current.docking)
+ num->max_hw_overlays = hwc_dev->ext_ovls;
+
+ /* If FB is not same resolution as LCD don't use GFX pipe line*/
+ if (hwc_dev->primary_transform) {
+ num->max_hw_overlays -= NUM_NONSCALING_OVERLAYS;
+ num->max_scaling_overlays = num->max_hw_overlays;
+ } else
+ num->max_scaling_overlays = num->max_hw_overlays - nonscaling_ovls;
+}
+
+static bool can_dss_render_all(omap_hwc_device_t *hwc_dev)
+{
+ omap_hwc_ext_t *ext = &hwc_dev->ext;
+ counts_t *num = &hwc_dev->counts;
+ bool on_tv = hwc_dev->on_tv || (ext->on_tv && ext->current.enabled);
+ bool tform = ext->current.enabled && (ext->current.rotation || ext->current.hflip);
+
+ return !hwc_dev->force_sgx &&
+ /* must have at least one layer if using composition bypass to get sync object */
+ num->possible_overlay_layers &&
+ num->possible_overlay_layers <= num->max_hw_overlays &&
+ num->possible_overlay_layers == num->composited_layers &&
+ num->scaled_layers <= num->max_scaling_overlays &&
+ num->NV12 <= num->max_scaling_overlays &&
+ /* fits into TILER slot */
+ num->mem <= limits.tiler1d_slot_size &&
+ /* we cannot clone non-NV12 transformed layers */
+ (!tform || (num->NV12 == num->possible_overlay_layers) ||
+ (num->NV12 && ext->current.docking)) &&
+ /* HDMI cannot display BGR */
+ (num->BGR == 0 || (num->RGB == 0 && !on_tv) || !hwc_dev->flags_rgb_order) &&
+ /* If nv12_only flag is set DSS should only render NV12 */
+ (!hwc_dev->flags_nv12_only || (num->BGR == 0 && num->RGB == 0));
+}
+
+static inline bool can_dss_render_layer(omap_hwc_device_t *hwc_dev, hwc_layer_1_t *layer)
+{
+ IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
+
+ omap_hwc_ext_t *ext = &hwc_dev->ext;
+ bool cloning = ext->current.enabled && (!ext->current.docking || (handle!=NULL ? dockable(layer) : 0));
+ bool on_tv = hwc_dev->on_tv || (ext->on_tv && cloning);
+ bool tform = cloning && (ext->current.rotation || ext->current.hflip);
+
+ return is_valid_layer(hwc_dev, layer, handle) &&
+ /* cannot rotate non-NV12 layers on external display */
+ (!tform || is_NV12(handle)) &&
+ /* skip non-NV12 layers if also using SGX (if nv12_only flag is set) */
+ (!hwc_dev->flags_nv12_only || (!hwc_dev->use_sgx || is_NV12(handle))) &&
+ /* make sure RGB ordering is consistent (if rgb_order flag is set) */
+ (!(hwc_dev->swap_rb ? is_RGB(handle) : is_BGR(handle)) ||
+ !hwc_dev->flags_rgb_order) &&
+ /* TV can only render RGB */
+ !(on_tv && is_BGR(handle));
+}
+
+static inline int display_area(struct dss2_ovl_info *o)
+{
+ return o->cfg.win.w * o->cfg.win.h;
+}
+
+static int clone_layer(omap_hwc_device_t *hwc_dev, int ix) {
+ struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data;
+ omap_hwc_ext_t *ext = &hwc_dev->ext;
+ int ext_ovl_ix = dsscomp->num_ovls - hwc_dev->post2_layers;
+ struct dss2_ovl_info *o = &dsscomp->ovls[dsscomp->num_ovls];
+
+ if (dsscomp->num_ovls >= MAX_HW_OVERLAYS) {
+ ALOGE("**** cannot clone layer #%d. using all %d overlays.", ix, dsscomp->num_ovls);
+ return -EBUSY;
+ }
+
+ memcpy(o, dsscomp->ovls + ix, sizeof(*o));
+
+ /* reserve overlays at end for other display */
+ o->cfg.ix = MAX_HW_OVERLAYS - 1 - ext_ovl_ix;
+ o->cfg.mgr_ix = 1;
+ /*
+ * Here the assumption is that overlay0 is the one attached to FB.
+ * Hence this clone_layer call is for FB cloning (provided use_sgx is true).
+ */
+ /* For the external displays whose transform is the same as
+ * that of primary display, ion_handles would be NULL hence
+ * the below logic doesn't execute.
+ */
+ if (ix == 0 && hwc_dev->ion_handles[sync_id%2] && hwc_dev->use_sgx) {
+ o->addressing = OMAP_DSS_BUFADDR_ION;
+ o->ba = (int)hwc_dev->ion_handles[sync_id%2];
+ } else {
+ o->addressing = OMAP_DSS_BUFADDR_OVL_IX;
+ o->ba = ix;
+ }
+
+ /* use distinct z values (to simplify z-order checking) */
+ o->cfg.zorder += hwc_dev->post2_layers;
+
+ adjust_ext_layer(&hwc_dev->ext, o);
+ dsscomp->num_ovls++;
+ return 0;
+}
+
+static int clone_external_layer(omap_hwc_device_t *hwc_dev, int ix) {
+ struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data;
+ omap_hwc_ext_t *ext = &hwc_dev->ext;
+
+ /* mirror only 1 external layer */
+ struct dss2_ovl_info *o = &dsscomp->ovls[ix];
+
+ /* full screen video after transformation */
+ uint32_t xres = o->cfg.crop.w, yres = o->cfg.crop.h;
+ if ((ext->current.rotation + o->cfg.rotation) & 1)
+ swap(xres, yres);
+ float xpy = ext->lcd_xpy * o->cfg.win.w / o->cfg.win.h;
+ if (o->cfg.rotation & 1)
+ xpy = o->cfg.crop.h / xpy / o->cfg.crop.w;
+ else
+ xpy = o->cfg.crop.h * xpy / o->cfg.crop.w;
+ if (ext->current.rotation & 1)
+ xpy = 1. / xpy;
+
+ /* adjust hdmi mode based on resolution */
+ if (xres != ext->last_xres_used ||
+ yres != ext->last_yres_used ||
+ xpy < ext->last_xpy * (1.f - ASPECT_RATIO_TOLERANCE) ||
+ xpy * (1.f - ASPECT_RATIO_TOLERANCE) > ext->last_xpy) {
+ ALOGD("set up HDMI for %d*%d\n", xres, yres);
+ if (set_best_hdmi_mode(hwc_dev, xres, yres, xpy)) {
+ ext->current.enabled = 0;
+ return -ENODEV;
+ }
+ }
+
+ struct hwc_rect region = {
+ .left = o->cfg.win.x, .top = o->cfg.win.y,
+ .right = o->cfg.win.x + o->cfg.win.w,
+ .bottom = o->cfg.win.y + o->cfg.win.h
+ };
+ set_ext_matrix(&hwc_dev->ext, region);
+
+ return clone_layer(hwc_dev, ix);
+}
+
+#ifdef OMAP_ENHANCEMENT_S3D
+const char hdmiS3DTypePath[] = "/sys/devices/platform/omapdss/display1/s3d_type";
+const char hdmiS3DEnablePath[] = "/sys/devices/platform/omapdss/display1/s3d_enable";
+
+static void enable_s3d_hdmi(omap_hwc_device_t *hwc_dev, bool enable)
+{
+ size_t bytesWritten;
+ char data;
+ int fd;
+
+ if (hwc_dev->ext.s3d_enabled == enable) {
+ return;
+ }
+
+ if (enable) {
+ char type[2];
+
+ switch(hwc_dev->ext.s3d_type) {
+ case eSideBySide:
+ snprintf(type, sizeof(type), "%d", HDMI_SIDE_BY_SIDE_HALF);
+ break;
+ case eTopBottom:
+ snprintf(type, sizeof(type), "%d", HDMI_TOPBOTTOM);
+ break;
+ default:
+ return;
+ }
+
+ fd = open(hdmiS3DTypePath, O_WRONLY);
+ if (fd < 0) {
+ ALOGE("Failed to open sysfs %s", hdmiS3DTypePath);
+ return;
+ }
+ bytesWritten = write(fd, type, sizeof(type));
+ close(fd);
+
+ if (bytesWritten != sizeof(type)) {
+ ALOGE("Failed to write (%s) to sysfs %s", type, hdmiS3DTypePath);
+ return;
+ }
+ }
+ data = enable ? '1' : '0';
+
+ fd = open(hdmiS3DEnablePath, O_WRONLY);
+ if (fd < 0) {
+ ALOGE("Failed to open sysfs %s", hdmiS3DEnablePath);
+ return;
+ }
+ bytesWritten = write(fd, &data, 1);
+ close(fd);
+
+ if (bytesWritten != 1) {
+ ALOGE("Failed to write(%d) to sysfs %s", enable, hdmiS3DEnablePath);
+ return;
+ }
+
+ hwc_dev->ext.s3d_enabled = enable;
+}
+
+static void adjust_ext_s3d_layer(omap_hwc_device_t *hwc_dev,
+ struct dss2_ovl_info *ovl, bool left_view)
+{
+ struct dss2_ovl_cfg *oc = &ovl->cfg;
+ float x, y, w, h;
+
+ switch (hwc_dev->s3d_input_type) {
+ case eSideBySide:
+ oc->crop.w = oc->crop.w/2;
+ if ((left_view && hwc_dev->s3d_input_order == eRightViewFirst) ||
+ (!left_view && hwc_dev->s3d_input_order == eLeftViewFirst)) {
+ oc->crop.x = oc->crop.x + oc->crop.w;
+ }
+ break;
+ case eTopBottom:
+ oc->crop.h = oc->crop.h/2;
+ if ((left_view && hwc_dev->s3d_input_order == eRightViewFirst) ||
+ (!left_view && hwc_dev->s3d_input_order == eLeftViewFirst)) {
+ oc->crop.y = oc->crop.y + oc->crop.h;
+ }
+ break;
+ default:
+ /* Should never fall here! */
+ ALOGE("Unsupported S3D layer type!");
+ break;
+ }
+
+ switch (hwc_dev->ext.s3d_type) {
+ case eSideBySide:
+ oc->win.w = oc->win.w/2;
+ if ((left_view && hwc_dev->ext.s3d_order == eRightViewFirst) ||
+ (!left_view && hwc_dev->ext.s3d_order == eLeftViewFirst)) {
+ oc->win.x = oc->win.x/2 + hwc_dev->ext.xres/2;
+ } else {
+ oc->win.x = oc->win.x/2;
+ }
+ break;
+ case eTopBottom:
+ oc->win.h = oc->win.h/2;
+ if ((left_view && hwc_dev->ext.s3d_order == eRightViewFirst) ||
+ (!left_view && hwc_dev->ext.s3d_order == eLeftViewFirst)) {
+ oc->win.y = oc->win.y/2 + hwc_dev->ext.yres/2;
+ } else {
+ oc->win.y = oc->win.y/2;
+ }
+ break;
+ default:
+ /* Currently unhandled!!! */
+ ALOGE("Unsupported S3D display type!");
+ break;
+ }
+}
+
+static int clone_s3d_external_layer(omap_hwc_device_t *hwc_dev, int ix_s3d)
+{
+ struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data;
+ int r;
+
+ /* S3D layers are forced into docking layers. If the display layout and
+ * the layer layout don't match, we have to use 2 overlay pipelines */
+ r = clone_external_layer(hwc_dev, ix_s3d);
+ if (r) {
+ ALOGE("Failed to clone s3d layer (%d)", r);
+ return r;
+ }
+
+ r = clone_layer(hwc_dev, ix_s3d);
+ if (r) {
+ ALOGE("Failed to clone s3d layer (%d)", r);
+ return r;
+ }
+
+ if (dsscomp->num_ovls < 2) {
+ ALOGE("Number of overlays is inconsistent (%d)", dsscomp->num_ovls);
+ return -EINVAL;
+ }
+
+ adjust_ext_s3d_layer(hwc_dev, &dsscomp->ovls[dsscomp->num_ovls - 1], true);
+ adjust_ext_s3d_layer(hwc_dev, &dsscomp->ovls[dsscomp->num_ovls - 2], false);
+
+ return 0;
+}
+#endif
+static int setup_mirroring(omap_hwc_device_t *hwc_dev)
+{
+ omap_hwc_ext_t *ext = &hwc_dev->ext;
+
+ uint32_t xres = WIDTH(ext->mirror_region);
+ uint32_t yres = HEIGHT(ext->mirror_region);
+ if (ext->current.rotation & 1)
+ swap(xres, yres);
+ if (set_best_hdmi_mode(hwc_dev, xres, yres, ext->lcd_xpy))
+ return -ENODEV;
+ set_ext_matrix(ext, ext->mirror_region);
+ return 0;
+}
+
+/*
+ * We're using "implicit" synchronization, so make sure we aren't passing any
+ * sync object descriptors around.
+ */
+static void check_sync_fds(size_t numDisplays, hwc_display_contents_1_t** displays)
+{
+ //ALOGD("checking sync FDs");
+ unsigned int i, j;
+ for (i = 0; i < numDisplays; i++) {
+ hwc_display_contents_1_t* list = displays[i];
+ if (list->retireFenceFd >= 0) {
+ ALOGW("retireFenceFd[%u] was %d", i, list->retireFenceFd);
+ list->retireFenceFd = -1;
+ }
+
+ for (j = 0; j < list->numHwLayers; j++) {
+ hwc_layer_1_t* layer = &list->hwLayers[j];
+ if (layer->acquireFenceFd >= 0) {
+ ALOGW("acquireFenceFd[%u][%u] was %d, closing", i, j, layer->acquireFenceFd);
+ close(layer->acquireFenceFd);
+ layer->acquireFenceFd = -1;
+ }
+ if (layer->releaseFenceFd >= 0) {
+ ALOGW("releaseFenceFd[%u][%u] was %d", i, j, layer->releaseFenceFd);
+ layer->releaseFenceFd = -1;
+ }
+ }
+ }
+}
+
+static void blit_reset(omap_hwc_device_t *hwc_dev)
+{
+ hwc_dev->blit_flags = 0;
+ hwc_dev->blit_num = 0;
+ hwc_dev->post2_blit_buffers = 0;
+ hwc_dev->comp_data.blit_data.rgz_items = 0;
+}
+
+static bool blit_layers(omap_hwc_device_t *hwc_dev, hwc_display_contents_1_t *list, int bufoff)
+{
+ if (!list || hwc_dev->ext.mirror.enabled)
+ goto err_out;
+
+ int rgz_in_op;
+ int rgz_out_op;
+
+ switch (hwc_dev->blt_mode) {
+ case BLTMODE_PAINT:
+ rgz_in_op = RGZ_IN_HWCCHK;
+ rgz_out_op = RGZ_OUT_BVCMD_PAINT;
+ break;
+ case BLTMODE_REGION:
+ default:
+ rgz_in_op = RGZ_IN_HWC;
+ rgz_out_op = RGZ_OUT_BVCMD_REGION;
+ break;
+ }
+
+ /*
+ * Request the layer identities to SurfaceFlinger, first figure out if the
+ * operation is supported
+ */
+ if (!(list->flags & HWC_EXTENDED_API) || !hwc_dev->procs ||
+ hwc_dev->procs->extension_cb(hwc_dev->procs, HWC_EXTENDED_OP_LAYERDATA, NULL, -1) != 0)
+ goto err_out;
+
+ /* Check if we have enough space in the extended layer list */
+ if ((sizeof(hwc_layer_extended_t) * list->numHwLayers) > sizeof(grgz_ext_layer_list))
+ goto err_out;
+
+ uint32_t i;
+ for (i = 0; i < list->numHwLayers; i++) {
+ hwc_layer_extended_t *ext_layer = &grgz_ext_layer_list.layers[i];
+ ext_layer->idx = i;
+ if (hwc_dev->procs->extension_cb(hwc_dev->procs, HWC_EXTENDED_OP_LAYERDATA,
+ (void **) &ext_layer, sizeof(hwc_layer_extended_t)) != 0)
+ goto err_out;
+ }
+
+ rgz_in_params_t in = {
+ .op = rgz_in_op,
+ .data = {
+ .hwc = {
+ .dstgeom = &gscrngeom,
+ .layers = list->hwLayers,
+ .extlayers = grgz_ext_layer_list.layers,
+ .layerno = list->numHwLayers
+ }
+ }
+ };
+
+ /*
+ * This means if all the layers marked for the FRAMEBUFFER cannot be
+ * blitted, do not blit, for e.g. SKIP layers
+ */
+ if (rgz_in(&in, &grgz) != RGZ_ALL)
+ goto err_out;
+
+ uint32_t count = 0;
+ for (i = 0; i < list->numHwLayers; i++) {
+ if (list->hwLayers[i].compositionType != HWC_OVERLAY) {
+ count++;
+ }
+ }
+
+ rgz_out_params_t out = {
+ .op = rgz_out_op,
+ .data = {
+ .bvc = {
+ .dstgeom = &gscrngeom,
+ .noblend = 0,
+ }
+ }
+ };
+
+ if (rgz_out(&grgz, &out) != 0) {
+ ALOGE("Failed generating blits");
+ goto err_out;
+ }
+
+ /* This is a special situation where the regionizer decided no blits are
+ * needed for this frame but there are blit buffers to synchronize with. Can
+ * happen only if the regionizer is enabled otherwise it's likely a bug
+ */
+ if (rgz_out_op != RGZ_OUT_BVCMD_REGION && out.data.bvc.out_blits == 0 && out.data.bvc.out_nhndls > 0) {
+ ALOGE("Regionizer invalid output blit_num %d, post2_blit_buffers %d", out.data.bvc.out_blits, out.data.bvc.out_nhndls);
+ goto err_out;
+ }
+
+ hwc_dev->blit_flags |= HWC_BLT_FLAG_USE_FB;
+ hwc_dev->blit_num = out.data.bvc.out_blits;
+ hwc_dev->post2_blit_buffers = out.data.bvc.out_nhndls;
+ for (i = 0; i < hwc_dev->post2_blit_buffers; i++) {
+ //ALOGI("blit buffers[%d] = %p", bufoff, out.data.bvc.out_hndls[i]);
+ hwc_dev->buffers[bufoff++] = out.data.bvc.out_hndls[i];
+ }
+
+ struct rgz_blt_entry *res_blit_ops = (struct rgz_blt_entry *) out.data.bvc.cmdp;
+ memcpy(hwc_dev->comp_data.blit_data.rgz_blts, res_blit_ops, sizeof(*res_blit_ops) * out.data.bvc.cmdlen);
+ ALOGI_IF(debugblt, "blt struct sz %d", sizeof(*res_blit_ops) * out.data.bvc.cmdlen);
+ ALOGE_IF(hwc_dev->blit_num != out.data.bvc.cmdlen,"blit_num != out.data.bvc.cmdlen, %d != %d", hwc_dev->blit_num, out.data.bvc.cmdlen);
+
+ /* all layers will be rendered without SGX help either via DSS or blitter */
+ for (i = 0; i < list->numHwLayers; i++) {
+ if (list->hwLayers[i].compositionType != HWC_OVERLAY) {
+ list->hwLayers[i].compositionType = HWC_OVERLAY;
+ //ALOGI("blitting layer %d", i);
+ list->hwLayers[i].hints &= ~HWC_HINT_TRIPLE_BUFFER;
+ }
+ list->hwLayers[i].hints &= ~HWC_HINT_CLEAR_FB;
+ }
+ return true;
+
+err_out:
+ rgz_release(&grgz);
+ return false;
+}
+
+void debug_post2(omap_hwc_device_t *hwc_dev, int nbufs)
+{
+ if (!debugpost2)
+ return;
+ struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data;
+ int i;
+ for (i=0; i<nbufs; i++) {
+ ALOGI("buf[%d] hndl %p", i, hwc_dev->buffers[i]);
+ }
+ for (i=0; i < dsscomp->num_ovls; i++) {
+ ALOGI("ovl[%d] ba %d", i, dsscomp->ovls[i].ba);
+ }
+}
+
+static int free_tiler2d_buffers(omap_hwc_device_t *hwc_dev)
+{
+ int i;
+
+ for (i = 0 ; i < NUM_EXT_DISPLAY_BACK_BUFFERS; i++) {
+ ion_free(hwc_dev->ion_fd, hwc_dev->ion_handles[i]);
+ hwc_dev->ion_handles[i] = NULL;
+ }
+ return 0;
+}
+
+static int allocate_tiler2d_buffers(omap_hwc_device_t *hwc_dev)
+{
+ int ret, i;
+ size_t stride;
+
+ if (hwc_dev->ion_fd < 0) {
+ ALOGE("No ion fd, hence can't allocate tiler2d buffers");
+ return -1;
+ }
+
+ for (i = 0; i < NUM_EXT_DISPLAY_BACK_BUFFERS; i++) {
+ if (hwc_dev->ion_handles[i])
+ return 0;
+ }
+
+ for (i = 0 ; i < NUM_EXT_DISPLAY_BACK_BUFFERS; i++) {
+ ret = ion_alloc_tiler(hwc_dev->ion_fd, hwc_dev->fb_dev->base.width, hwc_dev->fb_dev->base.height,
+ TILER_PIXEL_FMT_32BIT, 0, &hwc_dev->ion_handles[i], &stride);
+ if (ret)
+ goto handle_error;
+
+ ALOGI("ion handle[%d][%p]", i, hwc_dev->ion_handles[i]);
+ }
+ return 0;
+
+handle_error:
+ free_tiler2d_buffers(hwc_dev);
+ return -1;
+}
+
+static int hwc_prepare(struct hwc_composer_device_1 *dev, size_t numDisplays,
+ hwc_display_contents_1_t** displays)
+{
+ if (!numDisplays || displays == NULL) {
+ return 0;
+ }
+
+ hwc_display_contents_1_t* list = displays[0]; // ignore displays beyond the first
+ omap_hwc_device_t *hwc_dev = (omap_hwc_device_t *)dev;
+ struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data;
+ counts_t *num = &hwc_dev->counts;
+ uint32_t i, ix;
+
+ pthread_mutex_lock(&hwc_dev->lock);
+ memset(dsscomp, 0x0, sizeof(*dsscomp));
+ dsscomp->sync_id = sync_id++;
+
+ gather_layer_statistics(hwc_dev, list);
+
+ decide_supported_cloning(hwc_dev);
+
+ /* phase 3 logic */
+ if (can_dss_render_all(hwc_dev)) {
+ /* All layers can be handled by the DSS -- don't use SGX for composition */
+ hwc_dev->use_sgx = 0;
+ hwc_dev->swap_rb = num->BGR != 0;
+ } else {
+ /* Use SGX for composition plus first 3 layers that are DSS renderable */
+ hwc_dev->use_sgx = 1;
+ hwc_dev->swap_rb = is_BGR_format(hwc_dev->fb_dev->base.format);
+ }
+
+ /* setup pipes */
+ int z = 0;
+ int fb_z = -1;
+ int ix_docking = -1;
+#ifdef OMAP_ENHANCEMENT_S3D
+ int ix_s3d = -1;
+#endif
+ bool scaled_gfx = false;
+ bool blit_all = false;
+ blit_reset(hwc_dev);
+
+ /* If the SGX is used or we are going to blit something we need a framebuffer
+ * and a DSS pipe
+ */
+ bool needs_fb = hwc_dev->use_sgx;
+
+ if (hwc_dev->blt_policy == BLTPOLICY_ALL) {
+ /* Check if we can blit everything */
+ blit_all = blit_layers(hwc_dev, list, 0);
+ if (blit_all) {
+ needs_fb = 1;
+ hwc_dev->use_sgx = 0;
+ /* No need to swap red and blue channels */
+ hwc_dev->swap_rb = 0;
+ }
+ }
+
+ /* If a framebuffer is needed, begin using VID1 for DSS overlay layers,
+ * we need GFX for FB
+ */
+ dsscomp->num_ovls = needs_fb ? 1 /*VID1*/ : 0 /*GFX*/;
+
+ /* set up if DSS layers */
+ uint32_t mem_used = 0;
+ for (i = 0; list && i < list->numHwLayers && !blit_all; i++) {
+ hwc_layer_1_t *layer = &list->hwLayers[i];
+ IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
+
+ if (dsscomp->num_ovls < num->max_hw_overlays &&
+ can_dss_render_layer(hwc_dev, layer) &&
+ (!hwc_dev->force_sgx ||
+ /* render protected and dockable layers via DSS */
+ is_protected(layer) ||
+ is_upscaled_NV12(hwc_dev, layer) ||
+ (hwc_dev->ext.current.docking && hwc_dev->ext.current.enabled && dockable(layer))) &&
+ mem_used + mem1d(handle) <= limits.tiler1d_slot_size &&
+ /* can't have a transparent overlay in the middle of the framebuffer stack */
+ !(is_BLENDED(layer) && fb_z >= 0)) {
+
+ /* render via DSS overlay */
+ mem_used += mem1d(handle);
+ layer->compositionType = HWC_OVERLAY;
+ /*
+ * This hint will not be used in vanilla ICS, but maybe in
+ * JellyBean, it is useful to distinguish between blts and true
+ * overlays
+ */
+ layer->hints |= HWC_HINT_TRIPLE_BUFFER;
+
+ /* clear FB above all opaque layers if rendering via SGX */
+ if (hwc_dev->use_sgx && !is_BLENDED(layer))
+ layer->hints |= HWC_HINT_CLEAR_FB;
+
+ hwc_dev->buffers[dsscomp->num_ovls] = layer->handle;
+ //ALOGI("dss buffers[%d] = %p", dsscomp->num_ovls, hwc_dev->buffers[dsscomp->num_ovls]);
+
+ setup_layer(hwc_dev,
+ &dsscomp->ovls[dsscomp->num_ovls],
+ layer,
+ z,
+ handle->iFormat,
+ handle->iWidth,
+ handle->iHeight);
+
+ dsscomp->ovls[dsscomp->num_ovls].cfg.ix = dsscomp->num_ovls + hwc_dev->primary_transform;
+ dsscomp->ovls[dsscomp->num_ovls].addressing = OMAP_DSS_BUFADDR_LAYER_IX;
+ dsscomp->ovls[dsscomp->num_ovls].ba = dsscomp->num_ovls;
+
+ /* ensure GFX layer is never scaled */
+ if ((dsscomp->num_ovls == 0) && (!hwc_dev->primary_transform)) {
+ scaled_gfx = scaled(layer) || is_NV12(handle);
+ } else if (scaled_gfx && !scaled(layer) && !is_NV12(handle)) {
+ /* swap GFX layer with this one */
+ dsscomp->ovls[dsscomp->num_ovls].cfg.ix = 0;
+ dsscomp->ovls[0].cfg.ix = dsscomp->num_ovls;
+ scaled_gfx = 0;
+ }
+
+ /* remember largest dockable layer */
+ if (dockable(layer) &&
+ (ix_docking < 0 ||
+ display_area(&dsscomp->ovls[dsscomp->num_ovls]) > display_area(&dsscomp->ovls[ix_docking])))
+ ix_docking = dsscomp->num_ovls;
+#ifdef OMAP_ENHANCEMENT_S3D
+ /* remember the ix for s3d layer */
+ if (get_s3d_layout_type(layer) != eMono) {
+ ix_s3d = dsscomp->num_ovls;
+ }
+#endif
+ dsscomp->num_ovls++;
+ z++;
+ } else if (hwc_dev->use_sgx) {
+ if (fb_z < 0) {
+ /* NOTE: we are not handling transparent cutout for now */
+ fb_z = z;
+ z++;
+ } else {
+ /* move fb z-order up (by lowering dss layers) */
+ while (fb_z < z - 1)
+ dsscomp->ovls[1 + fb_z++].cfg.zorder--;
+ }
+ }
+ }
+
+ /* if scaling GFX (e.g. only 1 scaled surface) use a VID pipe */
+ if (scaled_gfx)
+ dsscomp->ovls[0].cfg.ix = dsscomp->num_ovls;
+
+ if (hwc_dev->blt_policy == BLTPOLICY_DEFAULT) {
+ /*
+ * As long as we keep blitting on consecutive frames keep the regionizer
+ * state, if this is not possible the regionizer state is unreliable and
+ * we need to reset its state.
+ */
+ if (hwc_dev->use_sgx) {
+ if (blit_layers(hwc_dev, list, dsscomp->num_ovls == 1 ? 0 : dsscomp->num_ovls)) {
+ hwc_dev->use_sgx = 0;
+ }
+ } else
+ rgz_release(&grgz);
+ }
+
+ /* If the SGX is not used and there is blit data we need a framebuffer and
+ * a DSS pipe well configured for it
+ */
+ if (needs_fb) {
+ /* assign a z-layer for fb */
+ if (fb_z < 0) {
+ if (!hwc_dev->blt_policy != BLTPOLICY_DISABLED && num->composited_layers)
+ ALOGE("**** should have assigned z-layer for fb");
+ fb_z = z++;
+ }
+ /*
+ * This is needed because if we blit all we would lose the handle of
+ * the first layer
+ */
+ if (hwc_dev->use_sgx) {
+ hwc_dev->buffers[0] = NULL;
+ }
+ setup_layer_base(&dsscomp->ovls[0].cfg, fb_z,
+ hwc_dev->fb_dev->base.format,
+ 1, /* FB is always premultiplied */
+ hwc_dev->fb_dev->base.width,
+ hwc_dev->fb_dev->base.height);
+ dsscomp->ovls[0].cfg.pre_mult_alpha = 1;
+ dsscomp->ovls[0].addressing = OMAP_DSS_BUFADDR_LAYER_IX;
+ dsscomp->ovls[0].ba = 0;
+ dsscomp->ovls[0].cfg.ix = hwc_dev->primary_transform;
+ }
+
+ /* mirror layers */
+ hwc_dev->post2_layers = dsscomp->num_ovls;
+
+ omap_hwc_ext_t *ext = &hwc_dev->ext;
+ if (ext->current.enabled && ((!num->protected && hwc_dev->ext_ovls) ||
+ (hwc_dev->ext_ovls_wanted && hwc_dev->ext_ovls >= hwc_dev->ext_ovls_wanted))) {
+#ifdef OMAP_ENHANCEMENT_S3D
+ if (ext->current.docking && ix_s3d >= 0) {
+ if (clone_s3d_external_layer(hwc_dev, ix_s3d) == 0) {
+ dsscomp->ovls[dsscomp->num_ovls - 2].cfg.zorder = z++;
+ dsscomp->ovls[dsscomp->num_ovls - 1].cfg.zorder = z++;
+ /* For now, show only the left view of an S3D layer
+ * in the local display while we have hdmi attached */
+ switch (hwc_dev->s3d_input_type) {
+ case eSideBySide:
+ dsscomp->ovls[ix_s3d].cfg.crop.w = dsscomp->ovls[ix_s3d].cfg.crop.w/2;
+ break;
+ case eTopBottom:
+ dsscomp->ovls[ix_s3d].cfg.crop.h = dsscomp->ovls[ix_s3d].cfg.crop.h/2;
+ break;
+ default:
+ ALOGE("Unsupported S3D input type");
+ break;
+ }
+ }
+ } else if (ext->current.docking && ix_docking >= 0) {
+#else
+ if (ext->current.docking && ix_docking >= 0) {
+#endif
+ if (clone_external_layer(hwc_dev, ix_docking) == 0)
+ dsscomp->ovls[dsscomp->num_ovls - 1].cfg.zorder = z++;
+ } else if (ext->current.docking && ix_docking < 0 && ext->force_dock) {
+ ix_docking = dsscomp->num_ovls;
+ struct dss2_ovl_info *oi = &dsscomp->ovls[ix_docking];
+ image_info_t *dock_image = get_dock_image();
+ setup_layer_base(&oi->cfg, 0, HAL_PIXEL_FORMAT_BGRA_8888, 1,
+ dock_image->width, dock_image->height);
+ oi->cfg.stride = dock_image->rowbytes;
+ if (clone_external_layer(hwc_dev, ix_docking) == 0) {
+ oi->addressing = OMAP_DSS_BUFADDR_FB;
+ oi->ba = 0;
+ z++;
+ }
+ } else if (!ext->current.docking) {
+ int res = 0;
+
+ /* reset mode if we are coming from docking */
+ if (ext->last.docking)
+ res = setup_mirroring(hwc_dev);
+
+ /* mirror all layers */
+ for (ix = 0; res == 0 && ix < hwc_dev->post2_layers; ix++) {
+ if (clone_layer(hwc_dev, ix))
+ break;
+ z++;
+ }
+ }
+ }
+
+ /* Apply transform for primary display */
+ if (hwc_dev->primary_transform)
+ for (i = 0; i < dsscomp->num_ovls; i++) {
+ if(dsscomp->ovls[i].cfg.mgr_ix == 0)
+ adjust_primary_display_layer(hwc_dev, &dsscomp->ovls[i]);
+ }
+
+#ifdef OMAP_ENHANCEMENT_S3D
+ enable_s3d_hdmi(hwc_dev, ix_s3d >= 0);
+#endif
+ ext->last = ext->current;
+
+ if (z != dsscomp->num_ovls || dsscomp->num_ovls > MAX_HW_OVERLAYS)
+ ALOGE("**** used %d z-layers for %d overlays\n", z, dsscomp->num_ovls);
+
+ /* verify all z-orders and overlay indices are distinct */
+ for (i = z = ix = 0; i < dsscomp->num_ovls; i++) {
+ struct dss2_ovl_cfg *c = &dsscomp->ovls[i].cfg;
+
+ if (z & (1 << c->zorder))
+ ALOGE("**** used z-order #%d multiple times", c->zorder);
+ if (ix & (1 << c->ix))
+ ALOGE("**** used ovl index #%d multiple times", c->ix);
+ z |= 1 << c->zorder;
+ ix |= 1 << c->ix;
+ }
+ dsscomp->mode = DSSCOMP_SETUP_DISPLAY;
+ dsscomp->mgrs[0].ix = 0;
+ dsscomp->mgrs[0].alpha_blending = 1;
+ dsscomp->mgrs[0].swap_rb = hwc_dev->swap_rb;
+ dsscomp->num_mgrs = 1;
+
+ if (ext->current.enabled || hwc_dev->last_ext_ovls) {
+ dsscomp->mgrs[1] = dsscomp->mgrs[0];
+ dsscomp->mgrs[1].ix = 1;
+ dsscomp->num_mgrs++;
+ hwc_dev->ext_ovls = dsscomp->num_ovls - hwc_dev->post2_layers;
+ }
+
+ /*
+ * Whilst the mode of the display is being changed drop compositions to the
+ * display
+ */
+ if (ext->last_mode == 0 && hwc_dev->on_tv) {
+ dsscomp->num_ovls = 0;
+ }
+
+ if (debug) {
+ ALOGD("prepare (%d) - %s (comp=%d, poss=%d/%d scaled, RGB=%d,BGR=%d,NV12=%d) (ext=%s%s%ddeg%s %dex/%dmx (last %dex,%din)\n",
+ dsscomp->sync_id,
+ hwc_dev->use_sgx ? "SGX+OVL" : "all-OVL",
+ num->composited_layers,
+ num->possible_overlay_layers, num->scaled_layers,
+ num->RGB, num->BGR, num->NV12,
+ ext->on_tv ? "tv+" : "",
+ ext->current.enabled ? ext->current.docking ? "dock+" : "mirror+" : "OFF+",
+ ext->current.rotation * 90,
+ ext->current.hflip ? "+hflip" : "",
+ hwc_dev->ext_ovls, num->max_hw_overlays, hwc_dev->last_ext_ovls, hwc_dev->last_int_ovls);
+ }
+
+ pthread_mutex_unlock(&hwc_dev->lock);
+ return 0;
+}
+
+static void reset_screen(omap_hwc_device_t *hwc_dev)
+{
+ static int first_set = 1;
+ int ret;
+
+ if (first_set) {
+ first_set = 0;
+ struct dsscomp_setup_dispc_data d = {
+ .num_mgrs = 1,
+ };
+ /* remove bootloader image from the screen as blank/unblank does not change the composition */
+ ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_SETUP_DISPC, &d);
+ if (ret)
+ ALOGW("failed to remove bootloader image");
+
+ /* blank and unblank fd to make sure display is properly programmed on boot.
+ * This is needed because the bootloader can not be trusted.
+ */
+ ret = ioctl(hwc_dev->fb_fd, FBIOBLANK, FB_BLANK_POWERDOWN);
+ if (ret)
+ ALOGW("failed to blank display");
+
+ ret = ioctl(hwc_dev->fb_fd, FBIOBLANK, FB_BLANK_UNBLANK);
+ if (ret)
+ ALOGW("failed to blank display");
+ }
+}
+
+static int hwc_set(struct hwc_composer_device_1 *dev,
+ size_t numDisplays, hwc_display_contents_1_t** displays)
+{
+ if (!numDisplays || displays == NULL) {
+ ALOGD("set: empty display list");
+ return 0;
+ }
+ hwc_display_t dpy = NULL;
+ hwc_surface_t sur = NULL;
+ hwc_display_contents_1_t* list = displays[0]; // ignore displays beyond the first
+ if (list != NULL) {
+ dpy = list->dpy;
+ sur = list->sur;
+ }
+ omap_hwc_device_t *hwc_dev = (omap_hwc_device_t *)dev;
+ struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data;
+ int err = 0;
+ bool invalidate;
+
+ pthread_mutex_lock(&hwc_dev->lock);
+
+ reset_screen(hwc_dev);
+
+ invalidate = hwc_dev->ext_ovls_wanted && (hwc_dev->ext_ovls < hwc_dev->ext_ovls_wanted) &&
+ (hwc_dev->counts.protected || !hwc_dev->ext_ovls);
+
+ if (debug)
+ dump_set_info(hwc_dev, list);
+
+ if (dpy && sur) {
+ // list can be NULL which means hwc is temporarily disabled.
+ // however, if dpy and sur are null it means we're turning the
+ // screen off. no shall not call eglSwapBuffers() in that case.
+
+ if (hwc_dev->use_sgx) {
+ if (!eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur)) {
+ ALOGE("eglSwapBuffers error");
+ err = HWC_EGL_ERROR;
+ goto err_out;
+ }
+ }
+
+ //dump_dsscomp(dsscomp);
+
+ // signal the event thread that a post has happened
+ write(hwc_dev->pipe_fds[1], "s", 1);
+ if (hwc_dev->force_sgx > 0)
+ hwc_dev->force_sgx--;
+
+ hwc_dev->comp_data.blit_data.rgz_flags = hwc_dev->blit_flags;
+ hwc_dev->comp_data.blit_data.rgz_items = hwc_dev->blit_num;
+ int omaplfb_comp_data_sz = sizeof(hwc_dev->comp_data) +
+ (hwc_dev->comp_data.blit_data.rgz_items * sizeof(struct rgz_blt_entry));
+
+
+ uint32_t nbufs = hwc_dev->post2_layers;
+ if (hwc_dev->post2_blit_buffers) {
+ /*
+ * We don't want to pass a NULL entry in the Post2, but we need to
+ * fix up buffer handle array and overlay indexes to account for
+ * this
+ */
+ nbufs += hwc_dev->post2_blit_buffers - 1;
+
+ if (hwc_dev->post2_layers > 1) {
+ uint32_t i, j;
+ for (i = 0; i < nbufs; i++) {
+ hwc_dev->buffers[i] = hwc_dev->buffers[i+1];
+ }
+ for (i = 1, j= 1; j < hwc_dev->post2_layers; i++, j++) {
+ dsscomp->ovls[j].ba = i;
+ }
+ }
+ }
+ ALOGI_IF(debugblt && hwc_dev->blt_policy != BLTPOLICY_DISABLED,
+ "Post2, blits %d, ovl_buffers %d, blit_buffers %d sgx %d",
+ hwc_dev->blit_num, hwc_dev->post2_layers, hwc_dev->post2_blit_buffers,
+ hwc_dev->use_sgx);
+
+ debug_post2(hwc_dev, nbufs);
+ err = hwc_dev->fb_dev->Post2((framebuffer_device_t *)hwc_dev->fb_dev,
+ hwc_dev->buffers,
+ nbufs,
+ dsscomp, omaplfb_comp_data_sz);
+ showfps();
+ }
+ hwc_dev->last_ext_ovls = hwc_dev->ext_ovls;
+ hwc_dev->last_int_ovls = hwc_dev->post2_layers;
+ if (err)
+ ALOGE("Post2 error");
+
+ check_sync_fds(numDisplays, displays);
+
+err_out:
+ pthread_mutex_unlock(&hwc_dev->lock);
+
+ if (invalidate)
+ hwc_dev->procs->invalidate(hwc_dev->procs);
+
+ return err;
+}
+
+static void hwc_dump(struct hwc_composer_device_1 *dev, char *buff, int buff_len)
+{
+ omap_hwc_device_t *hwc_dev = (omap_hwc_device_t *)dev;
+ struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data;
+ struct dump_buf log = {
+ .buf = buff,
+ .buf_len = buff_len,
+ };
+ int i;
+
+ dump_printf(&log, "omap_hwc %d:\n", dsscomp->num_ovls);
+ dump_printf(&log, " idle timeout: %dms\n", hwc_dev->idle);
+
+ for (i = 0; i < dsscomp->num_ovls; i++) {
+ struct dss2_ovl_cfg *cfg = &dsscomp->ovls[i].cfg;
+
+ dump_printf(&log, " layer %d:\n", i);
+ dump_printf(&log, " enabled:%s buff:%p %dx%d stride:%d\n",
+ cfg->enabled ? "true" : "false", hwc_dev->buffers[i],
+ cfg->width, cfg->height, cfg->stride);
+ dump_printf(&log, " src:(%d,%d) %dx%d dst:(%d,%d) %dx%d ix:%d zorder:%d\n",
+ cfg->crop.x, cfg->crop.y, cfg->crop.w, cfg->crop.h,
+ cfg->win.x, cfg->win.y, cfg->win.w, cfg->win.h,
+ cfg->ix, cfg->zorder);
+ }
+
+ if (hwc_dev->blt_policy != BLTPOLICY_DISABLED) {
+ dump_printf(&log, " bltpolicy: %s, bltmode: %s\n",
+ hwc_dev->blt_policy == BLTPOLICY_DEFAULT ? "default" :
+ hwc_dev->blt_policy == BLTPOLICY_ALL ? "all" : "unknown",
+ hwc_dev->blt_mode == BLTMODE_PAINT ? "paint" : "regionize");
+ }
+ dump_printf(&log, "\n");
+}
+
+static int hwc_device_close(hw_device_t* device)
+{
+ omap_hwc_device_t *hwc_dev = (omap_hwc_device_t *) device;;
+
+ if (hwc_dev) {
+ if (hwc_dev->dsscomp_fd >= 0)
+ close(hwc_dev->dsscomp_fd);
+ if (hwc_dev->hdmi_fb_fd >= 0)
+ close(hwc_dev->hdmi_fb_fd);
+ if (hwc_dev->fb_fd >= 0)
+ close(hwc_dev->fb_fd);
+ if (hwc_dev->ion_fd >= 0)
+ ion_close(hwc_dev->ion_fd);
+
+ /* pthread will get killed when parent process exits */
+ pthread_mutex_destroy(&hwc_dev->lock);
+ free(hwc_dev);
+ }
+
+ return 0;
+}
+
+static int open_fb_hal(IMG_framebuffer_device_public_t **fb_dev)
+{
+ const struct hw_module_t *psModule;
+ IMG_gralloc_module_public_t *psGrallocModule;
+ int err;
+
+ err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &psModule);
+ psGrallocModule = (IMG_gralloc_module_public_t *) psModule;
+
+ if(err)
+ goto err_out;
+
+ if (strcmp(psGrallocModule->base.common.author, "Imagination Technologies")) {
+ err = -EINVAL;
+ goto err_out;
+ }
+
+ *fb_dev = psGrallocModule->psFrameBufferDevice;
+
+ return 0;
+
+err_out:
+ ALOGE("Composer HAL failed to load compatible Graphics HAL");
+ return err;
+}
+
+static void set_primary_display_transform_matrix(omap_hwc_device_t *hwc_dev)
+{
+ /* create primary display translation matrix */
+ hwc_dev->fb_dis.ix = 0;/*Default display*/
+
+ int ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_QUERY_DISPLAY, &hwc_dev->fb_dis);
+ if (ret)
+ ALOGE("failed to get display info (%d): %m", errno);
+
+ int lcd_w = hwc_dev->fb_dis.timings.x_res;
+ int lcd_h = hwc_dev->fb_dis.timings.y_res;
+ int orig_w = hwc_dev->fb_dev->base.width;
+ int orig_h = hwc_dev->fb_dev->base.height;
+ hwc_rect_t region = {.left = 0, .top = 0, .right = orig_w, .bottom = orig_h};
+ hwc_dev->primary_region = region;
+ hwc_dev->primary_rotation = ((lcd_w > lcd_h) ^ (orig_w > orig_h)) ? 1 : 0;
+ hwc_dev->primary_transform = ((lcd_w != orig_w)||(lcd_h != orig_h)) ? 1 : 0;
+
+ ALOGI("transforming FB (%dx%d) => (%dx%d) rot%d", orig_w, orig_h, lcd_w, lcd_h, hwc_dev->primary_rotation);
+
+ /* reorientation matrix is:
+ m = (center-from-target-center) * (scale-to-target) * (mirror) * (rotate) * (center-to-original-center) */
+
+ memcpy(hwc_dev->primary_m, m_unit, sizeof(m_unit));
+ m_translate(hwc_dev->primary_m, -(orig_w >> 1), -(orig_h >> 1));
+ m_rotate(hwc_dev->primary_m, hwc_dev->primary_rotation);
+ if (hwc_dev->primary_rotation & 1)
+ swap(orig_w, orig_h);
+ m_scale(hwc_dev->primary_m, orig_w, lcd_w, orig_h, lcd_h);
+ m_translate(hwc_dev->primary_m, lcd_w >> 1, lcd_h >> 1);
+}
+
+#ifdef OMAP_ENHANCEMENT_S3D
+static void handle_s3d_hotplug(omap_hwc_ext_t *ext, bool state)
+{
+ struct edid_t *edid = NULL;
+ if (state) {
+ int fd = open("/sys/devices/platform/omapdss/display1/edid", O_RDONLY);
+ if (!fd)
+ return;
+ uint8_t edid_data[EDID_SIZE];
+ size_t bytes_read = read(fd, edid_data, EDID_SIZE);
+ close(fd);
+ if (bytes_read < EDID_SIZE)
+ return;
+ if (edid_parser_init(&edid, edid_data))
+ return;
+ }
+
+ ext->s3d_enabled = false;
+ ext->s3d_capable = false;
+ ext->s3d_type = eMono;
+ ext->s3d_order = eLeftViewFirst;
+
+ if (edid) {
+ ext->s3d_capable = edid_s3d_capable(edid);
+ /* For now assume Side-by-Side half support applies to all modes */
+ ext->s3d_type = eSideBySide;
+ ext->s3d_order = eLeftViewFirst;
+ edid_parser_deinit(edid);
+ }
+}
+#endif
+static void handle_hotplug(omap_hwc_device_t *hwc_dev)
+{
+ omap_hwc_ext_t *ext = &hwc_dev->ext;
+ bool state = ext->hdmi_state;
+
+ /* Ignore external HDMI logic if the primary display is HDMI */
+ if (hwc_dev->on_tv) {
+ ALOGI("Primary display is HDMI - skip clone/dock logic");
+
+ if (state) {
+ uint32_t xres = hwc_dev->fb_dev->base.width;
+ uint32_t yres = hwc_dev->fb_dev->base.height;
+ if (set_best_hdmi_mode(hwc_dev, xres, yres, ext->lcd_xpy)) {
+ ALOGE("Failed to set HDMI mode");
+ }
+ set_primary_display_transform_matrix(hwc_dev);
+
+ ioctl(hwc_dev->fb_fd, FBIOBLANK, FB_BLANK_UNBLANK);
+
+ if (hwc_dev->procs && hwc_dev->procs->invalidate) {
+ hwc_dev->procs->invalidate(hwc_dev->procs);
+ }
+ } else
+ ext->last_mode = 0;
+
+ return;
+ }
+
+ pthread_mutex_lock(&hwc_dev->lock);
+#ifdef OMAP_ENHANCEMENT_S3D
+ handle_s3d_hotplug(ext, state);
+#endif
+ ext->dock.enabled = ext->mirror.enabled = 0;
+ if (state) {
+ /* check whether we can clone and/or dock */
+ char value[PROPERTY_VALUE_MAX];
+ property_get("persist.hwc.docking.enabled", value, "1");
+ ext->dock.enabled = atoi(value) > 0;
+ property_get("persist.hwc.mirroring.enabled", value, "1");
+ ext->mirror.enabled = atoi(value) > 0;
+ property_get("persist.hwc.avoid_mode_change", value, "1");
+ ext->avoid_mode_change = atoi(value) > 0;
+
+ /* get cloning transformation */
+ property_get("persist.hwc.docking.transform", value, "0");
+ ext->dock.rotation = atoi(value) & EXT_ROTATION;
+ ext->dock.hflip = (atoi(value) & EXT_HFLIP) > 0;
+ ext->dock.docking = 1;
+ property_get("persist.hwc.mirroring.transform", value, hwc_dev->fb_dis.timings.y_res > hwc_dev->fb_dis.timings.x_res ? "3" : "0");
+ ext->mirror.rotation = atoi(value) & EXT_ROTATION;
+ ext->mirror.hflip = (atoi(value) & EXT_HFLIP) > 0;
+ ext->mirror.docking = 0;
+
+ if (ext->force_dock) {
+ /* restrict to docking with no transform */
+ ext->mirror.enabled = 0;
+ ext->dock.rotation = 0;
+ ext->dock.hflip = 0;
+
+ load_dock_image();
+ }
+
+ /* select best mode for mirroring */
+ if (ext->mirror.enabled) {
+ ext->current = ext->mirror;
+ ext->mirror_mode = 0;
+ if (setup_mirroring(hwc_dev) == 0) {
+ ext->mirror_mode = ext->last_mode;
+ ioctl(hwc_dev->hdmi_fb_fd, FBIOBLANK, FB_BLANK_UNBLANK);
+ } else
+ ext->mirror.enabled = 0;
+ }
+ /* Allocate backup buffers for FB rotation
+ * This is required only if the FB tranform is different from that
+ * of the external display and the FB is not in TILER2D space
+ */
+ if (ext->mirror.rotation && (limits.fbmem_type != DSSCOMP_FBMEM_TILER2D))
+ allocate_tiler2d_buffers(hwc_dev);
+
+ } else {
+ ext->last_mode = 0;
+ if (ext->mirror.rotation && (limits.fbmem_type != DSSCOMP_FBMEM_TILER2D)) {
+ /* free tiler 2D buffer on detach */
+ free_tiler2d_buffers(hwc_dev);
+ }
+ }
+ ALOGI("external display changed (state=%d, mirror={%s tform=%ddeg%s}, dock={%s tform=%ddeg%s%s}, tv=%d", state,
+ ext->mirror.enabled ? "enabled" : "disabled",
+ ext->mirror.rotation * 90,
+ ext->mirror.hflip ? "+hflip" : "",
+ ext->dock.enabled ? "enabled" : "disabled",
+ ext->dock.rotation * 90,
+ ext->dock.hflip ? "+hflip" : "",
+ ext->force_dock ? " forced" : "",
+ ext->on_tv);
+
+ pthread_mutex_unlock(&hwc_dev->lock);
+
+ /* hwc_dev->procs is set right after the device is opened, but there is
+ * still a race condition where a hotplug event might occur after the open
+ * but before the procs are registered. */
+ if (hwc_dev->procs)
+ hwc_dev->procs->invalidate(hwc_dev->procs);
+}
+
+static void handle_uevents(omap_hwc_device_t *hwc_dev, const char *buff, int len)
+{
+ int dock;
+ int hdmi;
+ int vsync;
+ int state = 0;
+ uint64_t timestamp = 0;
+ const char *s = buff;
+
+ dock = !strcmp(s, "change@/devices/virtual/switch/dock");
+ hdmi = !strcmp(s, "change@/devices/virtual/switch/hdmi");
+ vsync = !strcmp(s, "change@/devices/platform/omapfb") ||
+ !strcmp(s, "change@/devices/virtual/switch/omapfb-vsync");
+
+ if (!dock && !vsync && !hdmi)
+ return;
+
+ s += strlen(s) + 1;
+
+ while(*s) {
+ if (!strncmp(s, "SWITCH_STATE=", strlen("SWITCH_STATE=")))
+ state = atoi(s + strlen("SWITCH_STATE="));
+ else if (!strncmp(s, "SWITCH_TIME=", strlen("SWITCH_TIME=")))
+ timestamp = strtoull(s + strlen("SWITCH_TIME="), NULL, 0);
+ else if (!strncmp(s, "VSYNC=", strlen("VSYNC=")))
+ timestamp = strtoull(s + strlen("VSYNC="), NULL, 0);
+
+ s += strlen(s) + 1;
+ if (s - buff >= len)
+ break;
+ }
+
+ if (vsync) {
+ if (hwc_dev->procs)
+ hwc_dev->procs->vsync(hwc_dev->procs, 0, timestamp);
+ } else {
+ if (dock)
+ hwc_dev->ext.force_dock = state == 1;
+ else
+ hwc_dev->ext.hdmi_state = state == 1;
+ handle_hotplug(hwc_dev);
+ }
+}
+
+#ifdef SYSFS_VSYNC_NOTIFICATION
+static void *omap4_hwc_vsync_sysfs_loop(void *data)
+{
+ omap_hwc_device_t *hwc_dev = data;
+ static char buf[4096];
+ int vsync_timestamp_fd;
+ fd_set exceptfds;
+ int res;
+ int64_t timestamp = 0;
+
+ vsync_timestamp_fd = open("/sys/devices/platform/omapfb/vsync_time", O_RDONLY);
+ char thread_name[64] = "hwcVsyncThread";
+ prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0);
+ setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
+ memset(buf, 0, sizeof(buf));
+
+ ALOGD("Using sysfs mechanism for VSYNC notification");
+
+ FD_ZERO(&exceptfds);
+ FD_SET(vsync_timestamp_fd, &exceptfds);
+ do {
+ ssize_t len = read(vsync_timestamp_fd, buf, sizeof(buf));
+ timestamp = strtoull(buf, NULL, 0);
+ hwc_dev->procs->vsync(hwc_dev->procs, 0, timestamp);
+ select(vsync_timestamp_fd + 1, NULL, NULL, &exceptfds, NULL);
+ lseek(vsync_timestamp_fd, 0, SEEK_SET);
+ } while (1);
+
+ return NULL;
+}
+#endif
+
+static void *hdmi_thread(void *data)
+{
+ omap_hwc_device_t *hwc_dev = data;
+ static char uevent_desc[4096];
+ struct pollfd fds[2];
+ bool invalidate = false;
+ int timeout;
+ int err;
+
+ setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
+
+ uevent_init();
+
+ fds[0].fd = uevent_get_fd();
+ fds[0].events = POLLIN;
+ fds[1].fd = hwc_dev->pipe_fds[0];
+ fds[1].events = POLLIN;
+
+ timeout = hwc_dev->idle ? hwc_dev->idle : -1;
+
+ memset(uevent_desc, 0, sizeof(uevent_desc));
+
+ do {
+ err = poll(fds, hwc_dev->idle ? 2 : 1, timeout);
+
+ if (err == 0) {
+ if (hwc_dev->idle) {
+ if (hwc_dev->procs) {
+ pthread_mutex_lock(&hwc_dev->lock);
+ invalidate = hwc_dev->last_int_ovls > 1 && !hwc_dev->force_sgx;
+ if (invalidate) {
+ hwc_dev->force_sgx = 2;
+ }
+ pthread_mutex_unlock(&hwc_dev->lock);
+
+ if (invalidate) {
+ hwc_dev->procs->invalidate(hwc_dev->procs);
+ timeout = -1;
+ }
+ }
+
+ continue;
+ }
+ }
+
+ if (err == -1) {
+ if (errno != EINTR)
+ ALOGE("event error: %m");
+ continue;
+ }
+
+ if (hwc_dev->idle && fds[1].revents & POLLIN) {
+ char c;
+ read(hwc_dev->pipe_fds[0], &c, 1);
+ if (!hwc_dev->force_sgx)
+ timeout = hwc_dev->idle ? hwc_dev->idle : -1;
+ }
+
+ if (fds[0].revents & POLLIN) {
+ /* keep last 2 zeroes to ensure double 0 termination */
+ int len = uevent_next_event(uevent_desc, sizeof(uevent_desc) - 2);
+ handle_uevents(hwc_dev, uevent_desc, len);
+ }
+ } while (1);
+
+ return NULL;
+}
+
+static void hwc_registerProcs(struct hwc_composer_device_1* dev,
+ hwc_procs_t const* procs)
+{
+ omap_hwc_device_t *hwc_dev = (omap_hwc_device_t *) dev;
+
+ hwc_dev->procs = (typeof(hwc_dev->procs)) procs;
+}
+
+static int hwc_query(struct hwc_composer_device_1* dev, int what, int* value)
+{
+ omap_hwc_device_t *hwc_dev = (omap_hwc_device_t *) dev;
+
+ switch (what) {
+ case HWC_BACKGROUND_LAYER_SUPPORTED:
+ // we don't support the background layer yet
+ value[0] = 0;
+ break;
+ case HWC_VSYNC_PERIOD:
+ // vsync period in nanosecond
+ value[0] = 1000000000.0 / hwc_dev->fb_dev->base.fps;
+ break;
+ default:
+ // unsupported query
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int hwc_eventControl(struct hwc_composer_device_1* dev,
+ int dpy, int event, int enabled)
+{
+ omap_hwc_device_t *hwc_dev = (omap_hwc_device_t *) dev;
+
+ switch (event) {
+ case HWC_EVENT_VSYNC:
+ {
+ int val = !!enabled;
+ int err;
+
+ if (hwc_dev->use_sw_vsync) {
+ if (enabled)
+ start_sw_vsync(hwc_dev);
+ else
+ stop_sw_vsync();
+ return 0;
+ }
+
+ err = ioctl(hwc_dev->fb_fd, OMAPFB_ENABLEVSYNC, &val);
+ if (err < 0)
+ return -errno;
+
+ return 0;
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
+static int hwc_blank(struct hwc_composer_device_1 *dev, int dpy, int blank)
+{
+ // We're using an older method of screen blanking based on
+ // early_suspend in the kernel. No need to do anything here.
+ return 0;
+}
+
+static int hwc_device_open(const hw_module_t* module, const char* name, hw_device_t** device)
+{
+ omap_hwc_module_t *hwc_mod = (omap_hwc_module_t *)module;
+ omap_hwc_device_t *hwc_dev;
+ int err = 0;
+
+ if (strcmp(name, HWC_HARDWARE_COMPOSER)) {
+ return -EINVAL;
+ }
+
+ if (!hwc_mod->fb_dev) {
+ err = open_fb_hal(&hwc_mod->fb_dev);
+ if (err)
+ return err;
+
+ if (!hwc_mod->fb_dev) {
+ ALOGE("Framebuffer HAL not opened before HWC");
+ return -EFAULT;
+ }
+ hwc_mod->fb_dev->bBypassPost = 1;
+ }
+
+ hwc_dev = (omap_hwc_device_t *)malloc(sizeof(*hwc_dev));
+ if (hwc_dev == NULL)
+ return -ENOMEM;
+
+ memset(hwc_dev, 0, sizeof(*hwc_dev));
+
+ hwc_dev->base.common.tag = HARDWARE_DEVICE_TAG;
+ hwc_dev->base.common.version = HWC_DEVICE_API_VERSION_1_0;
+
+ if (use_sw_vsync()) {
+ hwc_dev->use_sw_vsync = true;
+ init_sw_vsync(hwc_dev);
+ }
+
+ hwc_dev->base.common.module = (hw_module_t *)module;
+ hwc_dev->base.common.close = hwc_device_close;
+ hwc_dev->base.prepare = hwc_prepare;
+ hwc_dev->base.set = hwc_set;
+ hwc_dev->base.eventControl = hwc_eventControl;
+ hwc_dev->base.blank = hwc_blank;
+ hwc_dev->base.dump = hwc_dump;
+ hwc_dev->base.registerProcs = hwc_registerProcs;
+ hwc_dev->base.query = hwc_query;
+
+ hwc_dev->fb_dev = hwc_mod->fb_dev;
+ *device = &hwc_dev->base.common;
+
+ hwc_dev->dsscomp_fd = open("/dev/dsscomp", O_RDWR);
+ if (hwc_dev->dsscomp_fd < 0) {
+ ALOGE("failed to open dsscomp (%d)", errno);
+ err = -errno;
+ goto done;
+ }
+
+ int ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_QUERY_PLATFORM, &limits);
+ if (ret) {
+ ALOGE("failed to get platform limits (%d): %m", errno);
+ err = -errno;
+ goto done;
+ }
+
+ hwc_dev->fb_fd = open("/dev/graphics/fb0", O_RDWR);
+ if (hwc_dev->fb_fd < 0) {
+ ALOGE("failed to open fb (%d)", errno);
+ err = -errno;
+ goto done;
+ }
+
+ err = init_dock_image(hwc_dev, limits.max_width, limits.max_height);
+ if (err)
+ goto done;
+
+ /* Allocate the maximum buffers that we can receive from HWC */
+ hwc_dev->buffers = malloc(sizeof(buffer_handle_t) * MAX_HWC_LAYERS);
+ if (!hwc_dev->buffers) {
+ err = -ENOMEM;
+ goto done;
+ }
+
+ ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_QUERY_DISPLAY, &hwc_dev->fb_dis);
+ if (ret) {
+ ALOGE("failed to get display info (%d): %m", errno);
+ err = -errno;
+ goto done;
+ }
+
+ hwc_dev->ion_fd = ion_open();
+ if (hwc_dev->ion_fd < 0) {
+ ALOGE("failed to open ion driver (%d)", errno);
+ }
+
+ int i;
+ for (i = 0; i < NUM_EXT_DISPLAY_BACK_BUFFERS; i++) {
+ hwc_dev->ion_handles[i] = NULL;
+ }
+
+ /* use default value in case some of requested display parameters missing */
+ hwc_dev->ext.lcd_xpy = 1.0;
+ if (hwc_dev->fb_dis.timings.x_res && hwc_dev->fb_dis.height_in_mm) {
+ hwc_dev->ext.lcd_xpy = (float)
+ hwc_dev->fb_dis.width_in_mm / hwc_dev->fb_dis.timings.x_res /
+ hwc_dev->fb_dis.height_in_mm * hwc_dev->fb_dis.timings.y_res;
+ }
+
+ if (hwc_dev->fb_dis.channel == OMAP_DSS_CHANNEL_DIGIT) {
+ ALOGI("Primary display is HDMI");
+ hwc_dev->on_tv = 1;
+ } else {
+ hwc_dev->hdmi_fb_fd = open("/dev/graphics/fb1", O_RDWR);
+ if (hwc_dev->hdmi_fb_fd < 0) {
+ ALOGE("failed to open hdmi fb (%d)", errno);
+ err = -errno;
+ goto done;
+ }
+ }
+
+ set_primary_display_transform_matrix(hwc_dev);
+
+ if (pipe(hwc_dev->pipe_fds) == -1) {
+ ALOGE("failed to event pipe (%d): %m", errno);
+ err = -errno;
+ goto done;
+ }
+
+ if (pthread_mutex_init(&hwc_dev->lock, NULL)) {
+ ALOGE("failed to create mutex (%d): %m", errno);
+ err = -errno;
+ goto done;
+ }
+
+ if (pthread_create(&hwc_dev->hdmi_thread, NULL, hdmi_thread, hwc_dev))
+ {
+ ALOGE("failed to create HDMI listening thread (%d): %m", errno);
+ err = -errno;
+ goto done;
+ }
+
+ /* get debug properties */
+
+ /* see if hwc is enabled at all */
+ char value[PROPERTY_VALUE_MAX];
+ property_get("debug.hwc.rgb_order", value, "1");
+ hwc_dev->flags_rgb_order = atoi(value);
+ property_get("debug.hwc.nv12_only", value, "0");
+ hwc_dev->flags_nv12_only = atoi(value);
+ property_get("debug.hwc.idle", value, "250");
+ hwc_dev->idle = atoi(value);
+
+ /* get the board specific clone properties */
+ /* 0:0:1280:720 */
+ if (property_get("persist.hwc.mirroring.region", value, "") <= 0 ||
+ sscanf(value, "%d:%d:%d:%d",
+ &hwc_dev->ext.mirror_region.left, &hwc_dev->ext.mirror_region.top,
+ &hwc_dev->ext.mirror_region.right, &hwc_dev->ext.mirror_region.bottom) != 4 ||
+ hwc_dev->ext.mirror_region.left >= hwc_dev->ext.mirror_region.right ||
+ hwc_dev->ext.mirror_region.top >= hwc_dev->ext.mirror_region.bottom) {
+ struct hwc_rect fb_region = { .right = hwc_dev->fb_dev->base.width, .bottom = hwc_dev->fb_dev->base.height };
+ hwc_dev->ext.mirror_region = fb_region;
+ }
+ ALOGI("clone region is set to (%d,%d) to (%d,%d)",
+ hwc_dev->ext.mirror_region.left, hwc_dev->ext.mirror_region.top,
+ hwc_dev->ext.mirror_region.right, hwc_dev->ext.mirror_region.bottom);
+
+ /* read switch state */
+ int sw_fd = open("/sys/class/switch/hdmi/state", O_RDONLY);
+ if (sw_fd >= 0) {
+ char value;
+ if (read(sw_fd, &value, 1) == 1)
+ hwc_dev->ext.hdmi_state = value == '1';
+ close(sw_fd);
+ }
+ sw_fd = open("/sys/class/switch/dock/state", O_RDONLY);
+ if (sw_fd >= 0) {
+ char value;
+ if (read(sw_fd, &value, 1) == 1)
+ hwc_dev->ext.force_dock = value == '1';
+ close(sw_fd);
+ }
+ handle_hotplug(hwc_dev);
+
+#ifdef SYSFS_VSYNC_NOTIFICATION
+ if (pthread_create(&hwc_dev->vsync_thread, NULL, omap4_hwc_vsync_sysfs_loop, hwc_dev))
+ {
+ ALOGE("pthread_create() failed (%d): %m", errno);
+ err = -errno;
+ goto done;
+ }
+#endif
+
+ ALOGI("open_device(rgb_order=%d nv12_only=%d)",
+ hwc_dev->flags_rgb_order, hwc_dev->flags_nv12_only);
+
+ int gc2d_fd = open("/dev/gcioctl", O_RDWR);
+ if (gc2d_fd < 0) {
+ ALOGI("Unable to open gc-core device (%d), blits disabled", errno);
+ hwc_dev->blt_policy = BLTPOLICY_DISABLED;
+ } else {
+ property_get("persist.hwc.bltmode", value, "1");
+ hwc_dev->blt_mode = atoi(value);
+ property_get("persist.hwc.bltpolicy", value, "1");
+ hwc_dev->blt_policy = atoi(value);
+ ALOGI("blitter present, blits mode %d, blits policy %d", hwc_dev->blt_mode, hwc_dev->blt_policy);
+ close(gc2d_fd);
+
+ if (rgz_get_screengeometry(hwc_dev->fb_fd, &gscrngeom,
+ hwc_dev->fb_dev->base.format) != 0) {
+ err = -EINVAL;
+ goto done;
+ }
+ }
+
+ property_get("persist.hwc.upscaled_nv12_limit", value, "2.");
+ sscanf(value, "%f", &hwc_dev->upscaled_nv12_limit);
+ if (hwc_dev->upscaled_nv12_limit < 0. || hwc_dev->upscaled_nv12_limit > 2048.) {
+ ALOGW("Invalid upscaled_nv12_limit (%s), setting to 2.", value);
+ hwc_dev->upscaled_nv12_limit = 2.;
+ }
+
+done:
+ if (err && hwc_dev) {
+ if (hwc_dev->dsscomp_fd >= 0)
+ close(hwc_dev->dsscomp_fd);
+ if (hwc_dev->hdmi_fb_fd >= 0)
+ close(hwc_dev->hdmi_fb_fd);
+ if (hwc_dev->fb_fd >= 0)
+ close(hwc_dev->fb_fd);
+ pthread_mutex_destroy(&hwc_dev->lock);
+ free(hwc_dev->buffers);
+ free(hwc_dev);
+ }
+
+ return err;
+}
+
+static struct hw_module_methods_t module_methods = {
+ .open = hwc_device_open,
+};
+
+omap_hwc_module_t HAL_MODULE_INFO_SYM = {
+ .base = {
+ .common = {
+ .tag = HARDWARE_MODULE_TAG,
+ .module_api_version = HWC_MODULE_API_VERSION_0_1,
+ .hal_api_version = HARDWARE_HAL_API_VERSION,
+ .id = HWC_HARDWARE_MODULE_ID,
+ .name = "OMAP 44xx Hardware Composer HAL",
+ .author = "Texas Instruments",
+ .methods = &module_methods,
+ },
+ },
+};
diff --git a/hwc/hwc_dev.h b/hwc/hwc_dev.h
new file mode 100644
index 0000000..32cc273
--- /dev/null
+++ b/hwc/hwc_dev.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) Texas Instruments - http://www.ti.com/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __HWC_DEV__
+#define __HWC_DEV__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <hardware/hwcomposer.h>
+#ifdef OMAP_ENHANCEMENT_S3D
+#include <ui/S3DFormat.h>
+#endif
+
+#include <linux/bltsville.h>
+#include <video/dsscomp.h>
+#include <video/omap_hwc.h>
+
+#include "hal_public.h"
+#include "rgz_2d.h"
+
+struct ext_transform {
+ uint8_t rotation : 3; /* 90-degree clockwise rotations */
+ uint8_t hflip : 1; /* flip l-r (after rotation) */
+ uint8_t enabled : 1; /* cloning enabled */
+ uint8_t docking : 1; /* docking vs. mirroring - used for state */
+};
+typedef struct ext_transform ext_transform_t;
+
+/* cloning support and state */
+struct omap_hwc_ext {
+ /* support */
+ ext_transform_t mirror; /* mirroring settings */
+ ext_transform_t dock; /* docking settings */
+ float lcd_xpy; /* pixel ratio for UI */
+ bool avoid_mode_change; /* use HDMI mode used for mirroring if possible */
+ bool force_dock; /* must dock */
+
+ /* state */
+ bool hdmi_state; /* whether HDMI is connected */
+ bool on_tv; /* using a tv */
+ ext_transform_t current; /* current settings */
+ ext_transform_t last; /* last-used settings */
+
+ /* configuration */
+ uint32_t last_xres_used; /* resolution and pixel ratio used for mode selection */
+ uint32_t last_yres_used;
+ uint32_t last_mode; /* 2-s complement of last HDMI mode set, 0 if none */
+ uint32_t mirror_mode; /* 2-s complement of mode used when mirroring */
+ float last_xpy;
+ uint16_t width; /* external screen dimensions */
+ uint16_t height;
+ uint32_t xres; /* external screen resolution */
+ uint32_t yres;
+ float m[2][3]; /* external transformation matrix */
+ hwc_rect_t mirror_region; /* region of screen to mirror */
+#ifdef OMAP_ENHANCEMENT_S3D
+ bool s3d_enabled;
+ bool s3d_capable;
+ enum S3DLayoutType s3d_type;
+ enum S3DLayoutOrder s3d_order;
+#endif
+};
+typedef struct omap_hwc_ext omap_hwc_ext_t;
+
+enum bltpolicy {
+ BLTPOLICY_DISABLED = 0,
+ BLTPOLICY_DEFAULT = 1, /* Default blit policy */
+ BLTPOLICY_ALL, /* Test mode to attempt to blit all */
+};
+
+enum bltmode {
+ BLTMODE_PAINT = 0, /* Attempt to blit layer by layer */
+ BLTMODE_REGION = 1, /* Attempt to blit layers via regions */
+};
+
+struct omap_hwc_module {
+ hwc_module_t base;
+
+ IMG_framebuffer_device_public_t *fb_dev;
+};
+typedef struct omap_hwc_module omap_hwc_module_t;
+
+struct counts {
+ uint32_t possible_overlay_layers;
+ uint32_t composited_layers;
+ uint32_t scaled_layers;
+ uint32_t RGB;
+ uint32_t BGR;
+ uint32_t NV12;
+ uint32_t dockable;
+ uint32_t protected;
+#ifdef OMAP_ENHANCEMENT_S3D
+ uint32_t s3d;
+#endif
+
+ uint32_t max_hw_overlays;
+ uint32_t max_scaling_overlays;
+ uint32_t mem;
+};
+typedef struct counts counts_t;
+
+struct omap_hwc_device {
+ /* static data */
+ hwc_composer_device_1_t base;
+ hwc_procs_t *procs;
+ pthread_t hdmi_thread;
+#ifdef SYSFS_VSYNC_NOTIFICATION
+ pthread_t vsync_thread;
+#endif
+ pthread_mutex_t lock;
+
+ IMG_framebuffer_device_public_t *fb_dev;
+ struct dsscomp_display_info fb_dis;
+ int fb_fd; /* file descriptor for /dev/fb0 */
+ int dsscomp_fd; /* file descriptor for /dev/dsscomp */
+ int hdmi_fb_fd; /* file descriptor for /dev/fb1 */
+ int pipe_fds[2]; /* pipe to event thread */
+
+ int img_mem_size; /* size of fb for hdmi */
+ void *img_mem_ptr; /* start of fb for hdmi */
+
+ int flags_rgb_order;
+ int flags_nv12_only;
+ float upscaled_nv12_limit;
+
+ bool on_tv; /* using a tv */
+ int force_sgx;
+ omap_hwc_ext_t ext; /* external mirroring data */
+ int idle;
+
+ float primary_m[2][3]; /* internal transformation matrix */
+ int primary_transform;
+ int primary_rotation;
+ hwc_rect_t primary_region;
+
+ buffer_handle_t *buffers;
+ bool use_sgx;
+ bool swap_rb;
+ uint32_t post2_layers; /* buffers used with DSS pipes*/
+ uint32_t post2_blit_buffers; /* buffers used with blit */
+ int ext_ovls; /* # of overlays on external display for current composition */
+ int ext_ovls_wanted; /* # of overlays that should be on external display for current composition */
+ int last_ext_ovls; /* # of overlays on external/internal display for last composition */
+ int last_int_ovls;
+#ifdef OMAP_ENHANCEMENT_S3D
+ enum S3DLayoutType s3d_input_type;
+ enum S3DLayoutOrder s3d_input_order;
+#endif
+ enum bltmode blt_mode;
+ enum bltpolicy blt_policy;
+
+ uint32_t blit_flags;
+ int blit_num;
+ struct omap_hwc_data comp_data; /* This is a kernel data structure */
+ struct rgz_blt_entry blit_ops[RGZ_MAX_BLITS];
+
+ counts_t counts;
+
+ int ion_fd;
+ struct ion_handle *ion_handles[2];
+ bool use_sw_vsync;
+
+};
+typedef struct omap_hwc_device omap_hwc_device_t;
+
+#endif
diff --git a/hwc/rgz_2d.c b/hwc/rgz_2d.c
new file mode 100644
index 0000000..ac4be96
--- /dev/null
+++ b/hwc/rgz_2d.c
@@ -0,0 +1,1997 @@
+/*
+ * Copyright (C) Texas Instruments - http://www.ti.com/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <time.h>
+#include <assert.h>
+#include <strings.h>
+#include <dlfcn.h>
+
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <linux/fb.h>
+#include <linux/bltsville.h>
+#include <video/dsscomp.h>
+#include <video/omap_hwc.h>
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include <hardware/hwcomposer.h>
+
+#include "hwc_dev.h"
+
+static int rgz_handle_to_stride(IMG_native_handle_t *h);
+#define BVDUMP(p,t,parms)
+#define HANDLE_TO_BUFFER(h) NULL
+/* Needs to be meaningful for TILER & GFX buffers and NV12 */
+#define HANDLE_TO_STRIDE(h) rgz_handle_to_stride(h)
+#define DSTSTRIDE(dstgeom) dstgeom->virtstride
+
+/* Borrowed macros from hwc.c vvv - consider sharing later */
+#define min(a, b) ( { typeof(a) __a = (a), __b = (b); __a < __b ? __a : __b; } )
+#define max(a, b) ( { typeof(a) __a = (a), __b = (b); __a > __b ? __a : __b; } )
+#define swap(a, b) do { typeof(a) __a = (a); (a) = (b); (b) = __a; } while (0)
+
+#define WIDTH(rect) ((rect).right - (rect).left)
+#define HEIGHT(rect) ((rect).bottom - (rect).top)
+
+#define is_RGB(format) ((format) == HAL_PIXEL_FORMAT_BGRA_8888 || (format) == HAL_PIXEL_FORMAT_RGB_565 || (format) == HAL_PIXEL_FORMAT_BGRX_8888)
+#define is_BGR(format) ((format) == HAL_PIXEL_FORMAT_RGBX_8888 || (format) == HAL_PIXEL_FORMAT_RGBA_8888)
+#define is_NV12(format) ((format) == HAL_PIXEL_FORMAT_TI_NV12 || (format) == HAL_PIXEL_FORMAT_TI_NV12_PADDED)
+
+#define HAL_PIXEL_FORMAT_BGRX_8888 0x1FF
+#define HAL_PIXEL_FORMAT_TI_NV12 0x100
+#define HAL_PIXEL_FORMAT_TI_NV12_PADDED 0x101
+/* Borrowed macros from hwc.c ^^^ */
+#define is_OPAQUE(format) ((format) == HAL_PIXEL_FORMAT_RGB_565 || (format) == HAL_PIXEL_FORMAT_RGBX_8888 || (format) == HAL_PIXEL_FORMAT_BGRX_8888)
+
+/* OUTP the means for grabbing diagnostic data */
+#define OUTP ALOGI
+#define OUTE ALOGE
+
+#define IS_BVCMD(params) (params->op == RGZ_OUT_BVCMD_REGION || params->op == RGZ_OUT_BVCMD_PAINT)
+
+#define RECT_INTERSECTS(a, b) (((a).bottom > (b).top) && ((a).top < (b).bottom) && ((a).right > (b).left) && ((a).left < (b).right))
+
+/* Buffer indexes used to distinguish background and layers with the clear fb hint */
+#define RGZ_BACKGROUND_BUFFIDX -2
+#define RGZ_CLEARHINT_BUFFIDX -1
+
+struct rgz_blts {
+ struct rgz_blt_entry bvcmds[RGZ_MAX_BLITS];
+ int idx;
+};
+
+
+static int rgz_hwc_layer_blit(rgz_out_params_t *params, rgz_layer_t *rgz_layer);
+static void rgz_blts_init(struct rgz_blts *blts);
+static void rgz_blts_free(struct rgz_blts *blts);
+static struct rgz_blt_entry* rgz_blts_get(struct rgz_blts *blts, rgz_out_params_t *params);
+static int rgz_blts_bvdirect(rgz_t* rgz, struct rgz_blts *blts, rgz_out_params_t *params);
+static void rgz_get_src_rect(hwc_layer_1_t* layer, blit_rect_t *subregion_rect, blit_rect_t *res_rect);
+static int hal_to_ocd(int color);
+static int rgz_get_orientation(unsigned int transform);
+static int rgz_get_flip_flags(unsigned int transform, int use_src2_flags);
+static int rgz_hwc_scaled(hwc_layer_1_t *layer);
+
+int debug = 0;
+struct rgz_blts blts;
+/* Represents a screen sized background layer */
+static hwc_layer_1_t bg_layer;
+
+static void svgout_header(int htmlw, int htmlh, int coordw, int coordh)
+{
+ OUTP("<svg xmlns=\"http://www.w3.org/2000/svg\""
+ "width=\"%d\" height=\"%d\""
+ "viewBox=\"0 0 %d %d\">",
+ htmlw, htmlh, coordw, coordh);
+}
+
+static void svgout_footer(void)
+{
+ OUTP("</svg>");
+}
+
+static void svgout_rect(blit_rect_t *r, char *color, char *text)
+{
+ OUTP("<rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" fill=\"%s\" "
+ "fill-opacity=\"%f\" stroke=\"black\" stroke-width=\"1\" />",
+ r->left, r->top, r->right - r->left, r->bottom - r->top, color, 1.0f);
+
+ if (!text)
+ return;
+
+ OUTP("<text x=\"%d\" y=\"%d\" style=\"font-size:30\" fill=\"black\">%s"
+ "</text>",
+ r->left, r->top + 40, text);
+}
+
+static int empty_rect(blit_rect_t *r)
+{
+ return !r->left && !r->top && !r->right && !r->bottom;
+}
+
+static int get_top_rect(blit_hregion_t *hregion, int subregion, blit_rect_t **routp)
+{
+ int l = hregion->nlayers - 1;
+ do {
+ *routp = &hregion->blitrects[l][subregion];
+ if (!empty_rect(*routp))
+ break;
+ }
+ while (--l >= 0);
+ return l;
+}
+
+/*
+ * The idea here is that we walk the layers from front to back and count the
+ * number of layers in the hregion until the first layer which doesn't require
+ * blending.
+ */
+static int get_layer_ops(blit_hregion_t *hregion, int subregion, int *bottom)
+{
+ int l = hregion->nlayers - 1;
+ int ops = 0;
+ *bottom = -1;
+ do {
+ if (!empty_rect(&hregion->blitrects[l][subregion])) {
+ ops++;
+ *bottom = l;
+ hwc_layer_1_t *layer = &hregion->rgz_layers[l]->hwc_layer;
+ IMG_native_handle_t *h = (IMG_native_handle_t *)layer->handle;
+ if ((layer->blending != HWC_BLENDING_PREMULT) || is_OPAQUE(h->iFormat))
+ break;
+ }
+ }
+ while (--l >= 0);
+ return ops;
+}
+
+static int get_layer_ops_next(blit_hregion_t *hregion, int subregion, int l)
+{
+ while (++l < hregion->nlayers) {
+ if (!empty_rect(&hregion->blitrects[l][subregion]))
+ return l;
+ }
+ return -1;
+}
+
+static int svgout_intersects_display(blit_rect_t *a, int dispw, int disph)
+{
+ return ((a->bottom > 0) && (a->top < disph) &&
+ (a->right > 0) && (a->left < dispw));
+}
+
+static void svgout_hregion(blit_hregion_t *hregion, int dispw, int disph)
+{
+ char *colors[] = {"red", "orange", "yellow", "green", "blue", "indigo", "violet", NULL};
+ int b;
+ for (b = 0; b < hregion->nsubregions; b++) {
+ blit_rect_t *rect;
+ (void)get_top_rect(hregion, b, &rect);
+ /* Only generate SVG for subregions intersecting the displayed area */
+ if (!svgout_intersects_display(rect, dispw, disph))
+ continue;
+ svgout_rect(rect, colors[b % 7], NULL);
+ }
+}
+
+static void rgz_out_svg(rgz_t *rgz, rgz_out_params_t *params)
+{
+ if (!rgz || !(rgz->state & RGZ_REGION_DATA)) {
+ OUTE("rgz_out_svg invoked with bad state");
+ return;
+ }
+ blit_hregion_t *hregions = rgz->hregions;
+ svgout_header(params->data.svg.htmlw, params->data.svg.htmlh,
+ params->data.svg.dispw, params->data.svg.disph);
+ int i;
+ for (i = 0; i < rgz->nhregions; i++) {
+
+ OUTP("<!-- hregion %d (subcount %d)-->", i, hregions[i].nsubregions);
+ svgout_hregion(&hregions[i], params->data.svg.dispw,
+ params->data.svg.disph);
+ }
+ svgout_footer();
+}
+
+/* XXX duplicate of hwc.c version */
+static void dump_layer(hwc_layer_1_t const* l, int iserr)
+{
+#define FMT(f) ((f) == HAL_PIXEL_FORMAT_TI_NV12 ? "NV12" : \
+ (f) == HAL_PIXEL_FORMAT_BGRX_8888 ? "xRGB32" : \
+ (f) == HAL_PIXEL_FORMAT_RGBX_8888 ? "xBGR32" : \
+ (f) == HAL_PIXEL_FORMAT_BGRA_8888 ? "ARGB32" : \
+ (f) == HAL_PIXEL_FORMAT_RGBA_8888 ? "ABGR32" : \
+ (f) == HAL_PIXEL_FORMAT_RGB_565 ? "RGB565" : "??")
+
+ OUTE("%stype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, {%d,%d,%d,%d}, {%d,%d,%d,%d}",
+ iserr ? ">> " : " ",
+ l->compositionType, l->flags, l->handle, l->transform, l->blending,
+ l->sourceCrop.left,
+ l->sourceCrop.top,
+ l->sourceCrop.right,
+ l->sourceCrop.bottom,
+ l->displayFrame.left,
+ l->displayFrame.top,
+ l->displayFrame.right,
+ l->displayFrame.bottom);
+ if (l->handle) {
+ IMG_native_handle_t *h = (IMG_native_handle_t *)l->handle;
+ OUTE("%s%d*%d(%s)",
+ iserr ? ">> " : " ",
+ h->iWidth, h->iHeight, FMT(h->iFormat));
+ OUTE("hndl %p", l->handle);
+ }
+}
+
+static void dump_all(rgz_layer_t *rgz_layers, unsigned int layerno, unsigned int errlayer)
+{
+ unsigned int i;
+ for (i = 0; i < layerno; i++) {
+ hwc_layer_1_t *l = &rgz_layers[i].hwc_layer;
+ OUTE("Layer %d", i);
+ dump_layer(l, errlayer == i);
+ }
+}
+
+static int rgz_out_bvdirect_paint(rgz_t *rgz, rgz_out_params_t *params)
+{
+ int rv = 0;
+ int i;
+ (void)rgz;
+
+ rgz_blts_init(&blts);
+
+ /* Begin from index 1 to remove the background layer from the output */
+ rgz_fb_state_t *cur_fb_state = &rgz->cur_fb_state;
+ for (i = 1; i < cur_fb_state->rgz_layerno; i++) {
+ rv = rgz_hwc_layer_blit(params, &cur_fb_state->rgz_layers[i]);
+ if (rv) {
+ OUTE("bvdirect_paint: error in layer %d: %d", i, rv);
+ dump_all(cur_fb_state->rgz_layers, cur_fb_state->rgz_layerno, i);
+ rgz_blts_free(&blts);
+ return rv;
+ }
+ }
+ rgz_blts_bvdirect(rgz, &blts, params);
+ rgz_blts_free(&blts);
+ return rv;
+}
+
+static void rgz_set_async(struct rgz_blt_entry *e, int async)
+{
+ e->bp.flags = async ? e->bp.flags | BVFLAG_ASYNC : e->bp.flags & ~BVFLAG_ASYNC;
+}
+
+static void rgz_get_screen_info(rgz_out_params_t *params, struct bvsurfgeom **screen_geom)
+{
+ *screen_geom = params->data.bvc.dstgeom;
+}
+
+static int rgz_is_blending_disabled(rgz_out_params_t *params)
+{
+ return params->data.bvc.noblend;
+}
+
+static void rgz_get_displayframe_rect(hwc_layer_1_t *layer, blit_rect_t *res_rect)
+{
+ res_rect->left = layer->displayFrame.left;
+ res_rect->top = layer->displayFrame.top;
+ res_rect->bottom = layer->displayFrame.bottom;
+ res_rect->right = layer->displayFrame.right;
+}
+
+/*
+ * Returns a clock-wise rotated view of the inner rectangle relative to
+ * the outer rectangle. The inner rectangle must be contained in the outer
+ * rectangle and coordinates must be relative to the top,left corner of the outer
+ * rectangle.
+ */
+static void rgz_get_rotated_view(blit_rect_t *outer_rect, blit_rect_t *inner_rect,
+ blit_rect_t *res_rect, int orientation)
+{
+ int outer_width = WIDTH(*outer_rect);
+ int outer_height = HEIGHT(*outer_rect);
+ int inner_width = WIDTH(*inner_rect);
+ int inner_height = HEIGHT(*inner_rect);
+ int delta_top = inner_rect->top - outer_rect->top;
+ int delta_left = inner_rect->left - outer_rect->left;
+
+ /* Normalize the angle */
+ orientation = (orientation % 360) + 360;
+
+ /*
+ * Calculate the top,left offset of the inner rectangle inside the outer
+ * rectangle depending on the tranformation value.
+ */
+ switch(orientation % 360) {
+ case 0:
+ res_rect->left = delta_left;
+ res_rect->top = delta_top;
+ break;
+ case 180:
+ res_rect->left = outer_width - inner_width - delta_left;
+ res_rect->top = outer_height - inner_height - delta_top;
+ break;
+ case 90:
+ res_rect->left = outer_height - inner_height - delta_top;
+ res_rect->top = delta_left;
+ break;
+ case 270:
+ res_rect->left = delta_top;
+ res_rect->top = outer_width - inner_width - delta_left;
+ break;
+ default:
+ OUTE("Invalid transform value %d", orientation);
+ }
+
+ if (orientation % 180)
+ swap(inner_width, inner_height);
+
+ res_rect->right = res_rect->left + inner_width;
+ res_rect->bottom = res_rect->top + inner_height;
+}
+
+static void rgz_get_src_rect(hwc_layer_1_t* layer, blit_rect_t *subregion_rect, blit_rect_t *res_rect)
+{
+ if (rgz_hwc_scaled(layer)) {
+ /*
+ * If the layer is scaled we use the whole cropping rectangle from the
+ * source and just move the clipping rectangle for the region we want to
+ * blit, this is done to prevent any artifacts when blitting subregions of
+ * a scaled layer.
+ */
+ res_rect->top = layer->sourceCrop.top;
+ res_rect->left = layer->sourceCrop.left;
+ res_rect->bottom = layer->sourceCrop.bottom;
+ res_rect->right = layer->sourceCrop.right;
+ return;
+ }
+
+ blit_rect_t display_frame;
+ rgz_get_displayframe_rect(layer, &display_frame);
+
+ /*
+ * Get the rotated subregion rectangle with respect to the display frame.
+ * In order to get this correctly we need to take in account the HWC
+ * orientation is clock-wise so to return to the 0 degree view we need to
+ * rotate counter-clock wise the orientation. For example, if the
+ * orientation is 90 we need to rotate -90 to return to a 0 degree view.
+ */
+ int src_orientation = 0 - rgz_get_orientation(layer->transform);
+ rgz_get_rotated_view(&display_frame, subregion_rect, res_rect, src_orientation);
+
+ /*
+ * In order to translate the resulting rectangle relative to the cropping
+ * rectangle the only thing left is account for the offset (result is already
+ * rotated).
+ */
+ res_rect->left += layer->sourceCrop.left;
+ res_rect->right += layer->sourceCrop.left;
+ res_rect->top += layer->sourceCrop.top;
+ res_rect->bottom += layer->sourceCrop.top;
+}
+
+/*
+ * Convert a destination geometry and rectangle to a specified rotated view.
+ * Since clipping rectangle is relative to the destination geometry it will be
+ * rotated as well.
+ */
+static void rgz_rotate_dst(struct rgz_blt_entry* e, int dst_orientation)
+{
+ struct bvsurfgeom *dstgeom = &e->dstgeom;
+ struct bvrect *dstrect = &e->bp.dstrect;
+ struct bvrect *cliprect = &e->bp.cliprect;
+
+ /*
+ * Create a rectangle that represents the destination geometry (outter
+ * rectangle), destination and clipping rectangles (inner rectangles).
+ */
+ blit_rect_t dstgeom_r;
+ dstgeom_r.top = dstgeom_r.left = 0;
+ dstgeom_r.bottom = dstgeom->height;
+ dstgeom_r.right = dstgeom->width;
+
+ blit_rect_t dstrect_r;
+ dstrect_r.top = dstrect->top;
+ dstrect_r.left = dstrect->left;
+ dstrect_r.bottom = dstrect->top + dstrect->height;
+ dstrect_r.right = dstrect->left + dstrect->width;
+
+ blit_rect_t cliprect_r;
+ cliprect_r.top = cliprect->top;
+ cliprect_r.left = cliprect->left;
+ cliprect_r.bottom = cliprect->top + cliprect->height;
+ cliprect_r.right = cliprect->left + cliprect->width;
+
+ /* Get the CW rotated view of the destination rectangle */
+ blit_rect_t res_rect;
+ rgz_get_rotated_view(&dstgeom_r, &dstrect_r, &res_rect, dst_orientation);
+ dstrect->left = res_rect.left;
+ dstrect->top = res_rect.top;
+ dstrect->width = WIDTH(res_rect);
+ dstrect->height = HEIGHT(res_rect);
+
+ rgz_get_rotated_view(&dstgeom_r, &cliprect_r, &res_rect, dst_orientation);
+ cliprect->left = res_rect.left;
+ cliprect->top = res_rect.top;
+ cliprect->width = WIDTH(res_rect);
+ cliprect->height = HEIGHT(res_rect);
+
+ if (dst_orientation % 180)
+ swap(e->dstgeom.width, e->dstgeom.height);
+}
+
+static void rgz_set_dst_data(rgz_out_params_t *params, blit_rect_t *subregion_rect,
+ struct rgz_blt_entry* e, int dst_orientation)
+{
+ struct bvsurfgeom *screen_geom;
+ rgz_get_screen_info(params, &screen_geom);
+
+ /* omaplfb is in charge of assigning the correct dstdesc in the kernel */
+ e->dstgeom.structsize = sizeof(struct bvsurfgeom);
+ e->dstgeom.format = screen_geom->format;
+ e->dstgeom.width = screen_geom->width;
+ e->dstgeom.height = screen_geom->height;
+ e->dstgeom.orientation = dst_orientation;
+ e->dstgeom.virtstride = DSTSTRIDE(screen_geom);
+
+ e->bp.dstrect.left = subregion_rect->left;
+ e->bp.dstrect.top = subregion_rect->top;
+ e->bp.dstrect.width = WIDTH(*subregion_rect);
+ e->bp.dstrect.height = HEIGHT(*subregion_rect);
+
+ /* Give a rotated buffer representation of the destination if requested */
+ if (e->dstgeom.orientation)
+ rgz_rotate_dst(e, dst_orientation);
+}
+
+/* Convert a source geometry and rectangle to a specified rotated view */
+static void rgz_rotate_src(struct rgz_blt_entry* e, int src_orientation, int is_src2)
+{
+ struct bvsurfgeom *srcgeom = is_src2 ? &e->src2geom : &e->src1geom;
+ struct bvrect *srcrect = is_src2 ? &e->bp.src2rect : &e->bp.src1rect;
+
+ /*
+ * Create a rectangle that represents the source geometry (outter rectangle),
+ * source rectangle (inner rectangle).
+ */
+ blit_rect_t srcgeom_r;
+ srcgeom_r.top = srcgeom_r.left = 0;
+ srcgeom_r.bottom = srcgeom->height;
+ srcgeom_r.right = srcgeom->width;
+
+ blit_rect_t srcrect_r;
+ srcrect_r.top = srcrect->top;
+ srcrect_r.left = srcrect->left;
+ srcrect_r.bottom = srcrect->top + srcrect->height;
+ srcrect_r.right = srcrect->left + srcrect->width;
+
+ /* Get the CW rotated view of the source rectangle */
+ blit_rect_t res_rect;
+ rgz_get_rotated_view(&srcgeom_r, &srcrect_r, &res_rect, src_orientation);
+
+ srcrect->left = res_rect.left;
+ srcrect->top = res_rect.top;
+ srcrect->width = WIDTH(res_rect);
+ srcrect->height = HEIGHT(res_rect);
+
+ if (src_orientation % 180)
+ swap(srcgeom->width, srcgeom->height);
+}
+
+static void rgz_set_src_data(rgz_out_params_t *params, rgz_layer_t *rgz_layer,
+ blit_rect_t *subregion_rect, struct rgz_blt_entry* e, int src_orientation,
+ int is_src2)
+{
+ hwc_layer_1_t *hwc_layer = &rgz_layer->hwc_layer;
+ struct bvbuffdesc *srcdesc = is_src2 ? &e->src2desc : &e->src1desc;
+ struct bvsurfgeom *srcgeom = is_src2 ? &e->src2geom : &e->src1geom;
+ struct bvrect *srcrect = is_src2 ? &e->bp.src2rect : &e->bp.src1rect;
+ IMG_native_handle_t *handle = (IMG_native_handle_t *)hwc_layer->handle;
+
+ srcdesc->structsize = sizeof(struct bvbuffdesc);
+ srcdesc->length = handle->iHeight * HANDLE_TO_STRIDE(handle);
+ srcdesc->auxptr = (void*)rgz_layer->buffidx;
+ srcgeom->structsize = sizeof(struct bvsurfgeom);
+ srcgeom->format = hal_to_ocd(handle->iFormat);
+ srcgeom->width = handle->iWidth;
+ srcgeom->height = handle->iHeight;
+ srcgeom->virtstride = HANDLE_TO_STRIDE(handle);
+
+ /* Find out what portion of the src we want to use for the blit */
+ blit_rect_t res_rect;
+ rgz_get_src_rect(hwc_layer, subregion_rect, &res_rect);
+ srcrect->left = res_rect.left;
+ srcrect->top = res_rect.top;
+ srcrect->width = WIDTH(res_rect);
+ srcrect->height = HEIGHT(res_rect);
+
+ /* Give a rotated buffer representation of this source if requested */
+ if (src_orientation) {
+ srcgeom->orientation = src_orientation;
+ rgz_rotate_src(e, src_orientation, is_src2);
+ } else
+ srcgeom->orientation = 0;
+}
+
+/*
+ * Set the clipping rectangle, if part of the subregion rectangle is outside
+ * the boundaries of the destination, remove only the out-of-bounds area
+ */
+static void rgz_set_clip_rect(rgz_out_params_t *params, blit_rect_t *subregion_rect,
+ struct rgz_blt_entry* e)
+{
+ struct bvsurfgeom *screen_geom;
+ rgz_get_screen_info(params, &screen_geom);
+
+ blit_rect_t clip_rect;
+ clip_rect.left = max(0, subregion_rect->left);
+ clip_rect.top = max(0, subregion_rect->top);
+ clip_rect.bottom = min(screen_geom->height, subregion_rect->bottom);
+ clip_rect.right = min(screen_geom->width, subregion_rect->right);
+
+ e->bp.cliprect.left = clip_rect.left;
+ e->bp.cliprect.top = clip_rect.top;
+ e->bp.cliprect.width = WIDTH(clip_rect);
+ e->bp.cliprect.height = HEIGHT(clip_rect);
+}
+
+/*
+ * Configures blit entry to set src2 is the same as the destination
+ */
+static void rgz_set_src2_is_dst(rgz_out_params_t *params, struct rgz_blt_entry* e)
+{
+ /* omaplfb is in charge of assigning the correct src2desc in the kernel */
+ e->src2geom = e->dstgeom;
+ e->src2desc.structsize = sizeof(struct bvbuffdesc);
+ e->src2desc.auxptr = (void*)HWC_BLT_DESC_FB_FN(0);
+ e->bp.src2rect = e->bp.dstrect;
+}
+
+static int rgz_is_layer_nv12(hwc_layer_1_t *layer)
+{
+ IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
+ return is_NV12(handle->iFormat);
+}
+
+/*
+ * Configure the scaling mode according to the layer format
+ */
+static void rgz_cfg_scale_mode(struct rgz_blt_entry* e, hwc_layer_1_t *layer)
+{
+ /*
+ * TODO: Revisit scaling mode assignment later, output between GPU and GC320
+ * seem different
+ */
+ e->bp.scalemode = rgz_is_layer_nv12(layer) ? BVSCALE_9x9_TAP : BVSCALE_BILINEAR;
+}
+
+/*
+ * Copies src1 into the framebuffer
+ */
+static struct rgz_blt_entry* rgz_hwc_subregion_copy(rgz_out_params_t *params,
+ blit_rect_t *subregion_rect, rgz_layer_t *rgz_src1)
+{
+ struct rgz_blt_entry* e = rgz_blts_get(&blts, params);
+ hwc_layer_1_t *hwc_src1 = &rgz_src1->hwc_layer;
+ e->bp.structsize = sizeof(struct bvbltparams);
+ e->bp.op.rop = 0xCCCC; /* SRCCOPY */
+ e->bp.flags = BVFLAG_CLIP | BVFLAG_ROP;
+ e->bp.flags |= rgz_get_flip_flags(hwc_src1->transform, 0);
+ rgz_set_async(e, 1);
+
+ blit_rect_t tmp_rect;
+ if (rgz_hwc_scaled(hwc_src1)) {
+ rgz_get_displayframe_rect(hwc_src1, &tmp_rect);
+ rgz_cfg_scale_mode(e, hwc_src1);
+ } else
+ tmp_rect = *subregion_rect;
+
+ int src1_orientation = rgz_get_orientation(hwc_src1->transform);
+ int dst_orientation = 0;
+
+ if (rgz_is_layer_nv12(hwc_src1)) {
+ /*
+ * Leave NV12 as 0 degree and rotate destination instead, this is done
+ * because of a GC limitation. Rotate destination CW.
+ */
+ dst_orientation = 360 - src1_orientation;
+ src1_orientation = 0;
+ }
+
+ rgz_set_src_data(params, rgz_src1, &tmp_rect, e, src1_orientation, 0);
+ rgz_set_clip_rect(params, subregion_rect, e);
+ rgz_set_dst_data(params, &tmp_rect, e, dst_orientation);
+
+ if((e->src1geom.format == OCDFMT_BGR124) ||
+ (e->src1geom.format == OCDFMT_RGB124) ||
+ (e->src1geom.format == OCDFMT_RGB16))
+ e->dstgeom.format = OCDFMT_BGR124;
+
+ return e;
+}
+
+/*
+ * Blends two layers and write the result in the framebuffer, src1 must be the
+ * top most layer while src2 is the one behind. If src2 is NULL means src1 will
+ * be blended with the current content of the framebuffer.
+ */
+static struct rgz_blt_entry* rgz_hwc_subregion_blend(rgz_out_params_t *params,
+ blit_rect_t *subregion_rect, rgz_layer_t *rgz_src1, rgz_layer_t *rgz_src2)
+{
+ struct rgz_blt_entry* e = rgz_blts_get(&blts, params);
+ hwc_layer_1_t *hwc_src1 = &rgz_src1->hwc_layer;
+ e->bp.structsize = sizeof(struct bvbltparams);
+ e->bp.op.blend = BVBLEND_SRC1OVER;
+ e->bp.flags = BVFLAG_CLIP | BVFLAG_BLEND;
+ e->bp.flags |= rgz_get_flip_flags(hwc_src1->transform, 0);
+ rgz_set_async(e, 1);
+
+ blit_rect_t tmp_rect;
+ if (rgz_hwc_scaled(hwc_src1)) {
+ rgz_get_displayframe_rect(hwc_src1, &tmp_rect);
+ rgz_cfg_scale_mode(e, hwc_src1);
+ } else
+ tmp_rect = *subregion_rect;
+
+ int src1_orientation = rgz_get_orientation(hwc_src1->transform);
+ int dst_orientation = 0;
+
+ if (rgz_is_layer_nv12(hwc_src1)) {
+ /*
+ * Leave NV12 as 0 degree and rotate destination instead, this is done
+ * because of a GC limitation. Rotate destination CW.
+ */
+ dst_orientation = 360 - src1_orientation;
+ src1_orientation = 0;
+ }
+
+ rgz_set_src_data(params, rgz_src1, &tmp_rect, e, src1_orientation, 0);
+ rgz_set_clip_rect(params, subregion_rect, e);
+ rgz_set_dst_data(params, &tmp_rect, e, dst_orientation);
+
+ if (rgz_src2) {
+ /*
+ * NOTE: Due to an API limitation it's not possible to blend src1 and
+ * src2 if both have scaling, hence only src1 is used for now
+ */
+ hwc_layer_1_t *hwc_src2 = &rgz_src2->hwc_layer;
+ if (rgz_hwc_scaled(hwc_src2))
+ OUTE("src2 layer %p has scaling, this is not supported", hwc_src2);
+ /*
+ * We shouldn't receive a NV12 buffer as src2 at this point, this is an
+ * invalid parameter for the blend request
+ */
+ if (rgz_is_layer_nv12(hwc_src2))
+ OUTE("invalid input layer, src2 layer %p is NV12", hwc_src2);
+ e->bp.flags |= rgz_get_flip_flags(hwc_src2->transform, 1);
+ int src2_orientation = rgz_get_orientation(hwc_src2->transform);
+ rgz_set_src_data(params, rgz_src2, subregion_rect, e, src2_orientation, 1);
+ } else
+ rgz_set_src2_is_dst(params, e);
+
+ return e;
+}
+
+/*
+ * Clear the destination buffer, if rect is NULL means the whole screen, rect
+ * cannot be outside the boundaries of the screen
+ */
+static void rgz_out_clrdst(rgz_out_params_t *params, blit_rect_t *rect)
+{
+ struct rgz_blt_entry* e = rgz_blts_get(&blts, params);
+ e->bp.structsize = sizeof(struct bvbltparams);
+ e->bp.op.rop = 0xCCCC; /* SRCCOPY */
+ e->bp.flags = BVFLAG_CLIP | BVFLAG_ROP;
+ rgz_set_async(e, 1);
+
+ struct bvsurfgeom *screen_geom;
+ rgz_get_screen_info(params, &screen_geom);
+
+ e->src1desc.structsize = sizeof(struct bvbuffdesc);
+ e->src1desc.length = 4; /* 1 pixel, 32bpp */
+ /*
+ * With the HWC we don't bother having a buffer for the fill we'll get the
+ * OMAPLFB to fixup the src1desc and stride if the auxiliary pointer is -1
+ */
+ e->src1desc.auxptr = (void*)-1;
+ e->src1geom.structsize = sizeof(struct bvsurfgeom);
+ e->src1geom.format = OCDFMT_RGBA24;
+ e->bp.src1rect.left = e->bp.src1rect.top = e->src1geom.orientation = 0;
+ e->src1geom.height = e->src1geom.width = e->bp.src1rect.height = e->bp.src1rect.width = 1;
+
+ blit_rect_t clear_rect;
+ if (rect) {
+ clear_rect.left = rect->left;
+ clear_rect.top = rect->top;
+ clear_rect.right = rect->right;
+ clear_rect.bottom = rect->bottom;
+ } else {
+ clear_rect.left = clear_rect.top = 0;
+ clear_rect.right = screen_geom->width;
+ clear_rect.bottom = screen_geom->height;
+ }
+
+ rgz_set_clip_rect(params, &clear_rect, e);
+ rgz_set_dst_data(params, &clear_rect, e, 0);
+}
+
+static int rgz_out_bvcmd_paint(rgz_t *rgz, rgz_out_params_t *params)
+{
+ int rv = 0;
+ int i, j;
+ params->data.bvc.out_blits = 0;
+ params->data.bvc.out_nhndls = 0;
+ rgz_blts_init(&blts);
+ rgz_out_clrdst(params, NULL);
+
+ /* Begin from index 1 to remove the background layer from the output */
+ rgz_fb_state_t *cur_fb_state = &rgz->cur_fb_state;
+ for (i = 1, j = 0; i < cur_fb_state->rgz_layerno; i++) {
+ rgz_layer_t *rgz_layer = &cur_fb_state->rgz_layers[i];
+ hwc_layer_1_t *l = &rgz_layer->hwc_layer;
+
+ //OUTP("blitting meminfo %d", rgz->rgz_layers[i].buffidx);
+
+ /*
+ * See if it is needed to put transparent pixels where this layer
+ * is located in the screen
+ */
+ if (rgz_layer->buffidx == -1) {
+ struct bvsurfgeom *scrgeom = params->data.bvc.dstgeom;
+ blit_rect_t srcregion;
+ srcregion.left = max(0, l->displayFrame.left);
+ srcregion.top = max(0, l->displayFrame.top);
+ srcregion.bottom = min(scrgeom->height, l->displayFrame.bottom);
+ srcregion.right = min(scrgeom->width, l->displayFrame.right);
+ rgz_out_clrdst(params, &srcregion);
+ continue;
+ }
+
+ rv = rgz_hwc_layer_blit(params, rgz_layer);
+ if (rv) {
+ OUTE("bvcmd_paint: error in layer %d: %d", i, rv);
+ dump_all(cur_fb_state->rgz_layers, cur_fb_state->rgz_layerno, i);
+ rgz_blts_free(&blts);
+ return rv;
+ }
+ params->data.bvc.out_hndls[j++] = l->handle;
+ params->data.bvc.out_nhndls++;
+ }
+
+ /* Last blit is made sync to act like a fence for the previous async blits */
+ struct rgz_blt_entry* e = &blts.bvcmds[blts.idx-1];
+ rgz_set_async(e, 0);
+
+ /* FIXME: we want to be able to call rgz_blts_free and populate the actual
+ * composition data structure ourselves */
+ params->data.bvc.cmdp = blts.bvcmds;
+ params->data.bvc.cmdlen = blts.idx;
+
+ if (params->data.bvc.out_blits >= RGZ_MAX_BLITS) {
+ rv = -1;
+ // rgz_blts_free(&blts); // FIXME
+ }
+ return rv;
+}
+
+static float getscalew(hwc_layer_1_t *layer)
+{
+ int w = WIDTH(layer->sourceCrop);
+ int h = HEIGHT(layer->sourceCrop);
+
+ if (layer->transform & HWC_TRANSFORM_ROT_90)
+ swap(w, h);
+
+ return ((float)WIDTH(layer->displayFrame)) / (float)w;
+}
+
+static float getscaleh(hwc_layer_1_t *layer)
+{
+ int w = WIDTH(layer->sourceCrop);
+ int h = HEIGHT(layer->sourceCrop);
+
+ if (layer->transform & HWC_TRANSFORM_ROT_90)
+ swap(w, h);
+
+ return ((float)HEIGHT(layer->displayFrame)) / (float)h;
+}
+
+/*
+ * Simple bubble sort on an array, ascending order
+ */
+static void rgz_bsort(int *a, int len)
+{
+ int i, j;
+ for (i = 0; i < len; i++) {
+ for (j = 0; j < i; j++) {
+ if (a[i] < a[j]) {
+ int temp = a[i];
+ a[i] = a[j];
+ a[j] = temp;
+ }
+ }
+ }
+}
+
+/*
+ * Leave only unique numbers in a sorted array
+ */
+static int rgz_bunique(int *a, int len)
+{
+ int unique = 1;
+ int base = 0;
+ while (base + 1 < len) {
+ if (a[base] == a[base + 1]) {
+ int skip = 1;
+ while (base + skip < len && a[base] == a[base + skip])
+ skip++;
+ if (base + skip == len)
+ break;
+ int i;
+ for (i = 0; i < skip - 1; i++)
+ a[base + 1 + i] = a[base + skip];
+ }
+ unique++;
+ base++;
+ }
+ return unique;
+}
+
+static void rgz_gen_blitregions(rgz_t *rgz, blit_hregion_t *hregion, int screen_width)
+{
+/*
+ * 1. Get the offsets (left/right positions) of each layer within the
+ * hregion. Assume that layers describe the bounds of the hregion.
+ * 2. We should then be able to generate an array of rects
+ * 3. Each layer will have a different z-order, for each z-order
+ * find the intersection. Some intersections will be empty.
+ */
+
+ int offsets[RGZ_SUBREGIONMAX];
+ int noffsets=0;
+ int l, r;
+
+ /*
+ * Add damaged region, then all layers. We are guaranteed to not go outside
+ * of offsets array boundaries at this point.
+ */
+ offsets[noffsets++] = rgz->damaged_area.left;
+ offsets[noffsets++] = rgz->damaged_area.right;
+
+ for (l = 0; l < hregion->nlayers; l++) {
+ hwc_layer_1_t *layer = &hregion->rgz_layers[l]->hwc_layer;
+ /* Make sure the subregion is not outside the boundaries of the screen */
+ offsets[noffsets++] = max(0, layer->displayFrame.left);
+ offsets[noffsets++] = min(layer->displayFrame.right, screen_width);
+ }
+ rgz_bsort(offsets, noffsets);
+ noffsets = rgz_bunique(offsets, noffsets);
+ hregion->nsubregions = noffsets - 1;
+ bzero(hregion->blitrects, sizeof(hregion->blitrects));
+ for (r = 0; r + 1 < noffsets; r++) {
+ blit_rect_t subregion;
+ subregion.top = hregion->rect.top;
+ subregion.bottom = hregion->rect.bottom;
+ subregion.left = offsets[r];
+ subregion.right = offsets[r+1];
+
+ ALOGD_IF(debug, " sub l %d r %d",
+ subregion.left, subregion.right);
+ for (l = 0; l < hregion->nlayers; l++) {
+ hwc_layer_1_t *layer = &hregion->rgz_layers[l]->hwc_layer;
+ if (RECT_INTERSECTS(subregion, layer->displayFrame)) {
+
+ hregion->blitrects[l][r] = subregion;
+
+ ALOGD_IF(debug, "hregion->blitrects[%d][%d] (%d %d %d %d)", l, r,
+ hregion->blitrects[l][r].left,
+ hregion->blitrects[l][r].top,
+ hregion->blitrects[l][r].right,
+ hregion->blitrects[l][r].bottom);
+ }
+ }
+ }
+}
+
+static int rgz_hwc_scaled(hwc_layer_1_t *layer)
+{
+ int w = WIDTH(layer->sourceCrop);
+ int h = HEIGHT(layer->sourceCrop);
+
+ if (layer->transform & HWC_TRANSFORM_ROT_90)
+ swap(w, h);
+
+ return WIDTH(layer->displayFrame) != w || HEIGHT(layer->displayFrame) != h;
+}
+
+static int rgz_in_valid_hwc_layer(hwc_layer_1_t *layer)
+{
+ IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
+ if ((layer->flags & HWC_SKIP_LAYER) || !handle)
+ return 0;
+
+ if (is_NV12(handle->iFormat))
+ return handle->iFormat == HAL_PIXEL_FORMAT_TI_NV12;
+
+ /* FIXME: The following must be removed when GC supports vertical/horizontal
+ * buffer flips, please note having a FLIP_H and FLIP_V means 180 rotation
+ * which is supported indeed
+ */
+ if (layer->transform) {
+ int is_flipped = !!(layer->transform & HWC_TRANSFORM_FLIP_H) ^ !!(layer->transform & HWC_TRANSFORM_FLIP_V);
+ if (is_flipped) {
+ ALOGE("Layer %p is flipped %d", layer, layer->transform);
+ return 0;
+ }
+ }
+
+ switch(handle->iFormat) {
+ case HAL_PIXEL_FORMAT_BGRX_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+/* Reset dirty region data and state */
+static void rgz_delete_region_data(rgz_t *rgz){
+ if (!rgz)
+ return;
+ if (rgz->hregions)
+ free(rgz->hregions);
+ rgz->hregions = NULL;
+ rgz->nhregions = 0;
+ rgz->state &= ~RGZ_REGION_DATA;
+}
+
+static rgz_fb_state_t* get_prev_fb_state(rgz_t *rgz)
+{
+ return &rgz->fb_states[rgz->fb_state_idx];
+}
+
+static rgz_fb_state_t* get_next_fb_state(rgz_t *rgz)
+{
+ rgz->fb_state_idx = (rgz->fb_state_idx + 1) % RGZ_NUM_FB;
+ return &rgz->fb_states[rgz->fb_state_idx];
+}
+
+static void rgz_add_to_damaged_area(rgz_in_params_t *params, rgz_layer_t *rgz_layer,
+ blit_rect_t *damaged_area)
+{
+ struct bvsurfgeom *screen_geom = params->data.hwc.dstgeom;
+ hwc_layer_1_t *layer = &rgz_layer->hwc_layer;
+
+ blit_rect_t screen_rect;
+ screen_rect.left = screen_rect.top = 0;
+ screen_rect.right = screen_geom->width;
+ screen_rect.bottom = screen_geom->height;
+
+ /* Ignore the layer rectangle if it doesn't intersect the screen */
+ if (!RECT_INTERSECTS(screen_rect, layer->displayFrame))
+ return;
+
+ /* Clip the layer rectangle to the screen geometry */
+ blit_rect_t layer_rect;
+ rgz_get_displayframe_rect(layer, &layer_rect);
+ layer_rect.left = max(0, layer_rect.left);
+ layer_rect.top = max(0, layer_rect.top);
+ layer_rect.right = min(screen_rect.right, layer_rect.right);
+ layer_rect.bottom = min(screen_rect.bottom, layer_rect.bottom);
+
+ /* Then add the rectangle to the damage area */
+ if (empty_rect(damaged_area)) {
+ /* Adding for the first time */
+ damaged_area->left = layer_rect.left;
+ damaged_area->top = layer_rect.top;
+ damaged_area->right = layer_rect.right;
+ damaged_area->bottom = layer_rect.bottom;
+ } else {
+ /* Grow current damaged area */
+ damaged_area->left = min(damaged_area->left, layer_rect.left);
+ damaged_area->top = min(damaged_area->top, layer_rect.top);
+ damaged_area->right = max(damaged_area->right, layer_rect.right);
+ damaged_area->bottom = max(damaged_area->bottom, layer_rect.bottom);
+ }
+}
+
+/* Search a layer with the specified identity in the passed array */
+static rgz_layer_t* rgz_find_layer(rgz_layer_t *rgz_layers, int rgz_layerno,
+ uint32_t layer_identity)
+{
+ int i;
+ for (i = 0; i < rgz_layerno; i++) {
+ rgz_layer_t *rgz_layer = &rgz_layers[i];
+ /* Ignore background layer, it has no identity */
+ if (rgz_layer->buffidx == RGZ_BACKGROUND_BUFFIDX)
+ continue;
+ if (rgz_layer->identity == layer_identity)
+ return rgz_layer;
+ }
+ return NULL;
+}
+
+/* Determines if two layers with the same identity have changed its own window content */
+static int rgz_has_layer_content_changed(rgz_layer_t *cur_rgz_layer, rgz_layer_t *prev_rgz_layer)
+{
+ hwc_layer_1_t *cur_hwc_layer = &cur_rgz_layer->hwc_layer;
+ hwc_layer_1_t *prev_hwc_layer = &prev_rgz_layer->hwc_layer;
+
+ /* The background has no identity and never changes */
+ if (cur_rgz_layer->buffidx == RGZ_BACKGROUND_BUFFIDX &&
+ prev_rgz_layer->buffidx == RGZ_BACKGROUND_BUFFIDX)
+ return 0;
+
+ if (cur_rgz_layer->identity != prev_rgz_layer->identity) {
+ OUTE("%s: Invalid input, layer identities differ (current=%d, prev=%d)",
+ __func__, cur_rgz_layer->identity, prev_rgz_layer->identity);
+ return 1;
+ }
+
+ /* If the layer has the clear fb hint we don't care about the content */
+ if (cur_rgz_layer->buffidx == RGZ_CLEARHINT_BUFFIDX &&
+ prev_rgz_layer->buffidx == RGZ_CLEARHINT_BUFFIDX)
+ return 0;
+
+ /* Check if the layer content has changed */
+ if (cur_hwc_layer->handle != prev_hwc_layer->handle ||
+ cur_hwc_layer->transform != prev_hwc_layer->transform ||
+ cur_hwc_layer->sourceCrop.top != prev_hwc_layer->sourceCrop.top ||
+ cur_hwc_layer->sourceCrop.left != prev_hwc_layer->sourceCrop.left ||
+ cur_hwc_layer->sourceCrop.bottom != prev_hwc_layer->sourceCrop.bottom ||
+ cur_hwc_layer->sourceCrop.right != prev_hwc_layer->sourceCrop.right)
+ return 1;
+
+ return 0;
+}
+
+/* Determines if two layers with the same identity have changed their screen position */
+static int rgz_has_layer_frame_moved(rgz_layer_t *cur_rgz_layer, rgz_layer_t *target_rgz_layer)
+{
+ hwc_layer_1_t *cur_hwc_layer = &cur_rgz_layer->hwc_layer;
+ hwc_layer_1_t *target_hwc_layer = &target_rgz_layer->hwc_layer;
+
+ if (cur_rgz_layer->identity != target_rgz_layer->identity) {
+ OUTE("%s: Invalid input, layer identities differ (current=%d, target=%d)",
+ __func__, cur_rgz_layer->identity, target_rgz_layer->identity);
+ return 1;
+ }
+
+ if (cur_hwc_layer->displayFrame.top != target_hwc_layer->displayFrame.top ||
+ cur_hwc_layer->displayFrame.left != target_hwc_layer->displayFrame.left ||
+ cur_hwc_layer->displayFrame.bottom != target_hwc_layer->displayFrame.bottom ||
+ cur_hwc_layer->displayFrame.right != target_hwc_layer->displayFrame.right)
+ return 1;
+
+ return 0;
+}
+
+static void rgz_handle_dirty_region(rgz_t *rgz, rgz_in_params_t *params,
+ rgz_fb_state_t* prev_fb_state, rgz_fb_state_t* target_fb_state)
+{
+ /* Reset damaged area */
+ bzero(&rgz->damaged_area, sizeof(rgz->damaged_area));
+
+ int i;
+ rgz_fb_state_t *cur_fb_state = &rgz->cur_fb_state;
+
+ for (i = 0; i < cur_fb_state->rgz_layerno; i++) {
+ rgz_layer_t *cur_rgz_layer = &cur_fb_state->rgz_layers[i];
+ rgz_layer_t *prev_rgz_layer = NULL;
+ int layer_changed = 0;
+
+ if (i == 0) {
+ /*
+ * Background is always zero, no need to search for it. If the previous state
+ * is empty reset the dirty count for the background layer.
+ */
+ if (prev_fb_state->rgz_layerno)
+ prev_rgz_layer = &prev_fb_state->rgz_layers[0];
+ } else {
+ /* Find out if this layer was present in the previous frame */
+ prev_rgz_layer = rgz_find_layer(prev_fb_state->rgz_layers,
+ prev_fb_state->rgz_layerno, cur_rgz_layer->identity);
+ }
+
+ /* Check if the layer is new or if the content changed from the previous frame */
+ if (prev_rgz_layer && !rgz_has_layer_content_changed(cur_rgz_layer, prev_rgz_layer)) {
+ /* Copy previous dirty count */
+ cur_rgz_layer->dirty_count = prev_rgz_layer->dirty_count;
+ cur_rgz_layer->dirty_count -= cur_rgz_layer->dirty_count ? 1 : 0;
+ } else
+ cur_rgz_layer->dirty_count = RGZ_NUM_FB;
+
+ /* If the layer is new, redraw the layer area */
+ if (!prev_rgz_layer) {
+ rgz_add_to_damaged_area(params, cur_rgz_layer, &rgz->damaged_area);
+ continue;
+ }
+
+ /* Nothing more to do with the background layer */
+ if (i == 0)
+ continue;
+
+ /* Find out if the layer is present in the target frame */
+ rgz_layer_t *target_rgz_layer = rgz_find_layer(target_fb_state->rgz_layers,
+ target_fb_state->rgz_layerno, cur_rgz_layer->identity);
+
+ if (target_rgz_layer) {
+ /* Find out if the window size and position are different from the target frame */
+ if (rgz_has_layer_frame_moved(cur_rgz_layer, target_rgz_layer)) {
+ /*
+ * Redraw both layer areas. This will effectively clear the area where
+ * this layer was in the target frame and force to draw the new layer
+ * location.
+ */
+ rgz_add_to_damaged_area(params, cur_rgz_layer, &rgz->damaged_area);
+ rgz_add_to_damaged_area(params, target_rgz_layer, &rgz->damaged_area);
+ cur_rgz_layer->dirty_count = RGZ_NUM_FB;
+ }
+ } else {
+ /* If the layer is not in the target just draw it's new location */
+ rgz_add_to_damaged_area(params, cur_rgz_layer, &rgz->damaged_area);
+ }
+ }
+
+ /*
+ * Add to damage area layers missing from the target frame to the current frame
+ * ignoring the background
+ */
+ for (i = 1; i < target_fb_state->rgz_layerno; i++) {
+ rgz_layer_t *target_rgz_layer = &target_fb_state->rgz_layers[i];
+
+ rgz_layer_t *cur_rgz_layer = rgz_find_layer(cur_fb_state->rgz_layers,
+ cur_fb_state->rgz_layerno, target_rgz_layer->identity);
+
+ /* Layers present in the target have been handled already in the loop above */
+ if (cur_rgz_layer)
+ continue;
+
+ /* The target layer is not present in the current frame, redraw its area */
+ rgz_add_to_damaged_area(params, target_rgz_layer, &rgz->damaged_area);
+ }
+}
+
+/* Adds the background layer in first the position of the passed fb state */
+static void rgz_add_background_layer(rgz_fb_state_t *fb_state)
+{
+ rgz_layer_t *rgz_layer = &fb_state->rgz_layers[0];
+ rgz_layer->hwc_layer = bg_layer;
+ rgz_layer->buffidx = RGZ_BACKGROUND_BUFFIDX;
+ /* Set dummy handle to maintain dirty region state */
+ rgz_layer->hwc_layer.handle = (void*) 0x1;
+}
+
+static int rgz_in_hwccheck(rgz_in_params_t *p, rgz_t *rgz)
+{
+ hwc_layer_1_t *layers = p->data.hwc.layers;
+ hwc_layer_extended_t *extlayers = p->data.hwc.extlayers;
+ int layerno = p->data.hwc.layerno;
+
+ rgz->state &= ~RGZ_STATE_INIT;
+
+ if (!layers)
+ return -1;
+
+ /* For debugging */
+ //dump_all(layers, layerno, 0);
+
+ /*
+ * Store buffer index to be sent in the HWC Post2 list. Any overlay
+ * meminfos must come first
+ */
+ int l, memidx = 0;
+ for (l = 0; l < layerno; l++) {
+ if (layers[l].compositionType == HWC_OVERLAY)
+ memidx++;
+ }
+
+ int possible_blit = 0, candidates = 0;
+
+ /*
+ * Insert the background layer at the beginning of the list, maintain a
+ * state for dirty region handling
+ */
+ rgz_fb_state_t *cur_fb_state = &rgz->cur_fb_state;
+ rgz_add_background_layer(cur_fb_state);
+
+ for (l = 0; l < layerno; l++) {
+ if (layers[l].compositionType == HWC_FRAMEBUFFER) {
+ candidates++;
+ if (rgz_in_valid_hwc_layer(&layers[l]) &&
+ possible_blit < RGZ_INPUT_MAXLAYERS) {
+ rgz_layer_t *rgz_layer = &cur_fb_state->rgz_layers[possible_blit+1];
+ rgz_layer->hwc_layer = layers[l];
+ rgz_layer->identity = extlayers[l].identity;
+ rgz_layer->buffidx = memidx++;
+ possible_blit++;
+ }
+ continue;
+ }
+
+ if (layers[l].hints & HWC_HINT_CLEAR_FB) {
+ candidates++;
+ if (possible_blit < RGZ_INPUT_MAXLAYERS) {
+ /*
+ * Use only the layer rectangle as an input to regionize when the clear
+ * fb hint is present, mark this layer to identify it.
+ */
+ rgz_layer_t *rgz_layer = &cur_fb_state->rgz_layers[possible_blit+1];
+ rgz_layer->hwc_layer = layers[l];
+ rgz_layer->identity = extlayers[l].identity;
+ rgz_layer->buffidx = RGZ_CLEARHINT_BUFFIDX;
+ /* Set dummy handle to maintain dirty region state */
+ rgz_layer->hwc_layer.handle = (void*) 0x1;
+ possible_blit++;
+ }
+ }
+ }
+
+ if (!possible_blit || possible_blit != candidates) {
+ return -1;
+ }
+
+ rgz->state |= RGZ_STATE_INIT;
+ cur_fb_state->rgz_layerno = possible_blit + 1; /* Account for background layer */
+
+ /* Get the target and previous frame geometries */
+ rgz_fb_state_t* prev_fb_state = get_prev_fb_state(rgz);
+ rgz_fb_state_t* target_fb_state = get_next_fb_state(rgz);
+
+ /* Modifiy dirty counters and create the damaged region */
+ rgz_handle_dirty_region(rgz, p, prev_fb_state, target_fb_state);
+
+ /* Copy the current geometry to use it in the next frame */
+ memcpy(target_fb_state->rgz_layers, cur_fb_state->rgz_layers, sizeof(rgz_layer_t) * cur_fb_state->rgz_layerno);
+ target_fb_state->rgz_layerno = cur_fb_state->rgz_layerno;
+
+ return RGZ_ALL;
+}
+
+static int rgz_in_hwc(rgz_in_params_t *p, rgz_t *rgz)
+{
+ int i, j;
+ int yentries[RGZ_SUBREGIONMAX];
+ int dispw; /* widest layer */
+ int screen_width = p->data.hwc.dstgeom->width;
+ int screen_height = p->data.hwc.dstgeom->height;
+ rgz_fb_state_t *cur_fb_state = &rgz->cur_fb_state;
+
+ if (!(rgz->state & RGZ_STATE_INIT)) {
+ OUTE("rgz_process started with bad state");
+ return -1;
+ }
+
+ /*
+ * Figure out if there is enough space to store the top-bottom coordinates
+ * of each layer including the damaged area
+ */
+ if (((cur_fb_state->rgz_layerno + 1) * 2) > RGZ_SUBREGIONMAX) {
+ OUTE("%s: Not enough space to store top-bottom coordinates of each layer (max %d, needed %d*2)",
+ __func__, RGZ_SUBREGIONMAX, cur_fb_state->rgz_layerno + 1);
+ return -1;
+ }
+
+ /* Delete the previous region data */
+ rgz_delete_region_data(rgz);
+
+ /*
+ * Find the horizontal regions, add damaged area first which is already
+ * inside display boundaries
+ */
+ int ylen = 0;
+ yentries[ylen++] = rgz->damaged_area.top;
+ yentries[ylen++] = rgz->damaged_area.bottom;
+ dispw = rgz->damaged_area.right;
+
+ /* Add the top and bottom coordinates of each layer */
+ for (i = 0; i < cur_fb_state->rgz_layerno; i++) {
+ hwc_layer_1_t *layer = &cur_fb_state->rgz_layers[i].hwc_layer;
+ /* Maintain regions inside display boundaries */
+ yentries[ylen++] = max(0, layer->displayFrame.top);
+ yentries[ylen++] = min(layer->displayFrame.bottom, screen_height);
+ dispw = dispw > layer->displayFrame.right ? dispw : layer->displayFrame.right;
+ }
+ rgz_bsort(yentries, ylen);
+ ylen = rgz_bunique(yentries, ylen);
+
+ /* at this point we have an array of horizontal regions */
+ rgz->nhregions = ylen - 1;
+
+ blit_hregion_t *hregions = calloc(rgz->nhregions, sizeof(blit_hregion_t));
+ if (!hregions) {
+ OUTE("Unable to allocate memory for hregions");
+ return -1;
+ }
+ rgz->hregions = hregions;
+
+ ALOGD_IF(debug, "Allocated %d regions (sz = %d), layerno = %d", rgz->nhregions,
+ rgz->nhregions * sizeof(blit_hregion_t), cur_fb_state->rgz_layerno);
+
+ for (i = 0; i < rgz->nhregions; i++) {
+ hregions[i].rect.top = yentries[i];
+ hregions[i].rect.bottom = yentries[i+1];
+ /* Avoid hregions outside the display boundaries */
+ hregions[i].rect.left = 0;
+ hregions[i].rect.right = dispw > screen_width ? screen_width : dispw;
+ hregions[i].nlayers = 0;
+ for (j = 0; j < cur_fb_state->rgz_layerno; j++) {
+ hwc_layer_1_t *layer = &cur_fb_state->rgz_layers[j].hwc_layer;
+ if (RECT_INTERSECTS(hregions[i].rect, layer->displayFrame)) {
+ int l = hregions[i].nlayers++;
+ hregions[i].rgz_layers[l] = &cur_fb_state->rgz_layers[j];
+ }
+ }
+ }
+
+ /* Calculate blit regions */
+ for (i = 0; i < rgz->nhregions; i++) {
+ rgz_gen_blitregions(rgz, &hregions[i], screen_width);
+ ALOGD_IF(debug, "hregion %3d: nsubregions %d", i, hregions[i].nsubregions);
+ ALOGD_IF(debug, " : %d to %d: ",
+ hregions[i].rect.top, hregions[i].rect.bottom);
+ for (j = 0; j < hregions[i].nlayers; j++)
+ ALOGD_IF(debug, " %p ", &hregions[i].rgz_layers[j]->hwc_layer);
+ }
+ rgz->state |= RGZ_REGION_DATA;
+ return 0;
+}
+
+/*
+ * generate a human readable description of the layer
+ *
+ * idx, flags, fmt, type, sleft, stop, sright, sbot, dleft, dtop, \
+ * dright, dbot, rot, flip, blending, scalew, scaleh, visrects
+ *
+ */
+static void rgz_print_layer(hwc_layer_1_t *l, int idx, int csv)
+{
+ char big_log[1024];
+ int e = sizeof(big_log);
+ char *end = big_log + e;
+ e -= snprintf(end - e, e, "<!-- LAYER-DAT: %d", idx);
+
+
+ e -= snprintf(end - e, e, "%s %p", csv ? "," : " hndl:",
+ l->handle ? l->handle : NULL);
+
+ e -= snprintf(end - e, e, "%s %s", csv ? "," : " flags:",
+ l->flags & HWC_SKIP_LAYER ? "skip" : "none");
+
+ IMG_native_handle_t *handle = (IMG_native_handle_t *)l->handle;
+ if (handle) {
+ e -= snprintf(end - e, e, "%s", csv ? ", " : " fmt: ");
+ switch(handle->iFormat) {
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ e -= snprintf(end - e, e, "bgra"); break;
+ case HAL_PIXEL_FORMAT_RGB_565:
+ e -= snprintf(end - e, e, "rgb565"); break;
+ case HAL_PIXEL_FORMAT_BGRX_8888:
+ e -= snprintf(end - e, e, "bgrx"); break;
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ e -= snprintf(end - e, e, "rgbx"); break;
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ e -= snprintf(end - e, e, "rgba"); break;
+ case HAL_PIXEL_FORMAT_TI_NV12:
+ case HAL_PIXEL_FORMAT_TI_NV12_PADDED:
+ e -= snprintf(end - e, e, "nv12"); break;
+ default:
+ e -= snprintf(end - e, e, "unknown");
+ }
+ e -= snprintf(end - e, e, "%s", csv ? ", " : " type: ");
+ if (handle->usage & GRALLOC_USAGE_HW_RENDER)
+ e -= snprintf(end - e, e, "hw");
+ else if (handle->usage & GRALLOC_USAGE_SW_READ_MASK ||
+ handle->usage & GRALLOC_USAGE_SW_WRITE_MASK)
+ e -= snprintf(end - e, e, "sw");
+ else
+ e -= snprintf(end - e, e, "unknown");
+ } else {
+ e -= snprintf(end - e, e, csv ? ", unknown" : " fmt: unknown");
+ e -= snprintf(end - e, e, csv ? ", na" : " type: na");
+ }
+ e -= snprintf(end - e, e, csv ? ", %d, %d, %d, %d" : " src: %d %d %d %d",
+ l->sourceCrop.left, l->sourceCrop.top, l->sourceCrop.right,
+ l->sourceCrop.bottom);
+ e -= snprintf(end - e, e, csv ? ", %d, %d, %d, %d" : " disp: %d %d %d %d",
+ l->displayFrame.left, l->displayFrame.top,
+ l->displayFrame.right, l->displayFrame.bottom);
+
+ e -= snprintf(end - e, e, "%s %s", csv ? "," : " rot:",
+ l->transform & HWC_TRANSFORM_ROT_90 ? "90" :
+ l->transform & HWC_TRANSFORM_ROT_180 ? "180" :
+ l->transform & HWC_TRANSFORM_ROT_270 ? "270" : "none");
+
+ char flip[5] = "";
+ strcat(flip, l->transform & HWC_TRANSFORM_FLIP_H ? "H" : "");
+ strcat(flip, l->transform & HWC_TRANSFORM_FLIP_V ? "V" : "");
+ if (!(l->transform & (HWC_TRANSFORM_FLIP_V|HWC_TRANSFORM_FLIP_H)))
+ strcpy(flip, "none");
+ e -= snprintf(end - e, e, "%s %s", csv ? "," : " flip:", flip);
+
+ e -= snprintf(end - e, e, "%s %s", csv ? "," : " blending:",
+ l->blending == HWC_BLENDING_NONE ? "none" :
+ l->blending == HWC_BLENDING_PREMULT ? "premult" :
+ l->blending == HWC_BLENDING_COVERAGE ? "coverage" : "invalid");
+
+ e -= snprintf(end - e, e, "%s %1.3f", csv ? "," : " scalew:", getscalew(l));
+ e -= snprintf(end - e, e, "%s %1.3f", csv ? "," : " scaleh:", getscaleh(l));
+
+ e -= snprintf(end - e, e, "%s %d", csv ? "," : " visrect:",
+ l->visibleRegionScreen.numRects);
+
+ if (!csv) {
+ e -= snprintf(end - e, e, " -->");
+ OUTP("%s", big_log);
+
+ size_t i = 0;
+ for (; i < l->visibleRegionScreen.numRects; i++) {
+ hwc_rect_t const *r = &l->visibleRegionScreen.rects[i];
+ OUTP("<!-- LAYER-VIS: %d: rect: %d %d %d %d -->",
+ i, r->left, r->top, r->right, r->bottom);
+ }
+ } else {
+ size_t i = 0;
+ for (; i < l->visibleRegionScreen.numRects; i++) {
+ hwc_rect_t const *r = &l->visibleRegionScreen.rects[i];
+ e -= snprintf(end - e, e, ", %d, %d, %d, %d",
+ r->left, r->top, r->right, r->bottom);
+ }
+ e -= snprintf(end - e, e, " -->");
+ OUTP("%s", big_log);
+ }
+}
+
+static void rgz_print_layers(hwc_display_contents_1_t* list, int csv)
+{
+ size_t i;
+ for (i = 0; i < list->numHwLayers; i++) {
+ hwc_layer_1_t *l = &list->hwLayers[i];
+ rgz_print_layer(l, i, csv);
+ }
+}
+
+static int hal_to_ocd(int color)
+{
+ switch(color) {
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ return OCDFMT_BGRA24;
+ case HAL_PIXEL_FORMAT_BGRX_8888:
+ return OCDFMT_BGR124;
+ case HAL_PIXEL_FORMAT_RGB_565:
+ return OCDFMT_RGB16;
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ return OCDFMT_RGBA24;
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ return OCDFMT_RGB124;
+ case HAL_PIXEL_FORMAT_TI_NV12:
+ return OCDFMT_NV12;
+ case HAL_PIXEL_FORMAT_YV12:
+ return OCDFMT_YV12;
+ default:
+ return OCDFMT_UNKNOWN;
+ }
+}
+
+static BVFN_MAP bv_map;
+static BVFN_BLT bv_blt;
+static BVFN_UNMAP bv_unmap;
+
+static int rgz_handle_to_stride(IMG_native_handle_t *h)
+{
+ int bpp = is_NV12(h->iFormat) ? 0 : (h->iFormat == HAL_PIXEL_FORMAT_RGB_565 ? 2 : 4);
+ int stride = ALIGN(h->iWidth, HW_ALIGN) * bpp;
+ return stride;
+}
+
+static int rgz_get_orientation(unsigned int transform)
+{
+ int orientation = 0;
+ if ((transform & HWC_TRANSFORM_FLIP_H) && (transform & HWC_TRANSFORM_FLIP_V))
+ orientation += 180;
+ if (transform & HWC_TRANSFORM_ROT_90)
+ orientation += 90;
+
+ return orientation;
+}
+
+static int rgz_get_flip_flags(unsigned int transform, int use_src2_flags)
+{
+ /*
+ * If vertical and horizontal flip flags are set it means a 180 rotation
+ * (with no flip) is intended for the layer, so we return 0 in that case.
+ */
+ int flip_flags = 0;
+ if (transform & HWC_TRANSFORM_FLIP_H)
+ flip_flags |= (use_src2_flags ? BVFLAG_HORZ_FLIP_SRC2 : BVFLAG_HORZ_FLIP_SRC1);
+ if (transform & HWC_TRANSFORM_FLIP_V)
+ flip_flags = flip_flags ? 0 : flip_flags | (use_src2_flags ? BVFLAG_VERT_FLIP_SRC2 : BVFLAG_VERT_FLIP_SRC1);
+ return flip_flags;
+}
+
+static int rgz_hwc_layer_blit(rgz_out_params_t *params, rgz_layer_t *rgz_layer)
+{
+ hwc_layer_1_t* layer = &rgz_layer->hwc_layer;
+ blit_rect_t srcregion;
+ rgz_get_displayframe_rect(layer, &srcregion);
+
+ int noblend = rgz_is_blending_disabled(params);
+ if (!noblend && layer->blending == HWC_BLENDING_PREMULT)
+ rgz_hwc_subregion_blend(params, &srcregion, rgz_layer, NULL);
+ else
+ rgz_hwc_subregion_copy(params, &srcregion, rgz_layer);
+
+ return 0;
+}
+
+static int rgz_can_blend_together(hwc_layer_1_t* src1_layer, hwc_layer_1_t* src2_layer)
+{
+ /* If any layer is scaled we cannot blend both layers in one blit */
+ if (rgz_hwc_scaled(src1_layer) || rgz_hwc_scaled(src2_layer))
+ return 0;
+
+ /* NV12 buffers don't have alpha information on it */
+ IMG_native_handle_t *src1_hndl = (IMG_native_handle_t *)src1_layer->handle;
+ IMG_native_handle_t *src2_hndl = (IMG_native_handle_t *)src2_layer->handle;
+ if (is_NV12(src1_hndl->iFormat) || is_NV12(src2_hndl->iFormat))
+ return 0;
+
+ return 1;
+}
+
+static void rgz_batch_entry(struct rgz_blt_entry* e, unsigned int flag, unsigned int set)
+{
+ e->bp.flags &= ~BVFLAG_BATCH_MASK;
+ e->bp.flags |= flag;
+ e->bp.batchflags |= set;
+}
+
+static int rgz_hwc_subregion_blit(blit_hregion_t *hregion, int sidx, rgz_out_params_t *params,
+ blit_rect_t *damaged_area)
+{
+ int lix;
+ int ldepth = get_layer_ops(hregion, sidx, &lix);
+ if (ldepth == 0) {
+ /* Impossible, there are no layers in this region even if the
+ * background is covering the whole screen
+ */
+ OUTE("hregion %p subregion %d doesn't have any ops", hregion, sidx);
+ return -1;
+ }
+
+ /* Determine if this region is dirty */
+ int dirty = 0;
+ blit_rect_t *subregion_rect = &hregion->blitrects[lix][sidx];
+ if (RECT_INTERSECTS(*damaged_area, *subregion_rect)) {
+ /* The subregion intersects the damaged area, draw unconditionally */
+ dirty = 1;
+ } else {
+ int dirtylix = lix;
+ while (dirtylix != -1) {
+ rgz_layer_t *rgz_layer = hregion->rgz_layers[dirtylix];
+ if (rgz_layer->dirty_count){
+ /* One of the layers is dirty, we need to generate blits for this subregion */
+ dirty = 1;
+ break;
+ }
+ dirtylix = get_layer_ops_next(hregion, sidx, dirtylix);
+ }
+ }
+ if (!dirty)
+ return 0;
+
+ /* Check if the bottom layer is the background */
+ if (hregion->rgz_layers[lix]->buffidx == RGZ_BACKGROUND_BUFFIDX) {
+ if (ldepth == 1) {
+ /* Background layer is the only operation, clear subregion */
+ rgz_out_clrdst(params, &hregion->blitrects[lix][sidx]);
+ return 0;
+ } else {
+ /* No need to generate blits with background layer if there is
+ * another layer on top of it, discard it
+ */
+ ldepth--;
+ lix = get_layer_ops_next(hregion, sidx, lix);
+ }
+ }
+
+ /*
+ * See if the depth most layer needs to be ignored. If this layer is the
+ * only operation, we need to clear this subregion.
+ */
+ if (hregion->rgz_layers[lix]->buffidx == RGZ_CLEARHINT_BUFFIDX) {
+ ldepth--;
+ if (!ldepth) {
+ rgz_out_clrdst(params, &hregion->blitrects[lix][sidx]);
+ return 0;
+ }
+ lix = get_layer_ops_next(hregion, sidx, lix);
+ }
+
+ int noblend = rgz_is_blending_disabled(params);
+
+ if (!noblend && ldepth > 1) { /* BLEND */
+ blit_rect_t *rect = &hregion->blitrects[lix][sidx];
+ struct rgz_blt_entry* e;
+
+ int s2lix = lix;
+ lix = get_layer_ops_next(hregion, sidx, lix);
+
+ /*
+ * We save a read and a write from the FB if we blend the bottom
+ * two layers, we can do this only if both layers are not scaled
+ */
+ int prev_layer_scaled = 0;
+ int prev_layer_nv12 = 0;
+ int first_batchflags = 0;
+ rgz_layer_t *rgz_src1 = hregion->rgz_layers[lix];
+ rgz_layer_t *rgz_src2 = hregion->rgz_layers[s2lix];
+ if (rgz_can_blend_together(&rgz_src1->hwc_layer, &rgz_src2->hwc_layer))
+ e = rgz_hwc_subregion_blend(params, rect, rgz_src1, rgz_src2);
+ else {
+ /* Return index to the first operation and make a copy of the first layer */
+ lix = s2lix;
+ rgz_src1 = hregion->rgz_layers[lix];
+ e = rgz_hwc_subregion_copy(params, rect, rgz_src1);
+ /*
+ * First blit is a copy, the rest will be blends, hence the operation
+ * changed on the second blit.
+ */
+ first_batchflags |= BVBATCH_OP;
+ prev_layer_nv12 = rgz_is_layer_nv12(&rgz_src1->hwc_layer);
+ prev_layer_scaled = rgz_hwc_scaled(&rgz_src1->hwc_layer);
+ }
+
+ /*
+ * Regardless if the first blit is a copy or blend, src2 may have changed
+ * on the second blit
+ */
+ first_batchflags |= BVBATCH_SRC2 | BVBATCH_SRC2RECT_ORIGIN | BVBATCH_SRC2RECT_SIZE;
+
+ rgz_batch_entry(e, BVFLAG_BATCH_BEGIN, 0);
+
+ /* Rest of layers blended with FB */
+ while((lix = get_layer_ops_next(hregion, sidx, lix)) != -1) {
+ int batchflags = first_batchflags;
+ first_batchflags = 0;
+ rgz_src1 = hregion->rgz_layers[lix];
+
+ /* Blend src1 into dst */
+ e = rgz_hwc_subregion_blend(params, rect, rgz_src1, NULL);
+
+ /*
+ * NOTE: After the first blit is configured, consequent blits are
+ * blend operations done with src1 and the destination, that is,
+ * src2 is the same as dst, any batchflag changed for the destination
+ * applies to src2 as well.
+ */
+
+ /* src1 parameters always change on every blit */
+ batchflags |= BVBATCH_SRC1 | BVBATCH_SRC1RECT_ORIGIN| BVBATCH_SRC1RECT_SIZE;
+
+ /*
+ * If the current/previous layer has scaling, destination rectangles
+ * likely changed as well as the scaling mode. Clipping rectangle
+ * remains the same as well as destination geometry.
+ */
+ int cur_layer_scaled = rgz_hwc_scaled(&rgz_src1->hwc_layer);
+ if (cur_layer_scaled || prev_layer_scaled) {
+ batchflags |= BVBATCH_DSTRECT_ORIGIN | BVBATCH_DSTRECT_SIZE |
+ BVBATCH_SRC2RECT_ORIGIN | BVBATCH_SRC2RECT_SIZE |
+ BVBATCH_SCALE;
+ }
+ prev_layer_scaled = cur_layer_scaled;
+
+ /*
+ * If the current/previous layer is NV12, the destination geometry
+ * could have been rotated, hence the destination and clipping
+ * rectangles might have been trasformed to match the rotated
+ * destination geometry.
+ */
+ int cur_layer_nv12 = rgz_is_layer_nv12(&rgz_src1->hwc_layer);
+ if (cur_layer_nv12 || prev_layer_nv12) {
+ batchflags |= BVBATCH_DST | BVBATCH_DSTRECT_ORIGIN | BVBATCH_DSTRECT_SIZE |
+ BVBATCH_SRC2 | BVBATCH_SRC2RECT_ORIGIN | BVBATCH_SRC2RECT_SIZE |
+ BVBATCH_CLIPRECT;
+ }
+ prev_layer_nv12 = cur_layer_nv12;
+
+ rgz_batch_entry(e, BVFLAG_BATCH_CONTINUE, batchflags);
+ }
+
+ if (e->bp.flags & BVFLAG_BATCH_BEGIN)
+ rgz_batch_entry(e, 0, 0);
+ else
+ rgz_batch_entry(e, BVFLAG_BATCH_END, 0);
+
+ } else { /* COPY */
+ blit_rect_t *rect = &hregion->blitrects[lix][sidx];
+ if (noblend) /* get_layer_ops() doesn't understand this so get the top */
+ lix = get_top_rect(hregion, sidx, &rect);
+ rgz_hwc_subregion_copy(params, rect, hregion->rgz_layers[lix]);
+ }
+ return 0;
+}
+
+struct bvbuffdesc gscrndesc = {
+ .structsize = sizeof(struct bvbuffdesc), .length = 0,
+ .auxptr = MAP_FAILED
+};
+struct bvsurfgeom gscrngeom = {
+ .structsize = sizeof(struct bvsurfgeom), .format = OCDFMT_UNKNOWN
+};
+
+static void rgz_blts_init(struct rgz_blts *blts)
+{
+ bzero(blts, sizeof(*blts));
+}
+
+static void rgz_blts_free(struct rgz_blts *blts)
+{
+ /* TODO ??? maybe we should dynamically allocate this */
+ rgz_blts_init(blts);
+}
+
+static struct rgz_blt_entry* rgz_blts_get(struct rgz_blts *blts, rgz_out_params_t *params)
+{
+ struct rgz_blt_entry *ne;
+ if (blts->idx < RGZ_MAX_BLITS) {
+ ne = &blts->bvcmds[blts->idx++];
+ if (IS_BVCMD(params))
+ params->data.bvc.out_blits++;
+ } else {
+ OUTE("!!! BIG PROBLEM !!! run out of blit entries");
+ ne = &blts->bvcmds[blts->idx - 1]; /* Return last slot */
+ }
+ return ne;
+}
+
+static int rgz_blts_bvdirect(rgz_t *rgz, struct rgz_blts *blts, rgz_out_params_t *params)
+{
+ struct bvbatch *batch = NULL;
+ int rv = -1;
+ int idx = 0;
+
+ while (idx < blts->idx) {
+ struct rgz_blt_entry *e = &blts->bvcmds[idx];
+ if (e->bp.flags & BVFLAG_BATCH_MASK)
+ e->bp.batch = batch;
+ rv = bv_blt(&e->bp);
+ if (rv) {
+ OUTE("BV_BLT failed: %d", rv);
+ BVDUMP("bv_blt:", " ", &e->bp);
+ return -1;
+ }
+ if (e->bp.flags & BVFLAG_BATCH_BEGIN)
+ batch = e->bp.batch;
+ idx++;
+ }
+ return rv;
+}
+
+static int rgz_out_region(rgz_t *rgz, rgz_out_params_t *params)
+{
+ if (!(rgz->state & RGZ_REGION_DATA)) {
+ OUTE("rgz_out_region invoked with bad state");
+ return -1;
+ }
+
+ rgz_blts_init(&blts);
+ ALOGD_IF(debug, "rgz_out_region:");
+
+ if (IS_BVCMD(params))
+ params->data.bvc.out_blits = 0;
+
+ int i;
+ for (i = 0; i < rgz->nhregions; i++) {
+ blit_hregion_t *hregion = &rgz->hregions[i];
+ int s;
+ ALOGD_IF(debug, "h[%d] nsubregions = %d", i, hregion->nsubregions);
+ if (hregion->nlayers == 0) {
+ /* Impossible, there are no layers in this region even if the
+ * background is covering the whole screen
+ */
+ OUTE("hregion %p doesn't have any ops", hregion);
+ return -1;
+ }
+ for (s = 0; s < hregion->nsubregions; s++) {
+ ALOGD_IF(debug, "h[%d] -> [%d]", i, s);
+ if (rgz_hwc_subregion_blit(hregion, s, params, &rgz->damaged_area))
+ return -1;
+ }
+ }
+
+ int rv = 0;
+
+ if (IS_BVCMD(params)) {
+ int j;
+ params->data.bvc.out_nhndls = 0;
+ rgz_fb_state_t *cur_fb_state = &rgz->cur_fb_state;
+ /* Begin from index 1 to remove the background layer from the output */
+ for (j = 1, i = 0; j < cur_fb_state->rgz_layerno; j++) {
+ rgz_layer_t *rgz_layer = &cur_fb_state->rgz_layers[j];
+ /* We don't need the handles for layers marked as -1 */
+ if (rgz_layer->buffidx == -1)
+ continue;
+ params->data.bvc.out_hndls[i++] = rgz_layer->hwc_layer.handle;
+ params->data.bvc.out_nhndls++;
+ }
+
+ if (blts.idx > 0) {
+ /* Last blit is made sync to act like a fence for the previous async blits */
+ struct rgz_blt_entry* e = &blts.bvcmds[blts.idx-1];
+ rgz_set_async(e, 0);
+ }
+
+ /* FIXME: we want to be able to call rgz_blts_free and populate the actual
+ * composition data structure ourselves */
+ params->data.bvc.cmdp = blts.bvcmds;
+ params->data.bvc.cmdlen = blts.idx;
+ if (params->data.bvc.out_blits >= RGZ_MAX_BLITS)
+ rv = -1;
+ //rgz_blts_free(&blts);
+ } else {
+ rv = rgz_blts_bvdirect(rgz, &blts, params);
+ rgz_blts_free(&blts);
+ }
+
+ return rv;
+}
+
+void rgz_profile_hwc(hwc_display_contents_1_t* list, int dispw, int disph)
+{
+ if (!list) /* A NULL composition list can occur */
+ return;
+
+ static char regiondump2[PROPERTY_VALUE_MAX] = "";
+ char regiondump[PROPERTY_VALUE_MAX];
+ property_get("debug.2dhwc.region", regiondump, "0");
+ int dumpregions = strncmp(regiondump, regiondump2, PROPERTY_VALUE_MAX);
+ if (dumpregions)
+ strncpy(regiondump2, regiondump, PROPERTY_VALUE_MAX);
+ else {
+ dumpregions = !strncmp(regiondump, "all", PROPERTY_VALUE_MAX) &&
+ (list->flags & HWC_GEOMETRY_CHANGED);
+ static int iteration = 0;
+ if (dumpregions)
+ sprintf(regiondump, "iteration %d", iteration++);
+ }
+
+ char dumplayerdata[PROPERTY_VALUE_MAX];
+ /* 0 - off, 1 - human readable, 2 - CSV */
+ property_get("debug.2dhwc.dumplayers", dumplayerdata, "0");
+ int dumplayers = atoi(dumplayerdata);
+ if (dumplayers && (list->flags & HWC_GEOMETRY_CHANGED)) {
+ OUTP("<!-- BEGUN-LAYER-DUMP: %d -->", list->numHwLayers);
+ rgz_print_layers(list, dumplayers == 1 ? 0 : 1);
+ OUTP("<!-- ENDED-LAYER-DUMP -->");
+ }
+
+ if(!dumpregions)
+ return;
+
+ rgz_t rgz;
+ rgz_in_params_t ip = { .data = { .hwc = {
+ .layers = list->hwLayers,
+ .layerno = list->numHwLayers } } };
+ ip.op = RGZ_IN_HWCCHK;
+ if (rgz_in(&ip, &rgz) == RGZ_ALL) {
+ ip.op = RGZ_IN_HWC;
+ if (rgz_in(&ip, &rgz) == RGZ_ALL) {
+ OUTP("<!-- BEGUN-SVG-DUMP: %s -->", regiondump);
+ OUTP("<b>%s</b>", regiondump);
+ rgz_out_params_t op = {
+ .op = RGZ_OUT_SVG,
+ .data = {
+ .svg = {
+ .dispw = dispw, .disph = disph,
+ .htmlw = 450, .htmlh = 800
+ }
+ },
+ };
+ rgz_out(&rgz, &op);
+ OUTP("<!-- ENDED-SVG-DUMP -->");
+ }
+ }
+ rgz_release(&rgz);
+}
+
+int rgz_get_screengeometry(int fd, struct bvsurfgeom *geom, int fmt)
+{
+ /* Populate Bltsville destination buffer information with framebuffer data */
+ struct fb_fix_screeninfo fb_fixinfo;
+ struct fb_var_screeninfo fb_varinfo;
+
+ ALOGI("Attempting to get framebuffer device info.");
+ if(ioctl(fd, FBIOGET_FSCREENINFO, &fb_fixinfo)) {
+ OUTE("Error getting fb_fixinfo");
+ return -EINVAL;
+ }
+
+ if(ioctl(fd, FBIOGET_VSCREENINFO, &fb_varinfo)) {
+ ALOGE("Error gettting fb_varinfo");
+ return -EINVAL;
+ }
+
+ bzero(&bg_layer, sizeof(bg_layer));
+ bg_layer.displayFrame.left = bg_layer.displayFrame.top = 0;
+ bg_layer.displayFrame.right = fb_varinfo.xres;
+ bg_layer.displayFrame.bottom = fb_varinfo.yres;
+
+ bzero(geom, sizeof(*geom));
+ geom->structsize = sizeof(*geom);
+ geom->width = fb_varinfo.xres;
+ geom->height = fb_varinfo.yres;
+ geom->virtstride = fb_fixinfo.line_length;
+ geom->format = hal_to_ocd(fmt);
+ geom->orientation = 0;
+ return 0;
+}
+
+int rgz_in(rgz_in_params_t *p, rgz_t *rgz)
+{
+ int rv = -1;
+ switch (p->op) {
+ case RGZ_IN_HWC:
+ rv = rgz_in_hwccheck(p, rgz);
+ if (rv == RGZ_ALL)
+ rv = rgz_in_hwc(p, rgz) ? 0 : RGZ_ALL;
+ break;
+ case RGZ_IN_HWCCHK:
+ bzero(rgz, sizeof(rgz_t));
+ rv = rgz_in_hwccheck(p, rgz);
+ break;
+ default:
+ return -1;
+ }
+ return rv;
+}
+
+void rgz_release(rgz_t *rgz)
+{
+ if (!rgz)
+ return;
+ if (rgz->hregions)
+ free(rgz->hregions);
+ bzero(rgz, sizeof(*rgz));
+}
+
+int rgz_out(rgz_t *rgz, rgz_out_params_t *params)
+{
+ switch (params->op) {
+ case RGZ_OUT_SVG:
+ rgz_out_svg(rgz, params);
+ return 0;
+ case RGZ_OUT_BVDIRECT_PAINT:
+ return rgz_out_bvdirect_paint(rgz, params);
+ case RGZ_OUT_BVCMD_PAINT:
+ return rgz_out_bvcmd_paint(rgz, params);
+ case RGZ_OUT_BVDIRECT_REGION:
+ case RGZ_OUT_BVCMD_REGION:
+ return rgz_out_region(rgz, params);
+ default:
+ return -1;
+ }
+}
+
diff --git a/hwc/rgz_2d.h b/hwc/rgz_2d.h
new file mode 100644
index 0000000..de41b82
--- /dev/null
+++ b/hwc/rgz_2d.h
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) Texas Instruments - http://www.ti.com/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __RGZ_2D__
+#define __RGZ_2D__
+
+#include <linux/bltsville.h>
+
+/*
+ * Maximum number of layers used to generate subregion rectangles in a
+ * horizontal region.
+ */
+#define RGZ_MAXLAYERS 13
+
+/*
+ * Maximum number of layers the regionizer will accept as input. Account for an
+ * additional 'background layer' to generate empty subregion rectangles and
+ * a damage region as well.
+ */
+#define RGZ_INPUT_MAXLAYERS (RGZ_MAXLAYERS - 2)
+
+/* Number of framebuffers to track */
+#define RGZ_NUM_FB 2
+
+/*
+ * Regionizer data
+ *
+ * This is an oqaque structure passed in by the client
+ */
+struct rgz;
+typedef struct rgz rgz_t;
+
+/*
+ * With an open framebuffer file descriptor get the geometry of
+ * the device
+ */
+int rgz_get_screengeometry(int fd, struct bvsurfgeom *geom, int fmt);
+
+/*
+ * Regionizer input parameters
+ */
+struct rgz_in_hwc {
+ int flags;
+ int layerno;
+ hwc_layer_1_t *layers;
+ hwc_layer_extended_t *extlayers;
+ struct bvsurfgeom *dstgeom;
+};
+
+typedef struct rgz_in_params {
+ int op; /* See RGZ_IN_* */
+ union {
+ struct rgz_in_hwc hwc;
+ } data;
+} rgz_in_params_t;
+
+typedef struct rgz_ext_layer_list {
+ hwc_layer_extended_t layers[RGZ_INPUT_MAXLAYERS];
+} rgz_ext_layer_list_t;
+
+/*
+ * Validate whether the HWC layers can be rendered
+ *
+ * Arguments (rgz_in_params_t):
+ * op RGZ_IN_HWCCHK
+ * data.hwc.layers HWC layer array
+ * data.hwc.layerno HWC layer array size
+ *
+ * Returns:
+ * rv = RGZ_ALL, -1 failure
+ */
+#define RGZ_IN_HWCCHK 1
+
+/*
+ * Regionize the HWC layers
+ *
+ * This generates region data which can be used with regionizer
+ * output function. This call will validate whether all or some of the
+ * layers can be rendered.
+ *
+ * The caller must use rgz_release when done with the region data
+ *
+ * Arguments (rgz_in_params_t):
+ * op RGZ_IN_HWC
+ * data.hwc.layers HWC layer array
+ * data.hwc.layerno HWC layer array size
+ *
+ * Returns:
+ * rv = RGZ_ALL, -1 failure
+ */
+#define RGZ_IN_HWC 2
+
+int rgz_in(rgz_in_params_t *param, rgz_t *rgz);
+
+/* This means all layers can be blitted */
+#define RGZ_ALL 1
+
+/*
+ * Free regionizer resources
+ */
+void rgz_release(rgz_t *rgz);
+
+/*
+ * Regionizer output operations
+ */
+struct rgz_out_bvcmd {
+ void *cmdp;
+ int cmdlen;
+ struct bvsurfgeom *dstgeom;
+ int noblend;
+ buffer_handle_t out_hndls[RGZ_INPUT_MAXLAYERS]; /* OUTPUT */
+ int out_nhndls; /* OUTPUT */
+ int out_blits; /* OUTPUT */
+};
+
+struct rgz_out_svg {
+ int dispw;
+ int disph;
+ int htmlw;
+ int htmlh;
+};
+
+struct rgz_out_bvdirect {
+ struct bvbuffdesc *dstdesc;
+ struct bvsurfgeom *dstgeom;
+ int noblend;
+};
+
+typedef struct rgz_out_params {
+ int op; /* See RGZ_OUT_* */
+ union {
+ struct rgz_out_bvcmd bvc;
+ struct rgz_out_bvdirect bv;
+ struct rgz_out_svg svg;
+ } data;
+} rgz_out_params_t;
+
+/*
+ * Regionizer output commands
+ */
+
+/*
+ * Output SVG from regionizer
+ *
+ * rgz_out_params_t:
+ *
+ * op RGZ_OUT_SVG
+ * data.svg.dispw
+ * data.svg.disph Display width and height these values will be the
+ * viewport dimensions i.e. the logical coordinate space
+ * rather than the physical size
+ * data.svg.htmlw
+ * data.svg.htmlh HTML output dimensions
+ */
+#define RGZ_OUT_SVG 0
+
+/*
+ * This commands generates bltsville command data structures for HWC which will
+ * paint layer by layer
+ *
+ * rgz_out_params_t:
+ *
+ * op RGZ_OUT_BVCMD_PAINT
+ * data.bvc.cmdp Pointer to buffer with cmd data
+ * data.bvc.cmdlen length of cmdp
+ * data.bvc.dstgeom bltsville struct describing the destination geometry
+ * data.bvc.noblend Test option to disable blending
+ * data.bvc.out_hndls Array of buffer handles (OUTPUT)
+ * data.bvc.out_nhndls Number of buffer handles (OUTPUT)
+ * data.bvc.out_blits Number of blits (OUTPUT)
+ */
+#define RGZ_OUT_BVCMD_PAINT 1
+
+/*
+ * This commands generates bltsville command data structures for HWC which will
+ * render via regions. This will involve a complete redraw of the screen.
+ *
+ * See RGZ_OUT_BVCMD_PAINT
+ */
+#define RGZ_OUT_BVCMD_REGION 2
+
+/*
+ * Perform actual blits painting each layer from back to front - this is a test
+ * command
+ *
+ * rgz_out_params_t:
+ *
+ * op RGZ_OUT_BVDIRECT_PAINT
+ * data.bv.dstdesc bltsville struct describing the destination buffer
+ * data.bv.dstgeom bltsville struct describing the destination geometry
+ * data.bv.list List of HWC layers to blit, only HWC_OVERLAY layers
+ * will be rendered
+ * data.bv.noblend Test option to disable blending
+ */
+#define RGZ_OUT_BVDIRECT_PAINT 3
+/*
+ * Perform actual blits where each blit is a subregion - this is a test mode
+ */
+#define RGZ_OUT_BVDIRECT_REGION 5
+
+int rgz_out(rgz_t *rgz, rgz_out_params_t* params);
+
+/*
+ * Produce instrumented logging of layer data
+ */
+void rgz_profile_hwc(hwc_display_contents_1_t* list, int dispw, int disph);
+
+/*
+ * ----------------------------------
+ * IMPLEMENTATION DETAILS FOLLOW HERE
+ * ----------------------------------
+ */
+
+/*
+ * Regionizer blit data structures
+ */
+typedef struct blit_rect {
+ int left, top, right, bottom;
+} blit_rect_t;
+
+/*
+ * A hregion is a horizontal area generated from the intersection of layers
+ * for a given composition.
+ *
+ * ----------------------------------------
+ * | layer 0 |
+ * | xxxxxxxxxxxxxxxxxx |
+ * | x layer 1 x |
+ * | x x |
+ * | x xxxxxxxxxxxxxxxxxxx
+ * | x x layer 2 x
+ * | x x x
+ * | xxxxxxxxxx x
+ * | x x
+ * | x x
+ * ---------------------xxxxxxxxxxxxxxxxxxx
+ *
+ * This can be broken up into a number of horizontal regions:
+ *
+ * ----------------------------------------
+ * | H1 l0 |
+ * |-----------xxxxxxxxxxxxxxxxxx---------|
+ * | H2 x x |
+ * | l0 x l01 x l0 |
+ * |-----------x--------xxxxxxxxxxxxxxxxxxx
+ * | H3 x x x x
+ * | l0 x l01 x l012 x l02 x
+ * |-----------xxxxxxxxxxxxxxxxxx---------x
+ * | H4 x x
+ * | l0 x l02 x
+ * ---------------------xxxxxxxxxxxxxxxxxxx
+ *
+ * Each hregion is just an array of rectangles. By accounting for the layers
+ * at different z-order, and hregion becomes a multi-dimensional array e.g. in
+ * the diagram above H4 has 2 sub-regions, layer 0 intersects with the first
+ * region and layers 0 and 2 intersect with the second region.
+ */
+#define RGZ_SUBREGIONMAX ((RGZ_MAXLAYERS << 1) - 1)
+#define RGZ_MAX_BLITS (RGZ_SUBREGIONMAX * RGZ_SUBREGIONMAX)
+
+typedef struct rgz_layer {
+ hwc_layer_1_t hwc_layer;
+ uint32_t identity;
+ int buffidx;
+ int dirty_count;
+} rgz_layer_t;
+
+typedef struct rgz_fb_state {
+ int rgz_layerno;
+ rgz_layer_t rgz_layers[RGZ_MAXLAYERS];
+} rgz_fb_state_t;
+
+typedef struct blit_hregion {
+ blit_rect_t rect;
+ rgz_layer_t *rgz_layers[RGZ_MAXLAYERS];
+ int nlayers;
+ int nsubregions;
+ blit_rect_t blitrects[RGZ_MAXLAYERS][RGZ_SUBREGIONMAX]; /* z-order | rectangle */
+} blit_hregion_t;
+
+enum { RGZ_STATE_INIT = 1, RGZ_REGION_DATA = 2} ;
+
+struct rgz {
+ /* All fields here are opaque to the caller */
+ blit_hregion_t *hregions;
+ int nhregions;
+ int state;
+ rgz_fb_state_t cur_fb_state;
+ int fb_state_idx; /* Target framebuffer index. Points to the fb where the blits will be applied to */
+ rgz_fb_state_t fb_states[RGZ_NUM_FB]; /* Storage for previous framebuffer geometry states */
+ blit_rect_t damaged_area; /* Area of the screen which will be redrawn unconditionally */
+};
+
+#endif /* __RGZ_2D__ */
diff --git a/hwc/sw_vsync.c b/hwc/sw_vsync.c
new file mode 100644
index 0000000..cf24b31
--- /dev/null
+++ b/hwc/sw_vsync.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) Texas Instruments - http://www.ti.com/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <sys/resource.h>
+#include <pthread.h>
+#include <time.h>
+
+#include <cutils/properties.h>
+#include <cutils/log.h>
+#include <utils/Timers.h>
+
+#include "hwc_dev.h"
+
+static pthread_t vsync_thread;
+static pthread_mutex_t vsync_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t vsync_cond;
+static bool vsync_loop_active = false;
+
+nsecs_t vsync_rate;
+
+static struct timespec diff(struct timespec start, struct timespec end)
+{
+ struct timespec temp;
+ if ((end.tv_nsec - start.tv_nsec) < 0) {
+ temp.tv_sec = end.tv_sec-start.tv_sec - 1;
+ temp.tv_nsec = 1000000000 + end.tv_nsec-start.tv_nsec;
+ } else {
+ temp.tv_sec = end.tv_sec - start.tv_sec;
+ temp.tv_nsec = end.tv_nsec - start.tv_nsec;
+ }
+ return temp;
+}
+
+static void *vsync_loop(void *data)
+{
+ struct timespec tp, tp_next, tp_sleep;
+ nsecs_t now = 0, period = vsync_rate, next_vsync = 0, next_fake_vsync = 0, sleep = 0;
+ omap_hwc_device_t *hwc_dev = (omap_hwc_device_t *)data;
+ tp_sleep.tv_sec = tp_sleep.tv_nsec = 0;
+ bool reset_timers = true;
+
+ setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
+
+ for (;;) {
+ pthread_mutex_lock(&vsync_mutex);
+ period = vsync_rate; /* re-read rate */
+ while (!vsync_loop_active) {
+ pthread_cond_wait(&vsync_cond, &vsync_mutex);
+ }
+ pthread_mutex_unlock(&vsync_mutex);
+
+ clock_gettime(CLOCK_MONOTONIC, &tp);
+ now = (tp.tv_sec * 1000000000) + tp.tv_nsec;
+ next_vsync = next_fake_vsync;
+ sleep = next_vsync - now;
+ if (sleep < 0) {
+ /* we missed, find where the next vsync should be */
+ sleep = (period - ((now - next_vsync) % period));
+ next_vsync = now + sleep;
+ }
+ next_fake_vsync = next_vsync + period;
+ tp_next.tv_sec = (next_vsync / 1000000000);
+ tp_next.tv_nsec = (next_vsync % 1000000000);
+ tp_sleep = diff(tp, tp_next);
+
+ nanosleep(&tp_sleep, NULL);
+ if (hwc_dev->procs && hwc_dev->procs->vsync) {
+ hwc_dev->procs->vsync(hwc_dev->procs, 0, next_vsync);
+ }
+ }
+ return NULL;
+}
+
+bool use_sw_vsync()
+{
+ char board[PROPERTY_VALUE_MAX];
+ bool rv = false;
+ property_get("ro.product.board", board, "");
+ if ((strncmp("blaze", board, PROPERTY_VALUE_MAX) == 0) ||
+ (strncmp("panda5", board, PROPERTY_VALUE_MAX) == 0)) {
+ /* TODO: panda5 really should support h/w vsync */
+ rv = true;
+ } else {
+ char value[PROPERTY_VALUE_MAX];
+ property_get("persist.hwc.sw_vsync", value, "0");
+ int use_sw_vsync = atoi(value);
+ rv = use_sw_vsync > 0;
+ }
+ ALOGI("Expecting %s vsync for %s", rv ? "s/w" : "h/w", board);
+ return rv;
+}
+
+void init_sw_vsync(omap_hwc_device_t *hwc_dev)
+{
+ pthread_cond_init(&vsync_cond, NULL);
+ pthread_create(&vsync_thread, NULL, vsync_loop, (void *)hwc_dev);
+}
+
+void start_sw_vsync()
+{
+ char refresh_rate[PROPERTY_VALUE_MAX];
+ property_get("persist.hwc.sw_vsync_rate", refresh_rate, "60");
+
+ pthread_mutex_lock(&vsync_mutex);
+ int rate = atoi(refresh_rate);
+ if (rate <= 0)
+ rate = 60;
+ vsync_rate = 1000000000 / rate;
+ if (vsync_loop_active) {
+ pthread_mutex_unlock(&vsync_mutex);
+ return;
+ }
+ vsync_loop_active = true;
+ pthread_mutex_unlock(&vsync_mutex);
+ pthread_cond_signal(&vsync_cond);
+}
+
+void stop_sw_vsync()
+{
+ pthread_mutex_lock(&vsync_mutex);
+ if (!vsync_loop_active) {
+ pthread_mutex_unlock(&vsync_mutex);
+ return;
+ }
+ vsync_loop_active = false;
+ pthread_mutex_unlock(&vsync_mutex);
+ pthread_cond_signal(&vsync_cond);
+}
diff --git a/hwc/sw_vsync.h b/hwc/sw_vsync.h
new file mode 100644
index 0000000..bb06165
--- /dev/null
+++ b/hwc/sw_vsync.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) Texas Instruments - http://www.ti.com/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SWVSYNC_H__
+#define __SWVSYNC_H__
+
+bool use_sw_vsync();
+void init_sw_vsync(omap_hwc_device_t *hwc_dev);
+void start_sw_vsync();
+void stop_sw_vsync();
+
+#endif
diff --git a/include/gralloc/ti_handle_wrapper.h b/include/gralloc/ti_handle_wrapper.h
new file mode 100644
index 0000000..9a4189f
--- /dev/null
+++ b/include/gralloc/ti_handle_wrapper.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) Texas Instruments - http://www.ti.com/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _TI_HANDLE_WRAPPER_H_
+#define _TI_HANDLE_WRAPPER_H_
+
+/*
+ * Provide wrapper api for getting fields from gralloc
+ * handles
+ */
+#define OMAP_LEGACY_HANDLE /* For now enable legacy handle by default */
+#ifdef OMAP_LEGACY_HANDLE
+
+#include "hal_public.h"
+typedef IMG_native_handle_t ti_hndl_t;
+
+#define HND_W(h) h->iWidth
+#define HND_H(h) h->iHeight
+#define HND_FMT(h) h->iFormat
+
+/*
+ * Return total number of ion fd entries in the handle.
+ *
+ * Legacy handle does not support ion fds, so will return 0, use this test
+ * to determine whether to get pvr fds instead.
+ */
+#define GET_ION_FD_COUNT(h) 0
+
+/*
+ * Return ion fd at index 'n'.
+ *
+ * Legacy handle does not support ion fds.
+ */
+#define GET_ION_FD(h, n) -1
+
+/*
+ * Return pvr fd
+ */
+#define GET_PVR_FD(h) h->fd[0]
+
+#else
+
+#include "gralloc/gralloc_ti_handle.h"
+#include "gralloc/hal_gpu_public.h"
+
+typedef gralloc_ti_handle ti_hndl_t;
+
+#define HND_W(h) h->width
+#define HND_H(h) h->height
+#define HND_FMT(h) h->format
+
+/*
+ * Return total number of ion fd entries in the handle.
+ */
+#define GET_ION_FD_COUNT(h) ti_gralloc_handle_num_of_planes(h)
+
+/*
+ * Return ion fd at index 'n'.
+ *
+ * When iterating through the fds, an fd with value < 0 indicates the start
+ * of the unused fd entries.
+ */
+#define GET_ION_FD(h, n) h->export_fds[n]
+
+/*
+ * Return pvr fd
+ */
+#define GET_PVR_FD(h) h->gpu_sync_fd
+
+#endif
+
+#endif /* _TI_HANDLE_WRAPPER_H_ */
diff --git a/include/hardware/gps.h b/include/hardware/gps.h
new file mode 100644
index 0000000..05b3b11
--- /dev/null
+++ b/include/hardware/gps.h
@@ -0,0 +1,686 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_INCLUDE_HARDWARE_GPS_H
+#define ANDROID_INCLUDE_HARDWARE_GPS_H
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <pthread.h>
+
+#include <hardware/hardware.h>
+
+__BEGIN_DECLS
+
+/**
+ * The id of this module
+ */
+#define GPS_HARDWARE_MODULE_ID "gps"
+
+
+/** Milliseconds since January 1, 1970 */
+typedef int64_t GpsUtcTime;
+
+/** Maximum number of SVs for gps_sv_status_callback(). */
+#define GPS_MAX_SVS 32
+
+/** Requested operational mode for GPS operation. */
+typedef uint32_t GpsPositionMode;
+// IMPORTANT: Note that the following values must match
+// constants in GpsLocationProvider.java.
+/** Mode for running GPS standalone (no assistance). */
+#define GPS_POSITION_MODE_STANDALONE 0
+/** AGPS MS-Based mode. */
+#define GPS_POSITION_MODE_MS_BASED 1
+/** AGPS MS-Assisted mode. */
+#define GPS_POSITION_MODE_MS_ASSISTED 2
+
+/** Requested recurrence mode for GPS operation. */
+typedef uint32_t GpsPositionRecurrence;
+// IMPORTANT: Note that the following values must match
+// constants in GpsLocationProvider.java.
+/** Receive GPS fixes on a recurring basis at a specified period. */
+#define GPS_POSITION_RECURRENCE_PERIODIC 0
+/** Request a single shot GPS fix. */
+#define GPS_POSITION_RECURRENCE_SINGLE 1
+
+/** GPS status event values. */
+typedef uint16_t GpsStatusValue;
+// IMPORTANT: Note that the following values must match
+// constants in GpsLocationProvider.java.
+/** GPS status unknown. */
+#define GPS_STATUS_NONE 0
+/** GPS has begun navigating. */
+#define GPS_STATUS_SESSION_BEGIN 1
+/** GPS has stopped navigating. */
+#define GPS_STATUS_SESSION_END 2
+/** GPS has powered on but is not navigating. */
+#define GPS_STATUS_ENGINE_ON 3
+/** GPS is powered off. */
+#define GPS_STATUS_ENGINE_OFF 4
+
+/** Flags to indicate which values are valid in a GpsLocation. */
+typedef uint16_t GpsLocationFlags;
+// IMPORTANT: Note that the following values must match
+// constants in GpsLocationProvider.java.
+/** GpsLocation has valid latitude and longitude. */
+#define GPS_LOCATION_HAS_LAT_LONG 0x0001
+/** GpsLocation has valid altitude. */
+#define GPS_LOCATION_HAS_ALTITUDE 0x0002
+/** GpsLocation has valid speed. */
+#define GPS_LOCATION_HAS_SPEED 0x0004
+/** GpsLocation has valid bearing. */
+#define GPS_LOCATION_HAS_BEARING 0x0008
+/** GpsLocation has valid accuracy. */
+#define GPS_LOCATION_HAS_ACCURACY 0x0010
+
+/** Flags for the gps_set_capabilities callback. */
+
+/** GPS HAL schedules fixes for GPS_POSITION_RECURRENCE_PERIODIC mode.
+ If this is not set, then the framework will use 1000ms for min_interval
+ and will start and call start() and stop() to schedule the GPS.
+ */
+#define GPS_CAPABILITY_SCHEDULING 0x0000001
+/** GPS supports MS-Based AGPS mode */
+#define GPS_CAPABILITY_MSB 0x0000002
+/** GPS supports MS-Assisted AGPS mode */
+#define GPS_CAPABILITY_MSA 0x0000004
+/** GPS supports single-shot fixes */
+#define GPS_CAPABILITY_SINGLE_SHOT 0x0000008
+/** GPS supports on demand time injection */
+#define GPS_CAPABILITY_ON_DEMAND_TIME 0x0000010
+
+/** Flags used to specify which aiding data to delete
+ when calling delete_aiding_data(). */
+typedef uint16_t GpsAidingData;
+// IMPORTANT: Note that the following values must match
+// constants in GpsLocationProvider.java.
+#define GPS_DELETE_EPHEMERIS 0x0001
+#define GPS_DELETE_ALMANAC 0x0002
+#define GPS_DELETE_POSITION 0x0004
+#define GPS_DELETE_TIME 0x0008
+#define GPS_DELETE_IONO 0x0010
+#define GPS_DELETE_UTC 0x0020
+#define GPS_DELETE_HEALTH 0x0040
+#define GPS_DELETE_SVDIR 0x0080
+#define GPS_DELETE_SVSTEER 0x0100
+#define GPS_DELETE_SADATA 0x0200
+#define GPS_DELETE_RTI 0x0400
+#define GPS_DELETE_CELLDB_INFO 0x8000
+#define GPS_DELETE_ALL 0xFFFF
+
+/** AGPS type */
+typedef uint16_t AGpsType;
+#define AGPS_TYPE_SUPL 1
+#define AGPS_TYPE_C2K 2
+
+typedef uint16_t AGpsSetIDType;
+#define AGPS_SETID_TYPE_NONE 0
+#define AGPS_SETID_TYPE_IMSI 1
+#define AGPS_SETID_TYPE_MSISDN 2
+
+/**
+ * String length constants
+ */
+#define GPS_NI_SHORT_STRING_MAXLEN 256
+#define GPS_NI_LONG_STRING_MAXLEN 2048
+
+/**
+ * GpsNiType constants
+ */
+typedef uint32_t GpsNiType;
+#define GPS_NI_TYPE_VOICE 1
+#define GPS_NI_TYPE_UMTS_SUPL 2
+#define GPS_NI_TYPE_UMTS_CTRL_PLANE 3
+
+/**
+ * GpsNiNotifyFlags constants
+ */
+typedef uint32_t GpsNiNotifyFlags;
+/** NI requires notification */
+#define GPS_NI_NEED_NOTIFY 0x0001
+/** NI requires verification */
+#define GPS_NI_NEED_VERIFY 0x0002
+/** NI requires privacy override, no notification/minimal trace */
+#define GPS_NI_PRIVACY_OVERRIDE 0x0004
+
+/**
+ * GPS NI responses, used to define the response in
+ * NI structures
+ */
+typedef int GpsUserResponseType;
+#define GPS_NI_RESPONSE_ACCEPT 1
+#define GPS_NI_RESPONSE_DENY 2
+#define GPS_NI_RESPONSE_NORESP 3
+
+/**
+ * NI data encoding scheme
+ */
+typedef int GpsNiEncodingType;
+#define GPS_ENC_NONE 0
+#define GPS_ENC_SUPL_GSM_DEFAULT 1
+#define GPS_ENC_SUPL_UTF8 2
+#define GPS_ENC_SUPL_UCS2 3
+#define GPS_ENC_UNKNOWN -1
+
+/** AGPS status event values. */
+typedef uint16_t AGpsStatusValue;
+/** GPS requests data connection for AGPS. */
+#define GPS_REQUEST_AGPS_DATA_CONN 1
+/** GPS releases the AGPS data connection. */
+#define GPS_RELEASE_AGPS_DATA_CONN 2
+/** AGPS data connection initiated */
+#define GPS_AGPS_DATA_CONNECTED 3
+/** AGPS data connection completed */
+#define GPS_AGPS_DATA_CONN_DONE 4
+/** AGPS data connection failed */
+#define GPS_AGPS_DATA_CONN_FAILED 5
+
+#define AGPS_REF_LOCATION_TYPE_GSM_CELLID 1
+#define AGPS_REF_LOCATION_TYPE_UMTS_CELLID 2
+#define AGPS_REG_LOCATION_TYPE_MAC 3
+
+/** Network types for update_network_state "type" parameter */
+#define AGPS_RIL_NETWORK_TYPE_MOBILE 0
+#define AGPS_RIL_NETWORK_TYPE_WIFI 1
+#define AGPS_RIL_NETWORK_TYPE_MOBILE_MMS 2
+#define AGPS_RIL_NETWORK_TYPE_MOBILE_SUPL 3
+#define AGPS_RIL_NETWORK_TTYPE_MOBILE_DUN 4
+#define AGPS_RIL_NETWORK_TTYPE_MOBILE_HIPRI 5
+#define AGPS_RIL_NETWORK_TTYPE_WIMAX 6
+
+/**
+ * Name for the GPS XTRA interface.
+ */
+#define GPS_XTRA_INTERFACE "gps-xtra"
+
+/**
+ * Name for the GPS DEBUG interface.
+ */
+#define GPS_DEBUG_INTERFACE "gps-debug"
+
+/**
+ * Name for the AGPS interface.
+ */
+#define AGPS_INTERFACE "agps"
+
+/**
+ * Name for NI interface
+ */
+#define GPS_NI_INTERFACE "gps-ni"
+
+/**
+ * Name for the AGPS-RIL interface.
+ */
+#define AGPS_RIL_INTERFACE "agps_ril"
+
+/** Represents a location. */
+typedef struct {
+ /** set to sizeof(GpsLocation) */
+ size_t size;
+ /** Contains GpsLocationFlags bits. */
+ uint16_t flags;
+ /** Represents latitude in degrees. */
+ double latitude;
+ /** Represents longitude in degrees. */
+ double longitude;
+ /** Represents altitude in meters above the WGS 84 reference
+ * ellipsoid. */
+ double altitude;
+ /** Represents speed in meters per second. */
+ float speed;
+ /** Represents heading in degrees. */
+ float bearing;
+ /** Represents expected accuracy in meters. */
+ float accuracy;
+ /** Timestamp for the location fix. */
+ GpsUtcTime timestamp;
+} GpsLocation;
+
+/** Represents the status. */
+typedef struct {
+ /** set to sizeof(GpsStatus) */
+ size_t size;
+ GpsStatusValue status;
+} GpsStatus;
+
+/** Represents SV information. */
+typedef struct {
+ /** set to sizeof(GpsSvInfo) */
+ size_t size;
+ /** Pseudo-random number for the SV. */
+ int prn;
+ /** Signal to noise ratio. */
+ float snr;
+ /** Elevation of SV in degrees. */
+ float elevation;
+ /** Azimuth of SV in degrees. */
+ float azimuth;
+ /** Unknown field in Samsung I9100 libgps
+ May be an indicator for constellation type
+ (GPS, GLONASS, Galileo)?
+ Used on GT-I9100, likely also present on GT-N7000,
+ SGH-I717, SGH-I727 but this needs confirmation.
+ */
+ int unknown_samsung_field;
+} GpsSvInfo;
+
+/** Represents SV status. */
+typedef struct {
+ /** set to sizeof(GpsSvStatus) */
+ size_t size;
+
+ /** Number of SVs currently visible. */
+ int num_svs;
+
+ /** Contains an array of SV information. */
+ GpsSvInfo sv_list[GPS_MAX_SVS];
+
+ /** Represents a bit mask indicating which SVs
+ * have ephemeris data.
+ */
+ uint32_t ephemeris_mask;
+
+ /** Represents a bit mask indicating which SVs
+ * have almanac data.
+ */
+ uint32_t almanac_mask;
+
+ /**
+ * Represents a bit mask indicating which SVs
+ * were used for computing the most recent position fix.
+ */
+ uint32_t used_in_fix_mask;
+} GpsSvStatus;
+
+/* 2G and 3G */
+/* In 3G lac is discarded */
+typedef struct {
+ uint16_t type;
+ uint16_t mcc;
+ uint16_t mnc;
+ uint16_t lac;
+ uint32_t cid;
+} AGpsRefLocationCellID;
+
+typedef struct {
+ uint8_t mac[6];
+} AGpsRefLocationMac;
+
+/** Represents ref locations */
+typedef struct {
+ uint16_t type;
+ union {
+ AGpsRefLocationCellID cellID;
+ AGpsRefLocationMac mac;
+ } u;
+} AGpsRefLocation;
+
+/** Callback with location information.
+ * Can only be called from a thread created by create_thread_cb.
+ */
+typedef void (* gps_location_callback)(GpsLocation* location);
+
+/** Callback with status information.
+ * Can only be called from a thread created by create_thread_cb.
+ */
+typedef void (* gps_status_callback)(GpsStatus* status);
+
+/** Callback with SV status information.
+ * Can only be called from a thread created by create_thread_cb.
+ */
+typedef void (* gps_sv_status_callback)(GpsSvStatus* sv_info);
+
+/** Callback for reporting NMEA sentences.
+ * Can only be called from a thread created by create_thread_cb.
+ */
+typedef void (* gps_nmea_callback)(GpsUtcTime timestamp, const char* nmea, int length);
+
+/** Callback to inform framework of the GPS engine's capabilities.
+ * Capability parameter is a bit field of GPS_CAPABILITY_* flags.
+ */
+typedef void (* gps_set_capabilities)(uint32_t capabilities);
+
+/** Callback utility for acquiring the GPS wakelock.
+ * This can be used to prevent the CPU from suspending while handling GPS events.
+ */
+typedef void (* gps_acquire_wakelock)();
+
+/** Callback utility for releasing the GPS wakelock. */
+typedef void (* gps_release_wakelock)();
+
+/** Callback for requesting NTP time */
+typedef void (* gps_request_utc_time)();
+
+/** Callback for creating a thread that can call into the Java framework code.
+ * This must be used to create any threads that report events up to the framework.
+ */
+typedef pthread_t (* gps_create_thread)(const char* name, void (*start)(void *), void* arg);
+
+/** GPS callback structure. */
+typedef struct {
+ /** set to sizeof(GpsCallbacks) */
+ size_t size;
+ gps_location_callback location_cb;
+ gps_status_callback status_cb;
+ gps_sv_status_callback sv_status_cb;
+ gps_nmea_callback nmea_cb;
+ gps_set_capabilities set_capabilities_cb;
+ gps_acquire_wakelock acquire_wakelock_cb;
+ gps_release_wakelock release_wakelock_cb;
+ gps_create_thread create_thread_cb;
+ gps_request_utc_time request_utc_time_cb;
+} GpsCallbacks;
+
+
+/** Represents the standard GPS interface. */
+typedef struct {
+ /** set to sizeof(GpsInterface) */
+ size_t size;
+ /**
+ * Opens the interface and provides the callback routines
+ * to the implemenation of this interface.
+ */
+ int (*init)( GpsCallbacks* callbacks );
+
+ /** Starts navigating. */
+ int (*start)( void );
+
+ /** Stops navigating. */
+ int (*stop)( void );
+
+ /** Closes the interface. */
+ void (*cleanup)( void );
+
+ /** Injects the current time. */
+ int (*inject_time)(GpsUtcTime time, int64_t timeReference,
+ int uncertainty);
+
+ /** Injects current location from another location provider
+ * (typically cell ID).
+ * latitude and longitude are measured in degrees
+ * expected accuracy is measured in meters
+ */
+ int (*inject_location)(double latitude, double longitude, float accuracy);
+
+ /**
+ * Specifies that the next call to start will not use the
+ * information defined in the flags. GPS_DELETE_ALL is passed for
+ * a cold start.
+ */
+ void (*delete_aiding_data)(GpsAidingData flags);
+
+ /**
+ * min_interval represents the time between fixes in milliseconds.
+ * preferred_accuracy represents the requested fix accuracy in meters.
+ * preferred_time represents the requested time to first fix in milliseconds.
+ */
+ int (*set_position_mode)(GpsPositionMode mode, GpsPositionRecurrence recurrence,
+ uint32_t min_interval, uint32_t preferred_accuracy, uint32_t preferred_time);
+
+ /** Get a pointer to extension information. */
+ const void* (*get_extension)(const char* name);
+} GpsInterface;
+
+/** Callback to request the client to download XTRA data.
+ * The client should download XTRA data and inject it by calling inject_xtra_data().
+ * Can only be called from a thread created by create_thread_cb.
+ */
+typedef void (* gps_xtra_download_request)();
+
+/** Callback structure for the XTRA interface. */
+typedef struct {
+ gps_xtra_download_request download_request_cb;
+ gps_create_thread create_thread_cb;
+} GpsXtraCallbacks;
+
+/** Extended interface for XTRA support. */
+typedef struct {
+ /** set to sizeof(GpsXtraInterface) */
+ size_t size;
+ /**
+ * Opens the XTRA interface and provides the callback routines
+ * to the implemenation of this interface.
+ */
+ int (*init)( GpsXtraCallbacks* callbacks );
+ /** Injects XTRA data into the GPS. */
+ int (*inject_xtra_data)( char* data, int length );
+} GpsXtraInterface;
+
+/** Extended interface for DEBUG support. */
+typedef struct {
+ /** set to sizeof(GpsDebugInterface) */
+ size_t size;
+
+ /**
+ * This function should return any information that the native
+ * implementation wishes to include in a bugreport.
+ */
+ size_t (*get_internal_state)(char* buffer, size_t bufferSize);
+} GpsDebugInterface;
+
+/** Represents the status of AGPS. */
+typedef struct {
+ /** set to sizeof(AGpsStatus) */
+ size_t size;
+
+ AGpsType type;
+ AGpsStatusValue status;
+ uint32_t ipaddr;
+} AGpsStatus;
+
+/** Callback with AGPS status information.
+ * Can only be called from a thread created by create_thread_cb.
+ */
+typedef void (* agps_status_callback)(AGpsStatus* status);
+
+/** Callback structure for the AGPS interface. */
+typedef struct {
+ agps_status_callback status_cb;
+ gps_create_thread create_thread_cb;
+} AGpsCallbacks;
+
+
+/** Extended interface for AGPS support. */
+typedef struct {
+ /** set to sizeof(AGpsInterface) */
+ size_t size;
+
+ /**
+ * Opens the AGPS interface and provides the callback routines
+ * to the implemenation of this interface.
+ */
+ void (*init)( AGpsCallbacks* callbacks );
+ /**
+ * Notifies that a data connection is available and sets
+ * the name of the APN to be used for SUPL.
+ */
+ int (*data_conn_open)( const char* apn );
+ /**
+ * Notifies that the AGPS data connection has been closed.
+ */
+ int (*data_conn_closed)();
+ /**
+ * Notifies that a data connection is not available for AGPS.
+ */
+ int (*data_conn_failed)();
+ /**
+ * Sets the hostname and port for the AGPS server.
+ */
+ int (*set_server)( AGpsType type, const char* hostname, int port );
+} AGpsInterface;
+
+
+/** Represents an NI request */
+typedef struct {
+ /** set to sizeof(GpsNiNotification) */
+ size_t size;
+
+ /**
+ * An ID generated by HAL to associate NI notifications and UI
+ * responses
+ */
+ int notification_id;
+
+ /**
+ * An NI type used to distinguish different categories of NI
+ * events, such as GPS_NI_TYPE_VOICE, GPS_NI_TYPE_UMTS_SUPL, ...
+ */
+ GpsNiType ni_type;
+
+ /**
+ * Notification/verification options, combinations of GpsNiNotifyFlags constants
+ */
+ GpsNiNotifyFlags notify_flags;
+
+ /**
+ * Timeout period to wait for user response.
+ * Set to 0 for no time out limit.
+ */
+ int timeout;
+
+ /**
+ * Default response when time out.
+ */
+ GpsUserResponseType default_response;
+
+ /**
+ * Requestor ID
+ */
+ char requestor_id[GPS_NI_SHORT_STRING_MAXLEN];
+
+ /**
+ * Notification message. It can also be used to store client_id in some cases
+ */
+ char text[GPS_NI_LONG_STRING_MAXLEN];
+
+ /**
+ * Client name decoding scheme
+ */
+ GpsNiEncodingType requestor_id_encoding;
+
+ /**
+ * Client name decoding scheme
+ */
+ GpsNiEncodingType text_encoding;
+
+ /**
+ * A pointer to extra data. Format:
+ * key_1 = value_1
+ * key_2 = value_2
+ */
+ char extras[GPS_NI_LONG_STRING_MAXLEN];
+
+} GpsNiNotification;
+
+/** Callback with NI notification.
+ * Can only be called from a thread created by create_thread_cb.
+ */
+typedef void (*gps_ni_notify_callback)(GpsNiNotification *notification);
+
+/** GPS NI callback structure. */
+typedef struct
+{
+ /**
+ * Sends the notification request from HAL to GPSLocationProvider.
+ */
+ gps_ni_notify_callback notify_cb;
+ gps_create_thread create_thread_cb;
+} GpsNiCallbacks;
+
+/**
+ * Extended interface for Network-initiated (NI) support.
+ */
+typedef struct
+{
+ /** set to sizeof(GpsNiInterface) */
+ size_t size;
+
+ /** Registers the callbacks for HAL to use. */
+ void (*init) (GpsNiCallbacks *callbacks);
+
+ /** Sends a response to HAL. */
+ void (*respond) (int notif_id, GpsUserResponseType user_response);
+} GpsNiInterface;
+
+struct gps_device_t {
+ struct hw_device_t common;
+
+ /**
+ * Set the provided lights to the provided values.
+ *
+ * Returns: 0 on succes, error code on failure.
+ */
+ const GpsInterface* (*get_gps_interface)(struct gps_device_t* dev);
+};
+
+#define AGPS_RIL_REQUEST_SETID_IMSI (1<<0L)
+#define AGPS_RIL_REQUEST_SETID_MSISDN (1<<1L)
+
+#define AGPS_RIL_REQUEST_REFLOC_CELLID (1<<0L)
+#define AGPS_RIL_REQUEST_REFLOC_MAC (1<<1L)
+
+typedef void (*agps_ril_request_set_id)(uint32_t flags);
+typedef void (*agps_ril_request_ref_loc)(uint32_t flags);
+
+typedef struct {
+ agps_ril_request_set_id request_setid;
+ agps_ril_request_ref_loc request_refloc;
+ gps_create_thread create_thread_cb;
+} AGpsRilCallbacks;
+
+/** Extended interface for AGPS_RIL support. */
+typedef struct {
+ /** set to sizeof(AGpsRilInterface) */
+ size_t size;
+ /**
+ * Opens the AGPS interface and provides the callback routines
+ * to the implemenation of this interface.
+ */
+ void (*init)( AGpsRilCallbacks* callbacks );
+
+ /**
+ * Sets the reference location.
+ */
+ void (*set_ref_location) (const AGpsRefLocation *agps_reflocation, size_t sz_struct);
+ /**
+ * Sets the set ID.
+ */
+ void (*set_set_id) (AGpsSetIDType type, const char* setid);
+
+ /**
+ * Send network initiated message.
+ */
+ void (*ni_message) (uint8_t *msg, size_t len);
+
+ /**
+ * Notify GPS of network status changes.
+ * These parameters match values in the android.net.NetworkInfo class.
+ */
+ void (*update_network_state) (int connected, int type, int roaming, const char* extra_info);
+
+ /**
+ * Notify GPS of network status changes.
+ * These parameters match values in the android.net.NetworkInfo class.
+ */
+ void (*update_network_availability) (int avaiable, const char* apn);
+} AGpsRilInterface;
+
+__END_DECLS
+
+#endif /* ANDROID_INCLUDE_HARDWARE_GPS_H */
+
diff --git a/include/hardware/hwcomposer.h b/include/hardware/hwcomposer.h
new file mode 100644
index 0000000..6dff3eb
--- /dev/null
+++ b/include/hardware/hwcomposer.h
@@ -0,0 +1,643 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_H
+#define ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_H
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+#include <hardware/gralloc.h>
+#include <hardware/hardware.h>
+#include <cutils/native_handle.h>
+
+#include <hardware/hwcomposer_defs.h>
+
+__BEGIN_DECLS
+
+/*****************************************************************************/
+
+/* for compatibility */
+#define HWC_MODULE_API_VERSION HWC_MODULE_API_VERSION_0_1
+#define HWC_DEVICE_API_VERSION HWC_DEVICE_API_VERSION_0_1
+#define HWC_API_VERSION HWC_DEVICE_API_VERSION
+
+/* Users of this header can define HWC_REMOVE_DEPRECATED_VERSIONS to test that
+ * they still work with just the current version declared, before the
+ * deprecated versions are actually removed.
+ *
+ * To find code that still depends on the old versions, set the #define to 1
+ * here. Code that explicitly sets it to zero (rather than simply not defining
+ * it) will still see the old versions.
+ */
+#if !defined(HWC_REMOVE_DEPRECATED_VERSIONS)
+#define HWC_REMOVE_DEPRECATED_VERSIONS 0
+#endif
+
+/*****************************************************************************/
+
+/**
+ * The id of this module
+ */
+#define HWC_HARDWARE_MODULE_ID "hwcomposer"
+
+/**
+ * Name of the sensors device to open
+ */
+#define HWC_HARDWARE_COMPOSER "composer"
+
+typedef struct hwc_rect {
+ int left;
+ int top;
+ int right;
+ int bottom;
+} hwc_rect_t;
+
+typedef struct hwc_region {
+ size_t numRects;
+ hwc_rect_t const* rects;
+} hwc_region_t;
+
+typedef struct hwc_color {
+ uint8_t r;
+ uint8_t g;
+ uint8_t b;
+ uint8_t a;
+} hwc_color_t;
+
+typedef struct hwc_layer_1 {
+ /*
+ * Initially set to HWC_FRAMEBUFFER, HWC_BACKGROUND, or
+ * HWC_FRAMEBUFFER_TARGET.
+ *
+ * HWC_FRAMEBUFFER
+ * Indicates the layer will be drawn into the framebuffer
+ * using OpenGL ES. The HWC can toggle this value to HWC_OVERLAY to
+ * indicate it will handle the layer.
+ *
+ * HWC_BACKGROUND
+ * Indicates this is a special "background" layer. The only valid field
+ * is backgroundColor. The HWC can toggle this value to HWC_FRAMEBUFFER
+ * to indicate it CANNOT handle the background color.
+ *
+ * HWC_FRAMEBUFFER_TARGET
+ * Indicates this layer is the framebuffer surface used as the target of
+ * OpenGL ES composition. If the HWC sets all other layers to HWC_OVERLAY
+ * or HWC_BACKGROUND, then no OpenGL ES composition will be done, and
+ * this layer should be ignored during set().
+ *
+ * This flag (and the framebuffer surface layer) will only be used if the
+ * HWC version is HWC_DEVICE_API_VERSION_1_1 or higher. In older versions,
+ * the OpenGL ES target surface is communicated by the (dpy, sur) fields
+ * in hwc_compositor_device_1_t.
+ */
+ int32_t compositionType;
+
+ /* see hwc_layer_t::hints above */
+ uint32_t hints;
+
+ /* see hwc_layer_t::flags above */
+ uint32_t flags;
+
+ union {
+ /* color of the background. hwc_color_t.a is ignored */
+ hwc_color_t backgroundColor;
+
+ struct {
+ /* handle of buffer to compose. This handle is guaranteed to have been
+ * allocated from gralloc using the GRALLOC_USAGE_HW_COMPOSER usage flag. If
+ * the layer's handle is unchanged across two consecutive prepare calls and
+ * the HWC_GEOMETRY_CHANGED flag is not set for the second call then the
+ * HWComposer implementation may assume that the contents of the buffer have
+ * not changed. */
+ buffer_handle_t handle;
+
+ /* transformation to apply to the buffer during composition */
+ uint32_t transform;
+
+ /* blending to apply during composition */
+ int32_t blending;
+
+ /* area of the source to consider, the origin is the top-left corner of
+ * the buffer */
+ hwc_rect_t sourceCrop;
+
+ /* where to composite the sourceCrop onto the display. The sourceCrop
+ * is scaled using linear filtering to the displayFrame. The origin is the
+ * top-left corner of the screen.
+ */
+ hwc_rect_t displayFrame;
+
+ /* visible region in screen space. The origin is the
+ * top-left corner of the screen.
+ * The visible region INCLUDES areas overlapped by a translucent layer.
+ */
+ hwc_region_t visibleRegionScreen;
+
+ /* Sync fence object that will be signaled when the buffer's
+ * contents are available. May be -1 if the contents are already
+ * available. This field is only valid during set(), and should be
+ * ignored during prepare(). The set() call must not wait for the
+ * fence to be signaled before returning, but the HWC must wait for
+ * all buffers to be signaled before reading from them.
+ *
+ * HWC_FRAMEBUFFER layers will never have an acquire fence, since
+ * reads from them are complete before the framebuffer is ready for
+ * display.
+ *
+ * The HWC takes ownership of the acquireFenceFd and is responsible
+ * for closing it when no longer needed.
+ */
+ int acquireFenceFd;
+
+ /* During set() the HWC must set this field to a file descriptor for
+ * a sync fence object that will signal after the HWC has finished
+ * reading from the buffer. The field is ignored by prepare(). Each
+ * layer should have a unique file descriptor, even if more than one
+ * refer to the same underlying fence object; this allows each to be
+ * closed independently.
+ *
+ * If buffer reads can complete at significantly different times,
+ * then using independent fences is preferred. For example, if the
+ * HWC handles some layers with a blit engine and others with
+ * overlays, then the blit layers can be reused immediately after
+ * the blit completes, but the overlay layers can't be reused until
+ * a subsequent frame has been displayed.
+ *
+ * Since HWC doesn't read from HWC_FRAMEBUFFER layers, it shouldn't
+ * produce a release fence for them. The releaseFenceFd will be -1
+ * for these layers when set() is called.
+ *
+ * The HWC client taks ownership of the releaseFenceFd and is
+ * responsible for closing it when no longer needed.
+ */
+ int releaseFenceFd;
+ };
+ };
+
+ /* Allow for expansion w/o breaking binary compatibility.
+ * Pad layer to 96 bytes, assuming 32-bit pointers.
+ */
+ int32_t reserved[24 - 18];
+
+} hwc_layer_1_t;
+
+#ifdef OMAP_ENHANCEMENT
+
+/*
+ * HWC extension operations, see HWC_EXTENDED_API
+ */
+enum {
+ /*
+ * Get extra layer data
+ * @params
+ * data: hwc_layer_extended_t
+ */
+ HWC_EXTENDED_OP_LAYERDATA = 1,
+
+ /*
+ * Returns layer stack identifier
+ * @params
+ * data: hwc_layer_stack_t
+ */
+ HWC_EXTENDED_OP_LAYERSTACK = 2,
+};
+
+typedef struct hwc_layer_extended {
+ /*
+ * Layer index (input)
+ */
+ uint32_t idx;
+
+ /*
+ * Display index (input)
+ */
+ int32_t dpy;
+
+ /*
+ * Provides a unique identity for this layer (output)
+ */
+ uint32_t identity;
+} hwc_layer_extended_t;
+
+typedef struct hwc_layer_stack {
+ /*
+ * Display index (input)
+ */
+ int32_t dpy;
+
+ /*
+ * Layer stack identifier for this display (output)
+ */
+ uint32_t stack;
+} hwc_layer_stack_t;
+
+typedef struct hwc_layer_list_extended {
+ size_t numHwLayers;
+ hwc_layer_extended_t hwLayers[0];
+} hwc_layer_list_extended_t;
+
+#endif
+
+/* This represents a display, typically an EGLDisplay object */
+typedef void* hwc_display_t;
+
+/* This represents a surface, typically an EGLSurface object */
+typedef void* hwc_surface_t;
+
+/*
+ * hwc_display_contents_1_t::flags values
+ */
+enum {
+ /*
+ * HWC_GEOMETRY_CHANGED is set by SurfaceFlinger to indicate that the list
+ * passed to (*prepare)() has changed by more than just the buffer handles
+ * and acquire fences.
+ */
+ HWC_GEOMETRY_CHANGED = 0x00000001,
+#ifdef OMAP_ENHANCEMENT
+ /*
+ * HWC_EXTENDED_API is set by SurfaceFlinger to indicate that the h/w
+ * composer HAL api has been extended and that the HAL implementation
+ * can use functions in the extended ABI.
+ */
+ HWC_EXTENDED_API = 0x80000000,
+#endif
+};
+
+/*
+ * Description of the contents to output on a display.
+ *
+ * This is the top-level structure passed to the prepare and set calls to
+ * negotiate and commit the composition of a display image.
+ */
+typedef struct hwc_display_contents_1 {
+ /* File descriptor referring to a Sync HAL fence object which will signal
+ * when this composition is retired. For a physical display, a composition
+ * is retired when it has been replaced on-screen by a subsequent set. For
+ * a virtual display, the composition is retired when the writes to
+ * outputBuffer are complete and can be read. The fence object is created
+ * and returned by the set call; this field will be -1 on entry to prepare
+ * and set. SurfaceFlinger will close the returned file descriptor.
+ */
+ int retireFenceFd;
+
+ union {
+ /* Fields only relevant for HWC_DEVICE_VERSION_1_0. */
+ struct {
+ /* (dpy, sur) is the target of SurfaceFlinger's OpenGL ES
+ * composition for HWC_DEVICE_VERSION_1_0. They aren't relevant to
+ * prepare. The set call should commit this surface atomically to
+ * the display along with any overlay layers.
+ */
+ hwc_display_t dpy;
+ hwc_surface_t sur;
+ };
+
+ /* Fields only relevant for HWC_DEVICE_VERSION_1_2 and later. */
+ struct {
+ /* outbuf is the buffer that receives the composed image for
+ * virtual displays. Writes to the outbuf must wait until
+ * outbufAcquireFenceFd signals. A fence that will signal when
+ * writes to outbuf are complete should be returned in
+ * retireFenceFd.
+ *
+ * For physical displays, outbuf will be NULL.
+ */
+ buffer_handle_t outbuf;
+
+ /* File descriptor for a fence that will signal when outbuf is
+ * ready to be written. The h/w composer is responsible for closing
+ * this when no longer needed.
+ *
+ * Will be -1 whenever outbuf is NULL, or when the outbuf can be
+ * written immediately.
+ */
+ int outbufAcquireFenceFd;
+ };
+ };
+
+ /* List of layers that will be composed on the display. The buffer handles
+ * in the list will be unique. If numHwLayers is 0, all composition will be
+ * performed by SurfaceFlinger.
+ */
+ uint32_t flags;
+ size_t numHwLayers;
+ hwc_layer_1_t hwLayers[0];
+
+} hwc_display_contents_1_t;
+
+/* see hwc_composer_device::registerProcs()
+ * All of the callbacks are required and non-NULL unless otherwise noted.
+ */
+typedef struct hwc_procs {
+ /*
+ * (*invalidate)() triggers a screen refresh, in particular prepare and set
+ * will be called shortly after this call is made. Note that there is
+ * NO GUARANTEE that the screen refresh will happen after invalidate()
+ * returns (in particular, it could happen before).
+ * invalidate() is GUARANTEED TO NOT CALL BACK into the h/w composer HAL and
+ * it is safe to call invalidate() from any of hwc_composer_device
+ * hooks, unless noted otherwise.
+ */
+ void (*invalidate)(const struct hwc_procs* procs);
+
+ /*
+ * (*vsync)() is called by the h/w composer HAL when a vsync event is
+ * received and HWC_EVENT_VSYNC is enabled on a display
+ * (see: hwc_event_control).
+ *
+ * the "disp" parameter indicates which display the vsync event is for.
+ * the "timestamp" parameter is the system monotonic clock timestamp in
+ * nanosecond of when the vsync event happened.
+ *
+ * vsync() is GUARANTEED TO NOT CALL BACK into the h/w composer HAL.
+ *
+ * It is expected that vsync() is called from a thread of at least
+ * HAL_PRIORITY_URGENT_DISPLAY with as little latency as possible,
+ * typically less than 0.5 ms.
+ *
+ * It is a (silent) error to have HWC_EVENT_VSYNC enabled when calling
+ * hwc_composer_device.set(..., 0, 0, 0) (screen off). The implementation
+ * can either stop or continue to process VSYNC events, but must not
+ * crash or cause other problems.
+ */
+ void (*vsync)(const struct hwc_procs* procs, int disp, int64_t timestamp);
+
+ /*
+ * (*hotplug)() is called by the h/w composer HAL when a display is
+ * connected or disconnected. The PRIMARY display is always connected and
+ * the hotplug callback should not be called for it.
+ *
+ * The disp parameter indicates which display type this event is for.
+ * The connected parameter indicates whether the display has just been
+ * connected (1) or disconnected (0).
+ *
+ * The hotplug() callback may call back into the h/w composer on the same
+ * thread to query refresh rate and dpi for the display. Additionally,
+ * other threads may be calling into the h/w composer while the callback
+ * is in progress.
+ *
+ * The h/w composer must serialize calls to the hotplug callback; only
+ * one thread may call it at a time.
+ *
+ * This callback will be NULL if the h/w composer is using
+ * HWC_DEVICE_API_VERSION_1_0.
+ */
+ void (*hotplug)(const struct hwc_procs* procs, int disp, int connected);
+
+#ifdef OMAP_ENHANCEMENT
+ /*
+ * (*extension_cb)() is called by the h/w composer HAL. Its purpose is
+ * to extend the api from h/w composer to SurfaceFlinger.
+ *
+ * In order to handle mismatching build configuration between
+ * SurfaceFlinger and the h/w composer HAL. The HAL will only call
+ * this callback if HWC_EXTENDED_API is passed in hwc_layer_list_t
+ * flags.
+ *
+ * The "operation" parameter specifies the specific extension required
+ * the caller and callee should maintain the ABI between each other in
+ * the same way as kernel ioctl calls do.
+ *
+ * If the "size" parameter is -1 a return value of zero indicates the
+ * given operation is supported.
+ */
+ int (*extension_cb)(struct hwc_procs* procs,
+ int operation,
+ void** data,
+ int size);
+
+#endif
+} hwc_procs_t;
+
+
+/*****************************************************************************/
+
+typedef struct hwc_module {
+ struct hw_module_t common;
+} hwc_module_t;
+
+typedef struct hwc_composer_device_1 {
+ struct hw_device_t common;
+
+ /*
+ * (*prepare)() is called for each frame before composition and is used by
+ * SurfaceFlinger to determine what composition steps the HWC can handle.
+ *
+ * (*prepare)() can be called more than once, the last call prevails.
+ *
+ * The HWC responds by setting the compositionType field in each layer to
+ * either HWC_FRAMEBUFFER or HWC_OVERLAY. In the former case, the
+ * composition for the layer is handled by SurfaceFlinger with OpenGL ES,
+ * in the later case, the HWC will have to handle the layer's composition.
+ *
+ * (*prepare)() is called with HWC_GEOMETRY_CHANGED to indicate that the
+ * list's geometry has changed, that is, when more than just the buffer's
+ * handles have been updated. Typically this happens (but is not limited to)
+ * when a window is added, removed, resized or moved.
+ *
+ * For HWC 1.0, numDisplays will always be one, and displays[0] will be
+ * non-NULL.
+ *
+ * For HWC 1.1, numDisplays will always be HWC_NUM_DISPLAY_TYPES. Entries
+ * for unsupported or disabled/disconnected display types will be NULL.
+ *
+ * For HWC 1.2 and later, numDisplays will be HWC_NUM_DISPLAY_TYPES or more.
+ * The extra entries correspond to enabled virtual displays, and will be
+ * non-NULL. In HWC 1.2, support for one virtual display is required, and
+ * no more than one will be used. Future HWC versions might require more.
+ *
+ * returns: 0 on success. An negative error code on error. If an error is
+ * returned, SurfaceFlinger will assume that none of the layer will be
+ * handled by the HWC.
+ */
+ int (*prepare)(struct hwc_composer_device_1 *dev,
+ size_t numDisplays, hwc_display_contents_1_t** displays);
+
+ /*
+ * (*set)() is used in place of eglSwapBuffers(), and assumes the same
+ * functionality, except it also commits the work list atomically with
+ * the actual eglSwapBuffers().
+ *
+ * The layer lists are guaranteed to be the same as the ones returned from
+ * the last call to (*prepare)().
+ *
+ * When this call returns the caller assumes that the displays will be
+ * updated in the near future with the content of their work lists, without
+ * artifacts during the transition from the previous frame.
+ *
+ * A display with zero layers indicates that the entire composition has
+ * been handled by SurfaceFlinger with OpenGL ES. In this case, (*set)()
+ * behaves just like eglSwapBuffers().
+ *
+ * For HWC 1.0, numDisplays will always be one, and displays[0] will be
+ * non-NULL.
+ *
+ * For HWC 1.1, numDisplays will always be HWC_NUM_DISPLAY_TYPES. Entries
+ * for unsupported or disabled/disconnected display types will be NULL.
+ *
+ * For HWC 1.2 and later, numDisplays will be HWC_NUM_DISPLAY_TYPES or more.
+ * The extra entries correspond to enabled virtual displays, and will be
+ * non-NULL. In HWC 1.2, support for one virtual display is required, and
+ * no more than one will be used. Future HWC versions might require more.
+ *
+ * IMPORTANT NOTE: There is an implicit layer containing opaque black
+ * pixels behind all the layers in the list. It is the responsibility of
+ * the hwcomposer module to make sure black pixels are output (or blended
+ * from).
+ *
+ * IMPORTANT NOTE: In the event of an error this call *MUST* still cause
+ * any fences returned in the previous call to set to eventually become
+ * signaled. The caller may have already issued wait commands on these
+ * fences, and having set return without causing those fences to signal
+ * will likely result in a deadlock.
+ *
+ * returns: 0 on success. A negative error code on error:
+ * HWC_EGL_ERROR: eglGetError() will provide the proper error code (only
+ * allowed prior to HWComposer 1.1)
+ * Another code for non EGL errors.
+ */
+ int (*set)(struct hwc_composer_device_1 *dev,
+ size_t numDisplays, hwc_display_contents_1_t** displays);
+
+ /*
+ * eventControl(..., event, enabled)
+ * Enables or disables h/w composer events for a display.
+ *
+ * eventControl can be called from any thread and takes effect
+ * immediately.
+ *
+ * Supported events are:
+ * HWC_EVENT_VSYNC
+ *
+ * returns -EINVAL if the "event" parameter is not one of the value above
+ * or if the "enabled" parameter is not 0 or 1.
+ */
+ int (*eventControl)(struct hwc_composer_device_1* dev, int disp,
+ int event, int enabled);
+
+ /*
+ * blank(..., blank)
+ * Blanks or unblanks a display's screen.
+ *
+ * Turns the screen off when blank is nonzero, on when blank is zero.
+ * Multiple sequential calls with the same blank value must be supported.
+ * The screen state transition must be be complete when the function
+ * returns.
+ *
+ * returns 0 on success, negative on error.
+ */
+ int (*blank)(struct hwc_composer_device_1* dev, int disp, int blank);
+
+ /*
+ * Used to retrieve information about the h/w composer
+ *
+ * Returns 0 on success or -errno on error.
+ */
+ int (*query)(struct hwc_composer_device_1* dev, int what, int* value);
+
+ /*
+ * (*registerProcs)() registers callbacks that the h/w composer HAL can
+ * later use. It will be called immediately after the composer device is
+ * opened with non-NULL procs. It is FORBIDDEN to call any of the callbacks
+ * from within registerProcs(). registerProcs() must save the hwc_procs_t
+ * pointer which is needed when calling a registered callback.
+ */
+ void (*registerProcs)(struct hwc_composer_device_1* dev,
+ hwc_procs_t const* procs);
+
+ /*
+ * This field is OPTIONAL and can be NULL.
+ *
+ * If non NULL it will be called by SurfaceFlinger on dumpsys
+ */
+ void (*dump)(struct hwc_composer_device_1* dev, char *buff, int buff_len);
+
+ /*
+ * (*getDisplayConfigs)() returns handles for the configurations available
+ * on the connected display. These handles must remain valid as long as the
+ * display is connected.
+ *
+ * Configuration handles are written to configs. The number of entries
+ * allocated by the caller is passed in *numConfigs; getDisplayConfigs must
+ * not try to write more than this number of config handles. On return, the
+ * total number of configurations available for the display is returned in
+ * *numConfigs. If *numConfigs is zero on entry, then configs may be NULL.
+ *
+ * HWC_DEVICE_API_VERSION_1_1 does not provide a way to choose a config.
+ * For displays that support multiple configurations, the h/w composer
+ * implementation should choose one and report it as the first config in
+ * the list. Reporting the not-chosen configs is not required.
+ *
+ * Returns 0 on success or -errno on error. If disp is a hotpluggable
+ * display type and no display is connected, an error should be returned.
+ *
+ * This field is REQUIRED for HWC_DEVICE_API_VERSION_1_1 and later.
+ * It should be NULL for previous versions.
+ */
+ int (*getDisplayConfigs)(struct hwc_composer_device_1* dev, int disp,
+ uint32_t* configs, size_t* numConfigs);
+
+ /*
+ * (*getDisplayAttributes)() returns attributes for a specific config of a
+ * connected display. The config parameter is one of the config handles
+ * returned by getDisplayConfigs.
+ *
+ * The list of attributes to return is provided in the attributes
+ * parameter, terminated by HWC_DISPLAY_NO_ATTRIBUTE. The value for each
+ * requested attribute is written in order to the values array. The
+ * HWC_DISPLAY_NO_ATTRIBUTE attribute does not have a value, so the values
+ * array will have one less value than the attributes array.
+ *
+ * This field is REQUIRED for HWC_DEVICE_API_VERSION_1_1 and later.
+ * It should be NULL for previous versions.
+ *
+ * If disp is a hotpluggable display type and no display is connected,
+ * or if config is not a valid configuration for the display, a negative
+ * value should be returned.
+ */
+ int (*getDisplayAttributes)(struct hwc_composer_device_1* dev, int disp,
+ uint32_t config, const uint32_t* attributes, int32_t* values);
+
+ /*
+ * Reserved for future use. Must be NULL.
+ */
+ void* reserved_proc[4];
+
+} hwc_composer_device_1_t;
+
+/** convenience API for opening and closing a device */
+
+static inline int hwc_open_1(const struct hw_module_t* module,
+ hwc_composer_device_1_t** device) {
+ return module->methods->open(module,
+ HWC_HARDWARE_COMPOSER, (struct hw_device_t**)device);
+}
+
+static inline int hwc_close_1(hwc_composer_device_1_t* device) {
+ return device->common.close(&device->common);
+}
+
+/*****************************************************************************/
+
+#if !HWC_REMOVE_DEPRECATED_VERSIONS
+#include <hardware/hwcomposer_v0.h>
+#endif
+
+__END_DECLS
+
+#endif /* ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_H */
diff --git a/include/hardware/hwcomposer_defs.h b/include/hardware/hwcomposer_defs.h
new file mode 100644
index 0000000..c611376
--- /dev/null
+++ b/include/hardware/hwcomposer_defs.h
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_DEFS_H
+#define ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_DEFS_H
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+#include <hardware/gralloc.h>
+#include <hardware/hardware.h>
+#include <cutils/native_handle.h>
+
+__BEGIN_DECLS
+
+/*****************************************************************************/
+
+#define HWC_HEADER_VERSION 1
+
+#define HWC_MODULE_API_VERSION_0_1 HARDWARE_MODULE_API_VERSION(0, 1)
+
+#define HWC_DEVICE_API_VERSION_0_1 HARDWARE_DEVICE_API_VERSION_2(0, 1, HWC_HEADER_VERSION)
+#define HWC_DEVICE_API_VERSION_0_2 HARDWARE_DEVICE_API_VERSION_2(0, 2, HWC_HEADER_VERSION)
+#define HWC_DEVICE_API_VERSION_0_3 HARDWARE_DEVICE_API_VERSION_2(0, 3, HWC_HEADER_VERSION)
+#define HWC_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION_2(1, 0, HWC_HEADER_VERSION)
+#define HWC_DEVICE_API_VERSION_1_1 HARDWARE_DEVICE_API_VERSION_2(1, 1, HWC_HEADER_VERSION)
+#define HWC_DEVICE_API_VERSION_1_2 HARDWARE_DEVICE_API_VERSION_2(1, 2, HWC_HEADER_VERSION)
+
+enum {
+ /* hwc_composer_device_t::set failed in EGL */
+ HWC_EGL_ERROR = -1
+};
+
+/*
+ * hwc_layer_t::hints values
+ * Hints are set by the HAL and read by SurfaceFlinger
+ */
+enum {
+ /*
+ * HWC can set the HWC_HINT_TRIPLE_BUFFER hint to indicate to SurfaceFlinger
+ * that it should triple buffer this layer. Typically HWC does this when
+ * the layer will be unavailable for use for an extended period of time,
+ * e.g. if the display will be fetching data directly from the layer and
+ * the layer can not be modified until after the next set().
+ */
+ HWC_HINT_TRIPLE_BUFFER = 0x00000001,
+
+ /*
+ * HWC sets HWC_HINT_CLEAR_FB to tell SurfaceFlinger that it should clear the
+ * framebuffer with transparent pixels where this layer would be.
+ * SurfaceFlinger will only honor this flag when the layer has no blending
+ *
+ */
+ HWC_HINT_CLEAR_FB = 0x00000002
+};
+
+/*
+ * hwc_layer_t::flags values
+ * Flags are set by SurfaceFlinger and read by the HAL
+ */
+enum {
+ /*
+ * HWC_SKIP_LAYER is set by SurfaceFlnger to indicate that the HAL
+ * shall not consider this layer for composition as it will be handled
+ * by SurfaceFlinger (just as if compositionType was set to HWC_OVERLAY).
+ */
+ HWC_SKIP_LAYER = 0x00000001,
+};
+
+/*
+ * hwc_layer_t::compositionType values
+ */
+enum {
+ /* this layer is to be drawn into the framebuffer by SurfaceFlinger */
+ HWC_FRAMEBUFFER = 0,
+
+ /* this layer will be handled in the HWC */
+ HWC_OVERLAY = 1,
+
+ /* this is the background layer. it's used to set the background color.
+ * there is only a single background layer */
+ HWC_BACKGROUND = 2,
+
+ /* this layer holds the result of compositing the HWC_FRAMEBUFFER layers.
+ * Added in HWC_DEVICE_API_VERSION_1_1. */
+ HWC_FRAMEBUFFER_TARGET = 3,
+
+ /* this layer will be handled in the HWC, using a blit engine */
+ HWC_BLIT = 4,
+};
+
+/*
+ * hwc_layer_t::blending values
+ */
+enum {
+ /* no blending */
+ HWC_BLENDING_NONE = 0x0100,
+
+ /* ONE / ONE_MINUS_SRC_ALPHA */
+ HWC_BLENDING_PREMULT = 0x0105,
+
+ /* SRC_ALPHA / ONE_MINUS_SRC_ALPHA */
+ HWC_BLENDING_COVERAGE = 0x0405
+};
+
+/*
+ * hwc_layer_t::transform values
+ */
+enum {
+ /* flip source image horizontally */
+ HWC_TRANSFORM_FLIP_H = HAL_TRANSFORM_FLIP_H,
+ /* flip source image vertically */
+ HWC_TRANSFORM_FLIP_V = HAL_TRANSFORM_FLIP_V,
+ /* rotate source image 90 degrees clock-wise */
+ HWC_TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90,
+ /* rotate source image 180 degrees */
+ HWC_TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180,
+ /* rotate source image 270 degrees clock-wise */
+ HWC_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270,
+};
+
+/* attributes queriable with query() */
+enum {
+ /*
+ * Availability: HWC_DEVICE_API_VERSION_0_2
+ * Must return 1 if the background layer is supported, 0 otherwise.
+ */
+ HWC_BACKGROUND_LAYER_SUPPORTED = 0,
+
+ /*
+ * Availability: HWC_DEVICE_API_VERSION_0_3
+ * Returns the vsync period in nanoseconds.
+ *
+ * This query is not used for HWC_DEVICE_API_VERSION_1_1 and later.
+ * Instead, the per-display attribute HWC_DISPLAY_VSYNC_PERIOD is used.
+ */
+ HWC_VSYNC_PERIOD = 1,
+
+ /*
+ * Availability: HWC_DEVICE_API_VERSION_1_1
+ * Returns a mask of supported display types.
+ */
+ HWC_DISPLAY_TYPES_SUPPORTED = 2,
+};
+
+/* display attributes returned by getDisplayAttributes() */
+enum {
+ /* Indicates the end of an attribute list */
+ HWC_DISPLAY_NO_ATTRIBUTE = 0,
+
+ /* The vsync period in nanoseconds */
+ HWC_DISPLAY_VSYNC_PERIOD = 1,
+
+ /* The number of pixels in the horizontal and vertical directions. */
+ HWC_DISPLAY_WIDTH = 2,
+ HWC_DISPLAY_HEIGHT = 3,
+
+ /* The number of pixels per thousand inches of this configuration.
+ *
+ * Scaling DPI by 1000 allows it to be stored in an int without losing
+ * too much precision.
+ *
+ * If the DPI for a configuration is unavailable or the HWC implementation
+ * considers it unreliable, it should set these attributes to zero.
+ */
+ HWC_DISPLAY_DPI_X = 4,
+ HWC_DISPLAY_DPI_Y = 5,
+};
+
+/* Allowed events for hwc_methods::eventControl() */
+enum {
+ HWC_EVENT_VSYNC = 0
+};
+
+/* Display types and associated mask bits. */
+enum {
+ HWC_DISPLAY_PRIMARY = 0,
+ HWC_DISPLAY_EXTERNAL = 1, // HDMI, DP, etc.
+ HWC_NUM_DISPLAY_TYPES
+};
+
+enum {
+ HWC_DISPLAY_PRIMARY_BIT = 1 << HWC_DISPLAY_PRIMARY,
+ HWC_DISPLAY_EXTERNAL_BIT = 1 << HWC_DISPLAY_EXTERNAL,
+};
+
+/*****************************************************************************/
+
+__END_DECLS
+
+#endif /* ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_DEFS_H */
diff --git a/include/hardware/hwcomposer_v0.h b/include/hardware/hwcomposer_v0.h
new file mode 100644
index 0000000..473819b
--- /dev/null
+++ b/include/hardware/hwcomposer_v0.h
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This header contains deprecated HWCv0 interface declarations. Don't include
+ * this header directly; it will be included by <hardware/hwcomposer.h> unless
+ * HWC_REMOVE_DEPRECATED_VERSIONS is defined to non-zero.
+ */
+#ifndef ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_H
+#error "This header should only be included by hardware/hwcomposer.h"
+#endif
+
+#ifndef ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_V0_H
+#define ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_V0_H
+
+struct hwc_composer_device;
+
+/*
+ * availability: HWC_DEVICE_API_VERSION_0_3
+ *
+ * struct hwc_methods cannot be embedded in other structures as
+ * sizeof(struct hwc_methods) cannot be relied upon.
+ *
+ */
+typedef struct hwc_methods {
+
+ /*************************************************************************
+ * HWC_DEVICE_API_VERSION_0_3
+ *************************************************************************/
+
+ /*
+ * eventControl(..., event, enabled)
+ * Enables or disables h/w composer events.
+ *
+ * eventControl can be called from any thread and takes effect
+ * immediately.
+ *
+ * Supported events are:
+ * HWC_EVENT_VSYNC
+ *
+ * returns -EINVAL if the "event" parameter is not one of the value above
+ * or if the "enabled" parameter is not 0 or 1.
+ */
+
+ int (*eventControl)(
+ struct hwc_composer_device* dev, int event, int enabled);
+
+} hwc_methods_t;
+
+typedef struct hwc_layer {
+ /*
+ * initially set to HWC_FRAMEBUFFER or HWC_BACKGROUND.
+ * HWC_FRAMEBUFFER
+ * indicates the layer will be drawn into the framebuffer
+ * using OpenGL ES.
+ * The HWC can toggle this value to HWC_OVERLAY, to indicate
+ * it will handle the layer.
+ *
+ * HWC_BACKGROUND
+ * indicates this is a special "background" layer. The only valid
+ * field is backgroundColor. HWC_BACKGROUND can only be used with
+ * HWC_API_VERSION >= 0.2
+ * The HWC can toggle this value to HWC_FRAMEBUFFER, to indicate
+ * it CANNOT handle the background color
+ *
+ */
+ int32_t compositionType;
+
+ /* see hwc_layer_t::hints above */
+ uint32_t hints;
+
+ /* see hwc_layer_t::flags above */
+ uint32_t flags;
+
+ union {
+ /* color of the background. hwc_color_t.a is ignored */
+ hwc_color_t backgroundColor;
+
+ struct {
+ /* handle of buffer to compose. This handle is guaranteed to have been
+ * allocated from gralloc using the GRALLOC_USAGE_HW_COMPOSER usage flag. If
+ * the layer's handle is unchanged across two consecutive prepare calls and
+ * the HWC_GEOMETRY_CHANGED flag is not set for the second call then the
+ * HWComposer implementation may assume that the contents of the buffer have
+ * not changed. */
+ buffer_handle_t handle;
+
+ /* transformation to apply to the buffer during composition */
+ uint32_t transform;
+
+ /* blending to apply during composition */
+ int32_t blending;
+
+ /* area of the source to consider, the origin is the top-left corner of
+ * the buffer */
+ hwc_rect_t sourceCrop;
+
+ /* where to composite the sourceCrop onto the display. The sourceCrop
+ * is scaled using linear filtering to the displayFrame. The origin is the
+ * top-left corner of the screen.
+ */
+ hwc_rect_t displayFrame;
+
+ /* visible region in screen space. The origin is the
+ * top-left corner of the screen.
+ * The visible region INCLUDES areas overlapped by a translucent layer.
+ */
+ hwc_region_t visibleRegionScreen;
+ };
+ };
+} hwc_layer_t;
+
+/*
+ * List of layers.
+ * The handle members of hwLayers elements must be unique.
+ */
+typedef struct hwc_layer_list {
+ uint32_t flags;
+ size_t numHwLayers;
+ hwc_layer_t hwLayers[0];
+} hwc_layer_list_t;
+
+/*****************************************************************************/
+
+typedef struct hwc_composer_device {
+ struct hw_device_t common;
+
+ /*
+ * (*prepare)() is called for each frame before composition and is used by
+ * SurfaceFlinger to determine what composition steps the HWC can handle.
+ *
+ * (*prepare)() can be called more than once, the last call prevails.
+ *
+ * The HWC responds by setting the compositionType field to either
+ * HWC_FRAMEBUFFER or HWC_OVERLAY. In the former case, the composition for
+ * this layer is handled by SurfaceFlinger with OpenGL ES, in the later
+ * case, the HWC will have to handle this layer's composition.
+ *
+ * (*prepare)() is called with HWC_GEOMETRY_CHANGED to indicate that the
+ * list's geometry has changed, that is, when more than just the buffer's
+ * handles have been updated. Typically this happens (but is not limited to)
+ * when a window is added, removed, resized or moved.
+ *
+ * a NULL list parameter or a numHwLayers of zero indicates that the
+ * entire composition will be handled by SurfaceFlinger with OpenGL ES.
+ *
+ * returns: 0 on success. An negative error code on error. If an error is
+ * returned, SurfaceFlinger will assume that none of the layer will be
+ * handled by the HWC.
+ */
+ int (*prepare)(struct hwc_composer_device *dev, hwc_layer_list_t* list);
+
+ /*
+ * (*set)() is used in place of eglSwapBuffers(), and assumes the same
+ * functionality, except it also commits the work list atomically with
+ * the actual eglSwapBuffers().
+ *
+ * The list parameter is guaranteed to be the same as the one returned
+ * from the last call to (*prepare)().
+ *
+ * When this call returns the caller assumes that:
+ *
+ * - the display will be updated in the near future with the content
+ * of the work list, without artifacts during the transition from the
+ * previous frame.
+ *
+ * - all objects are available for immediate access or destruction, in
+ * particular, hwc_region_t::rects data and hwc_layer_t::layer's buffer.
+ * Note that this means that immediately accessing (potentially from a
+ * different process) a buffer used in this call will not result in
+ * screen corruption, the driver must apply proper synchronization or
+ * scheduling (eg: block the caller, such as gralloc_module_t::lock(),
+ * OpenGL ES, Camera, Codecs, etc..., or schedule the caller's work
+ * after the buffer is freed from the actual composition).
+ *
+ * a NULL list parameter or a numHwLayers of zero indicates that the
+ * entire composition has been handled by SurfaceFlinger with OpenGL ES.
+ * In this case, (*set)() behaves just like eglSwapBuffers().
+ *
+ * dpy, sur, and list are set to NULL to indicate that the screen is
+ * turning off. This happens WITHOUT prepare() being called first.
+ * This is a good time to free h/w resources and/or power
+ * the relevant h/w blocks down.
+ *
+ * IMPORTANT NOTE: there is an implicit layer containing opaque black
+ * pixels behind all the layers in the list.
+ * It is the responsibility of the hwcomposer module to make
+ * sure black pixels are output (or blended from).
+ *
+ * returns: 0 on success. An negative error code on error:
+ * HWC_EGL_ERROR: eglGetError() will provide the proper error code
+ * Another code for non EGL errors.
+ *
+ */
+ int (*set)(struct hwc_composer_device *dev,
+ hwc_display_t dpy,
+ hwc_surface_t sur,
+ hwc_layer_list_t* list);
+
+ /*
+ * This field is OPTIONAL and can be NULL.
+ *
+ * If non NULL it will be called by SurfaceFlinger on dumpsys
+ */
+ void (*dump)(struct hwc_composer_device* dev, char *buff, int buff_len);
+
+ /*
+ * This field is OPTIONAL and can be NULL.
+ *
+ * (*registerProcs)() registers a set of callbacks the h/w composer HAL
+ * can later use. It is FORBIDDEN to call any of the callbacks from
+ * within registerProcs(). registerProcs() must save the hwc_procs_t pointer
+ * which is needed when calling a registered callback.
+ * Each call to registerProcs replaces the previous set of callbacks.
+ * registerProcs is called with NULL to unregister all callbacks.
+ *
+ * Any of the callbacks can be NULL, in which case the corresponding
+ * functionality is not supported.
+ */
+ void (*registerProcs)(struct hwc_composer_device* dev,
+ hwc_procs_t const* procs);
+
+ /*
+ * This field is OPTIONAL and can be NULL.
+ * availability: HWC_DEVICE_API_VERSION_0_2
+ *
+ * Used to retrieve information about the h/w composer
+ *
+ * Returns 0 on success or -errno on error.
+ */
+ int (*query)(struct hwc_composer_device* dev, int what, int* value);
+
+ /*
+ * Reserved for future use. Must be NULL.
+ */
+ void* reserved_proc[4];
+
+ /*
+ * This field is OPTIONAL and can be NULL.
+ * availability: HWC_DEVICE_API_VERSION_0_3
+ */
+ hwc_methods_t const *methods;
+
+} hwc_composer_device_t;
+
+/** convenience API for opening and closing a device */
+
+static inline int hwc_open(const struct hw_module_t* module,
+ hwc_composer_device_t** device) {
+ return module->methods->open(module,
+ HWC_HARDWARE_COMPOSER, (struct hw_device_t**)device);
+}
+
+static inline int hwc_close(hwc_composer_device_t* device) {
+ return device->common.close(&device->common);
+}
+
+/*****************************************************************************/
+
+#endif /* ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_V0_H */
diff --git a/include/ion_ti/ion.h b/include/ion_ti/ion.h
new file mode 100644
index 0000000..05fe1ec
--- /dev/null
+++ b/include/ion_ti/ion.h
@@ -0,0 +1,49 @@
+/*
+ * ion.c
+ *
+ * Memory Allocator functions for ion
+ *
+ * Copyright 2011 Google, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TI_ION_H
+#define __TI_ION_H
+
+#include "linux_ion.h"
+#include "omap_ion.h"
+
+__BEGIN_DECLS
+
+int ion_open();
+int ion_close(int fd);
+int ion_alloc(int fd, size_t len, size_t align, unsigned int flags,
+ struct ion_handle **handle);
+int ion_alloc_tiler(int fd, size_t w, size_t h, int fmt, unsigned int flags,
+ struct ion_handle **handle, size_t *stride);
+int ion_free(int fd, struct ion_handle *handle);
+int ion_map(int fd, struct ion_handle *handle, size_t length, int prot,
+ int flags, off_t offset, unsigned char **ptr, int *map_fd);
+int ion_share(int fd, struct ion_handle *handle, int *share_fd);
+int ion_import(int fd, int share_fd, struct ion_handle **handle);
+int ion_map_cacheable(int fd, struct ion_handle *handle, size_t length,
+ int prot, int flags, off_t offset, unsigned char **ptr, int *map_fd);
+int ion_flush_cached(int fd, struct ion_handle *handle, size_t length,
+ unsigned char *ptr);
+int ion_inval_cached(int fd, struct ion_handle *handle, size_t length,
+ unsigned char *ptr);
+
+__END_DECLS
+
+#endif /* __TI_ION_H */
diff --git a/include/ion_ti/linux_ion.h b/include/ion_ti/linux_ion.h
new file mode 100644
index 0000000..300853a
--- /dev/null
+++ b/include/ion_ti/linux_ion.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ION_H
+#define _LINUX_ION_H
+#include <linux/types.h>
+struct ion_handle;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum ion_heap_type {
+ ION_HEAP_TYPE_SYSTEM,
+ ION_HEAP_TYPE_SYSTEM_CONTIG,
+ ION_HEAP_TYPE_CARVEOUT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ ION_HEAP_TYPE_CUSTOM,
+ ION_NUM_HEAPS,
+};
+#define ION_HEAP_SYSTEM_MASK (1 << ION_HEAP_TYPE_SYSTEM)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ION_HEAP_SYSTEM_CONTIG_MASK (1 << ION_HEAP_TYPE_SYSTEM_CONTIG)
+#define ION_HEAP_CARVEOUT_MASK (1 << ION_HEAP_TYPE_CARVEOUT)
+struct ion_allocation_data {
+ size_t len;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ size_t align;
+ unsigned int flags;
+ struct ion_handle *handle;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ion_fd_data {
+ struct ion_handle *handle;
+ int fd;
+ unsigned char cacheable;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct ion_handle_data {
+ struct ion_handle *handle;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ion_custom_data {
+ unsigned int cmd;
+ unsigned long arg;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ion_cached_user_buf_data {
+ struct ion_handle *handle;
+ unsigned long vaddr;
+ size_t size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define ION_IOC_MAGIC 'I'
+#define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, struct ion_allocation_data)
+#define ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ION_IOC_MAP _IOWR(ION_IOC_MAGIC, 2, struct ion_fd_data)
+#define ION_IOC_SHARE _IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data)
+#define ION_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, int)
+#define ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ION_IOC_FLUSH_CACHED _IOWR(ION_IOC_MAGIC, 7, struct ion_cached_user_buf_data)
+#define ION_IOC_INVAL_CACHED _IOWR(ION_IOC_MAGIC, 8, struct ion_cached_user_buf_data)
+#endif
diff --git a/include/ion_ti/omap_ion.h b/include/ion_ti/omap_ion.h
new file mode 100644
index 0000000..b8a6228
--- /dev/null
+++ b/include/ion_ti/omap_ion.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_OMAP_ION_H
+#define _LINUX_OMAP_ION_H
+#include <linux/types.h>
+struct omap_ion_tiler_alloc_data {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ size_t w;
+ size_t h;
+ int fmt;
+ unsigned int flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ struct ion_handle *handle;
+ size_t stride;
+ size_t offset;
+ unsigned int out_align;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ unsigned int token;
+};
+enum {
+ OMAP_ION_HEAP_TYPE_TILER = ION_HEAP_TYPE_CUSTOM + 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define OMAP_ION_HEAP_TILER_MASK (1 << OMAP_ION_HEAP_TYPE_TILER)
+enum {
+ OMAP_ION_TILER_ALLOC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+enum {
+ TILER_PIXEL_FMT_MIN = 0,
+ TILER_PIXEL_FMT_8BIT = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ TILER_PIXEL_FMT_16BIT = 1,
+ TILER_PIXEL_FMT_32BIT = 2,
+ TILER_PIXEL_FMT_PAGE = 3,
+ TILER_PIXEL_FMT_MAX = 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+enum {
+ OMAP_ION_HEAP_LARGE_SURFACES,
+ OMAP_ION_HEAP_TILER,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ OMAP_ION_HEAP_SECURE_INPUT,
+};
+#endif
diff --git a/kernel-headers/linux/android_alarm.h b/kernel-headers/linux/android_alarm.h
new file mode 100644
index 0000000..d719c95
--- /dev/null
+++ b/kernel-headers/linux/android_alarm.h
@@ -0,0 +1,112 @@
+/* include/linux/android_alarm.h
+ *
+ * Copyright (C) 2006-2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _LINUX_ANDROID_ALARM_H
+#define _LINUX_ANDROID_ALARM_H
+
+#include <linux/ioctl.h>
+#include <linux/time.h>
+
+enum android_alarm_type {
+ /* return code bit numbers or set alarm arg */
+ ANDROID_ALARM_RTC_WAKEUP,
+ ANDROID_ALARM_RTC,
+ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
+ ANDROID_ALARM_ELAPSED_REALTIME,
+ ANDROID_ALARM_SYSTEMTIME,
+
+ ANDROID_ALARM_TYPE_COUNT,
+
+ /* return code bit numbers */
+ /* ANDROID_ALARM_TIME_CHANGE = 16 */
+};
+
+#ifdef __KERNEL__
+
+#include <linux/ktime.h>
+#include <linux/rbtree.h>
+
+/*
+ * The alarm interface is similar to the hrtimer interface but adds support
+ * for wakeup from suspend. It also adds an elapsed realtime clock that can
+ * be used for periodic timers that need to keep runing while the system is
+ * suspended and not be disrupted when the wall time is set.
+ */
+
+/**
+ * struct alarm - the basic alarm structure
+ * @node: red black tree node for time ordered insertion
+ * @type: alarm type. rtc/elapsed-realtime/systemtime, wakeup/non-wakeup.
+ * @softexpires: the absolute earliest expiry time of the alarm.
+ * @expires: the absolute expiry time.
+ * @function: alarm expiry callback function
+ *
+ * The alarm structure must be initialized by alarm_init()
+ *
+ */
+
+struct alarm {
+ struct rb_node node;
+ enum android_alarm_type type;
+ ktime_t softexpires;
+ ktime_t expires;
+ void (*function)(struct alarm *);
+};
+
+void alarm_init(struct alarm *alarm,
+ enum android_alarm_type type, void (*function)(struct alarm *));
+void alarm_start_range(struct alarm *alarm, ktime_t start, ktime_t end);
+int alarm_try_to_cancel(struct alarm *alarm);
+int alarm_cancel(struct alarm *alarm);
+ktime_t alarm_get_elapsed_realtime(void);
+
+/* set rtc while preserving elapsed realtime */
+int alarm_set_rtc(const struct timespec ts);
+#if defined(CONFIG_RTC_CHN_ALARM_BOOT)
+void alarm_set_alarmboot(char *alarmboot_data);
+#endif
+
+#endif
+
+enum android_alarm_return_flags {
+ ANDROID_ALARM_RTC_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_WAKEUP,
+ ANDROID_ALARM_RTC_MASK = 1U << ANDROID_ALARM_RTC,
+ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK =
+ 1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
+ ANDROID_ALARM_ELAPSED_REALTIME_MASK =
+ 1U << ANDROID_ALARM_ELAPSED_REALTIME,
+ ANDROID_ALARM_SYSTEMTIME_MASK = 1U << ANDROID_ALARM_SYSTEMTIME,
+ ANDROID_ALARM_TIME_CHANGE_MASK = 1U << 16
+};
+
+/* Disable alarm */
+#define ANDROID_ALARM_CLEAR(type) _IO('a', 0 | ((type) << 4))
+
+/* Ack last alarm and wait for next */
+#define ANDROID_ALARM_WAIT _IO('a', 1)
+
+#define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size)
+/* Set alarm */
+#define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec)
+#define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec)
+#define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec)
+#define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec)
+#if defined(CONFIG_RTC_CHN_ALARM_BOOT)
+#define ANDROID_ALARM_SET_ALARM _IOW('a', 7, struct timespec)
+#endif
+#define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0)))
+#define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4)
+
+#endif
diff --git a/kernel-headers/linux/bltsville.h b/kernel-headers/linux/bltsville.h
new file mode 100644
index 0000000..42256c3
--- /dev/null
+++ b/kernel-headers/linux/bltsville.h
@@ -0,0 +1,592 @@
+/*
+ * bltsville.h
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef BLTSVILLE_H
+#define BLTSVILLE_H
+
+#include "ocd.h"
+#include "bverror.h"
+#include "bvblend.h"
+#include "bvfilter.h"
+#include "bvbuffdesc.h"
+#include "bvcache.h"
+#include "bventry.h"
+#include "bvsurfgeom.h"
+
+/*
+ * bvrect - This structure is used to specify rectangles in BLTsville.
+ */
+struct bvrect {
+ int left;
+ int top;
+ unsigned int width;
+ unsigned int height;
+};
+
+
+/*
+ * BVFLAG_* - These define the type of BLT to be performed and are placed in
+ * the bvparams.flags element.
+ */
+#define BVFLAG_OP_SHIFT 0
+#define BVFLAG_OP_MASK (0xF << BVFLAG_OP_SHIFT)
+
+/* 0 reserved */
+#define BVFLAG_ROP (0x1 << BVFLAG_OP_SHIFT) /* ROP4 spec'd in rop */
+#define BVFLAG_BLEND (0x2 << BVFLAG_OP_SHIFT) /* blend spec'd in blend */
+/* 3 reserved */
+#define BVFLAG_FILTER (0x4 << BVFLAG_OP_SHIFT) /* filter spec'd in filter */
+/* 5-F reserved */
+
+#define BVFLAG_KEY_SRC 0x00000010 /* source color key - value spec'd
+ by pcolorkey; Mutually exclusive
+ with BVFLAG_KEY_DST */
+#define BVFLAG_KEY_DST 0x00000020 /* dest color key - value spec'd
+ by pcolorkey; Mutually exclusive
+ with BVFLAG_KEY_SRC */
+#define BVFLAG_CLIP 0x00000040 /* clipping rectangle spec'd by
+ cliprect */
+#define BVFLAG_SRCMASK 0x00000080 /* when scaling a masked copy, mask
+ at the source instead of the
+ (default) destination */
+
+#define BVFLAG_ASYNC 0x00000100 /* call should return once queued */
+
+#define BVFLAG_TILE_SRC1 0x00000200 /* source 1 is tiled */
+#define BVFLAG_TILE_SRC2 0x00000400 /* source 2 is tiled */
+#define BVFLAG_TILE_MASK 0x00000800 /* mask is tiled */
+
+
+#define BVFLAG_BATCH_SHIFT 12
+#define BVFLAG_BATCH_MASK (3 << BVFLAG_BATCH_SHIFT)
+
+#define BVFLAG_BATCH_NONE (0 << BVFLAG_BATCH_SHIFT) /* not batched */
+#define BVFLAG_BATCH_BEGIN (1 << BVFLAG_BATCH_SHIFT) /* begin batch */
+#define BVFLAG_BATCH_CONTINUE (2 << BVFLAG_BATCH_SHIFT) /* continue batch */
+#define BVFLAG_BATCH_END (3 << BVFLAG_BATCH_SHIFT) /* end batch */
+
+
+#define BVFLAG_HORZ_FLIP_SRC1 0x00004000 /* flip src1 horizontally */
+#define BVFLAG_VERT_FLIP_SRC1 0x00008000 /* flip src1 vertically */
+#define BVFLAG_HORZ_FLIP_SRC2 0x00010000 /* flip src2 horizontally */
+#define BVFLAG_VERT_FLIP_SRC2 0x00020000 /* flip src2 vertically */
+#define BVFLAG_HORZ_FLIP_MASK 0x00040000 /* flip mask horizontally */
+#define BVFLAG_VERT_FLIP_MASK 0x00080000 /* flip mask vertically */
+
+
+#define BVFLAG_SCALE_RETURN 0x00100000 /* return scale type used */
+#define BVFLAG_DITHER_RETURN 0x00200000 /* return dither type used */
+/**** Bits 31-22 reserved ****/
+
+/*
+ * BVIMPL_* - BLTsville implementations may be combined under managers to
+ * allow clients to take advantage of multiple implementations without doing
+ * so explicitly. The BVIMPL_* definition are placed into the
+ * bvparams.implementation member by the client to override the manager's
+ * choice of implementation.
+ */
+#define BVIMPL_ANY 0
+#define BVIMPL_FIRST_HW (1 << 31) /* Continues to the right */
+#define BVIMPL_FIRST_CPU (1 << 0) /* Continues to the left */
+
+
+/*
+ * bvscalemode - This specifies the type of scaling to perform.
+ */
+#define BVSCALEDEF_VENDOR_SHIFT 24
+#define BVSCALEDEF_VENDOR_MASK (0xFF << BVSCALEDEF_VENDOR_SHIFT)
+
+#define BVSCALEDEF_VENDOR_ALL (0 << BVSCALEDEF_VENDOR_SHIFT)
+#define BVSCALEDEF_VENDOR_TI (1 << BVSCALEDEF_VENDOR_SHIFT)
+/* 0xF0-0xFE reserved */
+#define BVSCALEDEF_VENDOR_GENERIC (0xFF << BVSCALEDEF_VENDOR_SHIFT)
+
+/***** VENDOR_GENERIC definitions *****/
+/**** Bits 23-22 indicate classification ****/
+#define BVSCALEDEF_CLASS_SHIFT 22
+#define BVSCALEDEF_IMPLICIT (0 << BVSCALEDEF_CLASS_SHIFT)
+#define BVSCALEDEF_EXPLICIT (1 << BVSCALEDEF_CLASS_SHIFT)
+/* 2-3 reserved */
+#define BVSCALEDEF_CLASS_MASK (3 << BVSCALEDEF_CLASS_MASK)
+
+/**** IMPLICIT definitions ****/
+/*** Bits 21-16 indicate the quality (speed) desired ***/
+#define BVSCALEDEF_QUALITY_SHIFT 16
+#define BVSCALEDEF_FASTEST (0x00 << BVSCALEDEF_QUALITY_SHIFT)
+#define BVSCALEDEF_GOOD (0x15 << BVSCALEDEF_QUALITY_SHIFT)
+#define BVSCALEDEF_BETTER (0x2A << BVSCALEDEF_QUALITY_SHIFT)
+#define BVSCALEDEF_BEST (0x3F << BVSCALEDEF_QUALITY_SHIFT)
+#define BVSCALEDEF_QUALITY_MASK (0x3F << BVSCALEDEF_QUALITY_MASK)
+/* Bits 15-12 are reserved */
+/*** Bits 11-8 indicate the desired technique ***/
+#define BVSCALEDEF_TECHNIQUE_SHIFT 8
+#define BVSCALEDEF_DONT_CARE (0x0 << BVSCALEDEF_TECHNIQUE_SHIFT)
+#define BVSCALEDEF_NOT_NEAREST_NEIGHBOR (0x1 << BVSCALEDEF_TECHNIQUE_SHIFT)
+#define BVSCALEDEF_POINT_SAMPLE (0x2 << BVSCALEDEF_TECHNIQUE_SHIFT)
+#define BVSCALEDEF_INTERPOLATED (0x3 << BVSCALEDEF_TECHNIQUE_SHIFT)
+#define BVSCALEDEF_TECHNIQUE_MASK (0xF << BVSCALEDEF_TECHNIQUE_SHIFT)
+/* Bits 7-2 reserved */
+/*** Bits 1-0 indicate the type of image ***/
+#define BVSCALEDEF_TYPE_SHIFT 0
+/* 0 don't know */
+#define BVSCALEDEF_PHOTO (1 << BVSCALEDEF_TYPE_SHIFT)
+#define BVSCALEDEF_DRAWING (2 << BVSCALEDEF_TYPE_SHIFT)
+/* 3 reserved */
+#define BVSCALEDEF_TYPE_MASK (3 << BVSCALEDEF_TYPE_MASK)
+
+/**** EXPLICIT definitions ****/
+/* Bits 21-16 reserved */
+#define BVSCALEDEF_HORZ_SHIFT 8
+#define BVSCALEDEF_HORZ_MASK (0xFF << BVSCALEDEF_HORZ_SHIFT)
+
+#define BVSCALEDEF_VERT_SHIFT 0
+#define BVSCALEDEF_VERT_MASK (0xFF << BVSCALEDEF_VERT_SHIFT)
+
+#define BVSCALEDEF_NEAREST_NEIGHBOR 0x00
+#define BVSCALEDEF_LINEAR 0x01
+#define BVSCALEDEF_CUBIC 0x02
+#define BVSCALEDEF_3_TAP 0x03
+/* 0x04 reserved */
+#define BVSCALEDEF_5_TAP 0x05
+/* 0x06 reserved */
+#define BVSCALEDEF_7_TAP 0x07
+/* 0x08 reserved */
+#define BVSCALEDEF_9_TAP 0x09
+/* 0x0A-0xFF reserved */
+
+enum bvscalemode {
+ BVSCALE_FASTEST = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_FASTEST |
+ BVSCALEDEF_DONT_CARE,
+ BVSCALE_FASTEST_NOT_NEAREST_NEIGHBOR = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_FASTEST |
+ BVSCALEDEF_NOT_NEAREST_NEIGHBOR,
+ BVSCALE_FASTEST_POINT_SAMPLE = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_FASTEST |
+ BVSCALEDEF_POINT_SAMPLE,
+ BVSCALE_FASTEST_INTERPOLATED = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_FASTEST |
+ BVSCALEDEF_INTERPOLATED,
+ BVSCALE_FASTEST_PHOTO = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_FASTEST |
+ BVSCALEDEF_PHOTO,
+ BVSCALE_FASTEST_DRAWING = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_FASTEST |
+ BVSCALEDEF_DRAWING,
+ BVSCALE_GOOD = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_GOOD |
+ BVSCALEDEF_DONT_CARE,
+ BVSCALE_GOOD_POINT_SAMPLE = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_GOOD |
+ BVSCALEDEF_POINT_SAMPLE,
+ BVSCALE_GOOD_INTERPOLATED = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_GOOD |
+ BVSCALEDEF_INTERPOLATED,
+ BVSCALE_GOOD_PHOTO = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_GOOD |
+ BVSCALEDEF_PHOTO,
+ BVSCALE_GOOD_DRAWING = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_GOOD |
+ BVSCALEDEF_DRAWING,
+ BVSCALE_BETTER = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_BETTER |
+ BVSCALEDEF_DONT_CARE,
+ BVSCALE_BETTER_POINT_SAMPLE = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_BETTER |
+ BVSCALEDEF_POINT_SAMPLE,
+ BVSCALE_BETTER_INTERPOLATED = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_BETTER |
+ BVSCALEDEF_INTERPOLATED,
+ BVSCALE_BETTER_PHOTO = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_BETTER |
+ BVSCALEDEF_PHOTO,
+ BVSCALE_BETTER_DRAWING = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_BETTER |
+ BVSCALEDEF_DRAWING,
+ BVSCALE_BEST = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_BEST |
+ BVSCALEDEF_DONT_CARE,
+ BVSCALE_BEST_POINT_SAMPLE = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_BEST |
+ BVSCALEDEF_POINT_SAMPLE,
+ BVSCALE_BEST_INTERPOLATED = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_BEST |
+ BVSCALEDEF_INTERPOLATED,
+ BVSCALE_BEST_PHOTO = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_BEST |
+ BVSCALEDEF_PHOTO,
+ BVSCALE_BEST_DRAWING = BVSCALEDEF_VENDOR_ALL |
+ BVSCALEDEF_IMPLICIT |
+ BVSCALEDEF_BEST |
+ BVSCALEDEF_DRAWING,
+
+ BVSCALE_NEAREST_NEIGHBOR = BVSCALEDEF_VENDOR_GENERIC |
+ BVSCALEDEF_EXPLICIT |
+ (BVSCALEDEF_NEAREST_NEIGHBOR << BVSCALEDEF_HORZ_SHIFT) |
+ (BVSCALEDEF_NEAREST_NEIGHBOR << BVSCALEDEF_VERT_SHIFT),
+ BVSCALE_BILINEAR = BVSCALEDEF_VENDOR_GENERIC |
+ BVSCALEDEF_EXPLICIT |
+ (BVSCALEDEF_LINEAR << BVSCALEDEF_HORZ_SHIFT) |
+ (BVSCALEDEF_LINEAR << BVSCALEDEF_VERT_SHIFT),
+ BVSCALE_BICUBIC = BVSCALEDEF_VENDOR_GENERIC |
+ BVSCALEDEF_EXPLICIT |
+ (BVSCALEDEF_CUBIC << BVSCALEDEF_HORZ_SHIFT) |
+ (BVSCALEDEF_CUBIC << BVSCALEDEF_VERT_SHIFT),
+ BVSCALE_3x3_TAP = BVSCALEDEF_VENDOR_GENERIC |
+ BVSCALEDEF_EXPLICIT |
+ (BVSCALEDEF_3_TAP << BVSCALEDEF_HORZ_SHIFT) |
+ (BVSCALEDEF_3_TAP << BVSCALEDEF_VERT_SHIFT),
+ BVSCALE_5x5_TAP = BVSCALEDEF_VENDOR_GENERIC |
+ BVSCALEDEF_EXPLICIT |
+ (BVSCALEDEF_5_TAP << BVSCALEDEF_HORZ_SHIFT) |
+ (BVSCALEDEF_5_TAP << BVSCALEDEF_VERT_SHIFT),
+ BVSCALE_7x7_TAP = BVSCALEDEF_VENDOR_GENERIC |
+ BVSCALEDEF_EXPLICIT |
+ (BVSCALEDEF_7_TAP << BVSCALEDEF_HORZ_SHIFT) |
+ (BVSCALEDEF_7_TAP << BVSCALEDEF_VERT_SHIFT),
+ BVSCALE_9x9_TAP = BVSCALEDEF_VENDOR_GENERIC |
+ BVSCALEDEF_EXPLICIT |
+ (BVSCALEDEF_9_TAP << BVSCALEDEF_HORZ_SHIFT) |
+ (BVSCALEDEF_9_TAP << BVSCALEDEF_VERT_SHIFT),
+
+#ifdef BVSCALE_EXTERNAL_INCLUDE
+#include BVSCALE_EXTERNAL_INCLUDE
+#endif
+};
+
+
+/*
+ * bvdithermode - This defines the type of dithering to use.
+ */
+#define BVDITHERDEF_VENDOR_SHIFT 24
+#define BVDITHERDEF_VENDOR_MASK (0xFF << BVDITHERDEF_VENDOR_SHIFT)
+
+#define BVDITHERDEF_VENDOR_ALL (0 << BVDITHERDEF_VENDOR_SHIFT)
+#define BVDITHERDEF_VENDOR_TI (1 << BVDITHERDEF_VENDOR_SHIFT)
+/* 0xF0-0xFE reserved */
+#define BVDITHERDEF_VENDOR_GENERIC (0xFF << BVDITHERDEF_VENDOR_SHIFT)
+
+/***** VENDOR_GENERIC definitions *****/
+/* Bits 23-18 reserved */
+/**** Bits 17-16 indicate the type of image - 0 = don't know ****/
+#define BVDITHERDEF_TYPE_SHIFT 16
+#define BVDITHERDEF_PHOTO (0x01 << BVDITHERDEF_TYPE_SHIFT)
+#define BVDITHERDEF_DRAWING (0x02 << BVDITHERDEF_TYPE_SHIFT)
+/**** Bits 15-8 indicate the desired technique ****/
+#define BVDITHERDEF_TECHNIQUE_SHIFT 8
+#define BVDITHERDEF_DONT_CARE (0x00 << BVDITHERDEF_TECHNIQUE_SHIFT)
+#define BVDITHERDEF_RANDOM (0x01 << BVDITHERDEF_TECHNIQUE_SHIFT)
+#define BVDITHERDEF_ORDERED (0x02 << BVDITHERDEF_TECHNIQUE_SHIFT)
+#define BVDITHERDEF_DIFFUSED (0x04 << BVDITHERDEF_TECHNIQUE_SHIFT)
+#define BVDITHERDEF_ON (0xFF << BVDITHERDEF_TECHNIQUE_SHIFT)
+/**** Bits 7-0 indicate the quality (speed) desired ****/
+#define BVDITHERDEF_QUALITY_SHIFT 0
+#define BVDITHERDEF_FASTEST (0x00 << BVDITHERDEF_QUALITY_SHIFT)
+#define BVDITHERDEF_GOOD (0x55 << BVDITHERDEF_QUALITY_SHIFT)
+#define BVDITHERDEF_BETTER (0xAA << BVDITHERDEF_QUALITY_SHIFT)
+#define BVDITHERDEF_BEST (0xFF << BVDITHERDEF_QUALITY_SHIFT)
+
+enum bvdithermode {
+ BVDITHER_FASTEST = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_FASTEST |
+ BVDITHERDEF_DONT_CARE,
+ BVDITHER_FASTEST_ON = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_FASTEST |
+ BVDITHERDEF_ON,
+ BVDITHER_FASTEST_RANDOM = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_FASTEST |
+ BVDITHERDEF_RANDOM,
+ BVDITHER_FASTEST_ORDERED = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_FASTEST |
+ BVDITHERDEF_ORDERED,
+ BVDITHER_FASTEST_DIFFUSED = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_FASTEST |
+ BVDITHERDEF_DIFFUSED,
+ BVDITHER_FASTEST_PHOTO = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_FASTEST |
+ BVDITHERDEF_PHOTO,
+ BVDITHER_FASTEST_DRAWING = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_FASTEST |
+ BVDITHERDEF_DRAWING,
+ BVDITHER_GOOD = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_GOOD |
+ BVDITHERDEF_DONT_CARE,
+ BVDITHER_GOOD_ON = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_GOOD |
+ BVDITHERDEF_ON,
+ BVDITHER_GOOD_RANDOM = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_GOOD |
+ BVDITHERDEF_RANDOM,
+ BVDITHER_GOOD_ORDERED = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_GOOD |
+ BVDITHERDEF_ORDERED,
+ BVDITHER_GOOD_DIFFUSED = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_GOOD |
+ BVDITHERDEF_DIFFUSED,
+ BVDITHER_GOOD_PHOTO = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_GOOD |
+ BVDITHERDEF_PHOTO,
+ BVDITHER_GOOD_DRAWING = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_GOOD |
+ BVDITHERDEF_DRAWING,
+ BVDITHER_BETTER = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BETTER |
+ BVDITHERDEF_DONT_CARE,
+ BVDITHER_BETTER_ON = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BETTER |
+ BVDITHERDEF_ON,
+ BVDITHER_BETTER_RANDOM = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BETTER |
+ BVDITHERDEF_RANDOM,
+ BVDITHER_BETTER_ORDERED = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BETTER |
+ BVDITHERDEF_ORDERED,
+ BVDITHER_BETTER_DIFFUSED = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BETTER |
+ BVDITHERDEF_DIFFUSED,
+ BVDITHER_BETTER_PHOTO = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BETTER |
+ BVDITHERDEF_PHOTO,
+ BVDITHER_BETTER_DRAWING = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BETTER |
+ BVDITHERDEF_DRAWING,
+ BVDITHER_BEST = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BEST |
+ BVDITHERDEF_DONT_CARE,
+ BVDITHER_BEST_ON = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BEST |
+ BVDITHERDEF_ON,
+ BVDITHER_BEST_RANDOM = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BEST |
+ BVDITHERDEF_RANDOM,
+ BVDITHER_BEST_ORDERED = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BEST |
+ BVDITHERDEF_ORDERED,
+ BVDITHER_BEST_DIFFUSED = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BEST |
+ BVDITHERDEF_DIFFUSED,
+ BVDITHER_BEST_PHOTO = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BEST |
+ BVDITHERDEF_PHOTO,
+ BVDITHER_BEST_DRAWING = BVDITHERDEF_VENDOR_ALL |
+ BVDITHERDEF_BEST |
+ BVDITHERDEF_DRAWING,
+
+ BVDITHER_NONE = BVDITHERDEF_VENDOR_GENERIC + 0,
+ BVDITHER_ORDERED_2x2 = BVDITHERDEF_VENDOR_GENERIC + 4,
+ BVDITHER_ORDERED_4x4 = BVDITHERDEF_VENDOR_GENERIC + 16,
+ BVDITHER_ORDERED_2x2_4x4 = BVDITHERDEF_VENDOR_GENERIC + 4 + 16,
+ /* 2x2 for 6->8, 4x4 for 5->8 */
+
+#ifdef BVDITHER_EXTERNAL_INCLUDE
+#include BVDITHER_EXTERNAL_INCLUDE
+#endif
+};
+
+
+/*
+ * BVTILE_* flags - These specify parameters used when tiling.
+ */
+#define BVTILE_LEFT_SHIFT 0
+#define BVTILE_TOP_SHIFT (BVTILE_LEFT_SHIFT + 2)
+#define BVTILE_RIGHT_SHIFT (BVTILE_TOP_SHIFT + 2)
+#define BVTILE_BOTTOM_SHIFT (BVTILE_RIGHT_SHIFT + 2)
+#define BVTILE_LEFT_REPEAT (0 << BVTILE_LEFT_SHIFT) /* ...012301230123 */
+#define BVTILE_TOP_REPEAT (0 << BVTILE_TOP_SHIFT) /* ...012301230123 */
+#define BVTILE_RIGHT_REPEAT (0 << BVTILE_RIGHT_SHIFT) /* 012301230123... */
+#define BVTILE_BOTTOM_REPEAT (0 << BVTILE_BOTTOM_SHIFT) /* 012301230123... */
+#define BVTILE_LEFT_MIRROR (1 << BVTILE_LEFT_SHIFT) /* ...012332100123 */
+#define BVTILE_TOP_MIRROR (1 << BVTILE_TOP_SHIFT) /* ...012332100123 */
+#define BVTILE_RIGHT_MIRROR (1 << BVTILE_RIGHT_SHIFT) /* 012332100123... */
+#define BVTILE_BOTTOM_MIRROR (1 << BVTILE_BOTTOM_SHIFT) /* 012332100123... */
+
+/*
+ * bvtileparams - This structure provides additional parameters needed when
+ * tiling. This structure replaces the bvbuffdesc in bvbltparams when the
+ * associated BVFLAG_TILE_* flag is set in bvbltparams.flags.
+ */
+struct bvtileparams {
+ unsigned int structsize; /* used to ID structure version */
+ unsigned long flags; /* tile flags */
+ void *virtaddr; /* pointer to the brush */
+ int dstleft; /* horizontal offset */
+ int dsttop; /* vertical offset */
+ unsigned int srcwidth; /* w/dst width to spec horz scale */
+ unsigned int srcheight; /* w/dst height to spec vert scale */
+};
+
+/*
+ * BVBATCH_* - These flags specify the parameters that change between
+ * batched BLTs, when BVFLAG_CONTINUE or BVFLAG_END set.
+ */
+#define BVBATCH_OP 0x00000001 /* type of operation changed */
+#define BVBATCH_KEY 0x00000002 /* color key changed */
+#define BVBATCH_MISCFLAGS 0x00000004 /* other flags changed */
+#define BVBATCH_ALPHA 0x00000008 /* global alpha changed */
+#define BVBATCH_DITHER 0x00000010 /* dither changed */
+#define BVBATCH_SCALE 0x00000020 /* scaling type changed */
+/* Bits 6-7 reserved */
+#define BVBATCH_DST 0x00000100 /* destination surface changed */
+#define BVBATCH_SRC1 0x00000200 /* source 1 surface changed */
+#define BVBATCH_SRC2 0x00000400 /* source 2 surface changed */
+#define BVBATCH_MASK 0x00000800 /* mask surface changed */
+#define BVBATCH_DSTRECT_ORIGIN 0x00001000 /* dest rect origin changed */
+#define BVBATCH_DSTRECT_SIZE 0x00002000 /* dest rect dimensions changed */
+#define BVBATCH_SRC1RECT_ORIGIN 0x00004000 /* src 1 rect origin changed */
+#define BVBATCH_SRC1RECT_SIZE 0x00008000 /* src 1 rect dimensions changed */
+#define BVBATCH_SRC2RECT_ORIGIN 0x00010000 /* src 2 rect origin changed */
+#define BVBATCH_SRC2RECT_SIZE 0x00020000 /* src 2 rect dimensions changed */
+#define BVBATCH_MASKRECT_ORIGIN 0x00040000 /* mask rect origin changed */
+#define BVBATCH_MASKRECT_SIZE 0x00080000 /* mask rect dimensions changed */
+#define BVBATCH_CLIPRECT_ORIGIN 0x00100000 /* Clip rect origin changed */
+#define BVBATCH_CLIPRECT_SIZE 0x00200000 /* Clip rect dimensions changed */
+#define BVBATCH_CLIPRECT (BVBATCH_CLIPRECT_ORIGIN | \
+ BVBATCH_CLIPRECT_SIZE) /* clip rect... */
+ /* ...changed */
+#define BVBATCH_TILE_SRC1 0x00400000 /* tile params for src 1 changed */
+#define BVBATCH_TILE_SRC2 0x00800000 /* tile params for src 2 changed */
+#define BVBATCH_TILE_MASK 0x00100000 /* tile params for mask changed */
+/* Bits 30-21 reserved */
+#define BVBATCH_ENDNOP 0x80000000 /* just end batch, don't do BLT;
+ only with BVFLAG_BATCH_END */
+
+/*
+ * bvcallbackerror - This structure is passed into the callback function
+ * if an error occurs.
+ */
+struct bvcallbackerror {
+ unsigned int structsize; /* used to ID structure version */
+ enum bverror error; /* error during async BLT */
+ char *errdesc; /* 0-terminated ASCII string
+ with extended error info (not
+ for end users) */
+};
+
+/*
+ * bvbatch - an implementation-specific container for batch information;
+ * not used by client; forward declaration here
+ */
+struct bvbatch;
+
+/*
+ * bvinbuff - provides the buffer in bvbltparams
+ */
+union bvinbuff {
+ struct bvbuffdesc *desc; /* buffer description when
+ associated BVFLAG_TILE_*
+ is not set */
+ struct bvtileparams *tileparams; /* tile params when associated
+ BVFLAG_TILE_* flag is set */
+};
+
+/*
+ * bvop - used to hold the operation in bvbltparams
+ */
+union bvop {
+ unsigned short rop; /* when BVFLAG_ROP set */
+ enum bvblend blend; /* when BVFLAG_BLEND set */
+ struct bvfilter *filter; /* when BVFLAG_FILTER set */
+};
+
+
+/*
+ * bvbltparams - This structure is passed into bv_blt() to specify the
+ * parameters for a BLT.
+ */
+struct bvbltparams {
+ unsigned int structsize; /* (i) used to ID structure version */
+ char *errdesc; /* (o) 0-terminated ASCII string
+ with extended error info (not
+ for end users) */
+
+ unsigned long implementation; /* (i) override manager choice */
+
+ unsigned long flags; /* (i) see BVFLAG_* above */
+
+ union bvop op; /* (i) operation; determined by
+ BVFLAG_OP_MASK bits in flags */
+
+ void *colorkey; /* (i) pointer to color key pixel
+ matching non-SUBSAMPLE format
+ of the keyed surface when
+ BVFLAG_KEY_* is set */
+
+ union bvalpha globalalpha; /* (i) global alpha when BVFLAG_BLEND
+ set in flags and
+ BVBLENDDEF_GLOBAL_* is set in
+ blend; typed determined by
+ BVBLENDDEF_GLOBAL_* */
+
+ enum bvscalemode scalemode; /* (i/o) type of scaling */
+ enum bvdithermode dithermode; /* (i/o) type of dither */
+
+ struct bvbuffdesc *dstdesc; /* (i) dest after bv_map() */
+ struct bvsurfgeom *dstgeom; /* (i) dest surf fmt and geometry */
+ struct bvrect dstrect; /* (i) rect into which data written */
+
+ union bvinbuff src1; /* (i) src1 buffer */
+ struct bvsurfgeom *src1geom; /* (i) src1 surf fmt and geometry */
+ struct bvrect src1rect; /* (i) rect from which data is read */
+
+ union bvinbuff src2; /* (i) src2 buffer */
+ struct bvsurfgeom *src2geom; /* (i) src2 surf fmt and geometry */
+ struct bvrect src2rect; /* (i) rect from which data is read */
+
+ union bvinbuff mask; /* (i) mask buffer */
+ struct bvsurfgeom *maskgeom; /* (i) mask surf fmt and geometry */
+ struct bvrect maskrect; /* (i) rect from which data is read */
+
+ struct bvrect cliprect; /* (i) dest clipping rect when
+ BVFLAG_CLIP flag set */
+
+ unsigned long batchflags; /* (i) BVBATCH_* flags used to
+ indicate params changed between
+ batch BLTs */
+ struct bvbatch *batch; /* (i/o) handle for associated batch;
+ returned when
+ BVFLAG_BATCH_BEGIN set;
+ provided to subsequent BLTs
+ with BVFLAG_BATCH_CONTINUE */
+
+ void (*callbackfn)(struct bvcallbackerror *err,
+ unsigned long callbackdata); /* (i) callback
+ function when
+ BVFLAG_ASYNC is set -
+ err is 0 when no
+ error; handle contains
+ callbackdata below */
+ unsigned long callbackdata; /* (i) callback data */
+};
+
+#endif /* BLTSVILLE_H */
diff --git a/kernel-headers/linux/bvblend.h b/kernel-headers/linux/bvblend.h
new file mode 100644
index 0000000..8e63999
--- /dev/null
+++ b/kernel-headers/linux/bvblend.h
@@ -0,0 +1,507 @@
+/*
+ * bvblend.h
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ * This file defines the types of shared blends available.
+ *
+ * To extend the list of blends, create a file containing additional
+ * enumerations to be added to enum bvblend below. Then #define
+ * BVBLEND_EXTERNAL_INCLUDE as the name of that file before including
+ * this file in your project.
+ */
+
+#ifndef BVBLEND_H
+#define BVBLEND_H
+
+/*
+ * bvblend - specifies the type of blending operation to perform; only valid
+ * when BVFLAG_BLEND is set in the bvbltparams.flags field.
+ */
+
+/*
+ * The blendmode value is divided into two sections.
+ *
+ * [31:28] The most significant 4 bits indicate the blend format.
+ *
+ * [27:0] The remainder of the bits is defined by the format chosen.
+ *
+ * 3322222222221111111111
+ * 10987654321098765432109876543210
+ * [ ][ ]
+ * | |
+ * format defined by format
+ */
+
+#define BVBLENDDEF_FORMAT_SHIFT 28
+#define BVBLENDDEF_FORMAT_MASK (0xF << BVBLENDDEF_FORMAT_SHIFT)
+
+#define BVBLENDDEF_FORMAT_CLASSIC (0x0 << BVBLENDDEF_FORMAT_SHIFT)
+#define BVBLENDDEF_FORMAT_ESSENTIAL (0x1 << BVBLENDDEF_FORMAT_SHIFT)
+
+/*
+ * The BVBLENDDEF_FORMAT_CLASSIC is meant to handle the classic Porter-Duff
+ * equations. It can also handle the DirectFB blending.
+ * BVBLENDDEF_FORMAT_CLASSIC is based on the following equations:
+ *
+ * Cd = K1 x C1 + K2 x C2
+ * Ad = K3 x A1 + K4 x A2
+ *
+ * where:
+ * Cd: destination color
+ * C1: source 1 color
+ * C2: source 2 color
+ * Ad: destination alpha
+ * A1: source 1 alpha
+ * A2: source 2 alpha
+ * K#: one of the constants defined using the bitfields below.
+ */
+
+/*
+ * The 28 bits for BVBLENDDEF_FORMAT_CLASSIC are divided into 5 sections.
+ *
+ * The most significant 4 bits are modifiers, used to include additional
+ * alpha values from global or remote sources.
+ *
+ * [27] The most significant bit indicates that a remote alpha is to be
+ * included in the blend. The format of this is defined by
+ * bvbltparams.maskgeom.format.
+ *
+ * [26] The next bit is reserved.
+ *
+ * [25:24] The next 2 bits are used to indicate that a global alpha is to be
+ * included, and what its format is:
+ * 00: no global included
+ * 01: global included; bvbltparams.globalalpha.size8 is used (0 -> 255)
+ * 10: this value is reserved
+ * 11: global included; bvbltparams.flogalalpha.fp is used (0.0 -> 1.0)
+ *
+ * The remaining bits are divided into 4 sections, one to define each of the
+ * constants:
+ *
+ * [23:18] - K1
+ * [17:12] - K2
+ * [11:6] - K3
+ * [5:0] - K4
+ *
+ * The format is the same for all 4 constant fields:
+ *
+ * [5:4] The first 2 bits of each field indicates the way in which the other
+ * 2 fields are interpreted:
+ * 00: only As: the other two fields contain only As; there should be only
+ * one valid A value between the two fields
+ * 01: minimum: the value of the constant is the minimum of the two fields
+ * 10: maximum: the value of the constant is the maximum of the two fields
+ * 11: only Cs: the other two fields contain only Cs; there should be only
+ * one valid C value between the two fields
+ *
+ * [3:2] The middle 2 bits of each field contain the inverse field:
+ * 00: 1-C1 ("don't care" for "only As")
+ * 01: 1-A1 ("don't care" for "only Cs")
+ * 10: 1-C2 ("don't care" for "only As")
+ * 11: 1-A2 ("don't care" for "only Cs")
+ *
+ * [1:0] The last 2 bits if each field contain the normal field:
+ * 00: C1 ("don't care" for "only As")
+ * 01: A1 ("don't care" for "only Cs")
+ * 10: C2 ("don't care" for "only As")
+ * 11: A2 ("don't care" for "only Cs")
+ *
+ * EXCEPTIONS:
+ *
+ * 00 00 00 - The value 00 00 00, which normally would indicate "only As"
+ * with two "don't care" fields, is interpreted as a 0.
+ *
+ * 11 11 11 - The value 11 11 11, which normally would indicate "only Cs"
+ * with two "don't care" fields, is interpreted as a 1.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Put together, these can define portions of the blend equations that can be
+ * put together in a variety of ways:
+ *
+ * 00 00 00: undefined -> zero
+ * 00 00 01: A1 (preferred)
+ * 00 00 10: undefined
+ * 00 00 11: A2 (preferred)
+ * 00 01 00: 1-A1 (preferred)
+ * 00 01 01: undefined
+ * 00 01 10: 1-A1 (use 00 01 00)
+ * 00 01 11: undefined
+ * 00 10 00: undefined
+ * 00 10 01: A1 (use 00 00 01)
+ * 00 10 10: undefined
+ * 00 10 11: A2 (use 00 00 11)
+ * 00 11 00: 1-A2 (preferred)
+ * 00 11 01: undefined
+ * 00 11 10: 1-A2 (use 00 11 00)
+ * 00 11 11: undefined
+ *
+ * 01 00 00: min(C1,1-C1)
+ * 01 00 01: min(A1,1-C1)
+ * 01 00 10: min(C2,1-C1)
+ * 01 00 11: min(A2,1-C1)
+ * 01 01 00: min(C1,1-A1)
+ * 01 01 01: min(A1,1-A1)
+ * 01 01 10: min(C2,1-A1)
+ * 01 01 11: min(A2,1-A1)
+ * 01 10 00: min(C1,1-C2)
+ * 01 10 01: min(A1,1-C2)
+ * 01 10 10: min(C2,1-C2)
+ * 01 10 11: min(A2,1-C2)
+ * 01 11 00: min(C1,1-A2)
+ * 01 11 01: min(A1,1-A2)
+ * 01 11 10: min(C2,1-A2)
+ * 01 11 11: min(A2,1-A2)
+ *
+ * 10 00 00: max(C1,1-C1)
+ * 10 00 01: max(A1,1-C1)
+ * 10 00 10: max(C2,1-C1)
+ * 10 00 11: max(A2,1-C1)
+ * 10 01 00: max(C1,1-A1)
+ * 10 01 01: max(A1,1-A1)
+ * 10 01 10: max(C2,1-A1)
+ * 10 01 11: max(A2,1-A1)
+ * 10 10 00: max(C1,1-C2)
+ * 10 10 01: max(A1,1-C2)
+ * 10 10 10: max(C2,1-C2)
+ * 10 10 11: max(A2,1-C2)
+ * 10 11 00: max(C1,1-A2)
+ * 10 11 01: max(A1,1-A2)
+ * 10 11 10: max(C2,1-A2)
+ * 10 11 11: max(A2,1-A2)
+ *
+ * 11 00 00: undefined
+ * 11 00 01: 1-C1 (use 11 00 11)
+ * 11 00 10: undefined
+ * 11 00 11: 1-C1 (preferred)
+ * 11 01 00: C1 (use 11 11 00)
+ * 11 01 01: undefined
+ * 11 01 10: C2 (use 11 11 10)
+ * 11 01 11: undefined
+ * 11 10 00: undefined
+ * 11 10 01: 1-C2 (use 11 10 11)
+ * 11 10 10: undefined
+ * 11 10 11: 1-C2 (preferred)
+ * 11 11 00: C1 (preferred)
+ * 11 11 01: undefined
+ * 11 11 10: C2 (preferred)
+ * 11 11 11: undefined -> one
+ *
+ * ==========================================================================
+ * DirectFB
+ * ==========================================================================
+ *
+ * Putting these together into the proper constants, the blending equations
+ * can be built for DirectFB as well:
+ *
+ * For DirectFB, the SetSrcBlendFunction() and SetDstBlendFunction() can
+ * specify 121 combinations of blends (11 x 11). It's impractical to
+ * specify these combinations individually. Instead, the settings indicated
+ * by each call should be bitwise OR'd to make the proper single value used in
+ * BLTsville.
+ *
+ * binary value <- SetSrcBlendFunction()
+ * [--K1--] [--K2--] [--K3--] [--K4--]
+ * 0000 0000 00 00 00 xx xx xx 00 00 00 xx xx xx <- DSBF_ZERO
+ * 0000 0000 11 11 11 xx xx xx 11 11 11 xx xx xx <- DSBF_ONE
+ * 0000 0000 11 11 00 xx xx xx 00 00 01 xx xx xx <- DSBF_SRCCOLOR
+ * 0000 0000 11 00 11 xx xx xx 00 01 00 xx xx xx <- DSBF_INVSRCCOLOR
+ * 0000 0000 00 00 01 xx xx xx 00 00 01 xx xx xx <- DSBF_SRCALPHA
+ * 0000 0000 00 01 00 xx xx xx 00 01 00 xx xx xx <- DSBF_INVSRCALPHA
+ * 0000 0000 11 11 10 xx xx xx 00 00 11 xx xx xx <- DSBF_DESTCOLOR
+ * 0000 0000 11 10 11 xx xx xx 00 11 00 xx xx xx <- DSBF_INVDESTCOLOR
+ * 0000 0000 00 00 11 xx xx xx 00 00 11 xx xx xx <- DSBF_DESTALPHA
+ * 0000 0000 00 11 00 xx xx xx 00 11 00 xx xx xx <- DSBF_INVDESTALPHA
+ * 0000 0000 01 11 01 xx xx xx 11 11 11 xx xx xx <- DSBF_SRCALPHASAT
+ *
+ * binary value <- SetDstBlendFunction()
+ * [--K1--] [--K2--] [--K3--] [--K4--]
+ * 0000 0000 xx xx xx 00 00 00 xx xx xx 00 00 00 <- DSBF_ZERO
+ * 0000 0000 xx xx xx 11 11 11 xx xx xx 11 11 11 <- DSBF_ONE
+ * 0000 0000 xx xx xx 11 11 00 xx xx xx 00 00 01 <- DSBF_SRCCOLOR
+ * etc.
+ *
+ * ==========================================================================
+ * Porter-Duff
+ * ==========================================================================
+ *
+ * For Porter-Duff, the equations can be more specifically defined. For
+ * convenience, these are enumerated below. These utilize the local alpha as
+ * indicated. To use global or remote alpha, these enumerations need to be
+ * modified. For example, to include the global alpha in the Porter-Duff
+ * SRC1OVER blend, the blend could be defined like this:
+ * params.op.blend = BVBLEND_SRC1OVER +
+ * BVBLENDDEF_GLOBAL_UCHAR;
+ *
+ * To include the remote alpha, the blend could be defined like this:
+ * params.op.blend = BVBLEND_SRC1OVER +
+ * BVBLENDDEF_REMOTE;
+ *
+ * And to include both:
+ * params.op.blend = BVBLEND_SRC1OVER +
+ * BVBLENDDEF_GLOBAL_UCHAR +
+ * BVBLENDDEF_REMOTE;
+ *
+ * Note that if the source color formats include local alphas, the local
+ * alphas, global alpha, and remote alpha will be used together.
+ *
+ * Note also that the equations assume the surfaces are premultiplied. So
+ * if the surface formats indicate that they are not premultiplied, the
+ * alpha multiplication of each color is done prior to using the surface
+ * values in the equations.
+ *
+ * For example, BVBLEND_SRC1OVER specifies the equations:
+ * Cd = 1 x C1 + (1 - A1) x C2
+ * Ad = 1 x A1 + (1 - A1) x A2
+ *
+ * If the format of surface 1 is non-premultiplied, the equations
+ * are modified to include the multiplication explicitly:
+ * Cd = 1 x A1 x C1 + (1 - A1) x C2
+ * Ad = 1 x A1 + (1 - A1) x A2
+ *
+ * Likewise, if the format of surface 2 is non-premultiplied, the
+ * equations are modified for this:
+ * Cd = 1 x C1 + (1 - A1) x A2 x C2
+ * Ad = 1 x A1 + (1 - A1) x A2
+ *
+ * When including global or remote alphas, these values are used to modify
+ * the source 1 value values before being used in the blend equation:
+ * C1 = Ag x C1
+ * A1 = Ag x A1
+ * -or-
+ * C1 = Ar x C1
+ * A1 = Ar x A1
+ * -or-
+ * C1 = Ag x Ar x C1
+ * A1 = Ag x Ar x A1
+ *
+ */
+
+#define BVBLENDDEF_MODE_SHIFT 4
+#define BVBLENDDEF_INV_SHIFT 2
+#define BVBLENDDEF_NORM_SHIFT 0
+
+#define BVBLENDDEF_ONLY_A (0 << BVBLENDDEF_MODE_SHIFT)
+#define BVBLENDDEF_MIN (1 << BVBLENDDEF_MODE_SHIFT)
+#define BVBLENDDEF_MAX (2 << BVBLENDDEF_MODE_SHIFT)
+#define BVBLENDDEF_ONLY_C (3 << BVBLENDDEF_MODE_SHIFT)
+#define BVBLENDDEF_MODE_MASK (3 << BVBLENDDEF_MODE_SHIFT)
+
+#define BVBLENDDEF_NORM_C1 (0 << BVBLENDDEF_NORM_SHIFT)
+#define BVBLENDDEF_NORM_A1 (1 << BVBLENDDEF_NORM_SHIFT)
+#define BVBLENDDEF_NORM_C2 (2 << BVBLENDDEF_NORM_SHIFT)
+#define BVBLENDDEF_NORM_A2 (3 << BVBLENDDEF_NORM_SHIFT)
+#define BVBLENDDEF_NORM_MASK (3 << BVBLENDDEF_NORM_SHIFT)
+
+#define BVBLENDDEF_INV_C1 (0 << BVBLENDDEF_INV_SHIFT)
+#define BVBLENDDEF_INV_A1 (1 << BVBLENDDEF_INV_SHIFT)
+#define BVBLENDDEF_INV_C2 (2 << BVBLENDDEF_INV_SHIFT)
+#define BVBLENDDEF_INV_A2 (3 << BVBLENDDEF_INV_SHIFT)
+#define BVBLENDDEF_INV_MASK (3 << BVBLENDDEF_INV_SHIFT)
+
+#define BVBLENDDEF_ONLY_A_NORM_xx BVBLENDDEF_NORM_C1
+#define BVBLENDDEF_ONLY_A_INV_xx BVBLENDDEF_INV_C1
+#define BVBLENDDEF_ONLY_C_NORM_xx BVBLENDDEF_NORM_A2
+#define BVBLENDDEF_ONLY_C_INV_xx BVBLENDDEF_INV_A2
+
+#define BVBLENDDEF_ZERO \
+ (BVBLENDDEF_ONLY_A | \
+ BVBLENDDEF_ONLY_A_NORM_xx | \
+ BVBLENDDEF_ONLY_A_INV_xx)
+#define BVBLENDDEF_C1 \
+ (BVBLENDDEF_ONLY_C | \
+ BVBLENDDEF_NORM_C1 | \
+ BVBLENDDEF_ONLY_C_INV_xx)
+#define BVBLENDDEF_A1 \
+ (BVBLENDDEF_ONLY_A | \
+ BVBLENDDEF_NORM_A1 | \
+ BVBLENDDEF_ONLY_A_INV_xx)
+#define BVBLENDDEF_C2 \
+ (BVBLENDDEF_ONLY_C | \
+ BVBLENDDEF_NORM_C2 | \
+ BVBLENDDEF_ONLY_C_INV_xx)
+#define BVBLENDDEF_A2 \
+ (BVBLENDDEF_ONLY_A | \
+ BVBLENDDEF_NORM_A2 | \
+ BVBLENDDEF_ONLY_A_INV_xx)
+#define BVBLENDDEF_ONE_MINUS_C1 \
+ (BVBLENDDEF_ONLY_C | \
+ BVBLENDDEF_ONLY_C_NORM_xx | \
+ BVBLENDDEF_INV_C1)
+#define BVBLENDDEF_ONE_MINUS_A1 \
+ (BVBLENDDEF_ONLY_A | \
+ BVBLENDDEF_ONLY_A_NORM_xx | \
+ BVBLENDDEF_INV_A1)
+#define BVBLENDDEF_ONE_MINUS_C2 \
+ (BVBLENDDEF_ONLY_C | \
+ BVBLENDDEF_ONLY_C_NORM_xx | \
+ BVBLENDDEF_INV_C2)
+#define BVBLENDDEF_ONE_MINUS_A2 \
+ (BVBLENDDEF_ONLY_A | \
+ BVBLENDDEF_ONLY_A_NORM_xx | \
+ BVBLENDDEF_INV_A2)
+#define BVBLENDDEF_ONE \
+ (BVBLENDDEF_ONLY_C | \
+ BVBLENDDEF_ONLY_C_NORM_xx | \
+ BVBLENDDEF_ONLY_C_INV_xx)
+
+#define BVBLENDDEF_K_MASK \
+ (BVBLENDDEF_MODE_MASK | \
+ BVBLENDDEF_INV_MASK | \
+ BVBLENDDEF_NORM_MASK)
+
+#define BVBLENDDEF_K1_SHIFT 18
+#define BVBLENDDEF_K2_SHIFT 12
+#define BVBLENDDEF_K3_SHIFT 6
+#define BVBLENDDEF_K4_SHIFT 0
+
+#define BVBLENDDEF_K1_MASK \
+ (BVBLENDDEF_K_MASK << BVBLENDDEF_K1_SHIFT)
+#define BVBLENDDEF_K2_MASK \
+ (BVBLENDDEF_K_MASK << BVBLENDDEF_K2_SHIFT)
+#define BVBLENDDEF_K3_MASK \
+ (BVBLENDDEF_K_MASK << BVBLENDDEF_K3_SHIFT)
+#define BVBLENDDEF_K4_MASK \
+ (BVBLENDDEF_K_MASK << BVBLENDDEF_K4_SHIFT)
+
+#define BVBLENDDEF_CLASSIC_EQUATION_MASK 0x00FFFFFF
+
+/*
+ * The following definitions are be used to modify the enumerations.
+ */
+#define BVBLENDDEF_REMOTE 0x08000000 /* mask surface provides alpha
+ for source 1 */
+
+/* Bit 26 reserved */
+
+/* These enable global alpha and define the type of globalalpha */
+#define BVBLENDDEF_GLOBAL_SHIFT 24
+#define BVBLENDDEF_GLOBAL_MASK (3 << BVBLENDDEF_GLOBAL_SHIFT)
+
+#define BVBLENDDEF_GLOBAL_NONE (0 << BVBLENDDEF_GLOBAL_SHIFT)
+#define BVBLENDDEF_GLOBAL_UCHAR (1 << BVBLENDDEF_GLOBAL_SHIFT)
+/* 2 reserved */
+#define BVBLENDDEF_GLOBAL_FLOAT (3 << BVBLENDDEF_GLOBAL_SHIFT)
+
+union bvalpha {
+ unsigned char size8; /* btwn 0 (0.0) and 255 (1.0) */
+ float fp; /* btwn 0.0 and 1.0 */
+};
+
+
+enum bvblend {
+ /* Porter-Duff blending equations */
+ BVBLEND_CLEAR = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_SRC1 = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_SRC2 = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_SRC1OVER = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A1 << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A1 << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_SRC2OVER = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ONE_MINUS_A2 << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A2 << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_SRC1IN = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_A2 << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_A2 << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_SRC2IN = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_A1 << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_A1 << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_SRC1OUT = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ONE_MINUS_A2 << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A2 << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_SRC2OUT = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A1 << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ZERO << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A1 << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_SRC1ATOP = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_A2 << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A1 << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_A2 << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A1 << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_SRC2ATOP = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ONE_MINUS_A2 << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_A1 << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A2 << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_A1 << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_XOR = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ONE_MINUS_A2 << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A1 << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A2 << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ONE_MINUS_A1 << BVBLENDDEF_K4_SHIFT),
+ BVBLEND_PLUS = BVBLENDDEF_FORMAT_CLASSIC |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K1_SHIFT) |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K2_SHIFT) |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K3_SHIFT) |
+ (BVBLENDDEF_ONE << BVBLENDDEF_K4_SHIFT),
+
+/*
+ * For FORMAT_ESSENTIAL, the variety of well-known blending functions from
+ * popular image manipulation programs are specified.
+ */
+
+ BVBLEND_NORMAL = BVBLENDDEF_FORMAT_ESSENTIAL + 0,
+ BVBLEND_LIGHTEN = BVBLENDDEF_FORMAT_ESSENTIAL + 1,
+ BVBLEND_DARKEN = BVBLENDDEF_FORMAT_ESSENTIAL + 2,
+ BVBLEND_MULTIPLY = BVBLENDDEF_FORMAT_ESSENTIAL + 3,
+ BVBLEND_AVERAGE = BVBLENDDEF_FORMAT_ESSENTIAL + 4,
+ BVBLEND_ADD = BVBLENDDEF_FORMAT_ESSENTIAL + 5,
+ BVBLEND_LINEAR_DODGE = BVBLEND_ADD,
+ BVBLEND_SUBTRACT = BVBLENDDEF_FORMAT_ESSENTIAL + 6,
+ BVBLEND_LINEAR_BURN = BVBLEND_SUBTRACT,
+ BVBLEND_DIFFERENCE = BVBLENDDEF_FORMAT_ESSENTIAL + 7,
+ BVBLEND_NEGATE = BVBLENDDEF_FORMAT_ESSENTIAL + 8,
+ BVBLEND_SCREEN = BVBLENDDEF_FORMAT_ESSENTIAL + 9,
+ BVBLEND_EXCLUSION = BVBLENDDEF_FORMAT_ESSENTIAL + 10,
+ BVBLEND_OVERLAY = BVBLENDDEF_FORMAT_ESSENTIAL + 11,
+ BVBLEND_SOFT_LIGHT = BVBLENDDEF_FORMAT_ESSENTIAL + 12,
+ BVBLEND_HARD_LIGHT = BVBLENDDEF_FORMAT_ESSENTIAL + 13,
+ BVBLEND_COLOR_DODGE = BVBLENDDEF_FORMAT_ESSENTIAL + 14,
+ BVBLEND_COLOR_BURN = BVBLENDDEF_FORMAT_ESSENTIAL + 15,
+ BVBLEND_LINEAR_LIGHT = BVBLENDDEF_FORMAT_ESSENTIAL + 16,
+ BVBLEND_VIVID_LIGHT = BVBLENDDEF_FORMAT_ESSENTIAL + 17,
+ BVBLEND_PIN_LIGHT = BVBLENDDEF_FORMAT_ESSENTIAL + 18,
+ BVBLEND_HARD_MIX = BVBLENDDEF_FORMAT_ESSENTIAL + 19,
+ BVBLEND_REFLECT = BVBLENDDEF_FORMAT_ESSENTIAL + 20,
+ BVBLEND_GLOW = BVBLENDDEF_FORMAT_ESSENTIAL + 21,
+ BVBLEND_PHOENIX = BVBLENDDEF_FORMAT_ESSENTIAL + 22,
+
+#ifdef BVBLEND_EXTERNAL_INCLUDE
+#define BVBLEND_EXTERNAL_INCLUDE
+#endif
+};
+
+#endif /* BVBLEND_H */
diff --git a/kernel-headers/linux/bvbuffdesc.h b/kernel-headers/linux/bvbuffdesc.h
new file mode 100644
index 0000000..8dab36f
--- /dev/null
+++ b/kernel-headers/linux/bvbuffdesc.h
@@ -0,0 +1,68 @@
+/*
+ * bvbuffdesc.h
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef BVBUFFDESC_H
+#define BVBUFFDESC_H
+
+/*
+ * bvbuffmap - This is a private structure used by BLTsville
+ * implementations to manage resources associated with a buffer. A pointer
+ * to this is returned from bv_map() and used in subsequent bv_blt() and
+ * bv_unmap() calls.
+ */
+struct bvbuffmap;
+
+#define BVATDEF_VENDOR_SHIFT 24
+#define BVATDEF_VENDOR_MASK (0xFF << BVATDEF_VENDOR_SHIFT)
+
+/* Common aux type */
+#define BVATDEF_VENDOR_ALL (0x00 << BVATDEF_VENDOR_SHIFT)
+
+/* Texas Instruments, Inc. */
+#define BVATDEF_VENDOR_TI (0x01 << BVATDEF_VENDOR_SHIFT)
+
+enum bvauxtype {
+ BVAT_NONE = 0, /* auxptr not used */
+ BVAT_PHYSDESC = /* handle points to bvphysdesc struct */
+ BVATDEF_VENDOR_ALL + 1,
+
+#ifdef BVAT_EXTERNAL_INCLUDE
+#include BVAT_EXTERNAL_INCLUDE
+#endif
+};
+
+
+struct bvphysdesc {
+ unsigned int structsize; /* used to identify struct version */
+ unsigned long pagesize; /* page size in bytes */
+ unsigned long *pagearray; /* array of physical pages */
+ unsigned int pagecount; /* number of pages in the pagearray */
+ unsigned long pageoffset; /* page offset in bytes */
+};
+
+/*
+ * bvbuffdesc - This structure is used to specify the buffer parameters
+ * in a call to bv_map().
+ */
+struct bvbuffdesc {
+ unsigned int structsize; /* used to identify struct version */
+ void *virtaddr; /* virtual ptr to start of buffer */
+ unsigned long length; /* length of the buffer in bytes */
+ struct bvbuffmap *map; /* resource(s) associated w/buffer */
+ enum bvauxtype auxtype; /* type of auxptr */
+ void *auxptr; /* additional buffer description data;
+ type depends on auxtype */
+};
+
+#endif /* BVBUFFDESC_H */
diff --git a/kernel-headers/linux/bvcache.h b/kernel-headers/linux/bvcache.h
new file mode 100644
index 0000000..af7f0ab
--- /dev/null
+++ b/kernel-headers/linux/bvcache.h
@@ -0,0 +1,44 @@
+/*
+ * bvcache.h
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef BVCACHE_H_
+#define BVCACHE_H_
+
+/* Forward declarations */
+struct bvbuffdesc;
+struct bvsurfgeom;
+struct bvrect;
+
+/*
+ * This defines which cache operation the user intends to use
+ * BVCACHE_CPU_TO_DEVICE = clean
+ * BVCACHE_CPU_FROM_DEVICE = invalidate
+ * BVCACHE_BIDIRECTIONAL = flush
+ */
+enum bvcacheop {
+ BVCACHE_BIDIRECTIONAL = 0,
+ BVCACHE_CPU_TO_DEVICE = 1,
+ BVCACHE_CPU_FROM_DEVICE = 2,
+ BVCACHE_RESERVED3 = 3,
+};
+
+struct bvcopparams {
+ unsigned int structsize; /* used to identify struct version */
+ struct bvbuffdesc *desc;
+ struct bvsurfgeom *geom;
+ struct bvrect *rect;
+ enum bvcacheop cacheop;
+};
+
+#endif /* BVCACHE_H_ */
diff --git a/kernel-headers/linux/bventry.h b/kernel-headers/linux/bventry.h
new file mode 100644
index 0000000..272c0e6
--- /dev/null
+++ b/kernel-headers/linux/bventry.h
@@ -0,0 +1,38 @@
+/*
+ * bventry.h
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef BVENTRY_H
+#define BVENTRY_H
+
+/* Forward declarations */
+struct bvbuffdesc;
+struct bvbltparams;
+struct bvcopparams;
+/*
+ * BLTsville interface definition.
+ */
+typedef enum bverror (*BVFN_MAP) (struct bvbuffdesc *buffdesc);
+typedef enum bverror (*BVFN_UNMAP) (struct bvbuffdesc *buffdesc);
+typedef enum bverror (*BVFN_BLT) (struct bvbltparams *bltparams);
+typedef enum bverror (*BVFN_CACHE)(struct bvcopparams *copparams);
+
+struct bventry {
+ unsigned int structsize; /* used to identify struct version */
+ BVFN_MAP bv_map;
+ BVFN_UNMAP bv_unmap;
+ BVFN_BLT bv_blt;
+ BVFN_CACHE bv_cache;
+};
+
+#endif /* BVENTRY_H */
diff --git a/kernel-headers/linux/bverror.h b/kernel-headers/linux/bverror.h
new file mode 100644
index 0000000..63abc70
--- /dev/null
+++ b/kernel-headers/linux/bverror.h
@@ -0,0 +1,306 @@
+/*
+ * bverror.h
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef BVERROR_H
+#define BVERROR_H
+
+/*
+ * bverror - These are error codes returned by BLTsville functions.
+ */
+#define BVERRDEF_VENDOR_SHIFT 24
+#define BVERRDEF_VENDOR_MASK (0xFF << BVERRDEF_VENDOR_SHIFT)
+
+#define BVERRDEF_VENDOR_ALL (0x00 << BVERRDEF_VENDOR_SHIFT)
+#define BVERRDEF_VENDOR_TI (0x01 << BVERRDEF_VENDOR_SHIFT)
+/* 0xF0-0xFF reserved */
+
+enum bverror {
+ BVERR_NONE = 0, /* no error */
+
+ BVERR_UNK = /* unknown error */
+ BVERRDEF_VENDOR_ALL + 1,
+ BVERR_OOM = /* memory allocation failure */
+ BVERRDEF_VENDOR_ALL + 2,
+ BVERR_RSRC = /* required resource unavailable */
+ BVERRDEF_VENDOR_ALL + 3,
+
+ BVERR_VIRTADDR = /* virtaddr is bad */
+ BVERRDEF_VENDOR_ALL + 1000,
+ BVERR_VIRTPTR =
+ BVERR_VIRTADDR, /* for backwards compatibility*/
+
+ BVERR_BUFFERDESC = /* invalid bvbufferdesc */
+ BVERRDEF_VENDOR_ALL + 10000,
+ BVERR_BUFFERDESC_VERS = /* bvbufferdesc.structsize too small */
+ BVERRDEF_VENDOR_ALL + 11000,
+ BVERR_BUFFERDESC_VIRTADDR = /* bad bvbufferdesc.virtaddr */
+ BVERRDEF_VENDOR_ALL + 12000,
+ BVERR_BUFFERDESC_LEN = /* bvbufferdesc.length not supported */
+ BVERRDEF_VENDOR_ALL + 13000,
+ BVERR_BUFFERDESC_ALIGNMENT = /* unsupported buffer base address */
+ BVERRDEF_VENDOR_ALL + 14000,
+
+ BVERR_BLTPARAMS_VERS = /* bvbltparams.structsize too small */
+ BVERRDEF_VENDOR_ALL + 20000,
+ BVERR_IMPLEMENTATION = /* bvbltparams.implementation unsupported */
+ BVERRDEF_VENDOR_ALL + 21000,
+ BVERR_FLAGS = /* bvbltparams.flags unsupported */
+ BVERRDEF_VENDOR_ALL + 22000,
+ BVERR_OP = /* unsupported operation */
+ BVERRDEF_VENDOR_ALL + 22100,
+ BVERR_KEY = /* type of color key not supported */
+ BVERRDEF_VENDOR_ALL + 22200,
+ BVERR_SRC1_TILE = /* src1 tiling not supported */
+ BVERRDEF_VENDOR_ALL + 22300,
+ BVERR_SRC2_TILE = /* src2 tiling not supported */
+ BVERRDEF_VENDOR_ALL + 22310,
+ BVERR_MASK_TILE = /* mask tiling not supported */
+ BVERRDEF_VENDOR_ALL + 22320,
+ BVERR_FLIP = /* flipping not supported */
+ BVERRDEF_VENDOR_ALL + 22400,
+ BVERR_ROP = /* ROP code not supported */
+ BVERRDEF_VENDOR_ALL + 23000,
+ BVERR_BLEND = /* blend not supported */
+ BVERRDEF_VENDOR_ALL + 23100,
+ BVERR_GLOBAL_ALPHA = /* type of global alpha not supported */
+ BVERRDEF_VENDOR_ALL + 23110,
+ BVERR_FILTER = /* filter type not supported */
+ BVERRDEF_VENDOR_ALL + 23200,
+ BVERR_FILTER_PARAMS_VERS = /* filter parameter structsize too small */
+ BVERRDEF_VENDOR_ALL + 23210,
+ BVERR_FILTER_PARAMS = /* filter parameters not supported */
+ BVERRDEF_VENDOR_ALL + 23220,
+ BVERR_SCALE_MODE = /* bvbltparams.scalemode not supported */
+ BVERRDEF_VENDOR_ALL + 24000,
+ BVERR_DITHER_MODE = /* bvbltparams.dithermode not supported */
+ BVERRDEF_VENDOR_ALL + 25000,
+
+ BVERR_DSTDESC = /* invalid bvbltparams.dstdesc */
+ BVERRDEF_VENDOR_ALL + 26000,
+ BVERR_DSTDESC_VERS = /* bvbufferdesc.structsize too small */
+ BVERRDEF_VENDOR_ALL + 26100,
+ BVERR_DSTDESC_VIRTADDR = /* bad bvbufferdesc.virtaddr */
+ BVERRDEF_VENDOR_ALL + 26200,
+ BVERR_DSTDESC_LEN = /* bvbufferdesc.length not supported */
+ BVERRDEF_VENDOR_ALL + 26300,
+ BVERR_DST_ALIGNMENT = /* unsupported buffer base address */
+ BVERRDEF_VENDOR_ALL + 26400,
+
+ BVERR_DSTGEOM = /* invalid bvbltparams.dstgeom */
+ BVERRDEF_VENDOR_ALL + 27000,
+ BVERR_DSTGEOM_VERS = /* dstgeom.structsize too small */
+ BVERRDEF_VENDOR_ALL + 27100,
+ BVERR_DSTGEOM_FORMAT = /* bltparams.dstgeom.format not supported */
+ BVERRDEF_VENDOR_ALL + 27200,
+ BVERR_DSTGEOM_STRIDE = /* bltparams.dstgeom.stride not supported */
+ BVERRDEF_VENDOR_ALL + 27300,
+ BVERR_DSTGEOM_PALETTE = /* dstgeom.paletteformat not supported */
+ BVERRDEF_VENDOR_ALL + 27400,
+
+
+ BVERR_DSTRECT = /* bvbltparams.dstrect not supported */
+ BVERRDEF_VENDOR_ALL + 28000,
+
+ BVERR_SRC1DESC = /* invalid bvbltparams.src1.desc */
+ BVERRDEF_VENDOR_ALL + 29000,
+ BVERR_SRC1DESC_VERS = /* bvbufferdesc.structsize too small */
+ BVERRDEF_VENDOR_ALL + 29100,
+ BVERR_SRC1DESC_VIRTADDR = /* bad bvbufferdesc.virtaddr */
+ BVERRDEF_VENDOR_ALL + 29200,
+ BVERR_SRC1DESC_LEN = /* bvbufferdesc.length not supported */
+ BVERRDEF_VENDOR_ALL + 29300,
+ BVERR_SRC1DESC_ALIGNMENT = /* unsupported buffer base address */
+ BVERRDEF_VENDOR_ALL + 29400,
+
+ BVERR_SRC1GEOM = /* invalid bvbltparams.src1geom */
+ BVERRDEF_VENDOR_ALL + 30000,
+ BVERR_SRC1GEOM_VERS = /* src1geom.structsize too small */
+ BVERRDEF_VENDOR_ALL + 30100,
+ BVERR_SRC1GEOM_FORMAT = /* bltparams.src1geom.format not supported */
+ BVERRDEF_VENDOR_ALL + 30200,
+ BVERR_SRC1GEOM_STRIDE = /* bltparams.src1geom.stride not supported */
+ BVERRDEF_VENDOR_ALL + 30300,
+ BVERR_SRC1GEOM_PALETTE = /* src1geom.paletteformat not supported */
+ BVERRDEF_VENDOR_ALL + 30400,
+
+ BVERR_SRC1RECT = /* bvbltparams.src1rect not supported */
+ BVERRDEF_VENDOR_ALL + 31000,
+
+ BVERR_SRC1_HORZSCALE = /* horz scale for src1->dst not supported */
+ BVERRDEF_VENDOR_ALL + 31100,
+ BVERR_SRC1_VERTSCALE = /* vert scale for src1->dst not supported */
+ BVERRDEF_VENDOR_ALL + 31200,
+ BVERR_SRC1_ROT = /* src1->dst rotation angle not supported */
+ BVERRDEF_VENDOR_ALL + 31300,
+
+ BVERR_SRC1_TILEPARAMS = /* invalid src1.tileparams */
+ BVERR_SRC1DESC,
+ BVERR_SRC1_TILE_VERS = /* src1.tileparams.structsize too small */
+ BVERRDEF_VENDOR_ALL + 32000,
+ BVERR_SRC1_TILEPARAMS_VERS =
+ BVERR_SRC1_TILE_VERS,
+ BVERR_SRC1_TILE_FLAGS = /* tileparams.flags not supported */
+ BVERRDEF_VENDOR_ALL + 32100,
+ BVERR_SRC1_TILEPARAMS_FLAGS =
+ BVERR_SRC1_TILE_FLAGS,
+ BVERR_SRC1_TILE_VIRTADDR =
+ BVERR_SRC1DESC_VIRTADDR,
+ BVERR_SRC1_TILEPARAMS_VIRTADDR =
+ BVERR_SRC1_TILE_VIRTADDR,
+ BVERR_SRC1_TILE_ORIGIN = /* tileparams.left or .top not supported */
+ BVERRDEF_VENDOR_ALL + 32200,
+ BVERR_SRC1_TILEPARAMS_ORIGIN =
+ BVERR_SRC1_TILE_ORIGIN,
+ BVERR_SRC1_TILE_SIZE = /* tileparams.width or .height not supported */
+ BVERRDEF_VENDOR_ALL + 32300,
+ BVERR_SRC1_TILEPARAMS_SIZE =
+ BVERR_SRC1_TILE_SIZE,
+
+ BVERR_SRC2DESC = /* invalid bvbltparams.src2.desc */
+ BVERRDEF_VENDOR_ALL + 33000,
+ BVERR_SRC2DESC_VERS = /* bvbufferdesc.structsize too small */
+ BVERRDEF_VENDOR_ALL + 33100,
+ BVERR_SRC2DESC_VIRTADDR = /* bad bvbufferdesc.virtaddr */
+ BVERRDEF_VENDOR_ALL + 33200,
+ BVERR_SRC2DESC_LEN = /* bvbufferdesc.length not supported */
+ BVERRDEF_VENDOR_ALL + 33300,
+ BVERR_SRC2DESC_ALIGNMENT = /* unsupported buffer base address */
+ BVERRDEF_VENDOR_ALL + 33400,
+
+ BVERR_SRC2GEOM = /* invalid bvbltparams.src2geom */
+ BVERRDEF_VENDOR_ALL + 34000,
+ BVERR_SRC2GEOM_VERS = /* src2geom.structsize too small */
+ BVERRDEF_VENDOR_ALL + 34100,
+ BVERR_SRC2GEOM_FORMAT = /* bltparams.src2geom.format not supported */
+ BVERRDEF_VENDOR_ALL + 34200,
+ BVERR_SRC2GEOM_STRIDE = /* bltparams.src2geom.stride not supported */
+ BVERRDEF_VENDOR_ALL + 34300,
+ BVERR_SRC2GEOM_PALETTE = /* src2geom.paletteformat not supported */
+ BVERRDEF_VENDOR_ALL + 34400,
+
+ BVERR_SRC2RECT = /* bvbltparams.src2rect not supported */
+ BVERRDEF_VENDOR_ALL + 35000,
+
+ BVERR_SRC2_HORZSCALE = /* horz scale for src2->dst not supported */
+ BVERRDEF_VENDOR_ALL + 35100,
+ BVERR_SRC2_VERTSCALE = /* vert scale for src2->dst not supported */
+ BVERRDEF_VENDOR_ALL + 35200,
+ BVERR_SRC2_ROT = /* src2->dst rotation angle not supported */
+ BVERRDEF_VENDOR_ALL + 35300,
+
+ BVERR_SRC2_TILEPARAMS = /* invalid src2.tileparams */
+ BVERR_SRC2DESC,
+ BVERR_SRC2_TILE_VERS = /* src2.tileparams.structsize too small */
+ BVERRDEF_VENDOR_ALL + 36000,
+ BVERR_SRC2_TILEPARAMS_VERS =
+ BVERR_SRC2_TILE_VERS,
+ BVERR_SRC2_TILE_FLAGS = /* tileparams.flags not supported */
+ BVERRDEF_VENDOR_ALL + 36100,
+ BVERR_SRC2_TILEPARAMS_FLAGS =
+ BVERR_SRC2_TILE_FLAGS,
+ BVERR_SRC2_TILE_VIRTADDR =
+ BVERR_SRC2DESC_VIRTADDR,
+ BVERR_SRC2_TILEPARAMS_VIRTADDR =
+ BVERR_SRC2_TILE_VIRTADDR,
+ BVERR_SRC2_TILE_ORIGIN = /* tileparams.left or .top not supported */
+ BVERRDEF_VENDOR_ALL + 36200,
+ BVERR_SRC2_TILEPARAMS_ORIGIN =
+ BVERR_SRC2_TILE_ORIGIN,
+ BVERR_SRC2_TILE_SIZE = /* tileparams.width or .height not supported */
+ BVERRDEF_VENDOR_ALL + 36300,
+ BVERR_SRC2_TILEPARAMS_SIZE =
+ BVERR_SRC2_TILE_SIZE,
+
+ BVERR_MASKDESC = /* invalid bvbltparams.mask.desc */
+ BVERRDEF_VENDOR_ALL + 37000,
+ BVERR_MASKDESC_VERS = /* bvbufferdesc.structsize too small */
+ BVERRDEF_VENDOR_ALL + 37100,
+ BVERR_MASKDESC_VIRTADDR = /* bad bvbufferdesc.virtaddr */
+ BVERRDEF_VENDOR_ALL + 37200,
+ BVERR_MASKDESC_LEN = /* bvbufferdesc.length not supported */
+ BVERRDEF_VENDOR_ALL + 37300,
+ BVERR_MASKDESC_ALIGNMENT = /* unsupported buffer base address */
+ BVERRDEF_VENDOR_ALL + 37400,
+
+ BVERR_MASKGEOM = /* invalid bvbltparams.maskgeom */
+ BVERRDEF_VENDOR_ALL + 38000,
+ BVERR_MASKGEOM_VERS = /* maskgeom.structsize too small */
+ BVERRDEF_VENDOR_ALL + 38100,
+ BVERR_MASKGEOM_FORMAT = /* bltparams.maskgeom.format not supported */
+ BVERRDEF_VENDOR_ALL + 38200,
+ BVERR_MASKGEOM_STRIDE = /* bltparams.maskgeom.stride not supported */
+ BVERRDEF_VENDOR_ALL + 38300,
+ BVERR_MASKGEOM_PALETTE = /* maskgeom.paletteformat not supported */
+ BVERRDEF_VENDOR_ALL + 38400,
+
+ BVERR_MASKRECT = /* bvbltparams.maskrect not supported */
+ BVERRDEF_VENDOR_ALL + 39000,
+
+ BVERR_MASK_HORZSCALE = /* horz scale for mask->dst not supported */
+ BVERRDEF_VENDOR_ALL + 39100,
+ BVERR_MASK_VERTSCALE = /* vert scale for mask->dst not supported */
+ BVERRDEF_VENDOR_ALL + 39200,
+ BVERR_MASK_ROT = /* mask->dst rotation angle not supported */
+ BVERRDEF_VENDOR_ALL + 39300,
+
+ BVERR_MASK_TILEPARAMS = /* invalid mask.tileparams */
+ BVERR_MASKDESC,
+ BVERR_MASK_TILE_VERS = /* mask.tileparams.structsize too small */
+ BVERRDEF_VENDOR_ALL + 40000,
+ BVERR_MASK_TILEPARAMS_VERS =
+ BVERR_MASK_TILE_VERS,
+ BVERR_MASK_TILE_FLAGS = /* tileparams.flags not supported */
+ BVERRDEF_VENDOR_ALL + 40100,
+ BVERR_MASK_TILEPARAMS_FLAGS =
+ BVERR_MASK_TILE_FLAGS,
+ BVERR_MASK_TILE_VIRTADDR =
+ BVERR_MASKDESC_VIRTADDR,
+ BVERR_MASK_TILEPARAMS_VIRTADDR =
+ BVERR_MASK_TILE_VIRTADDR,
+ BVERR_MASK_TILE_ORIGIN = /* tileparams.left or .top not supported */
+ BVERRDEF_VENDOR_ALL + 40200,
+ BVERR_MASK_TILEPARAMS_ORIGIN =
+ BVERR_MASK_TILE_ORIGIN,
+ BVERR_MASK_TILE_SIZE = /* tileparams.width or .height not supported */
+ BVERRDEF_VENDOR_ALL + 40300,
+ BVERR_MASK_TILEPARAMS_SIZE =
+ BVERR_MASK_TILE_SIZE,
+
+ BVERR_CLIP_RECT = /* bvbltparams.cliprect not supported */
+ BVERRDEF_VENDOR_ALL + 41000,
+
+ BVERR_BATCH_FLAGS = /* bvbltparams.batchflags not supported */
+ BVERRDEF_VENDOR_ALL + 42000,
+ BVERR_BATCH = /* bvbltparams.batch not valid */
+ BVERRDEF_VENDOR_ALL + 43000,
+
+ BVERR_OP_FAILED = /* async operation failed to start */
+ BVERRDEF_VENDOR_ALL + 50000,
+ BVERR_OP_INCOMPLETE = /* async operation failed mid-way */
+ BVERRDEF_VENDOR_ALL + 50001,
+ BVERR_MEMORY_ERROR = /* async operation triggered memory error */
+ BVERRDEF_VENDOR_ALL + 51000,
+
+ BVERR_FORMAT = /* unsupported format */
+ BVERRDEF_VENDOR_ALL + 52000,
+
+ BVERR_CACHEOP = /* unsupported cache operation */
+ BVERRDEF_VENDOR_ALL + 60000,
+
+#ifdef BVERR_EXTERNAL_INCLUDE
+#include BVERR_EXTERNAL_INCLUDE
+#endif
+};
+
+#endif /* BVERROR_H */
diff --git a/kernel-headers/linux/bvfilter.h b/kernel-headers/linux/bvfilter.h
new file mode 100644
index 0000000..f472529
--- /dev/null
+++ b/kernel-headers/linux/bvfilter.h
@@ -0,0 +1,50 @@
+/*
+ * bvfilter.h
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ * This file defines the types of shared filters available and the associated
+ * parameters.
+ *
+ * To extend the list of filters, create a file containing additional
+ * enumerations to be added to enum bvfilter below. Then #define
+ * BVFILTER_EXTERNAL_INCLUDE as the name of that file before including
+ * this file in your project. Parameters need to be in a different file.
+ */
+
+#ifndef BVFILTER_H
+#define BVFILTER_H
+
+/*
+ * bvfilter is an enumeration used to designate the type of filter being used.
+ */
+enum bvfiltertype {
+ BVFILTER_DUMMY
+ /* TBD */
+
+#ifdef BVFILTER_EXTERNAL_INCLUDE
+#include BVFILTER_EXTERNAL_INCLUDE
+#endif
+};
+
+/*
+ * bvfilterop contains the filter type and a pointer to the associated
+ * parameters when the BVFLAG_FILTER operation is specified in
+ * bvbltparams.flags.
+ */
+struct bvfilter {
+ enum bvfiltertype filter;
+ void *params;
+};
+
+#endif /* BVFILTER_H */
diff --git a/kernel-headers/linux/bvinternal.h b/kernel-headers/linux/bvinternal.h
new file mode 100644
index 0000000..82648b5
--- /dev/null
+++ b/kernel-headers/linux/bvinternal.h
@@ -0,0 +1,46 @@
+/*
+ * bvinternal.h
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ * This file contains definitions used by implementations of BLTsville
+ * 2-D libraries. It should not be used by clients.
+ */
+
+#ifndef BVINTERNAL_H
+#define BVINTENRAL_H
+
+/*
+ * bvbuffmap - The bvbuffmap structure is used to track resources
+ * associated with a buffer, such as a h/w MMU entry. The implementations
+ * add bvbuffmap objects when they allocate the resources. Then when a
+ * buffer is accessed, the implementations can regain access to the
+ * associated resources. The implementations allocate and populate this
+ * structure when a bv_map() call is made. It is used in subsequent
+ * bv_blt() and bv_unmap() calls. The latter frees the associated resource
+ * and the structure (if applicable). Note that a given resource might be
+ * used by more than one implementation.
+ */
+struct bvbuffmap {
+ unsigned int structsize; /* used to ID structure ver */
+
+ /* function to unmap this resource */
+ BVFN_UNMAP bv_unmap;
+
+ unsigned long handle; /* resource-specific info */
+
+ /* pointer to next resource mapping structure */
+ struct bvbuffmap *nextmap;
+};
+
+#endif /* BVINTERNAL_H */
diff --git a/kernel-headers/linux/bvsurfgeom.h b/kernel-headers/linux/bvsurfgeom.h
new file mode 100644
index 0000000..ef0ea2b
--- /dev/null
+++ b/kernel-headers/linux/bvsurfgeom.h
@@ -0,0 +1,40 @@
+/*
+ * bvsurfgeom.h
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef BVSURFGEOM_H
+#define BVSURFGEOM_H
+
+/*
+ * bvsurfdesc - This structure specifies the way a buffer should be used in a
+ * 2-D context.
+ */
+
+struct bvsurfgeom {
+ unsigned int structsize; /* used to identify struct version */
+ enum ocdformat format; /* color format of surface */
+ unsigned int width; /* width of the surface in pixels */
+ unsigned int height; /* height of the surface in lines */
+ int orientation; /* angle of the surface in degrees
+ (multiple of 90 only) */
+ long virtstride; /* distance from one pixel to the
+ pixel immediately below it in
+ virtual space */
+ enum ocdformat paletteformat; /* format of palette */
+ void *palette; /* array of palette entries of
+ paletteformat; only valid when
+ format includes BVFMTDEF_LUT;
+ number of entries is 2^bpp. */
+};
+
+#endif /* BVSURFGEOM_H */
diff --git a/kernel-headers/linux/ocd.h b/kernel-headers/linux/ocd.h
new file mode 100644
index 0000000..250b7a1
--- /dev/null
+++ b/kernel-headers/linux/ocd.h
@@ -0,0 +1,781 @@
+/*
+ * ocd.h
+ *
+ * Open Color format Definitions
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This file defines the Open Color format Definitions (OCD), an open,
+ * extensible, color format definition.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef OCD_H
+#define OCD_H
+
+/*
+ * ocdformat - specifies one of the supported color formats
+ *
+ * ocdformat consists of 8 bits indicating the vendor ID, followed by 24 bits
+ * specified by the vendor.
+ *
+ * VENDOR_ALL is a common ID with formats defined below.
+ */
+
+/****** Bits 31-24 are the vendor ID. The other 24 are vendor defined. ******/
+#define OCDFMTDEF_VENDOR_SHIFT 24
+#define OCDFMTDEF_VENDOR_MASK (0xFF << OCDFMTDEF_VENDOR_SHIFT)
+
+#define OCDFMTDEF_VENDOR_ALL \
+ (0x00 << OCDFMTDEF_VENDOR_SHIFT) /* Common format */
+#define OCDFMTDEF_VENDOR_TI \
+ (0x01 << OCDFMTDEF_VENDOR_SHIFT) /* Texas Instruments, Inc. */
+/* 0xF0-0xFF reserved */
+
+/***** OCDFMTDEF_VENDOR_ALL *****/
+/* The formats in this group are created using combinations of the values
+ listed below. */
+
+/*
+ * 33222222 222 21 1 1 1 11 111 1
+ * 10987654 321 09 8 7 6 54 321 0 9 876 543210
+ * [------] [-] [] | | | [] [-] | | [-] [----]
+ * | | | | | | | | | | | |
+ * | | | | | | | | | | | color bits minus 1
+ * | | | | | | | | | | |
+ * | | | | | | | | | | container
+ * | | | | | | | | | |
+ * | | | | | | | | | left justified
+ * | | | | | | | | |
+ * | | | | | | | | reversed
+ * | | | | | | | |
+ * | | | | | | | layout
+ * | | | | | | |
+ * | | | | | | subsampling
+ * | | | | | |
+ * | | | | | subsample position \
+ * | | | | | |
+ * | | | | non-premult/fill empty 0 > alpha components
+ * | | | | |
+ * | | | alpha /
+ * | | |
+ * | | standard
+ * | |
+ * | color space
+ * |
+ * vendor ID (VENDOR_ALL = 0x00)
+ */
+
+/**** Bits 23-21 define the color space. ****/
+#define OCDFMTDEF_CS_SHIFT 21
+#define OCDFMTDEF_CS_MASK (7 << OCDFMTDEF_CS_SHIFT)
+
+#define OCDFMTDEF_CS_MONO \
+ (0 << OCDFMTDEF_CS_SHIFT) /* Monochrome (luma only) */
+#define OCDFMTDEF_CS_LUT \
+ (1 << OCDFMTDEF_CS_SHIFT) /* Look-up table (using palette) */
+#define OCDFMTDEF_CS_RGB \
+ (2 << OCDFMTDEF_CS_SHIFT) /* Red, green, blue */
+#define OCDFMTDEF_CS_YCbCr \
+ (3 << OCDFMTDEF_CS_SHIFT) /* YCbCr (YUV) (luma & chroma) */
+#define OCDFMTDEF_CS_ALPHA \
+ (4 << OCDFMTDEF_CS_SHIFT) /* Alpha only (transparency) */
+/* 5 reserved */
+/* 6 reserved */
+/* 7 reserved */
+
+/**** Bits 20-19 define the standard ****/
+#define OCDFMTDEF_STD_SHIFT 19
+#define OCDFMTDEF_STD_MASK (3 << OCDFMTDEF_STD_SHIFT)
+
+#define OCDFMTDEF_STD_ITUR_601_YCbCr \
+ (0 << OCDFMTDEF_STD_SHIFT) /* ITU-R BT.601 - YCbCr only */
+/* 0 default for non-YCbCr */
+#define OCDFMTDEF_STD_ITUR_709_YCbCr \
+ (1 << OCDFMTDEF_STD_SHIFT) /* ITU-R BT.709 - YCbCr only */
+/* 1 reserved for non-YCbCr */
+/* 2 reserved */
+#define OCDFMTDEF_FULLSCALE_YCbCr \
+ (3 << OCDFMTDEF_STD_SHIFT) /* RGB 0 to 255 =>
+ YCbCr 0 to 255, -128 to 127 */
+/* 3 reserved for non-YCbCr */
+
+/**** Bits 18-16 are component modifiers for non-alpha c/s only ****/
+#define OCDFMTDEF_ALPHA \
+ (1 << 18) /* An alpha component is added to the format */
+#define OCDFMTDEF_NON_PREMULT \
+ (1 << 17) /* Component(s) is(are) not premultiplied by the alpha
+ (default is premultiplied) */
+#define OCDFMTDEF_FILL_EMPTY_0 \
+ (1 << 17) /* Empty bits are hard-wired to 0 (default is 1) */
+#define OCDFMTDEF_SUBSAMPLE_HORZ_ALIGNED \
+ (0 << 16) /* Subsamples aligned w/1st non-subsample (e.g. MPEG-2) */
+#define OCDFMTDEF_SUBSAMPLE_HORZ_CENTERED \
+ (1 << 16) /* Subsamples are between non-subsamples (e.g. MPEG-1) */
+
+/*** Bits 18-16 are used differently for alpha c/s ***/
+/* Bit 18 is reserved */
+/*** Bits 17-16 define the number of alpha components for alpha c/s ***/
+#define OCDFMTDEF_ALPHA_COMPONENTS_SHIFT 16
+#define OCDFMTDEF_ALPHA_COMPONENTS_MASK (3 << OCDFMTDEF_ALPHA_COMPONENTS_SHIFT)
+
+#define OCDFMTDEF_ALPHA_COMPONENTS_1 (0 << OCDFMTDEF_ALPHA_COMPONENTS_SHIFT)
+#define OCDFMTDEF_ALPHA_COMPONENTS_2 (1 << OCDFMTDEF_ALPHA_COMPONENTS_SHIFT)
+#define OCDFMTDEF_ALPHA_COMPONENTS_3 (2 << OCDFMTDEF_ALPHA_COMPONENTS_SHIFT)
+#define OCDFMTDEF_ALPHA_COMPONENTS_4 (3 << OCDFMTDEF_ALPHA_COMPONENTS_SHIFT)
+
+/**** Bits 15-14 define subsampling ****/
+#define OCDFMTDEF_SUBSAMPLE_SHIFT 14
+#define OCDFMTDEF_SUBSAMPLE_MASK (3 << OCDFMTDEF_SUBSAMPLE_SHIFT)
+
+#define OCDFMTDEF_SUBSAMPLE_NONE \
+ (0 << OCDFMTDEF_SUBSAMPLE_SHIFT) /* No subsampling;
+ each pixel has each component */
+#define OCDFMTDEF_SUBSAMPLE_422_YCbCr \
+ (1 << OCDFMTDEF_SUBSAMPLE_SHIFT) /* 4:2:2 subsampling;
+ each horizontal pair of pixels
+ has one Y (luma) component each,
+ but shares one Cb and Cr (chroma)
+ component. */
+/* 1 reserved for non-YCbCr */
+#define OCDFMTDEF_SUBSAMPLE_420_YCbCr \
+ (2 << OCDFMTDEF_SUBSAMPLE_SHIFT) /* 4:2:0 subsampling;
+ each square of four pixels has
+ one Y (luma) component each, but
+ shares one Cb and Cr (chroma)
+ component. */
+/* 2 reserved for non-YCbCr */
+#define OCDFMTDEF_SUBSAMPLE_411_YCbCr \
+ (3 << OCDFMTDEF_SUBSAMPLE_SHIFT) /* 4:1:1 subsampling;
+ each horizontal four pixels have
+ one Y (luma) component each, but
+ shares one Cb and Cr (chroma)
+ component. */
+/* 3 reserved for non-YCbCr */
+
+/**** Bits 13-11 define the memory layout
+ (combined with _REVERSED and _LEFT_JUSTIFIED) ****/
+#define OCDFMTDEF_LAYOUT_SHIFT 11
+#define OCDFMTDEF_LAYOUT_MASK (7 << OCDFMTDEF_LAYOUT_SHIFT)
+
+#define OCDFMTDEF_PACKED \
+ (0 << OCDFMTDEF_LAYOUT_SHIFT) /* Components interleaved together */
+#define OCDFMTDEF_DISTRIBUTED \
+ (1 << OCDFMTDEF_LAYOUT_SHIFT) /* Components are distributed evenly
+ across the container; e.g. a 64-bit
+ container with four 8-bit components
+ are distributed with 8 bits between
+ them: __C0__C1__C2__C3 */
+#define OCDFMTDEF_2_PLANE_YCbCr \
+ (2 << OCDFMTDEF_LAYOUT_SHIFT) /* Y component is separated from Cb & Cr
+ components. After the Y plane, an
+ interleaved CbCr plane follows. */
+/* 2 reserved for non-YCbCr */
+#define OCDFMTDEF_3_PLANE_STACKED \
+ (3 << OCDFMTDEF_LAYOUT_SHIFT) /* Y, Cb, and Cr components are
+ separated. After the Y plane is a Cb
+ plane, and then a Cr plane. */
+/* 3 reserved for non-YCbCr and non-RGB */
+/* 4 reserved */
+/* 5 reserved */
+/* 6 reserved */
+#define OCDFMTDEF_3_PLANE_SIDE_BY_SIDE_YCbCr \
+ (7 << OCDFMTDEF_LAYOUT_SHIFT) /* Y, Cb, and Cr components are
+ separated. After the Y plane the Cb
+ and Cr planes are separated but
+ side-by-side in memory (interleaved
+ on a line-by-line basis). */
+/* 7 reserved for non-YCbCr */
+
+/**** Bits 10-9 are layout modifiers. ****/
+#define OCDFMTDEF_REVERSED \
+ (1 << 10) /* Order of components reversed (default is RGB or CbCr) */
+#define OCDFMTDEF_LEFT_JUSTIFIED \
+ (1 << 9) /* Components are shifted left (default is shifted right);
+ for 3-plane YCbCr, this indicates wasted space to the
+ right of the Cb & Cr planes (stride matches Y plane). */
+
+/**** Bits 6-8 specify the container type. ****/
+#define OCDFMTDEF_CONTAINER_SHIFT 6
+#define OCDFMTDEF_CONTAINER_MASK (7 << OCDFMTDEF_CONTAINER_SHIFT)
+
+#define OCDFMTDEF_CONTAINER_8BIT (0 << OCDFMTDEF_CONTAINER_SHIFT)
+#define OCDFMTDEF_CONTAINER_16BIT (1 << OCDFMTDEF_CONTAINER_SHIFT)
+#define OCDFMTDEF_CONTAINER_24BIT (2 << OCDFMTDEF_CONTAINER_SHIFT)
+#define OCDFMTDEF_CONTAINER_32BIT (3 << OCDFMTDEF_CONTAINER_SHIFT)
+/* 4 (0x008000) reserved */
+#define OCDFMTDEF_CONTAINER_48BIT (5 << OCDFMTDEF_CONTAINER_SHIFT)
+/* 6 (0x00C000) reserved */
+#define OCDFMTDEF_CONTAINER_64BIT (7 << OCDFMTDEF_CONTAINER_SHIFT)
+
+/**** Bits 0-5 contain the total number of component bits minus one. ****/
+/* To calculate the number of bits for each RGBA component, use the following
+ * formula:
+ *
+ * green bits = int((color bits + 2) / 3)
+ * blue bits = int((color bits - green bits) / 2)
+ * red bits = color bits - green bits - blue bits
+ * alpha bits (when present) = container size - color bits
+ *
+ * Ex. 1: RGB16 -> 16 bits
+ * green bits = int((16 + 2) / 3) = 6
+ * blue bits = int((16 - 6) / 2) = 5
+ * red bits = 16 - 6 - 5 = 5
+ * alpha bits = n/a
+ * Ex. 2: ARGB16 -> 16 bits
+ * green bits = int((16 + 2) / 3) = 6
+ * blue bits = int((16 - 6) / 2) = 5
+ * red bits = 16 - 6 - 5 = 5
+ * alpha bits = 24 - 16 = 8
+ * Ex. 3: RGB32 -> 32 bits
+ * green bits = int((32 + 2) / 3) = 11
+ * blue bits = int((32 - 11) / 2) = 10
+ * red bits = 32 - 11 - 10 = 11
+ * alpha bits = n/a
+ *
+ * For planar formats, the container indicates the total number of bits on the
+ * subsampled boundary, while the component bits are the average number of
+ * bits per pixel.
+ *
+ * Ex. 1: YV12 -> YCbCr 4:2:0 w/8-bit samples -> 4x8 + 2x8 = 48 bit container
+ * 48 bits / 4 pixels = 12 bpp
+ * Ex. 2: NV16 -> YCbCr 4:2:2 w/8-bit samples -> 2x8 + 2x8 = 32 bit container
+ * 24 bits / 2 pixels = 16 bpp
+ */
+#define OCDFMTDEF_COMPONENTSIZEMINUS1_SHIFT 0
+#define OCDFMTDEF_COMPONENTSIZEMINUS1_MASK \
+ (0x3F << OCDFMTDEF_COMPONENTSIZEMINUS1_SHIFT)
+
+
+/*
+ * The formats below are constructed from the definitions above. However, not
+ * all formats possible are specified (and named) below. The other formats
+ * which can be uniquely formed using the above definitions are legitimate
+ * formats, and may be used as well.
+ */
+enum ocdformat {
+ OCDFMT_UNKNOWN = -1,
+ OCDFMT_NONE = OCDFMT_UNKNOWN,
+
+ /*** Alpha only ***/
+ /** Packed **/
+ OCDFMT_ALPHA1 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_ALPHA |
+ OCDFMTDEF_ALPHA_COMPONENTS_1 |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (1 - 1),
+ OCDFMT_ALPHA2 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_ALPHA |
+ OCDFMTDEF_ALPHA_COMPONENTS_1 |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (2 - 1),
+ OCDFMT_ALPHA4 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_ALPHA |
+ OCDFMTDEF_ALPHA_COMPONENTS_1 |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (4 - 1),
+ OCDFMT_ALPHA8 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_ALPHA |
+ OCDFMTDEF_ALPHA_COMPONENTS_1 |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (8 - 1),
+ /* Sub-pixel */
+ OCDFMT_ALPHA4x1 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_ALPHA |
+ OCDFMTDEF_ALPHA_COMPONENTS_4 |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (4 - 1),
+ OCDFMT_ALPHA3x8 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_ALPHA |
+ OCDFMTDEF_ALPHA_COMPONENTS_3 |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_24BIT |
+ (24 - 1),
+ OCDFMT_ALPHA4x8 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_ALPHA |
+ OCDFMTDEF_ALPHA_COMPONENTS_4 |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_32BIT |
+ (32 - 1),
+
+ /*** Monochrome ***/
+ /** Packed **/
+ OCDFMT_MONO1 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_MONO |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (1 - 1),
+ OCDFMT_MONO2 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_MONO |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (2 - 1),
+ OCDFMT_MONO4 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_MONO |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (4 - 1),
+ OCDFMT_MONO8 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_MONO |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (8 - 1),
+
+ /*** Palettized (look-up-table) ***/
+ /** Packed **/
+ OCDFMT_LUT1 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_LUT |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (1 - 1),
+ OCDFMT_LUT2 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_LUT |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (2 - 1),
+ OCDFMT_LUT4 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_LUT |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (4 - 1),
+ OCDFMT_LUT8 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_LUT |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_8BIT |
+ (8 - 1),
+
+ /*** RGB ***/
+ /** Packed **/
+ /* No subsampling */
+ OCDFMT_RGB12 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_RGB |
+ OCDFMTDEF_SUBSAMPLE_NONE |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_16BIT |
+ (12 - 1), /* (15):4:4:4 */
+ OCDFMT_xRGB12 = OCDFMT_RGB12,
+ OCDFMT_1RGB12 = OCDFMT_xRGB12,
+ OCDFMT_0RGB12 = OCDFMT_xRGB12 |
+ OCDFMTDEF_FILL_EMPTY_0, /* (0):4:4:4 */
+
+ OCDFMT_BGR12 = OCDFMT_RGB12 |
+ OCDFMTDEF_REVERSED, /* (15):4:4:4 */
+ OCDFMT_xBGR12 = OCDFMT_BGR12,
+ OCDFMT_1BGR12 = OCDFMT_xBGR12,
+ OCDFMT_0BGR12 = OCDFMT_xBGR12 |
+ OCDFMTDEF_FILL_EMPTY_0, /* (0):4:4:4 */
+
+ OCDFMT_RGBx12 = OCDFMT_xRGB12 |
+ OCDFMTDEF_LEFT_JUSTIFIED, /* 4:4:4:(15) */
+ OCDFMT_RGB112 = OCDFMT_RGBx12,
+ OCDFMT_RGB012 = OCDFMT_RGBx12 |
+ OCDFMTDEF_FILL_EMPTY_0, /* 4:4:4:(0) */
+
+ OCDFMT_BGRx12 = OCDFMT_xRGB12 |
+ OCDFMTDEF_LEFT_JUSTIFIED |
+ OCDFMTDEF_REVERSED, /* 4:4:4:(15) */
+ OCDFMT_BGR112 = OCDFMT_BGRx12,
+ OCDFMT_BGR012 = OCDFMT_BGRx12 |
+ OCDFMTDEF_FILL_EMPTY_0, /* 4:4:4:(0) */
+
+ OCDFMT_RGB15 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_RGB |
+ OCDFMTDEF_SUBSAMPLE_NONE |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_16BIT |
+ (15 - 1), /* (1):5:5:5 */
+ OCDFMT_xRGB15 = OCDFMT_RGB15,
+ OCDFMT_1RGB15 = OCDFMT_xRGB15,
+ OCDFMT_0RGB15 = OCDFMT_xRGB15 |
+ OCDFMTDEF_FILL_EMPTY_0, /* (0):5:5:5 */
+
+ OCDFMT_BGR15 = OCDFMT_RGB15 |
+ OCDFMTDEF_REVERSED, /* (1):5:5:5 */
+ OCDFMT_xBGR15 = OCDFMT_BGR15,
+ OCDFMT_1BGR15 = OCDFMT_xBGR15,
+ OCDFMT_0BGR15 = OCDFMT_xBGR15 |
+ OCDFMTDEF_FILL_EMPTY_0, /* (0):5:5:5 */
+
+ OCDFMT_RGBx15 = OCDFMT_RGB15 |
+ OCDFMTDEF_LEFT_JUSTIFIED, /* 5:5:5:(1) */
+ OCDFMT_RGB115 = OCDFMT_RGBx15,
+ OCDFMT_RGB015 = OCDFMT_RGBx15 |
+ OCDFMTDEF_FILL_EMPTY_0, /* 5:5:5:(0) */
+
+ OCDFMT_BGRx15 = OCDFMT_RGB15 |
+ OCDFMTDEF_LEFT_JUSTIFIED |
+ OCDFMTDEF_REVERSED, /* 5:5:5:(1) */
+ OCDFMT_BGR115 = OCDFMT_BGRx15,
+ OCDFMT_BGR015 = OCDFMT_BGRx15 |
+ OCDFMTDEF_FILL_EMPTY_0, /* 5:5:5:(0) */
+
+ OCDFMT_RGB16 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_RGB |
+ OCDFMTDEF_SUBSAMPLE_NONE |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_16BIT |
+ (16 - 1), /* 5:6:5 */
+ OCDFMT_BGR16 = OCDFMT_RGB16 |
+ OCDFMTDEF_REVERSED, /* 5:6:5 */
+
+ OCDFMT_RGB24 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_RGB |
+ OCDFMTDEF_SUBSAMPLE_NONE |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_24BIT |
+ (24 - 1), /* 8:8:8 */
+ OCDFMT_BGR24 = OCDFMT_RGB24 |
+ OCDFMTDEF_REVERSED, /* 8:8:8 */
+
+ OCDFMT_xRGB16 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_RGB |
+ OCDFMTDEF_SUBSAMPLE_NONE |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_24BIT |
+ (16 - 1), /* (255):5:6:5 */
+ OCDFMT_1RGB16 = OCDFMT_xRGB16,
+ OCDFMT_0RGB16 = OCDFMT_xRGB16 |
+ OCDFMTDEF_FILL_EMPTY_0, /* (0):5:6:5 */
+
+ OCDFMT_xBGR16 = OCDFMT_xRGB16 |
+ OCDFMTDEF_REVERSED, /* (255):5:6:5 */
+ OCDFMT_1BGR16 = OCDFMT_xBGR16,
+ OCDFMT_0BGR16 = OCDFMT_xBGR16 |
+ OCDFMTDEF_FILL_EMPTY_0, /* (0):5:6:5 */
+
+ OCDFMT_RGBx16 = OCDFMT_xRGB16 |
+ OCDFMTDEF_LEFT_JUSTIFIED, /* 5:6:5:(255) */
+ OCDFMT_RGB116 = OCDFMT_RGBx16,
+ OCDFMT_RGB016 = OCDFMT_RGBx16 |
+ OCDFMTDEF_FILL_EMPTY_0, /* 5:6:5:(0) */
+
+ OCDFMT_BGRx16 = OCDFMT_xRGB16 |
+ OCDFMTDEF_LEFT_JUSTIFIED |
+ OCDFMTDEF_REVERSED, /* 5:6:5:(255) */
+ OCDFMT_BGR116 = OCDFMT_BGRx16,
+ OCDFMT_BGR016 = OCDFMT_BGRx16 |
+ OCDFMTDEF_FILL_EMPTY_0, /* 5:6:5:(0) */
+
+ OCDFMT_xRGB24 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_RGB |
+ OCDFMTDEF_SUBSAMPLE_NONE |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_32BIT |
+ (24 - 1), /* (255):8:8:8 */
+ OCDFMT_1RGB24 = OCDFMT_xRGB24,
+ OCDFMT_0RGB24 = OCDFMT_xRGB24 |
+ OCDFMTDEF_FILL_EMPTY_0, /* (0):8:8:8 */
+
+ OCDFMT_xBGR24 = OCDFMT_xRGB24 |
+ OCDFMTDEF_REVERSED, /* (255):8:8:8 */
+ OCDFMT_1BGR24 = OCDFMT_xBGR24,
+ OCDFMT_0BGR24 = OCDFMT_xBGR24 |
+ OCDFMTDEF_FILL_EMPTY_0, /* (0):8:8:8 */
+
+ OCDFMT_RGBx24 = OCDFMT_xRGB24 |
+ OCDFMTDEF_LEFT_JUSTIFIED, /* 8:8:8:(255) */
+ OCDFMT_RGB124 = OCDFMT_RGBx24,
+ OCDFMT_RGB024 = OCDFMT_RGBx24 |
+ OCDFMTDEF_FILL_EMPTY_0, /* 8:8:8:(0) */
+
+ OCDFMT_BGRx24 = OCDFMT_xRGB24 |
+ OCDFMTDEF_LEFT_JUSTIFIED |
+ OCDFMTDEF_REVERSED, /* 8:8:8:(255) */
+ OCDFMT_BGR124 = OCDFMT_BGRx24,
+ OCDFMT_BGR024 = OCDFMT_BGRx24 |
+ OCDFMTDEF_FILL_EMPTY_0, /* 8:8:8:(0) */
+
+ /* Premultiplied ARGB */
+ OCDFMT_ARGB12 = OCDFMT_xRGB12 |
+ OCDFMTDEF_ALPHA, /* 4:4:4:4 */
+ OCDFMT_ABGR12 = OCDFMT_xBGR12 |
+ OCDFMTDEF_ALPHA, /* 4:4:4:4 */
+ OCDFMT_RGBA12 = OCDFMT_RGBx12 |
+ OCDFMTDEF_ALPHA, /* 4:4:4:4 */
+ OCDFMT_BGRA12 = OCDFMT_BGRx12 |
+ OCDFMTDEF_ALPHA, /* 4:4:4:4 */
+
+ OCDFMT_ARGB16 = OCDFMT_xRGB16 |
+ OCDFMTDEF_ALPHA, /* 8:5:6:5 */
+ OCDFMT_ABGR16 = OCDFMT_ARGB16 |
+ OCDFMTDEF_REVERSED, /* 8:5:6:5 */
+ OCDFMT_RGBA16 = OCDFMT_ARGB16 |
+ OCDFMTDEF_LEFT_JUSTIFIED, /* 5:6:5:8 */
+ OCDFMT_BGRA16 = OCDFMT_ARGB16 |
+ OCDFMTDEF_LEFT_JUSTIFIED |
+ OCDFMTDEF_REVERSED, /* 5:6:5:8 */
+
+ OCDFMT_ARGB24 = OCDFMT_xRGB24 |
+ OCDFMTDEF_ALPHA, /* 8:8:8:8 */
+ OCDFMT_ABGR24 = OCDFMT_xBGR24 |
+ OCDFMTDEF_ALPHA, /* 8:8:8:8 */
+ OCDFMT_RGBA24 = OCDFMT_RGBx24 |
+ OCDFMTDEF_ALPHA, /* 8:8:8:8 */
+ OCDFMT_BGRA24 = OCDFMT_BGRx24 |
+ OCDFMTDEF_ALPHA, /* 8:8:8:8 */
+
+ /* Non-premultiplied ARGB */
+ OCDFMT_nARGB12 = OCDFMT_ARGB12 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_ARGB12_NON_PREMULT = OCDFMT_nARGB12,
+
+ OCDFMT_nABGR12 = OCDFMT_ABGR12 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_ABGR12_NON_PREMULT = OCDFMT_nABGR12,
+
+ OCDFMT_nRGBA12 = OCDFMT_RGBA12 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_RGBA12_NON_PREMULT = OCDFMT_nRGBA12,
+
+ OCDFMT_nBGRA12 = OCDFMT_BGRA12 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_BGRA12_NON_PREMULT = OCDFMT_nBGRA12,
+
+ OCDFMT_ARGB15 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_RGB |
+ OCDFMTDEF_ALPHA |
+ OCDFMTDEF_NON_PREMULT |
+ OCDFMTDEF_SUBSAMPLE_NONE |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_16BIT |
+ (15 - 1), /* 1:5:5:5 - "normal"
+ format is not
+ premultiplied */
+ OCDFMT_nARGB15 = OCDFMT_ARGB15,
+ OCDFMT_ARGB15_NON_PREMULT = OCDFMT_nARGB15,
+
+ OCDFMT_ABGR15 = OCDFMT_ARGB15 |
+ OCDFMTDEF_REVERSED, /* 1:5:5:5 - "normal"
+ format is not
+ premultiplied */
+ OCDFMT_nABGR15 = OCDFMT_ABGR15,
+ OCDFMT_ABGR15_NON_PREMULT = OCDFMT_nABGR15,
+
+ OCDFMT_RGBA15 = OCDFMT_ARGB15 |
+ OCDFMTDEF_LEFT_JUSTIFIED, /* 5:5:5:1 - "normal"
+ format is not
+ premultiplied */
+ OCDFMT_nRGBA15 = OCDFMT_RGBA15,
+ OCDFMT_RGBA15_NON_PREMULT = OCDFMT_nRGBA15,
+
+ OCDFMT_BGRA15 = OCDFMT_ARGB15 |
+ OCDFMTDEF_LEFT_JUSTIFIED |
+ OCDFMTDEF_REVERSED, /* 5:5:5:1 - "normal"
+ format is not
+ premultiplied */
+ OCDFMT_nBGRA15 = OCDFMT_BGRA15,
+ OCDFMT_BGRA15_NON_PREMULT = OCDFMT_nRGBA15,
+
+ OCDFMT_nARGB16 = OCDFMT_ARGB16 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_ARGB16_NON_PREMULT = OCDFMT_nARGB16,
+
+ OCDFMT_nABGR16 = OCDFMT_ABGR16 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_ABGR16_NON_PREMULT = OCDFMT_nABGR16,
+
+ OCDFMT_nRGBA16 = OCDFMT_RGBA16 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_RGBA16_NON_PREMULT = OCDFMT_nRGBA16,
+
+ OCDFMT_nBGRA16 = OCDFMT_BGRA16 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_BGRA16_NON_PREMULT = OCDFMT_nBGRA16,
+
+ OCDFMT_nARGB24 = OCDFMT_ARGB24 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_ARGB24_NON_PREMULT = OCDFMT_nARGB24,
+
+ OCDFMT_nABGR24 = OCDFMT_ABGR24 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_ABGR24_NON_PREMULT = OCDFMT_nABGR24,
+
+ OCDFMT_nRGBA24 = OCDFMT_RGBA24 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_RGBA24_NON_PREMULT = OCDFMT_nRGBA24,
+
+ OCDFMT_nBGRA24 = OCDFMT_BGRA24 |
+ OCDFMTDEF_NON_PREMULT,
+ OCDFMT_BGRA24_NON_PREMULT = OCDFMT_nBGRA24,
+
+ /*** YCbCr ***/
+ /** Packed **/
+ /* YCbCr 4:2:2 */
+ OCDFMT_UYVY = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_422_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_HORZ_ALIGNED |
+ OCDFMTDEF_PACKED |
+ OCDFMTDEF_CONTAINER_32BIT |
+ (16 - 1),
+ OCDFMT_UYVY_601 = OCDFMT_UYVY |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_UYVY_709 = OCDFMT_UYVY |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+ OCDFMT_Y422 = OCDFMT_UYVY,
+ OCDFMT_Y422_601 = OCDFMT_UYVY_601,
+ OCDFMT_Y422_709 = OCDFMT_UYVY_709,
+
+ OCDFMT_VYUY = OCDFMT_UYVY |
+ OCDFMTDEF_REVERSED,
+ OCDFMT_VYUY_601 = OCDFMT_VYUY |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_VYUY_709 = OCDFMT_VYUY |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ OCDFMT_YUYV = OCDFMT_UYVY |
+ OCDFMTDEF_LEFT_JUSTIFIED,
+ OCDFMT_YUYV_601 = OCDFMT_YUYV |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_YUYV_709 = OCDFMT_YUYV |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+ OCDFMT_YUY2 = OCDFMT_YUYV,
+ OCDFMT_YUY2_601 = OCDFMT_YUYV_601,
+ OCDFMT_YUY2_709 = OCDFMT_YUYV_709,
+
+ OCDFMT_YVYU = OCDFMT_VYUY |
+ OCDFMTDEF_LEFT_JUSTIFIED,
+ OCDFMT_YVYU_601 = OCDFMT_YVYU |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_YVYU_709 = OCDFMT_YVYU |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ /** 3-plane **/
+ /* YCbCr 4:2:2 */
+ OCDFMT_YV16 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_422_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_HORZ_ALIGNED |
+ OCDFMTDEF_3_PLANE_STACKED |
+ OCDFMTDEF_CONTAINER_32BIT |
+ (16 - 1),
+ OCDFMT_YV16_601 = OCDFMT_YV16 |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_YV16_709 = OCDFMT_YV16 |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ /* YCbCr 4:2:0 */
+ OCDFMT_IYUV = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_420_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_HORZ_ALIGNED |
+ OCDFMTDEF_3_PLANE_STACKED |
+ OCDFMTDEF_CONTAINER_48BIT |
+ (12 - 1),
+ OCDFMT_IYUV_601 = OCDFMT_IYUV |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_IYUV_709 = OCDFMT_IYUV |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+ OCDFMT_I420 = OCDFMT_IYUV,
+ OCDFMT_I420_601 = OCDFMT_IYUV_601,
+ OCDFMT_I420_709 = OCDFMT_IYUV_709,
+
+ OCDFMT_YV12 = OCDFMT_IYUV |
+ OCDFMTDEF_REVERSED,
+ OCDFMT_YV12_601 = OCDFMT_YV12 |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_YV12_709 = OCDFMT_YV12 |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ OCDFMT_IMC3 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_420_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_HORZ_ALIGNED |
+ OCDFMTDEF_3_PLANE_STACKED |
+ OCDFMTDEF_LEFT_JUSTIFIED | /* Indicates wasted
+ space to the
+ right */
+ OCDFMTDEF_CONTAINER_48BIT |
+ (12 - 1),
+ OCDFMT_IMC3_601 = OCDFMT_IMC3 |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_IMC3_709 = OCDFMT_IMC3 |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ OCDFMT_IMC1 = OCDFMT_IMC3 |
+ OCDFMTDEF_REVERSED,
+ OCDFMT_IMC1_601 = OCDFMT_IMC1 |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_IMC1_709 = OCDFMT_IMC1 |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ OCDFMT_IMC4 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_YCbCr |
+ OCDFMTDEF_STD_ITUR_601_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_420_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_HORZ_ALIGNED |
+ OCDFMTDEF_3_PLANE_SIDE_BY_SIDE_YCbCr |
+ OCDFMTDEF_CONTAINER_48BIT |
+ (12 - 1),
+ OCDFMT_IMC4_601 = OCDFMT_IMC4 |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_IMC4_709 = OCDFMT_IMC4 |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ OCDFMT_IMC2 = OCDFMT_IMC4 |
+ OCDFMTDEF_REVERSED,
+ OCDFMT_IMC2_601 = OCDFMT_IMC2 |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_IMC2_709 = OCDFMT_IMC2 |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ /** 2-plane **/
+ /* YCbCr 4:2:2 */
+ OCDFMT_NV16 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_422_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_HORZ_ALIGNED |
+ OCDFMTDEF_2_PLANE_YCbCr |
+ OCDFMTDEF_CONTAINER_32BIT |
+ (16 - 1),
+ OCDFMT_NV16_601 = OCDFMT_NV16 |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_NV16_709 = OCDFMT_NV16 |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ OCDFMT_NV61 = OCDFMT_NV16 |
+ OCDFMTDEF_REVERSED,
+ OCDFMT_NV61_601 = OCDFMT_NV61 |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_NV61_709 = OCDFMT_NV61 |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ /* YCbCr 4:2:0 */
+ OCDFMT_NV12 = OCDFMTDEF_VENDOR_ALL |
+ OCDFMTDEF_CS_YCbCr |
+ OCDFMTDEF_STD_ITUR_601_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_420_YCbCr |
+ OCDFMTDEF_SUBSAMPLE_HORZ_ALIGNED |
+ OCDFMTDEF_2_PLANE_YCbCr |
+ OCDFMTDEF_CONTAINER_48BIT |
+ (12 - 1),
+ OCDFMT_NV12_601 = OCDFMT_NV12 |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_NV12_709 = OCDFMT_NV12 |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+ OCDFMT_NV21 = OCDFMT_NV12 |
+ OCDFMTDEF_REVERSED,
+ OCDFMT_NV21_601 = OCDFMT_NV21 |
+ OCDFMTDEF_STD_ITUR_601_YCbCr,
+ OCDFMT_NV21_709 = OCDFMT_NV21 |
+ OCDFMTDEF_STD_ITUR_709_YCbCr,
+
+#ifdef OCD_EXTERNAL_INCLUDE
+#include OCD_EXTERNAL_INCLUDE
+#endif
+};
+
+#endif /* OCD_H */
diff --git a/kernel-headers/linux/omap_ion.h b/kernel-headers/linux/omap_ion.h
new file mode 100644
index 0000000..c5a8ef7
--- /dev/null
+++ b/kernel-headers/linux/omap_ion.h
@@ -0,0 +1,106 @@
+/*
+ * include/linux/omap_ion.h
+ *
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _LINUX_OMAP_ION_H
+#define _LINUX_OMAP_ION_H
+
+#include <linux/types.h>
+
+/**
+ * struct omap_ion_tiler_alloc_data - metadata passed from userspace for allocations
+ * @w: width of the allocation
+ * @h: height of the allocation
+ * @fmt: format of the data (8, 16, 32bit or page)
+ * @flags: flags passed to heap
+ * @stride: stride of the allocation, returned to caller from kernel
+ * @handle: pointer that will be populated with a cookie to use to refer
+ * to this allocation
+ *
+ * Provided by userspace as an argument to the ioctl
+ */
+struct omap_ion_tiler_alloc_data {
+ size_t w;
+ size_t h;
+ int fmt;
+ unsigned int flags;
+ struct ion_handle *handle;
+ size_t stride;
+ size_t offset;
+ u32 out_align;
+ u32 token;
+};
+struct omap_ion_phys_addr_data {
+ struct ion_handle *handle;
+ unsigned long phys_addr;
+ size_t size;
+};
+
+#ifdef __KERNEL__
+int omap_ion_tiler_alloc(struct ion_client *client,
+ struct omap_ion_tiler_alloc_data *data);
+int omap_ion_nonsecure_tiler_alloc(struct ion_client *client,
+ struct omap_ion_tiler_alloc_data *data);
+/* given a handle in the tiler, return a list of tiler pages that back it */
+int omap_tiler_pages(struct ion_client *client, struct ion_handle *handle,
+ int *n, u32 ** tiler_pages);
+int omap_ion_share_fd_to_buffers(int fd, struct ion_buffer **buffers,
+ int *num_handles);
+int omap_tiler_vinfo(struct ion_client *client,
+ struct ion_handle *handle, unsigned int *vstride,
+ unsigned int *vsize);
+int omap_ion_preprocess_tiler_alloc(bool enable);
+#endif /* __KERNEL__ */
+
+/* additional heaps used only on omap */
+enum {
+ OMAP_ION_HEAP_TYPE_TILER = ION_HEAP_TYPE_CUSTOM + 1,
+ OMAP_ION_HEAP_TYPE_TILER_RESERVATION,
+};
+
+#define OMAP_ION_HEAP_TILER_MASK (1 << OMAP_ION_HEAP_TYPE_TILER)
+
+enum {
+ OMAP_ION_TILER_ALLOC,
+ OMAP_ION_PHYS_ADDR
+};
+
+/**
+ * These should match the defines in the tiler driver
+ */
+enum {
+ TILER_PIXEL_FMT_MIN = 0,
+ TILER_PIXEL_FMT_8BIT = 0,
+ TILER_PIXEL_FMT_16BIT = 1,
+ TILER_PIXEL_FMT_32BIT = 2,
+ TILER_PIXEL_FMT_PAGE = 3,
+ TILER_PIXEL_FMT_MAX = 3
+};
+
+/**
+ * List of heaps in the system
+ */
+enum {
+ OMAP_ION_HEAP_SYSTEM,
+ OMAP_ION_HEAP_TILER,
+ OMAP_ION_HEAP_SECURE_INPUT,
+ OMAP_ION_HEAP_NONSECURE_TILER,
+ OMAP_ION_HEAP_TILER_RESERVATION,
+ OMAP_ION_HEAP_SECURE_OUTPUT_WFDHDCP,
+ OMAP_ION_HEAP_TILER_CMA,
+};
+
+#endif /* _LINUX_ION_H */
+
diff --git a/kernel-headers/linux/omapfb.h b/kernel-headers/linux/omapfb.h
new file mode 100644
index 0000000..80c5dc6
--- /dev/null
+++ b/kernel-headers/linux/omapfb.h
@@ -0,0 +1,274 @@
+/*
+ * File: include/linux/omapfb.h
+ *
+ * Framebuffer driver for TI OMAP boards
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Author: Imre Deak <imre.deak@nokia.com>
+ *
+ * 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.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __LINUX_OMAPFB_H__
+#define __LINUX_OMAPFB_H__
+
+#include <linux/fb.h>
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/* IOCTL commands. */
+
+#define OMAP_IOW(num, dtype) _IOW('O', num, dtype)
+#define OMAP_IOR(num, dtype) _IOR('O', num, dtype)
+#define OMAP_IOWR(num, dtype) _IOWR('O', num, dtype)
+#define OMAP_IO(num) _IO('O', num)
+
+#define OMAPFB_MIRROR OMAP_IOW(31, int)
+#define OMAPFB_SYNC_GFX OMAP_IO(37)
+#define OMAPFB_VSYNC OMAP_IO(38)
+#define OMAPFB_SET_UPDATE_MODE OMAP_IOW(40, int)
+#define OMAPFB_GET_CAPS OMAP_IOR(42, struct omapfb_caps)
+#define OMAPFB_GET_UPDATE_MODE OMAP_IOW(43, int)
+#define OMAPFB_LCD_TEST OMAP_IOW(45, int)
+#define OMAPFB_CTRL_TEST OMAP_IOW(46, int)
+#define OMAPFB_UPDATE_WINDOW_OLD OMAP_IOW(47, struct omapfb_update_window_old)
+#define OMAPFB_SET_COLOR_KEY OMAP_IOW(50, struct omapfb_color_key)
+#define OMAPFB_GET_COLOR_KEY OMAP_IOW(51, struct omapfb_color_key)
+#define OMAPFB_SETUP_PLANE OMAP_IOW(52, struct omapfb_plane_info)
+#define OMAPFB_QUERY_PLANE OMAP_IOW(53, struct omapfb_plane_info)
+#define OMAPFB_UPDATE_WINDOW OMAP_IOW(54, struct omapfb_update_window)
+#define OMAPFB_SETUP_MEM OMAP_IOW(55, struct omapfb_mem_info)
+#define OMAPFB_QUERY_MEM OMAP_IOW(56, struct omapfb_mem_info)
+#define OMAPFB_WAITFORVSYNC OMAP_IO(57)
+#define OMAPFB_MEMORY_READ OMAP_IOR(58, struct omapfb_memory_read)
+#define OMAPFB_GET_OVERLAY_COLORMODE OMAP_IOR(59, struct omapfb_ovl_colormode)
+#define OMAPFB_WAITFORGO OMAP_IO(60)
+#define OMAPFB_GET_VRAM_INFO OMAP_IOR(61, struct omapfb_vram_info)
+#define OMAPFB_SET_TEARSYNC OMAP_IOW(62, struct omapfb_tearsync_info)
+#define OMAPFB_GET_DISPLAY_INFO OMAP_IOR(63, struct omapfb_display_info)
+#define OMAPFB_ENABLEVSYNC OMAP_IOW(64, int)
+
+#define OMAPFB_CAPS_GENERIC_MASK 0x00000fff
+#define OMAPFB_CAPS_LCDC_MASK 0x00fff000
+#define OMAPFB_CAPS_PANEL_MASK 0xff000000
+
+#define OMAPFB_CAPS_MANUAL_UPDATE 0x00001000
+#define OMAPFB_CAPS_TEARSYNC 0x00002000
+#define OMAPFB_CAPS_PLANE_RELOCATE_MEM 0x00004000
+#define OMAPFB_CAPS_PLANE_SCALE 0x00008000
+#define OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE 0x00010000
+#define OMAPFB_CAPS_WINDOW_SCALE 0x00020000
+#define OMAPFB_CAPS_WINDOW_OVERLAY 0x00040000
+#define OMAPFB_CAPS_WINDOW_ROTATE 0x00080000
+#define OMAPFB_CAPS_SET_BACKLIGHT 0x01000000
+
+/* Values from DSP must map to lower 16-bits */
+#define OMAPFB_FORMAT_MASK 0x00ff
+#define OMAPFB_FORMAT_FLAG_DOUBLE 0x0100
+#define OMAPFB_FORMAT_FLAG_TEARSYNC 0x0200
+#define OMAPFB_FORMAT_FLAG_FORCE_VSYNC 0x0400
+#define OMAPFB_FORMAT_FLAG_ENABLE_OVERLAY 0x0800
+#define OMAPFB_FORMAT_FLAG_DISABLE_OVERLAY 0x1000
+
+#define OMAPFB_MEMTYPE_SDRAM 0
+#define OMAPFB_MEMTYPE_SRAM 1
+#define OMAPFB_MEMTYPE_MAX 1
+
+#define OMAPFB_MEM_IDX_ENABLED 0x80
+#define OMAPFB_MEM_IDX_MASK 0x7f
+
+enum omapfb_color_format {
+ OMAPFB_COLOR_RGB565 = 0,
+ OMAPFB_COLOR_YUV422,
+ OMAPFB_COLOR_YUV420,
+ OMAPFB_COLOR_CLUT_8BPP,
+ OMAPFB_COLOR_CLUT_4BPP,
+ OMAPFB_COLOR_CLUT_2BPP,
+ OMAPFB_COLOR_CLUT_1BPP,
+ OMAPFB_COLOR_RGB444,
+ OMAPFB_COLOR_YUY422,
+
+ OMAPFB_COLOR_ARGB16,
+ OMAPFB_COLOR_RGB24U, /* RGB24, 32-bit container */
+ OMAPFB_COLOR_RGB24P, /* RGB24, 24-bit container */
+ OMAPFB_COLOR_ARGB32,
+ OMAPFB_COLOR_RGBA32,
+ OMAPFB_COLOR_RGBX32,
+};
+
+struct omapfb_update_window {
+ __u32 x, y;
+ __u32 width, height;
+ __u32 format;
+ __u32 out_x, out_y;
+ __u32 out_width, out_height;
+ __u32 reserved[8];
+};
+
+struct omapfb_update_window_old {
+ __u32 x, y;
+ __u32 width, height;
+ __u32 format;
+};
+
+enum omapfb_plane {
+ OMAPFB_PLANE_GFX = 0,
+ OMAPFB_PLANE_VID1,
+ OMAPFB_PLANE_VID2,
+};
+
+enum omapfb_channel_out {
+ OMAPFB_CHANNEL_OUT_LCD = 0,
+ OMAPFB_CHANNEL_OUT_DIGIT,
+};
+
+struct omapfb_plane_info {
+ __u32 pos_x;
+ __u32 pos_y;
+ __u8 enabled;
+ __u8 channel_out;
+ __u8 mirror;
+ __u8 mem_idx;
+ __u32 out_width;
+ __u32 out_height;
+ __u32 reserved2[12];
+};
+
+struct omapfb_mem_info {
+ __u32 size;
+ __u8 type;
+ __u8 reserved[3];
+};
+
+struct omapfb_caps {
+ __u32 ctrl;
+ __u32 plane_color;
+ __u32 wnd_color;
+};
+
+enum omapfb_color_key_type {
+ OMAPFB_COLOR_KEY_DISABLED = 0,
+ OMAPFB_COLOR_KEY_GFX_DST,
+ OMAPFB_COLOR_KEY_VID_SRC,
+};
+
+struct omapfb_color_key {
+ __u8 channel_out;
+ __u32 background;
+ __u32 trans_key;
+ __u8 key_type;
+};
+
+enum omapfb_update_mode {
+ OMAPFB_UPDATE_DISABLED = 0,
+ OMAPFB_AUTO_UPDATE,
+ OMAPFB_MANUAL_UPDATE
+};
+
+struct omapfb_memory_read {
+ __u16 x;
+ __u16 y;
+ __u16 w;
+ __u16 h;
+ size_t buffer_size;
+ void __user *buffer;
+};
+
+struct omapfb_ovl_colormode {
+ __u8 overlay_idx;
+ __u8 mode_idx;
+ __u32 bits_per_pixel;
+ __u32 nonstd;
+ struct fb_bitfield red;
+ struct fb_bitfield green;
+ struct fb_bitfield blue;
+ struct fb_bitfield transp;
+};
+
+struct omapfb_vram_info {
+ __u32 total;
+ __u32 free;
+ __u32 largest_free_block;
+ __u32 reserved[5];
+};
+
+struct omapfb_tearsync_info {
+ __u8 enabled;
+ __u8 reserved1[3];
+ __u16 line;
+ __u16 reserved2;
+};
+
+struct omapfb_display_info {
+ __u16 xres;
+ __u16 yres;
+ __u32 width; /* phys width of the display in micrometers */
+ __u32 height; /* phys height of the display in micrometers */
+ __u32 reserved[5];
+};
+
+#ifdef __KERNEL__
+
+#include <plat/board.h>
+
+#ifdef CONFIG_ARCH_OMAP1
+#define OMAPFB_PLANE_NUM 1
+#else
+#define OMAPFB_PLANE_NUM 3
+#endif
+
+struct omapfb_mem_region {
+ u32 paddr;
+ void __iomem *vaddr;
+ unsigned long size;
+ u8 type; /* OMAPFB_PLANE_MEM_* */
+ enum omapfb_color_format format;/* OMAPFB_COLOR_* */
+ unsigned format_used:1; /* Must be set when format is set.
+ * Needed b/c of the badly chosen 0
+ * base for OMAPFB_COLOR_* values
+ */
+ unsigned alloc:1; /* allocated by the driver */
+ unsigned map:1; /* kernel mapped by the driver */
+};
+
+struct omapfb_mem_desc {
+ int region_cnt;
+ struct omapfb_mem_region region[OMAPFB_PLANE_NUM];
+};
+
+struct omapfb_platform_data {
+ struct omap_lcd_config lcd;
+ struct omapfb_mem_desc mem_desc;
+ void *ctrl_platform_data;
+};
+
+/* in arch/arm/plat-omap/fb.c */
+extern void omapfb_set_platform_data(struct omapfb_platform_data *data);
+extern void omapfb_set_ctrl_platform_data(void *pdata);
+extern void omapfb_reserve_sdram_memblock(void);
+
+/* helper methods that may be used by other modules */
+enum omap_color_mode;
+struct omap_video_timings;
+int omapfb_mode_to_dss_mode(struct fb_var_screeninfo *var,
+ enum omap_color_mode *mode);
+void omapfb_fb2dss_timings(struct fb_videomode *fb_timings,
+ struct omap_video_timings *dss_timings);
+void omapfb_dss2fb_timings(struct omap_video_timings *dss_timings,
+ struct fb_videomode *fb_timings);
+
+#endif
+
+#endif /* __OMAPFB_H */
diff --git a/kernel-headers/linux/rpmsg_omx.h b/kernel-headers/linux/rpmsg_omx.h
new file mode 100644
index 0000000..c6ce94b
--- /dev/null
+++ b/kernel-headers/linux/rpmsg_omx.h
@@ -0,0 +1,156 @@
+/*
+ * OMX offloading remote processor driver
+ *
+ * Copyright(c) 2011 Texas Instruments. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name Texas Instruments nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RPMSG_OMX_H
+#define RPMSG_OMX_H
+
+#include <linux/ioctl.h>
+
+/**
+ * struct omx_pvr_data - metadata passed to/from userspace for a pvr register
+ * @fd: a file descriptor representing a pvr handle
+ * @num_handles: field filled by driver. userspace uses this to determine
+ * number of handles associated with fd
+ * @handles: opaque pointers pointing to buffers
+ */
+struct omx_pvr_data {
+ int fd;
+ unsigned int num_handles;
+ void *handles[2];
+};
+
+#define OMX_IOC_MAGIC 'X'
+
+#define OMX_IOCCONNECT _IOW(OMX_IOC_MAGIC, 1, char *)
+#define OMX_IOCIONREGISTER _IOWR(OMX_IOC_MAGIC, 2, struct ion_fd_data)
+#define OMX_IOCIONUNREGISTER _IOWR(OMX_IOC_MAGIC, 3, struct ion_fd_data)
+#define OMX_IOCPVRREGISTER _IOWR(OMX_IOC_MAGIC, 4, struct omx_pvr_data)
+#define OMX_IOC_MAXNR (4)
+#ifdef __KERNEL__
+
+/**
+ * enum omx_msg_types - various message types currently supported
+ *
+ * @OMX_CONN_REQ: a connection request message type. the message should carry
+ * the name of the OMX service which we try to connect to. An instance of
+ * that service will be created remotely, and its address will be sent as
+ * a reply.
+ *
+ * @OMX_CONN_RSP: a response to a connection request. the message will carry
+ * an error code (success/failure), and if connection established successfully,
+ * the addr field will carry the address of the newly created OMX instance.
+ *
+ * @OMX_DISCONNECT: disconnect remote OMX instance. this message tells
+ * remote processor to release the resources coupled with this connection
+ *
+ * @OMX_RAW_MSG: a message that should be propagated as-is to the user.
+ * this would immediately enable user space development to start.
+ * as we progress, most likely this message won't be needed anymore.
+ */
+enum omx_msg_types {
+ OMX_CONN_REQ = 0,
+ OMX_CONN_RSP = 1,
+ OMX_DISCONNECT = 4,
+ OMX_RAW_MSG = 5,
+ /* todo: do we need a disconnect response ? ION refcounts should allow
+ * asynchronous release of relevant buffers */
+};
+
+/**
+ * enum omx_error_codes - various error codes that will be used
+ *
+ * @OMX_SUCCESS: success
+ *
+ * @OMX_NOTSUPP: not supported
+ *
+ * @OMX_NOMEM: remote processor is out of memory
+ */
+enum omx_error_codes {
+ OMX_SUCCESS = 0,
+ OMX_NOTSUPP = 1,
+ OMX_NOMEM = 2,
+};
+
+/* keep documenting... */
+enum omx_state {
+ OMX_UNCONNECTED,
+ OMX_CONNECTED,
+ OMX_FAIL,
+};
+
+/**
+ * struct omx_msg_hdr - common header for all OMX messages
+ * @type: type of message, see enum omx_msg_types
+ * @flags: currently unused, should be zero
+ * @len: length of msg payload (in bytes)
+ * @data: the msg payload (depends on the message type)
+ *
+ * All OMX messages will start with this common header (which will begin
+ * right after the standard rpmsg header ends).
+ */
+struct omx_msg_hdr {
+ u32 type;
+ u32 flags;
+ u32 len;
+ char data[0];
+} __packed;
+
+struct omx_conn_rsp {
+ u32 status;
+ u32 addr;
+} __packed;
+
+struct omx_disc_req {
+ u32 addr;
+} __packed;
+
+
+#endif /* __KERNEL__ */
+
+/* temporarily exposed to user space too */
+struct omx_conn_req {
+ char name[48];
+} __packed;
+
+/* the packet structure (actual message sent to omx service) */
+struct omx_packet {
+ uint16_t desc; /* descriptor, and omx service status */
+ uint16_t msg_id; /* message id */
+ uint32_t flags; /* Set to a fixed value for now. */
+ uint32_t fxn_idx; /* Index into OMX service's function table.*/
+ int32_t result; /* The OMX function status. */
+ uint32_t data_size;/* Size of in/out data to/from the function. */
+ uint32_t data[0]; /* Payload of data_size char's passed to
+ function. */
+};
+
+#endif /* RPMSG_OMX_H */
diff --git a/kernel-headers/video/dsscomp.h b/kernel-headers/video/dsscomp.h
new file mode 100644
index 0000000..c2742bb
--- /dev/null
+++ b/kernel-headers/video/dsscomp.h
@@ -0,0 +1,709 @@
+#ifndef _LINUX_DSSCOMP_H
+#define _LINUX_DSSCOMP_H
+
+#ifdef __KERNEL__
+#include <video/omapdss.h>
+#else
+
+/* exporting enumerations from arch/arm/plat-omap/include/plat/display.h */
+enum omap_plane {
+ OMAP_DSS_GFX = 0,
+ OMAP_DSS_VIDEO1 = 1,
+ OMAP_DSS_VIDEO2 = 2,
+ OMAP_DSS_VIDEO3 = 3,
+ OMAP_DSS_WB = 4,
+};
+
+enum omap_channel {
+ OMAP_DSS_CHANNEL_LCD = 0,
+ OMAP_DSS_CHANNEL_DIGIT = 1,
+ OMAP_DSS_CHANNEL_LCD2 = 2,
+};
+
+enum omap_color_mode {
+ OMAP_DSS_COLOR_CLUT1 = 1 << 0, /* BITMAP 1 */
+ OMAP_DSS_COLOR_CLUT2 = 1 << 1, /* BITMAP 2 */
+ OMAP_DSS_COLOR_CLUT4 = 1 << 2, /* BITMAP 4 */
+ OMAP_DSS_COLOR_CLUT8 = 1 << 3, /* BITMAP 8 */
+
+ /* also referred to as RGB 12-BPP, 16-bit container */
+ OMAP_DSS_COLOR_RGB12U = 1 << 4, /* xRGB12-4444 */
+ OMAP_DSS_COLOR_ARGB16 = 1 << 5, /* ARGB16-4444 */
+ OMAP_DSS_COLOR_RGB16 = 1 << 6, /* RGB16-565 */
+
+ /* also referred to as RGB 24-BPP, 32-bit container */
+ OMAP_DSS_COLOR_RGB24U = 1 << 7, /* xRGB24-8888 */
+ OMAP_DSS_COLOR_RGB24P = 1 << 8, /* RGB24-888 */
+ OMAP_DSS_COLOR_YUV2 = 1 << 9, /* YUV2 4:2:2 co-sited */
+ OMAP_DSS_COLOR_UYVY = 1 << 10, /* UYVY 4:2:2 co-sited */
+ OMAP_DSS_COLOR_ARGB32 = 1 << 11, /* ARGB32-8888 */
+ OMAP_DSS_COLOR_RGBA32 = 1 << 12, /* RGBA32-8888 */
+
+ /* also referred to as RGBx 32 in TRM */
+ OMAP_DSS_COLOR_RGBX24 = 1 << 13, /* RGBx32-8888 */
+ OMAP_DSS_COLOR_RGBX32 = 1 << 13, /* RGBx32-8888 */
+ OMAP_DSS_COLOR_NV12 = 1 << 14, /* NV12 format: YUV 4:2:0 */
+
+ /* also referred to as RGBA12-4444 in TRM */
+ OMAP_DSS_COLOR_RGBA16 = 1 << 15, /* RGBA16-4444 */
+
+ OMAP_DSS_COLOR_RGBX12 = 1 << 16, /* RGBx16-4444 */
+ OMAP_DSS_COLOR_RGBX16 = 1 << 16, /* RGBx16-4444 */
+ OMAP_DSS_COLOR_ARGB16_1555 = 1 << 17, /* ARGB16-1555 */
+
+ /* also referred to as xRGB16-555 in TRM */
+ OMAP_DSS_COLOR_XRGB15 = 1 << 18, /* xRGB16-1555 */
+ OMAP_DSS_COLOR_XRGB16_1555 = 1 << 18, /* xRGB16-1555 */
+};
+
+/* Writeback data structures */
+enum omap_writeback_source {
+ OMAP_WB_LCD1 = 0,
+ OMAP_WB_TV = 1,
+ OMAP_WB_LCD2 = 2,
+ OMAP_WB_GFX = 3,
+ OMAP_WB_VID1 = 4,
+ OMAP_WB_VID2 = 5,
+ OMAP_WB_VID3 = 6
+};
+
+enum omap_writeback_mode {
+ OMAP_WB_CAPTURE_MODE = 0x0,
+ OMAP_WB_MEM2MEM_MODE = 0x1,
+};
+
+enum omap_dss_trans_key_type {
+ OMAP_DSS_COLOR_KEY_GFX_DST = 0,
+ OMAP_DSS_COLOR_KEY_VID_SRC = 1,
+};
+
+enum omap_dss_display_state {
+ OMAP_DSS_DISPLAY_DISABLED = 0,
+ OMAP_DSS_DISPLAY_ACTIVE,
+ OMAP_DSS_DISPLAY_SUSPENDED,
+ OMAP_DSS_DISPLAY_TRANSITION,
+};
+
+struct omap_video_timings {
+ /* Unit: pixels */
+ __u16 x_res;
+ /* Unit: pixels */
+ __u16 y_res;
+ /* Unit: KHz */
+ __u32 pixel_clock;
+ /* Unit: pixel clocks */
+ __u16 hsw; /* Horizontal synchronization pulse width */
+ /* Unit: pixel clocks */
+ __u16 hfp; /* Horizontal front porch */
+ /* Unit: pixel clocks */
+ __u16 hbp; /* Horizontal back porch */
+ /* Unit: line clocks */
+ __u16 vsw; /* Vertical synchronization pulse width */
+ /* Unit: line clocks */
+ __u16 vfp; /* Vertical front porch */
+ /* Unit: line clocks */
+ __u16 vbp; /* Vertical back porch */
+};
+
+/* YUV to RGB color conversion info */
+struct omap_dss_cconv_coefs {
+ __s16 ry, rcr, rcb;
+ __s16 gy, gcr, gcb;
+ __s16 by, bcr, bcb;
+
+ /* Y is 16..235, UV is 16..240 if not fullrange. Otherwise 0..255 */
+ __u16 full_range;
+} __attribute__ ((aligned(4)));
+
+struct omap_dss_cpr_coefs {
+ __s16 rr, rg, rb;
+ __s16 gr, gg, gb;
+ __s16 br, bg, bb;
+};
+
+#endif
+
+/* copy of fb_videomode */
+struct dsscomp_videomode {
+ const char *name; /* optional */
+ __u32 refresh; /* optional */
+ __u32 xres;
+ __u32 yres;
+ __u32 pixclock;
+ __u32 left_margin;
+ __u32 right_margin;
+ __u32 upper_margin;
+ __u32 lower_margin;
+ __u32 hsync_len;
+ __u32 vsync_len;
+ __u32 sync;
+ __u32 vmode;
+ __u32 flag;
+};
+
+/*
+ * Stereoscopic Panel types
+ * row, column, overunder, sidebyside options
+ * are with respect to native scan order
+ */
+enum s3d_disp_type {
+ S3D_DISP_NONE = 0,
+ S3D_DISP_FRAME_SEQ,
+ S3D_DISP_ROW_IL,
+ S3D_DISP_COL_IL,
+ S3D_DISP_PIX_IL,
+ S3D_DISP_CHECKB,
+ S3D_DISP_OVERUNDER,
+ S3D_DISP_SIDEBYSIDE,
+};
+
+/* Subsampling direction is based on native panel scan order.*/
+enum s3d_disp_sub_sampling {
+ S3D_DISP_SUB_SAMPLE_NONE = 0,
+ S3D_DISP_SUB_SAMPLE_V,
+ S3D_DISP_SUB_SAMPLE_H,
+};
+
+/*
+ * Indicates if display expects left view first followed by right or viceversa
+ * For row interlaved displays, defines first row view
+ * For column interleaved displays, defines first column view
+ * For checkerboard, defines first pixel view
+ * For overunder, defines top view
+ * For sidebyside, defines west view
+ */
+enum s3d_disp_order {
+ S3D_DISP_ORDER_L = 0,
+ S3D_DISP_ORDER_R = 1,
+};
+
+/*
+ * Indicates current view
+ * Used mainly for displays that need to trigger a sync signal
+ */
+enum s3d_disp_view {
+ S3D_DISP_VIEW_L = 0,
+ S3D_DISP_VIEW_R,
+};
+
+struct s3d_disp_info {
+ enum s3d_disp_type type;
+ enum s3d_disp_sub_sampling sub_samp;
+ enum s3d_disp_order order;
+ /*
+ * Gap between left and right views
+ * For over/under units are lines
+ * For sidebyside units are pixels
+ * For other types ignored
+ */
+ unsigned int gap;
+};
+
+enum omap_dss_ilace_mode {
+ OMAP_DSS_ILACE = (1 << 0), /* interlaced vs. progressive */
+ OMAP_DSS_ILACE_SEQ = (1 << 1), /* sequential vs interleaved */
+ OMAP_DSS_ILACE_SWAP = (1 << 2), /* swap fields, e.g. TB=>BT */
+
+ OMAP_DSS_ILACE_NONE = 0,
+ OMAP_DSS_ILACE_IL_TB = OMAP_DSS_ILACE,
+ OMAP_DSS_ILACE_IL_BT = OMAP_DSS_ILACE | OMAP_DSS_ILACE_SWAP,
+ OMAP_DSS_ILACE_SEQ_TB = OMAP_DSS_ILACE_IL_TB | OMAP_DSS_ILACE_SEQ,
+ OMAP_DSS_ILACE_SEQ_BT = OMAP_DSS_ILACE_IL_BT | OMAP_DSS_ILACE_SEQ,
+};
+
+/* YUV VC1 range mapping info */
+struct dss2_vc1_range_map_info {
+ __u8 enable; /* bool */
+
+ __u8 range_y; /* 0..7 */
+ __u8 range_uv; /* 0..7 */
+} __attribute__ ((aligned(4)));
+
+/* standard rectangle */
+struct dss2_rect_t {
+ __s32 x; /* left */
+ __s32 y; /* top */
+ __u32 w; /* width */
+ __u32 h; /* height */
+} __attribute__ ((aligned(4)));
+
+/* decimation constraints */
+struct dss2_decim {
+ __u8 min_x;
+ __u8 max_x; /* 0 is same as 255 */
+ __u8 min_y;
+ __u8 max_y; /* 0 is same as 255 */
+} __attribute__ ((aligned(4)));
+
+/*
+ * A somewhat more user friendly interface to the DSS2. This is a
+ * direct interface to the DSS2 overlay and overlay_manager modules.
+ * User-space APIs are provided for HW-specific control of DSS in
+ * contrast with V4L2/FB that are more generic, but in this process
+ * omit HW-specific features.
+ *
+ * For now managers are specified by display index as opposed to manager
+ * type, so that display0 is always the default display (e.g. HDMI on
+ * panda, and LCD blaze.) For now you would need to query the displays
+ * or use sysfs to find a specific display.
+ *
+ * Userspace operations are as follows:
+ *
+ * 1) check if DSS supports an overlay configuration, use DSSCIOC_CHECK_OVL
+ * ioctl with the manager, overlay, and setup-mode information filled out.
+ * All fields should be filled out as it may influence whether DSS can
+ * display/render the overlay.
+ *
+ * If proper address information is not available, it may be possible to
+ * use a type-of-address enumeration instead for luma/rgb and chroma (if
+ * applicable) frames.
+ *
+ * Do this for each overlay before attempting to configure DSS.
+ *
+ * 2) configure DSS pipelines for display/manager using DSSCOMP_SETUP_MANAGER
+ * ioctl. You can delay applying the settings until an dss2_manager_apply()
+ * is called for the internal composition object, if the APPLY bit of setup mode
+ * is not set. However the CAPTURE/DISPLAY bits of the setup mode settings will
+ * determine if at this time a capture will take place (in case of capture
+ * only mode). You may also set up additional pipelines with
+ * dss2_overlay_setup() before this.
+ *
+ * 3) On OMAP4/5 you can use the DSS WB pipeline to copy (and convert) a buffer
+ * using DSS. Use the DSSCIOC_WB_COPY ioctl for this. This is a blocking
+ * call, and it may possibly fail if an ongoing WB capture mode has been
+ * scheduled (which is outside of the current scope of the DSS2 interface.)
+ *
+ * There is also a one-shot configuration API (DSSCIOC_SETUP_DISPC). This
+ * allows you to set-up all overlays on all managers in one call. This call
+ * performs additional functionality:
+ *
+ * - it maps userspace 1D buffers into TILER 1D for the duration of the display
+ * - it disables all overlays that were specified before, but are no longer
+ * specified
+ *
+ */
+
+/*
+ * DSS2 overlay information. This structure contains all information
+ * needed to set up the overlay for a particular buffer to be displayed
+ * at a particular orientation.
+ *
+ * The following information is deemed to be set globally, so it is not
+ * included:
+ * - whether to enable zorder (always enabled)
+ * - whether to replicate/truncate color fields (it is decided per the
+ * whole manager/overlay settings, and is enabled unless overlay is
+ * directed to WB.)
+ *
+ * There is also no support for CLUT formats
+ *
+ * Requirements:
+ *
+ * 1) 0 <= crop.x <= crop.x + crop.w <= width
+ * 2) 0 <= crop.y <= crop.y + crop.h <= height
+ * 3) win.x <= win.x + win.w and win.w >= 0
+ * 4) win.y <= win.y + win.h and win.h >= 0
+ *
+ * 5) color_mode is supported by overlay
+ * 6) requested scaling is supported by overlay and functional clocks
+ *
+ * Notes:
+ *
+ * 1) Any portions of X:[pos_x, pos_x + out_width] and
+ * Y:[pos_y, pos_y + out_height] outside of the screen
+ * X:[0, screen.width], Y:[0, screen.height] will be cropped
+ * automatically without changing the scaling ratio.
+ *
+ * 2) Crop region will be adjusted to the pixel granularity:
+ * (2-by-1) for YUV422, (2-by-2) for YUV420. This will
+ * not modify the output region. Crop region is for the
+ * original (unrotated) buffer, so it does not change with
+ * rotation.
+ *
+ * 3) Rotation will not modify the output region, specifically
+ * its height and width. Also the coordinate system of the
+ * display is always (0,0) = top left.
+ *
+ * 4) cconv and vc1 only needs to be filled for YUV color modes.
+ *
+ * 5) vc1.range_y and vc1.range_uv only needs to be filled if
+ * vc1.enable is true.
+ */
+struct dss2_ovl_cfg {
+ __u16 width; /* buffer width */
+ __u16 height; /* buffer height */
+ __u32 stride; /* buffer stride */
+
+ enum omap_color_mode color_mode;
+ __u8 pre_mult_alpha; /* bool */
+ __u8 global_alpha; /* 0..255 */
+ __u8 rotation; /* 0..3 (*90 degrees clockwise) */
+ __u8 mirror; /* left-to-right: mirroring is applied after rotation */
+
+ enum omap_dss_ilace_mode ilace; /* interlace mode */
+
+ struct dss2_rect_t win; /* output window - on display */
+ struct dss2_rect_t crop; /* crop window - in source buffer */
+
+ struct dss2_decim decim; /* predecimation limits */
+
+ struct omap_dss_cconv_coefs cconv;
+ struct dss2_vc1_range_map_info vc1;
+
+ __u8 wb_source; /* pipe: is source or not, wb: capture device id */
+ enum omap_writeback_mode wb_mode;
+ __u8 ix; /* ovl index same as sysfs/overlay# */
+ __u8 zorder; /* 0..3 */
+ __u8 enabled; /* bool */
+ __u8 zonly; /* only set zorder and enabled bit */
+ __u8 mgr_ix; /* mgr index */
+} __attribute__ ((aligned(4)));
+
+enum omapdss_buffer_type {
+ OMAP_DSS_BUFTYPE_SDMA,
+ OMAP_DSS_BUFTYPE_TILER_8BIT,
+ OMAP_DSS_BUFTYPE_TILER_16BIT,
+ OMAP_DSS_BUFTYPE_TILER_32BIT,
+ OMAP_DSS_BUFTYPE_TILER_PAGE,
+};
+
+enum omapdss_buffer_addressing_type {
+ OMAP_DSS_BUFADDR_DIRECT, /* using direct addresses */
+ OMAP_DSS_BUFADDR_BYTYPE, /* using buffer types */
+ OMAP_DSS_BUFADDR_ION, /* using ion handle(s) */
+ OMAP_DSS_BUFADDR_GRALLOC, /* using gralloc handle */
+ OMAP_DSS_BUFADDR_OVL_IX, /* using a prior overlay */
+ OMAP_DSS_BUFADDR_LAYER_IX, /* using a Post2 layer */
+ OMAP_DSS_BUFADDR_FB, /* using framebuffer memory */
+};
+
+struct dss2_ovl_info {
+ struct dss2_ovl_cfg cfg;
+
+ enum omapdss_buffer_addressing_type addressing;
+
+ union {
+ /* user-space interfaces */
+ struct {
+ void *address; /* main buffer address */
+ void *uv_address; /* uv buffer */
+ };
+
+ /*
+ * For DSSCIOC_CHECK_OVL we allow specifying just the
+ * type of each buffer. This is used if we need to
+ * check whether DSS will be able to display a buffer
+ * if using a particular memory type before spending
+ * time to map/copy the buffer into that type of
+ * memory.
+ */
+ struct {
+ enum omapdss_buffer_type ba_type;
+ enum omapdss_buffer_type uv_type;
+ };
+
+ /* kernel-space interfaces */
+
+ /*
+ * for fbmem, highest 4-bits of address is fb index,
+ * rest of the bits are the offset
+ */
+ struct {
+ __u32 ba; /* base address or index */
+ __u32 uv; /* uv address */
+ };
+ };
+};
+
+/*
+ * DSS2 manager information.
+ *
+ * The following information is deemed to be set globally, so it is not
+ * included:
+ * gamma correction
+ * whether to enable zorder (always enabled)
+ * whether to replicate/truncate color fields (it is decided per the
+ * whole manager/overlay settings, and is enabled unless overlay is
+ * directed to WB.)
+ * Notes:
+ *
+ * 1) trans_key_type and trans_enabled only need to be filled if
+ * trans_enabled is true, and alpha_blending is false.
+ */
+struct dss2_mgr_info {
+ __u32 ix; /* display index same as sysfs/display# */
+
+ __u32 default_color;
+
+ enum omap_dss_trans_key_type trans_key_type;
+ __u32 trans_key;
+ struct omap_dss_cpr_coefs cpr_coefs;
+
+ __u8 trans_enabled; /* bool */
+
+ __u8 interlaced; /* bool */
+ __u8 alpha_blending; /* bool - overrides trans_enabled */
+ __u8 cpr_enabled; /* bool */
+ __u8 swap_rb; /* bool - swap red and blue */
+} __attribute__ ((aligned(4)));
+
+/*
+ * ioctl: DSSCIOC_SETUP_MGR, struct dsscomp_setup_mgr_data
+ *
+ * 1. sets manager of each ovl in composition to the display
+ * 2. calls set_dss_ovl_info() for each ovl to set up the
+ * overlay staging structures (this is a wrapper around ovl->set_info())
+ * 3. calls set_dss_mgr_info() for mgr to set up the manager
+ * staging structures (this is a wrapper around mgr->set_info())
+ * 4. if update is true:
+ * calls manager->apply()
+ * calls driver->update() in a non-blocking fashion
+ * this will program the DSS synchronously
+ *
+ * Notes:
+ *
+ * 1) x, y, w, h only needs to be set if update is true.
+ *
+ * All non-specified pipelines that currently are on the same display
+ * will remain the same as on the previous frame. You may want to
+ * disable unused pipelines to avoid surprises.
+ *
+ * If get_sync_obj is false, it returns 0 on success, <0 error value
+ * on failure.
+ *
+ * If get_sync_obj is true, it returns fd on success, or a negative value
+ * on failure. You can use the fd to wait on (using DSSCIOC_WAIT ioctl()).
+ *
+ * Note: frames do not get eclipsed when the display turns off. Queue a
+ * blank frame to eclipse old frames. Blank frames get eclipsed when
+ * programmed into DSS.
+ *
+ * (A blank frame is queued to the display automatically in Android before
+ * the display is turned off.)
+ *
+ * All overlays to be used on the frame must be listed. There is no way
+ * to add another overlay to a defined frame.
+ */
+enum dsscomp_setup_mode {
+ DSSCOMP_SETUP_MODE_APPLY = (1 << 0), /* applies changes to cache */
+ DSSCOMP_SETUP_MODE_DISPLAY = (1 << 1), /* calls display update */
+ DSSCOMP_SETUP_MODE_CAPTURE = (1 << 2), /* capture to WB */
+
+ /* just apply changes for next vsync/update */
+ DSSCOMP_SETUP_APPLY = DSSCOMP_SETUP_MODE_APPLY,
+ /* trigger an update (wait for vsync) */
+ DSSCOMP_SETUP_DISPLAY =
+ DSSCOMP_SETUP_MODE_APPLY | DSSCOMP_SETUP_MODE_DISPLAY,
+ /* capture to WB - WB must be configured */
+ DSSCOMP_SETUP_CAPTURE =
+ DSSCOMP_SETUP_MODE_APPLY | DSSCOMP_SETUP_MODE_CAPTURE,
+ /* display and capture to WB - WB must be configured */
+ DSSCOMP_SETUP_DISPLAY_CAPTURE =
+ DSSCOMP_SETUP_DISPLAY | DSSCOMP_SETUP_CAPTURE,
+};
+
+struct dsscomp_setup_mgr_data {
+ __u32 sync_id; /* synchronization ID - for debugging */
+
+ struct dss2_rect_t win; /* update region, set w/h to 0 for fullscreen */
+ enum dsscomp_setup_mode mode;
+ __u16 num_ovls; /* # of overlays used in the composition */
+ __u16 get_sync_obj; /* ioctl should return a sync object */
+
+ struct dss2_mgr_info mgr;
+ struct dss2_ovl_info ovls[0]; /* up to 5 overlays to set up */
+};
+
+/*
+ * ioctl: DSSCIOC_CHECK_OVL, struct dsscomp_check_ovl_data
+ *
+ * DISPLAY and/or CAPTURE bits must be filled for the mode field
+ * correctly to be able to decide correctly if DSS can properly
+ * render the overlay.
+ *
+ * ovl.ix is ignored.
+ *
+ * Returns a positive bitmask regarding which overlay of DSS can
+ * render the overlay as it is configured for the display/display's
+ * manager. NOTE: that overlays that are assigned to other displays
+ * may be returned. If there is an invalid configuration (negative
+ * sizes, etc.), a negative error value is returned.
+ *
+ * ovl->decim's min values will be modified to the smallest decimation that
+ * DSS can use to support the overlay configuration.
+ *
+ * Assumptions:
+ * - zorder will be distinct from other pipelines on that manager
+ * - overlay will be enabled and routed to the display specified
+ */
+struct dsscomp_check_ovl_data {
+ enum dsscomp_setup_mode mode;
+ struct dss2_mgr_info mgr;
+ struct dss2_ovl_info ovl;
+};
+
+/*
+ * This structure is used to set up the entire DISPC (all managers),
+ * and is analogous to dsscomp_setup_mgr_data.
+ *
+ * Additional features:
+ * - all overlays that were specified in a prior use of this
+ * structure, and are no longer specified, will be disabled.
+ * - 1D buffers under 4M will be mapped into TILER1D.
+ *
+ * Limitations:
+ * - only DISPLAY mode is supported (DISPLAY and APPLY bits will
+ * automatically be set)
+ * - getting a sync object is not supported.
+ */
+struct dsscomp_setup_dispc_data {
+ __u32 sync_id; /* synchronization ID - for debugging */
+
+ enum dsscomp_setup_mode mode;
+ __u16 num_ovls; /* # of overlays used in the composition */
+ __u16 num_mgrs; /* # of managers used in the composition */
+ __u16 get_sync_obj; /* ioctl should return a sync object */
+
+ struct dss2_mgr_info mgrs[3];
+ struct dss2_ovl_info ovls[5]; /* up to 5 overlays to set up */
+};
+
+/*
+ * ioctl: DSSCIOC_WB_COPY, struct dsscomp_wb_copy_data
+ *,
+ * Requirements:
+ * wb.ix must be OMAP_DSS_WB.
+ *
+ * Returns 0 on success (copy is completed), non-0 on failure.
+ */
+struct dsscomp_wb_copy_data {
+ struct dss2_ovl_info ovl, wb;
+};
+
+/*
+ * ioctl: DSSCIOC_QUERY_DISPLAY, struct dsscomp_display_info
+ *
+ * Gets informations about the display. Fill in ix and modedb_len before
+ * calling ioctl, and rest of the fields are filled in by ioctl. Up to
+ * modedb_len timings are retrieved in the order of display preference.
+ *
+ * Returns: 0 on success, non-0 error value on failure.
+ */
+struct dsscomp_display_info {
+ __u32 ix; /* display index (sysfs/display#) */
+ __u32 overlays_available; /* bitmask of available overlays */
+ __u32 overlays_owned; /* bitmask of owned overlays */
+ enum omap_channel channel;
+ enum omap_dss_display_state state;
+ __u8 enabled; /* bool: resume-state if suspended */
+ struct omap_video_timings timings;
+ struct s3d_disp_info s3d_info; /* any S3D specific information */
+ struct dss2_mgr_info mgr; /* manager information */
+ __u16 width_in_mm; /* screen dimensions */
+ __u16 height_in_mm;
+
+ __u32 modedb_len; /* number of video timings */
+ struct dsscomp_videomode modedb[]; /* display supported timings */
+};
+
+/*
+ * ioctl: DSSCIOC_SETUP_DISPLAY, struct dsscomp_setup_display_data
+ *
+ * Gets informations about the display. Fill in ix before calling
+ * ioctl, and rest of the fields are filled in by ioctl.
+ *
+ * Returns: 0 on success, non-0 error value on failure.
+ */
+struct dsscomp_setup_display_data {
+ __u32 ix; /* display index (sysfs/display#) */
+ struct dsscomp_videomode mode; /* video timings */
+};
+
+/*
+ * ioctl: DSSCIOC_WAIT, struct dsscomp_wait_data
+ *
+ * Use this ioctl to wait for one of the following events:
+ *
+ * A) the moment a composition is programmed into DSS
+ * B) the moment a composition is first displayed (or captured)
+ * C) the moment when a composition is no longer queued or displayed on a
+ * display (it is released). (A composition is assumed to be superceded
+ * when another composition has been programmed into DSS, even if that
+ * subsequent composition does not update/specify all overlays used by
+ * the prior composition; moreover, even if it uses the same buffers.)
+ *
+ * Set timeout to desired timeout value in microseconds.
+ *
+ * This ioctl must be used on the sync object returned by the
+ * DSSCIOC_SETUP_MGR or DSSCIOC_SETUP_DISPC ioctls.
+ *
+ * Returns: >=0 on success, <0 error value on failure (e.g. -ETIME).
+ */
+enum dsscomp_wait_phase {
+ DSSCOMP_WAIT_PROGRAMMED = 1,
+ DSSCOMP_WAIT_DISPLAYED,
+ DSSCOMP_WAIT_RELEASED,
+};
+
+struct dsscomp_wait_data {
+ __u32 timeout_us; /* timeout in microseconds */
+ enum dsscomp_wait_phase phase; /* phase to wait for */
+};
+
+enum dsscomp_fbmem_type {
+ DSSCOMP_FBMEM_TILER2D = 0,
+ DSSCOMP_FBMEM_VRAM = 1,
+};
+
+/*
+ * ioctl: DSSCIOC_QUERY_PLATFORM, struct dsscomp_platform_info
+ *
+ * Use this ioctl to get platform information needed to decide
+ * DSS/DSSCOMP capabilities, by filling out the passed structure with:
+ *
+ * A) predecimation limits
+ * B) maximum fclk (DSS is assumed to scale up to this fclk automatically
+ * to support frames)
+ * C) minimum and maximum sizes (for now we use the same limits for
+ * both source and window sizes, which works for OMAP4/5)
+ * D) scaler limitations. (assuming same max downscale limitation both
+ * horizontally/vertically; however, fclock requirements are only
+ * dependent on horizontal scaling, which works for OMAP4 ES1.1+ and
+ * OMAP5 only).
+ * integer_scale_ratio_limit is the maximum source width to round up
+ * fclock/pixclock to an integer.
+ * E) Tiler1D slot size
+ *
+ * Returns: 0 on success, <0 error value on failure (unlikely)
+ */
+
+struct dsscomp_platform_info {
+ /* decimation limits for 2D and 1D buffers */
+ __u8 max_xdecim_2d;
+ __u8 max_ydecim_2d;
+ __u8 max_xdecim_1d;
+ __u8 max_ydecim_1d;
+ __u32 fclk; /* dispc max fclk */
+ /* pipeline source/destination limits */
+ __u8 min_width;
+ __u16 max_width;
+ __u16 max_height;
+ /* scaler limitations */
+ __u8 max_downscale;
+ /* below this width, we assume integer pixelclk scale */
+ __u16 integer_scale_ratio_limit;
+ __u32 tiler1d_slot_size;
+ enum dsscomp_fbmem_type fbmem_type; /* TILER2D vs VRAM */
+};
+
+/* IOCTLS */
+#define DSSCIOC_SETUP_MGR _IOW('O', 128, struct dsscomp_setup_mgr_data)
+#define DSSCIOC_CHECK_OVL _IOWR('O', 129, struct dsscomp_check_ovl_data)
+#define DSSCIOC_WB_COPY _IOW('O', 130, struct dsscomp_wb_copy_data)
+#define DSSCIOC_QUERY_DISPLAY _IOWR('O', 131, struct dsscomp_display_info)
+#define DSSCIOC_WAIT _IOW('O', 132, struct dsscomp_wait_data)
+
+#define DSSCIOC_SETUP_DISPC _IOW('O', 133, struct dsscomp_setup_dispc_data)
+#define DSSCIOC_SETUP_DISPLAY _IOW('O', 134, struct dsscomp_setup_display_data)
+#define DSSCIOC_QUERY_PLATFORM _IOR('O', 135, struct dsscomp_platform_info)
+#endif
diff --git a/kernel-headers/video/omap_hwc.h b/kernel-headers/video/omap_hwc.h
new file mode 100644
index 0000000..120ee6e
--- /dev/null
+++ b/kernel-headers/video/omap_hwc.h
@@ -0,0 +1,99 @@
+#ifndef _LINUX_OMAP_HWC_H
+#define _LINUX_OMAP_HWC_H
+
+/*
+ * Client of the omap_hwc_data API
+ * -------------------------------
+ * This is really a kernel to kernel API (not an ioctl interface) but most of
+ * the values are populated in user space by a single client, specifically the
+ * Android hardware composer HAL (HWC) which is a library loaded by the
+ * SurfaceFlinger composition process.
+ *
+ * Implementation details
+ * ----------------------
+ * The SGX display driver (called OMAPLFB) will obtain this data structure
+ * from the GPU driver (aka PVR kernel services) as well as an array of
+ * memory descriptors managed by PVR services. OMAPLFB is responsible
+ * for fixing up the buffer data within the omap_hwc_data data structure
+ * before calling the DSSCOMP module and (optionally) the Bltsville kernel
+ * API/implementation.
+ *
+ * Buffer referencing
+ * ------------------
+ * When calling from the HWC (via PVR services) the actual address of buffers
+ * involved in composition are typically unknown. It is a convention to store
+ * an index in the appropriate field of the sub-structures in omap_hwc_data.
+ * PVR services also passes an array of memory data structures that these
+ * indexes (commonly) refer to.
+ *
+ * The dsscomp API fully describes how it manages buffering when called
+ * from a kernel client context. The simplest scenario is that individual
+ * overlays carry the buffer index in the overlay structure base address.
+ *
+ * For Bltsville kernel mode support, buffers are identified by storing the
+ * buffer index in the virtaddr of the various bvbuffdesc entries. Some
+ * exceptions are described below.
+ *
+ * Blitting
+ * --------
+ * Blit source buffers are managed in the same way as Post2 layers in the
+ * dsscomp API. The Android HWC constructs the blits using the Bltsville
+ * API but the actual blits are issued to Bltsville kernel mode implementation
+ * from OMAPLFB. Destination buffers are allocated and managed by OMAPLFB.
+ *
+ * When blitting it is expected that HWC will construct the overlay information
+ * appropriately in "dsscomp_data"
+ */
+
+/*
+ * Alternate blit descriptor information.
+ *
+ * As mentioned above buffers are refers to by index, alternate buffers
+ * can be refered to by the following
+ */
+#define HWC_BLT_DESC_FLAG 0x80000000
+
+/*
+ * With this value the descriptor refers to an available framebuffer. It
+ * is up to the client and OMAPLFB to track and manage the state of these
+ * buffers. The caller can also specify an overlay index that OMAPLFB will
+ * use when programming dsscomp with the result of the blit.
+ */
+#define HWC_BLT_DESC_FB 0x40000000
+
+#define HWC_BLT_DESC_FB_FN(ovlno) \
+ (HWC_BLT_DESC_FLAG | HWC_BLT_DESC_FB | (ovlno))
+
+/*
+ * This flag hints OMAPLFB the HWC has configured a DSS pipe for a blit FB
+ */
+#define HWC_BLT_FLAG_USE_FB (1 << 0)
+
+/*****************************************************************************/
+/* WARNING - These structs must keep in sync with user space code */
+/*****************************************************************************/
+struct rgz_blt_entry {
+ struct bvbltparams bp;
+ struct bvsurfgeom dstgeom;
+ struct bvsurfgeom src1geom;
+ struct bvbuffdesc src1desc;
+ struct bvsurfgeom src2geom;
+ struct bvbuffdesc src2desc;
+};
+
+struct omap_hwc_blit_data {
+ __u16 rgz_flags;
+ /* if rgz_items is 0 there is nothing to blit */
+ __u16 rgz_items;
+ struct rgz_blt_entry rgz_blts[0];
+};
+
+/*
+ * This structure is passed down from the Android HWC HAL
+ */
+struct omap_hwc_data {
+ struct dsscomp_setup_dispc_data dsscomp_data;
+ struct omap_hwc_blit_data blit_data;
+};
+
+#endif
diff --git a/libion_ti/Android.mk b/libion_ti/Android.mk
new file mode 100644
index 0000000..032408d
--- /dev/null
+++ b/libion_ti/Android.mk
@@ -0,0 +1,23 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := ion.c
+LOCAL_MODULE := libion_ti
+LOCAL_MODULE_TAGS := optional
+LOCAL_SHARED_LIBRARIES := liblog
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := ion.c ion_test.c
+LOCAL_MODULE := ion_ti_test
+LOCAL_MODULE_TAGS := optional tests
+LOCAL_SHARED_LIBRARIES := liblog
+include $(BUILD_EXECUTABLE)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := ion.c ion_test_2.c
+LOCAL_MODULE := ion_ti_test2
+LOCAL_MODULE_TAGS := optional tests
+LOCAL_SHARED_LIBRARIES := liblog
+include $(BUILD_EXECUTABLE)
+
diff --git a/libion_ti/ion.c b/libion_ti/ion.c
new file mode 100644
index 0000000..01459ab
--- /dev/null
+++ b/libion_ti/ion.c
@@ -0,0 +1,201 @@
+/*
+ * ion.c
+ *
+ * Memory Allocator functions for ion
+ *
+ * Copyright 2011 Google, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+
+#define LOG_TAG "ion"
+#include <cutils/log.h>
+
+#include "ion.h"
+
+int ion_open()
+{
+ int fd = open("/dev/ion", O_RDWR);
+ if (fd < 0)
+ ALOGE("open /dev/ion failed!\n");
+ return fd;
+}
+
+int ion_close(int fd)
+{
+ return close(fd);
+}
+
+static int ion_ioctl(int fd, int req, void *arg)
+{
+ int ret = ioctl(fd, req, arg);
+ if (ret < 0) {
+ ALOGE("ioctl %d failed with code %d: %s\n", req,
+ ret, strerror(errno));
+ return -errno;
+ }
+ return ret;
+}
+
+int ion_alloc(int fd, size_t len, size_t align, unsigned int flags,
+ struct ion_handle **handle)
+{
+ int ret;
+ struct ion_allocation_data data = {
+ .len = len,
+ .align = align,
+ .flags = flags,
+ };
+
+ ret = ion_ioctl(fd, ION_IOC_ALLOC, &data);
+ if (ret < 0)
+ return ret;
+ *handle = data.handle;
+ return ret;
+}
+
+int ion_alloc_tiler(int fd, size_t w, size_t h, int fmt, unsigned int flags,
+ struct ion_handle **handle, size_t *stride)
+{
+ int ret;
+ struct omap_ion_tiler_alloc_data alloc_data = {
+ .w = w,
+ .h = h,
+ .fmt = fmt,
+ .flags = flags,
+ .out_align = PAGE_SIZE,
+ .token = 0,
+ };
+
+ struct ion_custom_data custom_data = {
+ .cmd = OMAP_ION_TILER_ALLOC,
+ .arg = (unsigned long)(&alloc_data),
+ };
+
+ ret = ion_ioctl(fd, ION_IOC_CUSTOM, &custom_data);
+ if (ret < 0)
+ return ret;
+ *stride = alloc_data.stride;
+ *handle = alloc_data.handle;
+ return ret;
+}
+
+int ion_free(int fd, struct ion_handle *handle)
+{
+ struct ion_handle_data data = {
+ .handle = handle,
+ };
+ return ion_ioctl(fd, ION_IOC_FREE, &data);
+}
+
+int ion_map(int fd, struct ion_handle *handle, size_t length, int prot,
+ int flags, off_t offset, unsigned char **ptr, int *map_fd)
+{
+ struct ion_fd_data data = {
+ .handle = handle,
+ };
+ int ret = ion_ioctl(fd, ION_IOC_MAP, &data);
+ if (ret < 0)
+ return ret;
+ *map_fd = data.fd;
+ if (*map_fd < 0) {
+ ALOGE("map ioctl returned negative fd\n");
+ return -EINVAL;
+ }
+ *ptr = mmap(NULL, length, prot, flags, *map_fd, offset);
+ if (*ptr == MAP_FAILED) {
+ ALOGE("mmap failed: %s\n", strerror(errno));
+ return -errno;
+ }
+ return ret;
+}
+
+int ion_share(int fd, struct ion_handle *handle, int *share_fd)
+{
+ int map_fd;
+ struct ion_fd_data data = {
+ .handle = handle,
+ };
+ int ret = ion_ioctl(fd, ION_IOC_SHARE, &data);
+ if (ret < 0)
+ return ret;
+ *share_fd = data.fd;
+ if (*share_fd < 0) {
+ ALOGE("map ioctl returned negative fd\n");
+ return -EINVAL;
+ }
+ return ret;
+}
+
+int ion_import(int fd, int share_fd, struct ion_handle **handle)
+{
+ struct ion_fd_data data = {
+ .fd = share_fd,
+ };
+ int ret = ion_ioctl(fd, ION_IOC_IMPORT, &data);
+ if (ret < 0)
+ return ret;
+ *handle = data.handle;
+ return ret;
+}
+
+int ion_map_cacheable(int fd, struct ion_handle *handle, size_t length, int prot,
+ int flags, off_t offset, unsigned char **ptr, int *map_fd)
+{
+ struct ion_fd_data data = {
+ .handle = handle,
+ .cacheable = 1,
+ };
+ int ret = ion_ioctl(fd, ION_IOC_MAP, &data);
+ if (ret < 0)
+ return ret;
+ *map_fd = data.fd;
+ if (*map_fd < 0) {
+ ALOGE("map ioctl returned negative fd\n");
+ return -EINVAL;
+ }
+ *ptr = mmap(NULL, length, prot, flags, *map_fd, offset);
+ if (*ptr == MAP_FAILED) {
+ ALOGE("mmap failed: %s\n", strerror(errno));
+ return -errno;
+ }
+ return ret;
+}
+
+int ion_flush_cached(int fd, struct ion_handle *handle, size_t length,
+ unsigned char *ptr)
+{
+ struct ion_cached_user_buf_data data = {
+ .handle = handle,
+ .vaddr = (unsigned long)ptr,
+ .size = length,
+ };
+ return ion_ioctl(fd, ION_IOC_FLUSH_CACHED, &data);
+}
+
+int ion_inval_cached(int fd, struct ion_handle *handle, size_t length,
+ unsigned char *ptr)
+{
+ struct ion_cached_user_buf_data data = {
+ .handle = handle,
+ .vaddr = (unsigned long)ptr,
+ .size = length,
+ };
+ return ion_ioctl(fd, ION_IOC_INVAL_CACHED, &data);
+}
diff --git a/libion_ti/ion.h b/libion_ti/ion.h
new file mode 100644
index 0000000..05fe1ec
--- /dev/null
+++ b/libion_ti/ion.h
@@ -0,0 +1,49 @@
+/*
+ * ion.c
+ *
+ * Memory Allocator functions for ion
+ *
+ * Copyright 2011 Google, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TI_ION_H
+#define __TI_ION_H
+
+#include "linux_ion.h"
+#include "omap_ion.h"
+
+__BEGIN_DECLS
+
+int ion_open();
+int ion_close(int fd);
+int ion_alloc(int fd, size_t len, size_t align, unsigned int flags,
+ struct ion_handle **handle);
+int ion_alloc_tiler(int fd, size_t w, size_t h, int fmt, unsigned int flags,
+ struct ion_handle **handle, size_t *stride);
+int ion_free(int fd, struct ion_handle *handle);
+int ion_map(int fd, struct ion_handle *handle, size_t length, int prot,
+ int flags, off_t offset, unsigned char **ptr, int *map_fd);
+int ion_share(int fd, struct ion_handle *handle, int *share_fd);
+int ion_import(int fd, int share_fd, struct ion_handle **handle);
+int ion_map_cacheable(int fd, struct ion_handle *handle, size_t length,
+ int prot, int flags, off_t offset, unsigned char **ptr, int *map_fd);
+int ion_flush_cached(int fd, struct ion_handle *handle, size_t length,
+ unsigned char *ptr);
+int ion_inval_cached(int fd, struct ion_handle *handle, size_t length,
+ unsigned char *ptr);
+
+__END_DECLS
+
+#endif /* __TI_ION_H */
diff --git a/libion_ti/ion_test.c b/libion_ti/ion_test.c
new file mode 100644
index 0000000..ae7dead
--- /dev/null
+++ b/libion_ti/ion_test.c
@@ -0,0 +1,319 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "ion.h"
+
+size_t len = 1024*1024, align = 0;
+int prot = PROT_READ | PROT_WRITE;
+int map_flags = MAP_SHARED;
+int alloc_flags = 0;
+int test = -1;
+size_t width = 1024*1024, height = 1024*1024;
+int fmt = TILER_PIXEL_FMT_32BIT;
+int tiler_test = 0;
+size_t stride;
+
+int _ion_alloc_test(int *fd, struct ion_handle **handle)
+{
+ int ret;
+
+ *fd = ion_open();
+ if (*fd < 0)
+ return *fd;
+
+ if (tiler_test)
+ ret = ion_alloc_tiler(*fd, width, height, fmt, alloc_flags,
+ handle, &stride);
+ else
+ ret = ion_alloc(*fd, len, align, alloc_flags, handle);
+
+ if (ret)
+ printf("%s failed: %s\n", __func__, strerror(ret));
+ return ret;
+}
+
+void ion_alloc_test()
+{
+ int fd, ret;
+ struct ion_handle *handle;
+
+ if(_ion_alloc_test(&fd, &handle))
+ return;
+
+ ret = ion_free(fd, handle);
+ if (ret) {
+ printf("%s failed: %s %p\n", __func__, strerror(ret), handle);
+ return;
+ }
+ ion_close(fd);
+ printf("ion alloc test: passed\n");
+}
+
+void _ion_tiler_map_test(unsigned char *ptr)
+{
+ size_t row, col;
+
+ for (row = 0; row < height; row++)
+ for (col = 0; col < width; col++) {
+ int i = (row * stride) + col;
+ ptr[i] = (unsigned char)i;
+ }
+ for (row = 0; row < height; row++)
+ for (col = 0; col < width; col++) {
+ int i = (row * stride) + col;
+ if (ptr[i] != (unsigned char)i)
+ printf("%s failed wrote %d read %d from mapped "
+ "memory\n", __func__, i, ptr[i]);
+ }
+}
+
+
+void ion_map_test()
+{
+ int fd, map_fd, ret;
+ size_t i;
+ struct ion_handle *handle;
+ unsigned char *ptr;
+
+ if(_ion_alloc_test(&fd, &handle))
+ return;
+
+ if (tiler_test)
+ len = height * stride;
+ ret = ion_map(fd, handle, len, prot, map_flags, 0, &ptr, &map_fd);
+ if (ret)
+ return;
+
+ if (tiler_test)
+ _ion_tiler_map_test(ptr);
+ else {
+ for (i = 0; i < len; i++) {
+ ptr[i] = (unsigned char)i;
+ }
+ for (i = 0; i < len; i++)
+ if (ptr[i] != (unsigned char)i)
+ printf("%s failed wrote %d read %d from mapped "
+ "memory\n", __func__, i, ptr[i]);
+ }
+ /* clean up properly */
+ ret = ion_free(fd, handle);
+ ion_close(fd);
+ munmap(ptr, len);
+ close(map_fd);
+
+ _ion_alloc_test(&fd, &handle);
+ close(fd);
+
+#if 0
+ munmap(ptr, len);
+ close(map_fd);
+ ion_close(fd);
+
+ _ion_alloc_test(len, align, flags, &fd, &handle);
+ close(map_fd);
+ ret = ion_map(fd, handle, len, prot, flags, 0, &ptr, &map_fd);
+ /* don't clean up */
+#endif
+}
+
+void ion_share_test()
+
+{
+ struct ion_handle *handle;
+ int sd[2];
+ int num_fd = 1;
+ struct iovec count_vec = {
+ .iov_base = &num_fd,
+ .iov_len = sizeof num_fd,
+ };
+ char buf[CMSG_SPACE(sizeof(int))];
+ socketpair(AF_UNIX, SOCK_STREAM, 0, sd);
+ if (fork()) {
+ struct msghdr msg = {
+ .msg_control = buf,
+ .msg_controllen = sizeof buf,
+ .msg_iov = &count_vec,
+ .msg_iovlen = 1,
+ };
+
+ struct cmsghdr *cmsg;
+ int fd, share_fd, ret;
+ char *ptr;
+ /* parent */
+ if(_ion_alloc_test(&fd, &handle))
+ return;
+ ret = ion_share(fd, handle, &share_fd);
+ if (ret)
+ printf("share failed %s\n", strerror(errno));
+ ptr = mmap(NULL, len, prot, map_flags, share_fd, 0);
+ if (ptr == MAP_FAILED) {
+ return;
+ }
+ strcpy(ptr, "master");
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+ *(int *)CMSG_DATA(cmsg) = share_fd;
+ /* send the fd */
+ printf("master? [%10s] should be [master]\n", ptr);
+ printf("master sending msg 1\n");
+ sendmsg(sd[0], &msg, 0);
+ if (recvmsg(sd[0], &msg, 0) < 0)
+ perror("master recv msg 2");
+ printf("master? [%10s] should be [child]\n", ptr);
+
+ /* send ping */
+ sendmsg(sd[0], &msg, 0);
+ printf("master->master? [%10s]\n", ptr);
+ if (recvmsg(sd[0], &msg, 0) < 0)
+ perror("master recv 1");
+ } else {
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ char* ptr;
+ int fd, recv_fd;
+ char* child_buf[100];
+ /* child */
+ struct iovec count_vec = {
+ .iov_base = child_buf,
+ .iov_len = sizeof child_buf,
+ };
+
+ struct msghdr child_msg = {
+ .msg_control = buf,
+ .msg_controllen = sizeof buf,
+ .msg_iov = &count_vec,
+ .msg_iovlen = 1,
+ };
+
+ if (recvmsg(sd[1], &child_msg, 0) < 0)
+ perror("child recv msg 1");
+ cmsg = CMSG_FIRSTHDR(&child_msg);
+ if (cmsg == NULL) {
+ printf("no cmsg rcvd in child");
+ return;
+ }
+ recv_fd = *(int*)CMSG_DATA(cmsg);
+ if (recv_fd < 0) {
+ printf("could not get recv_fd from socket");
+ return;
+ }
+ printf("child %d\n", recv_fd);
+ fd = ion_open();
+ ptr = mmap(NULL, len, prot, map_flags, recv_fd, 0);
+ if (ptr == MAP_FAILED) {
+ return;
+ }
+ printf("child? [%10s] should be [master]\n", ptr);
+ strcpy(ptr, "child");
+ printf("child sending msg 2\n");
+ sendmsg(sd[1], &child_msg, 0);
+ }
+}
+
+int main(int argc, char* argv[]) {
+ int c;
+ enum tests {
+ ALLOC_TEST = 0, MAP_TEST, SHARE_TEST,
+ };
+
+ while (1) {
+ static struct option opts[] = {
+ {"alloc", no_argument, 0, 'a'},
+ {"alloc_flags", required_argument, 0, 'f'},
+ {"map", no_argument, 0, 'm'},
+ {"share", no_argument, 0, 's'},
+ {"len", required_argument, 0, 'l'},
+ {"align", required_argument, 0, 'g'},
+ {"map_flags", required_argument, 0, 'z'},
+ {"prot", required_argument, 0, 'p'},
+ {"alloc_tiler", no_argument, 0, 't'},
+ {"width", required_argument, 0, 'w'},
+ {"height", required_argument, 0, 'h'},
+ {"fmt", required_argument, 0, 'r'},
+ };
+ int i = 0;
+ c = getopt_long(argc, argv, "af:h:l:mr:stw:", opts, &i);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'l':
+ len = atol(optarg);
+ break;
+ case 'g':
+ align = atol(optarg);
+ break;
+ case 'z':
+ map_flags = 0;
+ map_flags |= strstr(optarg, "PROT_EXEC") ?
+ PROT_EXEC : 0;
+ map_flags |= strstr(optarg, "PROT_READ") ?
+ PROT_READ: 0;
+ map_flags |= strstr(optarg, "PROT_WRITE") ?
+ PROT_WRITE: 0;
+ map_flags |= strstr(optarg, "PROT_NONE") ?
+ PROT_NONE: 0;
+ break;
+ case 'p':
+ prot = 0;
+ prot |= strstr(optarg, "MAP_PRIVATE") ?
+ MAP_PRIVATE : 0;
+ prot |= strstr(optarg, "MAP_SHARED") ?
+ MAP_PRIVATE : 0;
+ break;
+ case 'f':
+ alloc_flags = atol(optarg);
+ break;
+ case 'a':
+ test = ALLOC_TEST;
+ break;
+ case 'm':
+ test = MAP_TEST;
+ break;
+ case 'r':
+ fmt = atol(optarg);
+ break;
+ case 's':
+ test = SHARE_TEST;
+ break;
+ case 'w':
+ width = atol(optarg);
+ break;
+ case 'h':
+ height = atol(optarg);
+ break;
+ case 't':
+ tiler_test = 1;
+ break;
+ }
+ }
+ printf("test %d, len %u, width %u, height %u fmt %u align %u, "
+ "map_flags %d, prot %d, alloc_flags %d\n", test, len, width,
+ height, fmt, align, map_flags, prot, alloc_flags);
+ switch (test) {
+ case ALLOC_TEST:
+ ion_alloc_test();
+ break;
+ case MAP_TEST:
+ ion_map_test();
+ break;
+ case SHARE_TEST:
+ ion_share_test();
+ break;
+ default:
+ printf("must specify a test (alloc, map, share)\n");
+ }
+ return 0;
+}
diff --git a/libion_ti/ion_test_2.c b/libion_ti/ion_test_2.c
new file mode 100644
index 0000000..5c19102
--- /dev/null
+++ b/libion_ti/ion_test_2.c
@@ -0,0 +1,479 @@
+/*
+ * Copyright (C) Texas Instruments - http://www.ti.com/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Test case to test ION Memory Allocator module
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "ion.h"
+
+size_t len = 1024*1024, align = 0;
+int prot = PROT_READ | PROT_WRITE;
+int map_flags = MAP_SHARED;
+int alloc_flags = 0;
+int test = -1;
+size_t width = 1024*1024, height = 1024*1024;
+int fmt = TILER_PIXEL_FMT_32BIT;
+int tiler_test = 0;
+size_t stride;
+
+int _ion_alloc_test(int fd, struct ion_handle **handle)
+{
+ int ret;
+
+ if (tiler_test)
+ ret = ion_alloc_tiler(fd, width, height, fmt, alloc_flags,
+ handle, &stride);
+ else
+ ret = ion_alloc(fd, len, align, alloc_flags, handle);
+
+ if (ret)
+ printf("%s() failed: %s\n", __func__, strerror(ret));
+ return ret;
+}
+
+int ion_alloc_test(int count)
+{
+ int fd, ret = 0, i, count_alloc;
+ struct ion_handle **handle;
+
+ fd = ion_open();
+ if (fd < 0) {
+ printf("%s(): FAILED to open ion device\n", __func__);
+ return -1;
+ }
+
+ handle = (struct ion_handle **)malloc(count * sizeof(struct ion_handle *));
+ if(handle == NULL) {
+ printf("%s() : FAILED to allocate memory for ion_handles\n", __func__);
+ return -ENOMEM;
+ }
+
+ /* Allocate ion_handles */
+ count_alloc = count;
+ for(i = 0; i < count; i++) {
+ ret = _ion_alloc_test(fd, &(handle[i]));
+ printf("%s(): Alloc handle[%d]=%p\n", __func__, i, handle[i]);
+ if(ret || ((int)handle[i] == -ENOMEM)) {
+ printf("%s(): Alloc handle[%d]=%p FAILED, err:%s\n",
+ __func__, i, handle[i], strerror(ret));
+ count_alloc = i;
+ goto err_alloc;
+ }
+ }
+
+ err_alloc:
+ /* Free ion_handles */
+ for (i = 0; i < count_alloc; i++) {
+ printf("%s(): Free handle[%d]=%p\n", __func__, i, handle[i]);
+ ret = ion_free(fd, handle[i]);
+ if (ret) {
+ printf("%s(): Free handle[%d]=%p FAILED, err:%s\n",
+ __func__, i, handle[i], strerror(ret));
+ }
+ }
+
+ ion_close(fd);
+ free(handle);
+ handle = NULL;
+
+ if(ret || (count_alloc != count)) {
+ printf("\nion alloc test: FAILED\n\n");
+ if(count_alloc != count)
+ ret = -ENOMEM;
+ }
+ else
+ printf("\nion alloc test: PASSED\n\n");
+
+ return ret;
+}
+
+void _ion_tiler_map_test(unsigned char *ptr)
+{
+ size_t row, col;
+
+ for (row = 0; row < height; row++)
+ for (col = 0; col < width; col++) {
+ int i = (row * stride) + col;
+ ptr[i] = (unsigned char)i;
+ }
+ for (row = 0; row < height; row++)
+ for (col = 0; col < width; col++) {
+ int i = (row * stride) + col;
+ if (ptr[i] != (unsigned char)i)
+ printf("%s(): FAILED, wrote %d read %d from mapped "
+ "memory\n", __func__, i, ptr[i]);
+ }
+}
+
+void _ion_map_test(unsigned char *ptr)
+{
+ size_t i;
+
+ for (i = 0; i < len; i++) {
+ ptr[i] = (unsigned char)i;
+ }
+ for (i = 0; i < len; i++) {
+ if (ptr[i] != (unsigned char)i)
+ printf("%s(): failed wrote %d read %d from mapped "
+ "memory\n", __func__, i, ptr[i]);
+ }
+}
+
+int ion_map_test(int count)
+{
+ int fd, ret = 0, i, count_alloc, count_map;
+ struct ion_handle **handle;
+ unsigned char **ptr;
+ int *map_fd;
+
+ fd = ion_open();
+ if (fd < 0) {
+ printf("%s(): FAILED to open ion device\n", __func__);
+ return -1;
+ }
+
+ handle = (struct ion_handle **)malloc(count * sizeof(struct ion_handle *));
+ if(handle == NULL) {
+ printf("%s(): FAILED to allocate memory for ion_handles\n", __func__);
+ return -ENOMEM;
+ }
+
+ count_alloc = count;
+ count_map = count;
+
+ /* Allocate ion_handles */
+ for(i = 0; i < count; i++) {
+ ret = _ion_alloc_test(fd, &(handle[i]));
+ printf("%s(): Alloc handle[%d]=%p\n", __func__, i, handle[i]);
+ if(ret || ((int)handle[i] == -ENOMEM)) {
+ printf("%s(): Alloc handle[%d]=%p FAILED, err:%s\n",
+ __func__, i, handle[i], strerror(ret));
+ count_alloc = i;
+ goto err_alloc;
+ }
+ }
+
+ /* Map ion_handles and validate */
+ if (tiler_test)
+ len = height * stride;
+
+ ptr = (unsigned char **)malloc(count * sizeof(unsigned char **));
+ map_fd = (int *)malloc(count * sizeof(int *));
+
+ for(i = 0; i < count; i++) {
+ /* Map ion_handle on userside */
+ ret = ion_map(fd, handle[i], len, prot, map_flags, 0, &(ptr[i]), &(map_fd[i]));
+ printf("%s(): Map handle[%d]=%p, map_fd=%d, ptr=%p\n",
+ __func__, i, handle[i], map_fd[i], ptr[i]);
+ if(ret) {
+ printf("%s Map handle[%d]=%p FAILED, err:%s\n",
+ __func__, i, handle[i], strerror(ret));
+ count_map = i;
+ goto err_map;
+ }
+
+ /* Validate mapping by writing the data and reading it back */
+ if (tiler_test)
+ _ion_tiler_map_test(ptr[i]);
+ else
+ _ion_map_test(ptr[i]);
+ }
+
+ /* clean up properly */
+ err_map:
+ for(i = 0; i < count_map; i++) {
+ /* Unmap ion_handles */
+ ret = munmap(ptr[i], len);
+ printf("%s(): Unmap handle[%d]=%p, map_fd=%d, ptr=%p\n",
+ __func__, i, handle[i], map_fd[i], ptr[i]);
+ if(ret) {
+ printf("%s(): Unmap handle[%d]=%p FAILED, err:%s\n",
+ __func__, i, handle[i], strerror(ret));
+ goto err_map;
+ }
+ /* Close fds */
+ close(map_fd[i]);
+ }
+ free(map_fd);
+ free(ptr);
+
+ err_alloc:
+ /* Free ion_handles */
+ for (i = 0; i < count_alloc; i++) {
+ printf("%s(): Free handle[%d]=%p\n", __func__, i, handle[i]);
+ ret = ion_free(fd, handle[i]);
+ if (ret) {
+ printf("%s(): Free handle[%d]=%p FAILED, err:%s\n",
+ __func__, i, handle[i], strerror(ret));
+ }
+ }
+
+ ion_close(fd);
+ free(handle);
+ handle = NULL;
+
+ if(ret || (count_alloc != count) || (count_map != count))
+ {
+ printf("\nion map test: FAILED\n\n");
+ if((count_alloc != count) || (count_map != count))
+ ret = -ENOMEM;
+ } else
+ printf("\nion map test: PASSED\n");
+
+ return ret;
+}
+
+/**
+ * Go on allocating buffers of specified size & type, untill the allocation fails.
+ * Then free 10 buffers and allocate 10 buffers again.
+ */
+int ion_alloc_fail_alloc_test()
+{
+ int fd, ret = 0, i;
+ struct ion_handle **handle;
+ const int COUNT_ALLOC_MAX = 200;
+ const int COUNT_REALLOC_MAX = 10;
+ int count_alloc = COUNT_ALLOC_MAX, count_realloc = COUNT_ALLOC_MAX;
+
+ fd = ion_open();
+ if (fd < 0) {
+ printf("%s(): FAILED to open ion device\n", __func__);
+ return -1;
+ }
+
+ handle = (struct ion_handle **)malloc(COUNT_ALLOC_MAX * sizeof(struct ion_handle *));
+ if(handle == NULL) {
+ printf("%s(): FAILED to allocate memory for ion_handles\n", __func__);
+ return -ENOMEM;
+ }
+
+ /* Allocate ion_handles as much as possible */
+ for(i = 0; i < COUNT_ALLOC_MAX; i++) {
+ ret = _ion_alloc_test(fd, &(handle[i]));
+ printf("%s(): Alloc handle[%d]=%p\n", __func__, i, handle[i]);
+ if(ret || ((int)handle[i] == -ENOMEM)) {
+ printf("%s(): Alloc handle[%d]=%p FAILED, err:%s\n\n",
+ __func__, i, handle[i], strerror(ret));
+ count_alloc = i;
+ break;
+ }
+ }
+
+ /* Free COUNT_REALLOC_MAX ion_handles */
+ for (i = count_alloc-1; i > (count_alloc-1 - COUNT_REALLOC_MAX); i--) {
+ printf("%s(): Free handle[%d]=%p\n", __func__, i, handle[i]);
+ ret = ion_free(fd, handle[i]);
+ if (ret) {
+ printf("%s(): Free handle[%d]=%p FAILED, err:%s\n\n",
+ __func__, i, handle[i], strerror(ret));
+ }
+ }
+
+ /* Again allocate COUNT_REALLOC_MAX ion_handles to test
+ that we are still able to allocate */
+ for(i = (count_alloc - COUNT_REALLOC_MAX); i < count_alloc; i++) {
+ ret = _ion_alloc_test(fd, &(handle[i]));
+ printf("%s(): Alloc handle[%d]=%p\n", __func__, i, handle[i]);
+ if(ret || ((int)handle[i] == -ENOMEM)) {
+ printf("%s(): Alloc handle[%d]=%p FAILED, err:%s\n\n",
+ __func__, i, handle[i], strerror(ret));
+ count_realloc = i;
+ goto err_alloc;
+ }
+ }
+ count_realloc = i;
+
+ err_alloc:
+ /* Free all ion_handles */
+ for (i = 0; i < count_alloc; i++) {
+ printf("%s(): Free handle[%d]=%p\n", __func__, i, handle[i]);
+ ret = ion_free(fd, handle[i]);
+ if (ret) {
+ printf("%s(): Free handle[%d]=%p FAILED, err:%s\n",
+ __func__, i, handle[i], strerror(ret));
+ }
+ }
+
+ ion_close(fd);
+ free(handle);
+ handle = NULL;
+
+ printf("\ncount_alloc=%d, count_realloc=%d\n",count_alloc, count_realloc);
+
+ if(ret || (count_alloc != count_realloc)) {
+ printf("\nion alloc->fail->alloc test: FAILED\n\n");
+ if(count_alloc != COUNT_ALLOC_MAX)
+ ret = -ENOMEM;
+ }
+ else
+ printf("\nion alloc->fail->alloc test: PASSED\n\n");
+
+ return ret;
+}
+
+int custom_test(int test_number)
+{
+ switch(test_number) {
+ case 1 :
+ return ion_alloc_fail_alloc_test();
+ default :
+ printf("%s(): Invalid custom_test_number=%d\n", __func__, test_number);
+ return -EINVAL;
+ }
+}
+
+int main(int argc, char* argv[]) {
+ int c, ret;
+ unsigned int count = 1, iteration = 1, j, custom_test_num = 1;
+ enum tests {
+ ALLOC_TEST = 0, MAP_TEST, CUSTOM_TEST,
+ };
+
+ while (1) {
+ static struct option opts[] = {
+ {"alloc", no_argument, 0, 'a'},
+ {"alloc_flags", required_argument, 0, 'f'},
+ {"map", no_argument, 0, 'm'},
+ {"custom", required_argument, 0, 'c'},
+ {"len", required_argument, 0, 'l'},
+ {"align", required_argument, 0, 'g'},
+ {"map_flags", required_argument, 0, 'z'},
+ {"prot", required_argument, 0, 'p'},
+ {"alloc_tiler", no_argument, 0, 't'},
+ {"width", required_argument, 0, 'w'},
+ {"height", required_argument, 0, 'h'},
+ {"fmt", required_argument, 0, 'r'},
+ {"count", required_argument, 0, 'n'},
+ {"iteration", required_argument, 0, 'i'},
+ };
+ int i = 0;
+ c = getopt_long(argc, argv, "af:h:l:mr:stw:c:n:i:", opts, &i);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'l':
+ len = atol(optarg);
+ break;
+ case 'g':
+ align = atol(optarg);
+ break;
+ case 'z':
+ map_flags = 0;
+ map_flags |= strstr(optarg, "PROT_EXEC") ?
+ PROT_EXEC : 0;
+ map_flags |= strstr(optarg, "PROT_READ") ?
+ PROT_READ: 0;
+ map_flags |= strstr(optarg, "PROT_WRITE") ?
+ PROT_WRITE: 0;
+ map_flags |= strstr(optarg, "PROT_NONE") ?
+ PROT_NONE: 0;
+ break;
+ case 'p':
+ prot = 0;
+ prot |= strstr(optarg, "MAP_PRIVATE") ?
+ MAP_PRIVATE : 0;
+ prot |= strstr(optarg, "MAP_SHARED") ?
+ MAP_PRIVATE : 0;
+ break;
+ case 'f':
+ alloc_flags = atol(optarg);
+ break;
+ case 'a':
+ test = ALLOC_TEST;
+ break;
+ case 'm':
+ test = MAP_TEST;
+ break;
+ case 'c':
+ test = CUSTOM_TEST;
+ printf("KALP : Case 'c'\n");
+ custom_test_num = atol(optarg);
+ break;
+ case 'r':
+ fmt = atol(optarg);
+ break;
+ case 'w':
+ width = atol(optarg);
+ break;
+ case 'h':
+ height = atol(optarg);
+ break;
+ case 't':
+ tiler_test = 1;
+ break;
+ case 'n':
+ printf("KALP : Case 'n'\n");
+ count = atol(optarg);
+ break;
+ case 'i':
+ printf("KALP : Case 'i'\n");
+ iteration = atol(optarg);
+ break;
+ }
+ }
+ printf("test %d, len %u, width %u, height %u, fmt %u, align %u, count %d, "
+ "iteration %d, map_flags %d, prot %d, alloc_flags %d\n", test, len, width,
+ height, fmt, align, count, iteration, map_flags, prot, alloc_flags);
+
+ switch (test) {
+ case ALLOC_TEST:
+ for(j = 0; j < iteration; j++) {
+ ret = ion_alloc_test(count);
+ if(ret) {
+ printf("\nion alloc test: FAILED at iteration-%d\n", j+1);
+ break;
+ }
+ }
+ break;
+
+ case MAP_TEST:
+ for(j = 0; j < iteration; j++) {
+ ret = ion_map_test(count);
+ if(ret) {
+ printf("\nion map test: FAILED at iteration-%d\n", j+1);
+ break;
+ }
+ }
+ break;
+
+ case CUSTOM_TEST:
+ ret = custom_test(custom_test_num);
+ if(ret) {
+ printf("\nion custom test #%d: FAILED\n", custom_test_num);
+ }
+ break;
+
+ default:
+ printf("must specify a test (alloc, map, custom)\n");
+ }
+
+ return 0;
+}
diff --git a/libion_ti/linux_ion.h b/libion_ti/linux_ion.h
new file mode 100644
index 0000000..300853a
--- /dev/null
+++ b/libion_ti/linux_ion.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ION_H
+#define _LINUX_ION_H
+#include <linux/types.h>
+struct ion_handle;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum ion_heap_type {
+ ION_HEAP_TYPE_SYSTEM,
+ ION_HEAP_TYPE_SYSTEM_CONTIG,
+ ION_HEAP_TYPE_CARVEOUT,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ ION_HEAP_TYPE_CUSTOM,
+ ION_NUM_HEAPS,
+};
+#define ION_HEAP_SYSTEM_MASK (1 << ION_HEAP_TYPE_SYSTEM)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ION_HEAP_SYSTEM_CONTIG_MASK (1 << ION_HEAP_TYPE_SYSTEM_CONTIG)
+#define ION_HEAP_CARVEOUT_MASK (1 << ION_HEAP_TYPE_CARVEOUT)
+struct ion_allocation_data {
+ size_t len;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ size_t align;
+ unsigned int flags;
+ struct ion_handle *handle;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ion_fd_data {
+ struct ion_handle *handle;
+ int fd;
+ unsigned char cacheable;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct ion_handle_data {
+ struct ion_handle *handle;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ion_custom_data {
+ unsigned int cmd;
+ unsigned long arg;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct ion_cached_user_buf_data {
+ struct ion_handle *handle;
+ unsigned long vaddr;
+ size_t size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define ION_IOC_MAGIC 'I'
+#define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, struct ion_allocation_data)
+#define ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ION_IOC_MAP _IOWR(ION_IOC_MAGIC, 2, struct ion_fd_data)
+#define ION_IOC_SHARE _IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data)
+#define ION_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, int)
+#define ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ION_IOC_FLUSH_CACHED _IOWR(ION_IOC_MAGIC, 7, struct ion_cached_user_buf_data)
+#define ION_IOC_INVAL_CACHED _IOWR(ION_IOC_MAGIC, 8, struct ion_cached_user_buf_data)
+#endif
diff --git a/libion_ti/omap_ion.h b/libion_ti/omap_ion.h
new file mode 100644
index 0000000..b8a6228
--- /dev/null
+++ b/libion_ti/omap_ion.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_OMAP_ION_H
+#define _LINUX_OMAP_ION_H
+#include <linux/types.h>
+struct omap_ion_tiler_alloc_data {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ size_t w;
+ size_t h;
+ int fmt;
+ unsigned int flags;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ struct ion_handle *handle;
+ size_t stride;
+ size_t offset;
+ unsigned int out_align;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ unsigned int token;
+};
+enum {
+ OMAP_ION_HEAP_TYPE_TILER = ION_HEAP_TYPE_CUSTOM + 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define OMAP_ION_HEAP_TILER_MASK (1 << OMAP_ION_HEAP_TYPE_TILER)
+enum {
+ OMAP_ION_TILER_ALLOC,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+enum {
+ TILER_PIXEL_FMT_MIN = 0,
+ TILER_PIXEL_FMT_8BIT = 0,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ TILER_PIXEL_FMT_16BIT = 1,
+ TILER_PIXEL_FMT_32BIT = 2,
+ TILER_PIXEL_FMT_PAGE = 3,
+ TILER_PIXEL_FMT_MAX = 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+enum {
+ OMAP_ION_HEAP_LARGE_SURFACES,
+ OMAP_ION_HEAP_TILER,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ OMAP_ION_HEAP_SECURE_INPUT,
+};
+#endif
diff --git a/libpower/Android.mk b/libpower/Android.mk
new file mode 100644
index 0000000..32be9e1
--- /dev/null
+++ b/libpower/Android.mk
@@ -0,0 +1,25 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := power.$(TARGET_BOOTLOADER_BOARD_NAME)
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_SRC_FILES := power.c
+LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libpower/power.c b/libpower/power.c
new file mode 100644
index 0000000..68ed7c6
--- /dev/null
+++ b/libpower/power.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define LOG_TAG "TI OMAP PowerHAL"
+#include <utils/Log.h>
+
+#include <hardware/hardware.h>
+#include <hardware/power.h>
+
+#define CPUFREQ_INTERACTIVE "/sys/devices/system/cpu/cpufreq/interactive/"
+#define CPUFREQ_CPU0 "/sys/devices/system/cpu/cpu0/cpufreq/"
+#define BOOSTPULSE_PATH (CPUFREQ_INTERACTIVE "boostpulse")
+
+#define MAX_FREQ_NUMBER 10
+#define NOM_FREQ_INDEX 2
+
+static int freq_num;
+static char *freq_list[MAX_FREQ_NUMBER];
+static char *max_freq, *nom_freq;
+
+struct omap_power_module {
+ struct power_module base;
+ pthread_mutex_t lock;
+ int boostpulse_fd;
+ int boostpulse_warned;
+ int inited;
+};
+
+static int str_to_tokens(char *str, char **token, int max_token_idx) {
+ char *pos, *start_pos = str;
+ char *token_pos;
+ int token_idx = 0;
+
+ if (!str || !token || !max_token_idx) {
+ return 0;
+ }
+
+ do {
+ token_pos = strtok_r(start_pos, " \t\r\n", &pos);
+
+ if (token_pos)
+ token[token_idx++] = strdup(token_pos);
+ start_pos = NULL;
+ } while (token_pos && token_idx < max_token_idx);
+
+ return token_idx;
+}
+
+static void sysfs_write(char *path, char *s) {
+ char buf[80];
+ int len;
+ int fd = open(path, O_WRONLY);
+
+ if (fd < 0) {
+ strerror_r(errno, buf, sizeof(buf));
+ ALOGE("Error opening %s: %s\n", path, buf);
+ return;
+ }
+
+ len = write(fd, s, strlen(s));
+ if (len < 0) {
+ strerror_r(errno, buf, sizeof(buf));
+ ALOGE("Error writing to %s: %s\n", path, buf);
+ }
+
+ close(fd);
+}
+
+static int sysfs_read(char *path, char *s, int s_size) {
+ char buf[80];
+ int len, i;
+ int fd;
+
+ if (!path || !s || !s_size) {
+ return -1;
+ }
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ strerror_r(errno, buf, sizeof(buf));
+ ALOGE("Error opening %s: %s\n", path, buf);
+ return fd;
+ }
+
+ len = read(fd, s, s_size-1);
+ if (len < 0) {
+ strerror_r(errno, buf, sizeof(buf));
+ ALOGE("Error reading from %s: %s\n", path, buf);
+ } else {
+ s[len] = '\0';
+ }
+
+ close(fd);
+ return len;
+}
+
+static void omap_power_init(struct power_module *module) {
+ struct omap_power_module *omap_device = (struct omap_power_module *) module;
+ int tmp;
+ char freq_buf[MAX_FREQ_NUMBER*10];
+
+ tmp = sysfs_read(CPUFREQ_CPU0 "scaling_available_frequencies", freq_buf, sizeof(freq_buf));
+ if (tmp <= 0) {
+ return;
+ }
+
+ freq_num = str_to_tokens(freq_buf, freq_list, MAX_FREQ_NUMBER);
+ if (!freq_num) {
+ return;
+ }
+
+ max_freq = freq_list[freq_num - 1];
+ tmp = (NOM_FREQ_INDEX > freq_num) ? freq_num : NOM_FREQ_INDEX;
+ nom_freq = freq_list[tmp - 1];
+
+ sysfs_write(CPUFREQ_INTERACTIVE "timer_rate", "20000");
+ sysfs_write(CPUFREQ_INTERACTIVE "min_sample_time","60000");
+ sysfs_write(CPUFREQ_INTERACTIVE "hispeed_freq", nom_freq);
+ sysfs_write(CPUFREQ_INTERACTIVE "go_hispeed_load", "50");
+ sysfs_write(CPUFREQ_INTERACTIVE "above_hispeed_delay", "100000");
+
+ ALOGI("Initialized successfully");
+ omap_device->inited = 1;
+}
+
+static int boostpulse_open(struct omap_power_module *omap_device) {
+ char buf[80];
+
+ pthread_mutex_lock(&omap_device->lock);
+
+ if (omap_device->boostpulse_fd < 0) {
+ omap_device->boostpulse_fd = open(BOOSTPULSE_PATH, O_WRONLY);
+
+ if (omap_device->boostpulse_fd < 0) {
+ if (!omap_device->boostpulse_warned) {
+ strerror_r(errno, buf, sizeof(buf));
+ ALOGE("Error opening %s: %s\n", BOOSTPULSE_PATH, buf);
+ omap_device->boostpulse_warned = 1;
+ }
+ }
+ }
+
+ pthread_mutex_unlock(&omap_device->lock);
+ return omap_device->boostpulse_fd;
+}
+
+static void omap_power_set_interactive(struct power_module *module, int on) {
+ struct omap_power_module *omap_device = (struct omap_power_module *) module;
+
+ if (!omap_device->inited)
+ return;
+
+ /*
+ * Lower maximum frequency when screen is off. CPU 0 and 1 share a
+ * cpufreq policy.
+ */
+
+ sysfs_write(CPUFREQ_CPU0 "scaling_max_freq", on ? max_freq : nom_freq);
+}
+
+static void omap_power_hint(struct power_module *module, power_hint_t hint, void *data) {
+ struct omap_power_module *omap_device = (struct omap_power_module *) module;
+ char buf[80];
+ int len;
+
+ if (!omap_device->inited)
+ return;
+
+ switch (hint) {
+ case POWER_HINT_INTERACTION:
+ if (boostpulse_open(omap_device) >= 0) {
+ len = write(omap_device->boostpulse_fd, "1", 1);
+
+ if (len < 0) {
+ strerror_r(errno, buf, sizeof(buf));
+ ALOGE("Error writing to %s: %s\n", BOOSTPULSE_PATH, buf);
+ }
+ }
+ break;
+
+ case POWER_HINT_VSYNC:
+ break;
+
+ default:
+ break;
+ }
+}
+
+static struct hw_module_methods_t power_module_methods = {
+ .open = NULL,
+};
+
+struct omap_power_module HAL_MODULE_INFO_SYM = {
+ .base = {
+ .common = {
+ .tag = HARDWARE_MODULE_TAG,
+ .module_api_version = POWER_MODULE_API_VERSION_0_2,
+ .hal_api_version = HARDWARE_HAL_API_VERSION,
+ .id = POWER_HARDWARE_MODULE_ID,
+ .name = "OMAP Power HAL",
+ .author = "The Android Open Source Project",
+ .methods = &power_module_methods,
+ },
+
+ .init = omap_power_init,
+ .setInteractive = omap_power_set_interactive,
+ .powerHint = omap_power_hint,
+ },
+
+ .lock = PTHREAD_MUTEX_INITIALIZER,
+ .boostpulse_fd = -1,
+ .boostpulse_warned = 0,
+};
diff --git a/proprietary-files.txt b/proprietary-files.txt
new file mode 100644
index 0000000..25655b3
--- /dev/null
+++ b/proprietary-files.txt
@@ -0,0 +1,29 @@
+system/etc/powervr.ini
+system/vendor/bin/pvrsrvctl_SGX540_120
+system/vendor/bin/pvrsrvctl_SGX544_112
+system/vendor/bin/pvrsrvinit
+system/vendor/lib/egl/libEGL_POWERVR_SGX540_120.so
+system/vendor/lib/egl/libEGL_POWERVR_SGX544_112.so
+system/vendor/lib/egl/libGLESv1_CM_POWERVR_SGX540_120.so
+system/vendor/lib/egl/libGLESv1_CM_POWERVR_SGX544_112.so
+system/vendor/lib/egl/libGLESv2_POWERVR_SGX540_120.so
+system/vendor/lib/egl/libGLESv2_POWERVR_SGX544_112.so
+system/vendor/lib/hw/gralloc.omap4430.so
+system/vendor/lib/hw/gralloc.omap4460.so
+system/vendor/lib/hw/gralloc.omap4470.so
+system/vendor/lib/libIMGegl_SGX540_120.so
+system/vendor/lib/libIMGegl_SGX544_112.so
+system/vendor/lib/libPVRScopeServices_SGX540_120.so
+system/vendor/lib/libPVRScopeServices_SGX544_112.so
+system/vendor/lib/libglslcompiler_SGX540_120.so
+system/vendor/lib/libglslcompiler_SGX544_112.so
+system/vendor/lib/libpvr2d_SGX540_120.so
+system/vendor/lib/libpvr2d_SGX544_112.so
+system/vendor/lib/libpvrANDROID_WSEGL_SGX540_120.so
+system/vendor/lib/libpvrANDROID_WSEGL_SGX544_112.so
+system/vendor/lib/libsrv_init_SGX540_120.so
+system/vendor/lib/libsrv_init_SGX544_112.so
+system/vendor/lib/libsrv_um_SGX540_120.so
+system/vendor/lib/libsrv_um_SGX544_112.so
+system/vendor/lib/libusc_SGX540_120.so
+system/vendor/lib/libusc_SGX544_112.so
diff --git a/pvr-source/GPL-COPYING b/pvr-source/GPL-COPYING
new file mode 100644
index 0000000..83d1261
--- /dev/null
+++ b/pvr-source/GPL-COPYING
@@ -0,0 +1,344 @@
+-------------------------------------------------------------------------
+
+ 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/pvr-source/INSTALL b/pvr-source/INSTALL
new file mode 100644
index 0000000..aefa6c3
--- /dev/null
+++ b/pvr-source/INSTALL
@@ -0,0 +1,72 @@
+
+SGX Embedded Systems DDK for the Linux kernel.
+Copyright (C) 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/pvr-source/MIT-COPYING b/pvr-source/MIT-COPYING
new file mode 100644
index 0000000..0cbd14e
--- /dev/null
+++ b/pvr-source/MIT-COPYING
@@ -0,0 +1,41 @@
+
+This software is Copyright (C) Imagination Technologies Ltd.
+
+You may use, distribute and copy this software under the terms of the MIT
+license displayed below.
+
+-----------------------------------------------------------------------------
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, this Software may be used under the terms of the GNU General
+Public License Version 2 ("GPL") in which case the provisions of GPL are
+applicable instead of those above.
+
+If you wish to allow use of your version of this Software only under the terms
+of GPL, and not to allow others to use your version of this file under the
+terms of the MIT license, indicate your decision by deleting from each file
+the provisions above and replace them with the notice and other provisions
+required by GPL as set out in the file called "GPL-COPYING" included in this
+distribution. If you do not delete the provisions above, a recipient may use
+your version of this file under the terms of either the MIT license or GPL.
+
+-----------------------------------------------------------------------------
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+-----------------------------------------------------------------------------
diff --git a/pvr-source/README b/pvr-source/README
new file mode 100644
index 0000000..2eae109
--- /dev/null
+++ b/pvr-source/README
@@ -0,0 +1,49 @@
+
+SGX Embedded Systems DDK for Linux kernel.
+Copyright (C) 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 the MIT
+license. Details of this license can be found in the file "MIT-COPYING".
+
+Alternatively, you may use, distribute and copy this software under the terms
+of the GNU General Public License version 2. The full GNU General Public
+License version 2 can be found in the file "GPL-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/pvr-source/eurasiacon/build/linux2/bits.mk b/pvr-source/eurasiacon/build/linux2/bits.mk
new file mode 100644
index 0000000..a1a7eef
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/bits.mk
@@ -0,0 +1,112 @@
+########################################################################### ###
+#@Title Useful special targets which don't build anything
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+ifneq ($(filter dumpvar-%,$(MAKECMDGOALS)),)
+dumpvar-%: ;
+$(foreach _var_to_dump,$(patsubst dumpvar-%,%,$(filter dumpvar-%,$(MAKECMDGOALS))),$(info $(if $(filter undefined,$(origin $(_var_to_dump))),# $$($(_var_to_dump)) is not set,$(_var_to_dump) := $($(_var_to_dump)))))
+endif
+
+ifneq ($(filter whereis-%,$(MAKECMDGOALS)),)
+whereis-%: ;
+$(foreach _module_to_find,$(patsubst whereis-%,%,$(filter whereis-%,$(MAKECMDGOALS))),$(info $(if $(INTERNAL_MAKEFILE_FOR_MODULE_$(_module_to_find)),$(INTERNAL_MAKEFILE_FOR_MODULE_$(_module_to_find)),# No module $(_module_to_find))))
+endif
+
+ifneq ($(filter whatis-%,$(MAKECMDGOALS)),)
+whatis-$(RELATIVE_OUT)/target/%: ;
+whatis-$(RELATIVE_OUT)/host/%: ;
+$(foreach _file_to_find,$(patsubst whatis-%,%,$(filter whatis-%,$(MAKECMDGOALS))),$(info $(strip $(foreach _m,$(ALL_MODULES),$(if $(filter $(_file_to_find),$(INTERNAL_TARGETS_FOR_$(_m))),$(_file_to_find) is in $(_m) which is defined in $(INTERNAL_MAKEFILE_FOR_MODULE_$(_m)),)))))
+endif
+
+.PHONY: ls-modules
+ls-modules:
+ @: $(foreach _m,$(ALL_MODULES),$(info $($(_m)_type) $(_m) $(patsubst $(TOP)/%,%,$(INTERNAL_MAKEFILE_FOR_MODULE_$(_m)))))
+
+ifeq ($(strip $(MAKECMDGOALS)),visualise)
+FORMAT ?= xlib
+GRAPHVIZ ?= neato
+visualise: $(OUT)/MAKE_RULES.dot
+ $(GRAPHVIZ) -T$(FORMAT) -o $(OUT)/MAKE_RULES.$(FORMAT) $<
+$(OUT)/MAKE_RULES.dot: $(OUT)/MAKE_RULES
+ perl $(MAKE_TOP)/tools/depgraph.pl -t $(TOP) -g $(firstword $(GRAPHVIZ)) $(OUT)/MAKE_RULES >$(OUT)/MAKE_RULES.dot
+$(OUT)/MAKE_RULES: $(ALL_MAKEFILES)
+ -$(MAKE) -C $(TOP) -f $(MAKE_TOP)/toplevel.mk TOP=$(TOP) OUT=$(OUT) ls-modules -qp >$(OUT)/MAKE_RULES 2>&1
+else
+visualise:
+ @: $(error visualise specified along with other goals. This is not supported)
+endif
+
+.PHONY: help
+help:
+ @echo 'Build targets'
+ @echo ' make, make build Build all components of the build'
+ @echo ' make components Build only the user-mode components'
+ @echo ' make kbuild Build only the kernel-mode components'
+ @echo ' make MODULE Build the module MODULE and all of its dependencies'
+ @echo ' make eurasiacon/binary2_.../target/libsomething.so'
+ @echo ' Build a particular file (including intermediates)'
+ @echo 'Variables'
+ @echo ' make V=1 ... Print the commands that are executed'
+ @echo ' make W=1 ... Enable extra compiler warnings'
+ @echo ' make D=opt ... Set build system debug option (D=help for a list)'
+ @echo ' make OUT=dir ... Place output+intermediates in specified directory'
+ @echo ' EXCLUDED_APIS=... List of APIs to remove from the build'
+ @echo ' make SOMEOPTION=1 ... Set configuration options (see config/core.mk)'
+ @echo ' Defaults are set by $(PVR_BUILD_DIR)/Makefile'
+ @echo 'Clean targets'
+ @echo ' make clean Remove only intermediates for the current build'
+ @echo ' make clobber As "make clean", but remove output files too'
+ @echo ' make clean-MODULE Clean (or clobber) only files for MODULE'
+ @echo ''
+ @echo 'Special targets'
+ @echo ' make whereis-MODULE Show the path to the Linux.mk defining MODULE'
+ @echo ' make whatis-FILE Show which module builds an output FILE'
+ @echo ' make ls-modules List all modules defined by makefiles'
+
+ifneq ($(filter help,$(D)),)
+empty :=
+space := $(empty) $(empty)
+$(info Debug options)
+$(info $(space)D=modules dump module info)
+$(info $(space)D=freeze-config prevent config changes)
+$(info $(space)D=config-changes dump diffs when config changes)
+$(info Options may be combined: make D=freeze-config,config-changes)
+$(error D=help given)
+endif
diff --git a/pvr-source/eurasiacon/build/linux2/buildvars.mk b/pvr-source/eurasiacon/build/linux2/buildvars.mk
new file mode 100644
index 0000000..24fa829
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/buildvars.mk
@@ -0,0 +1,217 @@
+########################################################################### ###
+#@Title Define global variables
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@Description This file is read once at the start of the build, after reading
+# in config.mk. It should define the non-MODULE_* variables used
+# in commands, like ALL_CFLAGS
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+ifeq ($(BUILD),debug)
+COMMON_USER_FLAGS := -O0
+else
+OPTIM ?= -O2
+COMMON_USER_FLAGS := $(OPTIM)
+endif
+
+# FIXME: We should probably audit the driver for aliasing
+#
+COMMON_USER_FLAGS += -fno-strict-aliasing
+
+# We always enable debugging. Either the release binaries are stripped
+# and the symbols put in the symbolpackage, or we're building debug.
+#
+COMMON_USER_FLAGS += -g
+
+# These flags are used for kernel, User C and User C++
+#
+COMMON_FLAGS = -W -Wall
+
+# Some GCC warnings are C only, so we must mask them from C++
+#
+COMMON_CFLAGS := $(COMMON_FLAGS) \
+ -Wdeclaration-after-statement -Wno-format-zero-length \
+ -Wmissing-prototypes -Wstrict-prototypes
+
+# Additional warnings, and optional warnings.
+#
+WARNING_CFLAGS := \
+ -Wpointer-arith -Wunused-parameter \
+ -Wmissing-format-attribute \
+ $(call cc-option,-Wno-missing-field-initializers) \
+ $(call cc-option,-fdiagnostics-show-option)
+
+ifeq ($(W),1)
+WARNING_CFLAGS += \
+ $(call cc-option,-Wbad-function-cast) \
+ $(call cc-option,-Wcast-qual) \
+ $(call cc-option,-Wcast-align) \
+ $(call cc-option,-Wconversion) \
+ $(call cc-option,-Wdisabled-optimization) \
+ $(call cc-option,-Wlogical-op) \
+ $(call cc-option,-Wmissing-declarations) \
+ $(call cc-option,-Wmissing-include-dirs) \
+ $(call cc-option,-Wnested-externs) \
+ $(call cc-option,-Wold-style-definition) \
+ $(call cc-option,-Woverlength-strings) \
+ $(call cc-option,-Wpacked) \
+ $(call cc-option,-Wpacked-bitfield-compat) \
+ $(call cc-option,-Wpadded) \
+ $(call cc-option,-Wredundant-decls) \
+ $(call cc-option,-Wshadow) \
+ $(call cc-option,-Wswitch-default) \
+ $(call cc-option,-Wvla) \
+ $(call cc-option,-Wwrite-strings)
+endif
+
+WARNING_CFLAGS += \
+ $(call cc-optional-warning,-Wunused-but-set-variable)
+
+HOST_WARNING_CFLAGS := \
+ -Wpointer-arith -Wunused-parameter \
+ -Wmissing-format-attribute \
+ $(call host-cc-option,-Wno-missing-field-initializers) \
+ $(call host-cc-option,-fdiagnostics-show-option)
+
+ifeq ($(W),1)
+HOST_WARNING_CFLAGS += \
+ $(call host-cc-option,-Wbad-function-cast) \
+ $(call host-cc-option,-Wcast-qual) \
+ $(call host-cc-option,-Wcast-align) \
+ $(call host-cc-option,-Wconversion) \
+ $(call host-cc-option,-Wdisabled-optimization) \
+ $(call host-cc-option,-Wlogical-op) \
+ $(call host-cc-option,-Wmissing-declarations) \
+ $(call host-cc-option,-Wmissing-include-dirs) \
+ $(call host-cc-option,-Wnested-externs) \
+ $(call host-cc-option,-Wold-style-definition) \
+ $(call host-cc-option,-Woverlength-strings) \
+ $(call host-cc-option,-Wpacked) \
+ $(call host-cc-option,-Wpacked-bitfield-compat) \
+ $(call host-cc-option,-Wpadded) \
+ $(call host-cc-option,-Wredundant-decls) \
+ $(call host-cc-option,-Wshadow) \
+ $(call host-cc-option,-Wswitch-default) \
+ $(call host-cc-option,-Wvla) \
+ $(call host-cc-option,-Wwrite-strings)
+endif
+
+HOST_WARNING_CFLAGS += \
+ $(call host-cc-optional-warning,-Wunused-but-set-variable)
+
+KBUILD_WARNING_CFLAGS := \
+ -Wno-unused-parameter -Wno-sign-compare
+KBUILD_WARNING_CFLAGS += \
+ $(call kernel-cc-optional-warning,-Wbad-function-cast) \
+ $(call kernel-cc-optional-warning,-Wcast-qual) \
+ $(call kernel-cc-optional-warning,-Wcast-align) \
+ $(call kernel-cc-optional-warning,-Wconversion) \
+ $(call kernel-cc-optional-warning,-Wdisabled-optimization) \
+ $(call kernel-cc-optional-warning,-Wlogical-op) \
+ $(call kernel-cc-optional-warning,-Wmissing-declarations) \
+ $(call kernel-cc-optional-warning,-Wmissing-include-dirs) \
+ $(call kernel-cc-optional-warning,-Wnested-externs) \
+ $(call kernel-cc-optional-warning,-Wno-missing-field-initializers) \
+ $(call kernel-cc-optional-warning,-Wold-style-definition) \
+ $(call kernel-cc-optional-warning,-Woverlength-strings) \
+ $(call kernel-cc-optional-warning,-Wpacked) \
+ $(call kernel-cc-optional-warning,-Wpacked-bitfield-compat) \
+ $(call kernel-cc-optional-warning,-Wpadded) \
+ $(call kernel-cc-optional-warning,-Wredundant-decls) \
+ $(call kernel-cc-optional-warning,-Wshadow) \
+ $(call kernel-cc-optional-warning,-Wswitch-default) \
+ $(call kernel-cc-optional-warning,-Wvla) \
+ $(call kernel-cc-optional-warning,-Wwrite-strings)
+
+# User C only
+#
+ALL_CFLAGS := \
+ $(COMMON_USER_FLAGS) $(COMMON_CFLAGS) $(WARNING_CFLAGS) \
+ $(SYS_CFLAGS)
+
+ALL_HOST_CFLAGS := \
+ $(COMMON_USER_FLAGS) $(COMMON_CFLAGS) $(HOST_WARNING_CFLAGS)
+
+# User C++ only
+#
+ALL_CXXFLAGS := \
+ $(COMMON_USER_FLAGS) $(COMMON_FLAGS) \
+ -fno-rtti -fno-exceptions \
+ -Wpointer-arith -Wunused-parameter \
+ $(SYS_CXXFLAGS)
+
+ALL_HOST_CXXFLAGS := \
+ $(COMMON_USER_FLAGS) $(COMMON_CFLAGS) -Wall
+
+# User C and C++
+#
+# NOTE: ALL_HOST_LDFLAGS should probably be using -rpath-link too, and if we
+# ever need to support building host shared libraries, it's required.
+#
+# We can't use it right now because we want to support non-GNU-compatible
+# linkers like the Darwin 'ld' which doesn't support -rpath-link.
+#
+ALL_HOST_LDFLAGS := -L$(HOST_OUT)
+ALL_LDFLAGS := -L$(TARGET_OUT) -Xlinker -rpath-link=$(TARGET_OUT)
+
+ifneq ($(strip $(TOOLCHAIN)),)
+ALL_LDFLAGS += -L$(TOOLCHAIN)/lib -Xlinker -rpath-link=$(TOOLCHAIN)/lib
+endif
+
+ifneq ($(strip $(LINKER_RPATH)),)
+ALL_LDFLAGS += $(addprefix -Xlinker -rpath=,$(LINKER_RPATH))
+endif
+
+ALL_LDFLAGS += $(SYS_LDFLAGS)
+
+# Kernel C only
+#
+ALL_KBUILD_CFLAGS := $(COMMON_CFLAGS) $(KBUILD_WARNING_CFLAGS) \
+ $(call kernel-cc-option,-Wno-type-limits) \
+ $(call kernel-cc-option,-Wno-pointer-arith) \
+ $(call kernel-cc-option,-Wno-aggregate-return) \
+ $(call kernel-cc-option,-Wno-unused-but-set-variable)
+
+# This variable contains a list of all modules built by kbuild
+ALL_KBUILD_MODULES :=
+
+# This variable contains a list of all modules which contain C++ source files
+ALL_CXX_MODULES :=
+
+# Toolchain triple for cross environment
+CROSS_TRIPLE := $(patsubst %-,%,$(CROSS_COMPILE))
diff --git a/pvr-source/eurasiacon/build/linux2/commands.mk b/pvr-source/eurasiacon/build/linux2/commands.mk
new file mode 100644
index 0000000..25e5ed1
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/commands.mk
@@ -0,0 +1,219 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# from-one-* recipes make a thing from one source file, so they use $<. Others
+# use $(MODULE_something) instead of $^
+
+# We expect that MODULE_*FLAGS contains all the flags we need, including the
+# flags for all modules (like $(ALL_CFLAGS) and $(ALL_HOST_CFLAGS)), and
+# excluding flags for include search dirs or for linking libraries. The
+# exceptions are ALL_EXE_LDFLAGS and ALL_LIB_LDFLAGS, since they depend on the
+# type of thing being linked, so they appear in the commands below
+
+define host-o-from-one-c
+$(if $(V),,@echo " HOST_CC " $(call relative-to-top,$<))
+$(HOST_CC) -MD -c $(MODULE_HOST_CFLAGS) $(MODULE_INCLUDE_FLAGS) \
+ -include $(CONFIG_H) $< -o $@
+endef
+
+define target-o-from-one-c
+$(if $(V),,@echo " CC " $(call relative-to-top,$<))
+$(CC) -MD -c $(MODULE_CFLAGS) $(MODULE_INCLUDE_FLAGS) \
+ -include $(CONFIG_H) $< -o $@
+endef
+
+# We use $(CC) to compile C++ files, and expect it to detect that it's
+# compiling C++
+define host-o-from-one-cxx
+$(if $(V),,@echo " HOST_CC " $(call relative-to-top,$<))
+$(HOST_CC) -MD -c $(MODULE_HOST_CXXFLAGS) $(MODULE_INCLUDE_FLAGS) \
+ -include $(CONFIG_H) $< -o $@
+endef
+
+define target-o-from-one-cxx
+$(if $(V),,@echo " CC " $(call relative-to-top,$<))
+$(CC) -MD -c $(MODULE_CXXFLAGS) $(MODULE_INCLUDE_FLAGS) \
+ -include $(CONFIG_H) $< -o $@
+endef
+
+define host-executable-from-o
+$(if $(V),,@echo " HOST_LD " $(call relative-to-top,$@))
+$(HOST_CC) $(MODULE_HOST_LDFLAGS) \
+ -o $@ $(sort $(MODULE_ALL_OBJECTS)) $(MODULE_LIBRARY_DIR_FLAGS) \
+ $(MODULE_LIBRARY_FLAGS)
+endef
+
+define host-executable-cxx-from-o
+$(if $(V),,@echo " HOST_LD " $(call relative-to-top,$@))
+$(HOST_CXX) $(MODULE_HOST_LDFLAGS) \
+ -o $@ $(sort $(MODULE_ALL_OBJECTS)) $(MODULE_LIBRARY_DIR_FLAGS) \
+ $(MODULE_LIBRARY_FLAGS)
+endef
+
+define target-executable-from-o
+$(if $(V),,@echo " LD " $(call relative-to-top,$@))
+$(CC) \
+ $(SYS_EXE_LDFLAGS) $(MODULE_LDFLAGS) -o $@ \
+ $(SYS_EXE_CRTBEGIN) $(sort $(MODULE_ALL_OBJECTS)) $(SYS_EXE_CRTEND) \
+ $(MODULE_LIBRARY_DIR_FLAGS) $(MODULE_LIBRARY_FLAGS) $(LIBGCC)
+endef
+
+define target-executable-cxx-from-o
+$(if $(V),,@echo " LD " $(call relative-to-top,$@))
+$(CXX) \
+ $(SYS_EXE_LDFLAGS) $(MODULE_LDFLAGS) -o $@ \
+ $(SYS_EXE_CRTBEGIN) $(sort $(MODULE_ALL_OBJECTS)) $(SYS_EXE_CRTEND) \
+ $(MODULE_LIBRARY_DIR_FLAGS) $(MODULE_LIBRARY_FLAGS) $(LIBGCC)
+endef
+
+define target-shared-library-from-o
+$(if $(V),,@echo " LD " $(call relative-to-top,$@))
+$(CC) -shared -Wl,-Bsymbolic \
+ $(SYS_LIB_LDFLAGS) $(MODULE_LDFLAGS) -o $@ \
+ $(SYS_LIB_CRTBEGIN) $(sort $(MODULE_ALL_OBJECTS)) $(SYS_LIB_CRTEND) \
+ $(MODULE_LIBRARY_DIR_FLAGS) $(MODULE_LIBRARY_FLAGS) $(LIBGCC)
+endef
+
+# If there were any C++ source files in a shared library, we use this recipe,
+# which runs the C++ compiler to link the final library
+define target-shared-library-cxx-from-o
+$(if $(V),,@echo " LD " $(call relative-to-top,$@))
+$(CXX) -shared -Wl,-Bsymbolic \
+ $(SYS_LIB_LDFLAGS) $(MODULE_LDFLAGS) -o $@ \
+ $(SYS_LIB_CRTBEGIN) $(sort $(MODULE_ALL_OBJECTS)) $(SYS_LIB_CRTEND) \
+ $(MODULE_LIBRARY_DIR_FLAGS) $(MODULE_LIBRARY_FLAGS) $(LIBGCC)
+endef
+
+define target-copy-debug-information
+$(OBJCOPY) --only-keep-debug $@ $(basename $@).dbg
+endef
+
+define host-strip-debug-information
+$(HOST_STRIP) --strip-unneeded $@
+endef
+
+define target-strip-debug-information
+$(STRIP) --strip-unneeded $@
+endef
+
+define target-add-debuglink
+$(if $(V),,@echo " DBGLINK " $(call relative-to-top,$(basename $@).dbg))
+$(OBJCOPY) --add-gnu-debuglink=$(basename $@).dbg $@
+endef
+
+define host-static-library-from-o
+$(if $(V),,@echo " HOST_AR " $(call relative-to-top,$@))
+$(HOST_AR) cru $@ $(sort $(MODULE_ALL_OBJECTS))
+endef
+
+define target-static-library-from-o
+$(if $(V),,@echo " AR " $(call relative-to-top,$@))
+$(AR) cru $@ $(sort $(MODULE_ALL_OBJECTS))
+endef
+
+define tab-c-from-y
+$(if $(V),,@echo " BISON " $(call relative-to-top,$<))
+$(BISON) $(MODULE_BISON_FLAGS) -o $@ -d $<
+endef
+
+define l-c-from-l
+$(if $(V),,@echo " FLEX " $(call relative-to-top,$<))
+$(FLEX) $(MODULE_FLEX_FLAGS) -o$@ $<
+endef
+
+define clean-dirs
+$(if $(V),,@echo " RM " $(call relative-to-top,$(MODULE_DIRS_TO_REMOVE)))
+$(RM) -rf $(MODULE_DIRS_TO_REMOVE)
+endef
+
+define make-directory
+$(MKDIR) -p $@
+endef
+
+define check-exports
+endef
+
+# Programs used in recipes
+
+BISON ?= bison
+CC ?= gcc
+CXX ?= g++
+HOST_CC ?= gcc
+HOST_CXX ?= g++
+JAR ?= jar
+JAVA ?= java
+JAVAC ?= javac
+ZIP ?= zip
+
+override AR := $(if $(V),,@)$(CROSS_COMPILE)ar
+override BISON := $(if $(V),,@)$(BISON)
+override BZIP2 := $(if $(V),,@)bzip2 -9
+override CC := $(if $(V),,@)$(CROSS_COMPILE)$(CC)
+override CC_CHECK := $(if $(V),,@)$(MAKE_TOP)/tools/cc-check.sh
+override CXX := $(if $(V),,@)$(CROSS_COMPILE)$(CXX)
+override CHMOD := $(if $(V),,@)chmod
+override CP := $(if $(V),,@)cp
+override ECHO := $(if $(V),,@)echo
+override FLEX := $(if $(V),,@)flex
+override GAWK := $(if $(V),,@)gawk
+override GREP := $(if $(V),,@)grep
+override HOST_AR := $(if $(V),,@)ar
+override HOST_CC := $(if $(V),,@)$(HOST_CC)
+override HOST_CXX := $(if $(V),,@)$(HOST_CXX)
+override HOST_STRIP := $(if $(V),,@)strip
+override INSTALL := $(if $(V),,@)install
+override JAR := $(if $(V),,@)$(JAR)
+override JAVA := $(if $(V),,@)$(JAVA)
+override JAVAC := $(if $(V),,@)$(JAVAC)
+override M4 := $(if $(V),,@)m4
+override MKDIR := $(if $(V),,@)mkdir
+override MV := $(if $(V),,@)mv
+override OBJCOPY := $(if $(V),,@)$(CROSS_COMPILE)objcopy
+override PDSASM := $(if $(V),,@)$(HOST_OUT)/pdsasm
+override RANLIB := $(if $(V),,@)$(CROSS_COMPILE)ranlib
+override RM := $(if $(V),,@)rm -f
+override SED := $(if $(V),,@)sed
+override STRIP := $(if $(V),,@)$(CROSS_COMPILE)strip
+override TAR := $(if $(V),,@)tar
+override TOUCH := $(if $(V),,@)touch
+override USEASM := $(if $(V),,@)$(HOST_OUT)/useasm
+override USELINK := $(if $(V),,@)$(HOST_OUT)/uselink
+override VHD2INC := $(if $(V),,@)$(HOST_OUT)/vhd2inc
+override ZIP := $(if $(V),,@)$(ZIP)
diff --git a/pvr-source/eurasiacon/build/linux2/common/android/arch_common.mk b/pvr-source/eurasiacon/build/linux2/common/android/arch_common.mk
new file mode 100644
index 0000000..6e16b14
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/common/android/arch_common.mk
@@ -0,0 +1,59 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+SYS_CFLAGS := \
+ -fno-short-enums -D__linux__ \
+ -I$(ANDROID_ROOT)/bionic/libc/arch-$(ANDROID_ARCH)/include \
+ -I$(ANDROID_ROOT)/bionic/libc/include \
+ -I$(ANDROID_ROOT)/bionic/libc/kernel/common \
+ -I$(ANDROID_ROOT)/bionic/libc/kernel/arch-$(ANDROID_ARCH) \
+ -I$(ANDROID_ROOT)/bionic/libm/include \
+ -I$(ANDROID_ROOT)/bionic/libm/include/$(ANDROID_ARCH) \
+ -I$(ANDROID_ROOT)/bionic/libthread_db/include \
+ -I$(ANDROID_ROOT)/frameworks/base/include \
+ -isystem $(ANDROID_ROOT)/system/core/include \
+ -I$(ANDROID_ROOT)/hardware/libhardware/include \
+ -I$(ANDROID_ROOT)/external/openssl/include
+
+SYS_EXE_LDFLAGS := \
+ -Bdynamic -nostdlib -Wl,-dynamic-linker,/system/bin/linker \
+ -lc -ldl -lcutils
+
+SYS_LIB_LDFLAGS := $(SYS_EXE_LDFLAGS)
diff --git a/pvr-source/eurasiacon/build/linux2/common/android/armv7-a.mk b/pvr-source/eurasiacon/build/linux2/common/android/armv7-a.mk
new file mode 100644
index 0000000..8c3f937
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/common/android/armv7-a.mk
@@ -0,0 +1,68 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+OPTIM := -Os
+
+ANDROID_ARCH := arm
+include ../common/android/arch_common.mk
+
+SYS_CFLAGS += -march=armv7-a
+
+SYS_EXE_CRTBEGIN := $(TOOLCHAIN)/lib/crtbegin_dynamic.o
+SYS_EXE_CRTEND := $(TOOLCHAIN)/lib/crtend_android.o
+
+# Handle the removal of the armelf.x and armelf.xsc linker scripts.
+ifeq ($(strip $(wildcard $(ANDROID_ROOT)/build/core/armelf.x)),)
+# The linker scripts have been removed. We need to use these options
+# instead.
+SYS_EXE_LDFLAGS += -Wl,-z,relro -Wl,-z,now
+SYS_LIB_LDFLAGS += -Wl,-z,relro -Wl,-z,now
+else
+# The linker scripts are still present in the Android tree, so we need to
+# use them.
+SYS_EXE_LDFLAGS += -Wl,-T$(ANDROID_ROOT)/build/core/armelf.x
+SYS_LIB_LDFLAGS += -Wl,-T$(ANDROID_ROOT)/build/core/armelf.xsc
+endif
+
+JNI_CPU_ABI := armeabi
+
+# Android builds are usually GPL
+#
+LDM_PLATFORM ?= 1
diff --git a/pvr-source/eurasiacon/build/linux2/common/android/extra_config.mk b/pvr-source/eurasiacon/build/linux2/common/android/extra_config.mk
new file mode 100644
index 0000000..320804e
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/common/android/extra_config.mk
@@ -0,0 +1,47 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+
+$(eval $(call BothConfigC,ANDROID,))
+
+
+
+
+
diff --git a/pvr-source/eurasiacon/build/linux2/common/android/features.mk b/pvr-source/eurasiacon/build/linux2/common/android/features.mk
new file mode 100644
index 0000000..18bc370
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/common/android/features.mk
@@ -0,0 +1,319 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+include ../common/android/platform_version.mk
+
+# Basic support option tuning for Android
+#
+SUPPORT_ANDROID_PLATFORM := 1
+SUPPORT_OPENGLES1_V1_ONLY := 1
+
+# Meminfo IDs are required for buffer stamps
+#
+SUPPORT_MEMINFO_IDS := 1
+
+# Need multi-process support in PDUMP
+#
+SUPPORT_PDUMP_MULTI_PROCESS := 1
+
+# Always print debugging after 5 seconds of no activity
+#
+CLIENT_DRIVER_DEFAULT_WAIT_RETRIES := 50
+
+# Android WSEGL is always the same
+#
+OPK_DEFAULT := libpvrANDROID_WSEGL.so
+
+# srvkm is always built, but bufferclass_example is only built
+# before EGL_image_external was generally available.
+#
+KERNEL_COMPONENTS := srvkm
+ifeq ($(is_at_least_honeycomb),0)
+KERNEL_COMPONENTS += bufferclass_example
+endif
+
+# Kernel modules are always installed here under Android
+#
+PVRSRV_MODULE_BASEDIR := /system/modules/
+
+# Use the new PVR_DPF implementation to allow lower message levels
+# to be stripped from production drivers
+#
+PVRSRV_NEW_PVR_DPF := 1
+
+# Production Android builds don't want PVRSRVGetDCSystemBuffer
+#
+SUPPORT_PVRSRV_GET_DC_SYSTEM_BUFFER := 0
+
+# Prefer to limit the 3D parameters heap to <16MB and move the
+# extra 48MB to the general heap. This only affects cores with
+# 28bit MMUs (520, 530, 531, 540).
+#
+SUPPORT_LARGE_GENERAL_HEAP := 1
+
+# Enable a page pool for uncached memory allocations. This improves
+# the performance of such allocations because the pages are temporarily
+# not returned to Linux and therefore do not have to be re-invalidated
+# (fewer cache invalidates are needed).
+#
+# Default the cache size to a maximum of 5400 pages (~21MB). If using
+# newer Linux kernels (>=3.0) the cache may be reclaimed and become
+# smaller than this maximum during runtime.
+#
+PVR_LINUX_MEM_AREA_POOL_MAX_PAGES ?= 5400
+
+##############################################################################
+# EGL connect/disconnect hooks only available since Froyo
+# Obsolete in future versions
+#
+ifeq ($(is_at_least_froyo),1)
+ifeq ($(is_at_least_icecream_sandwich),0)
+PVR_ANDROID_HAS_CONNECT_DISCONNECT := 1
+endif
+endif
+
+##############################################################################
+# Override surface field name for older versions
+#
+ifeq ($(is_at_least_gingerbread),0)
+PVR_ANDROID_SURFACE_FIELD_NAME := \"mSurface\"
+endif
+
+##############################################################################
+# Provide ANativeWindow{Buffer,} typedefs for older versions
+#
+ifeq ($(is_at_least_gingerbread),0)
+PVR_ANDROID_NEEDS_ANATIVEWINDOW_TYPEDEF := 1
+endif
+ifeq ($(is_at_least_icecream_sandwich),0)
+PVR_ANDROID_NEEDS_ANATIVEWINDOWBUFFER_TYPEDEF := 1
+endif
+
+##############################################################################
+# Handle various platform includes for unittests
+#
+UNITTEST_INCLUDES := eurasiacon/android
+
+ifeq ($(is_at_least_gingerbread),1)
+UNITTEST_INCLUDES += $(ANDROID_ROOT)/frameworks/base/native/include
+endif
+
+ifeq ($(is_at_least_jellybean),1)
+UNITTEST_INCLUDES += \
+ $(ANDROID_ROOT)/frameworks/native/include \
+ $(ANDROID_ROOT)/frameworks/native/opengl/include \
+ $(ANDROID_ROOT)/libnativehelper/include
+# FIXME: This is the old location for the JNI header.
+UNITTEST_INCLUDES += $(ANDROID_ROOT)/dalvik/libnativehelper/include
+else
+UNITTEST_INCLUDES += \
+ $(ANDROID_ROOT)/frameworks/base/opengl/include \
+ $(ANDROID_ROOT)/dalvik/libnativehelper/include
+endif
+
+# But it doesn't have OpenVG headers
+#
+UNITTEST_INCLUDES += eurasiacon/unittests/include
+
+##############################################################################
+# Future versions moved proprietary libraries to a vendor directory
+#
+ifeq ($(is_at_least_gingerbread),1)
+SHLIB_DESTDIR := /system/vendor/lib
+DEMO_DESTDIR := /system/vendor/bin
+else
+SHLIB_DESTDIR := /system/lib
+DEMO_DESTDIR := /system/bin
+endif
+
+# EGL libraries go in a special place
+#
+EGL_DESTDIR := $(SHLIB_DESTDIR)/egl
+
+##############################################################################
+# We can support OpenCL in the build since Froyo (stlport was added in 2.2)
+#
+ifeq ($(is_at_least_froyo),1)
+SYS_CXXFLAGS := \
+ -fuse-cxa-atexit \
+ $(SYS_CFLAGS) \
+ -I$(ANDROID_ROOT)/bionic \
+ -I$(ANDROID_ROOT)/external/stlport/stlport
+else
+SYS_CXXFLAGS := \
+ $(SYS_CFLAGS) \
+ -I$(ANDROID_ROOT)/bionic/libstdc++/include
+endif
+
+##############################################################################
+# Composition bypass feature, supported since Froyo.
+# In ICS, hardware composer (HWC) should be used instead.
+#
+ifeq ($(is_at_least_froyo),1)
+ifeq ($(is_at_least_honeycomb),0)
+PVR_ANDROID_HAS_NATIVE_BUFFER_TRANSFORM := 1
+SUPPORT_ANDROID_COMPOSITION_BYPASS := 1
+endif
+endif
+
+##############################################################################
+# In ICS, we have hardware composer (HWC) support.
+#
+# SUPPORT_ANDROID_COMPOSER_HAL adds Post2() to the framebuffer HAL interface
+# and is intended for inter-op with external HWC modules. It is always
+# enabled (but we allow it to be compiled out just in case).
+#
+# SUPPORT_ANDROID_COMPOSITION_BYPASS adds a new buffer type (client buffers
+# allocated from the framebuffer pool) which maximizes compatibility with
+# most 3rdparty display controllers. It is orthogonal to HWC support.
+#
+ifeq ($(is_at_least_honeycomb),1)
+SUPPORT_ANDROID_COMPOSER_HAL := 1
+endif
+
+##############################################################################
+# We have some extra GRALLOC_USAGE bits we need to handle in ICS
+#
+ifeq ($(is_at_least_honeycomb),1)
+PVR_ANDROID_HAS_GRALLOC_USAGE_EXTERNAL_DISP := 1
+PVR_ANDROID_HAS_GRALLOC_USAGE_PROTECTED := 1
+PVR_ANDROID_HAS_GRALLOC_USAGE_PRIVATE := 1
+endif
+
+##############################################################################
+# Support the new OES_EGL_image_external extension + YV12 buffers
+#
+ifeq ($(is_at_least_honeycomb),1)
+PVR_ANDROID_HAS_HAL_PIXEL_FORMAT_YV12 := 1
+GLES1_EXTENSION_EGL_IMAGE_EXTERNAL := 1
+GLES2_EXTENSION_EGL_IMAGE_EXTERNAL := 1
+endif
+
+##############################################################################
+# Gingerbread adds the native window cancelBuffer operation
+#
+ifeq ($(is_at_least_gingerbread),1)
+PVR_ANDROID_HAS_CANCELBUFFER := 1
+endif
+
+##############################################################################
+# Versions prior to ICS have another header we must include
+#
+ifeq ($(is_at_least_icecream_sandwich),0)
+PVR_ANDROID_HAS_ANDROID_NATIVE_BUFFER_H := 1
+endif
+
+##############################################################################
+# ICS added dump() hook to gralloc alloc_device_t API
+#
+ifeq ($(is_at_least_honeycomb),1)
+PVR_ANDROID_HAS_GRALLOC_DUMP := 1
+endif
+
+##############################################################################
+# ICS added support for the BGRX pixel format, and allows drivers to advertise
+# configs in this format instead of RGBX.
+#
+# The DDK provides a private definition of HAL_PIXEL_FORMAT_BGRX_8888. This
+# option exposes it as the native visual for 8888 configs with alpha ignored
+#
+ifeq ($(is_at_least_icecream_sandwich),1)
+SUPPORT_HAL_PIXEL_FORMAT_BGRX := 1
+endif
+
+##############################################################################
+# ICS added the ability for GL clients to pre-rotate their rendering to the
+# orientation desired by the compositor. The SGX DDK can use TRANSFORM_HINT
+# to access this functionality.
+#
+# This is required by some HWC implementations that cannot use the display
+# to rotate buffers, otherwise the HWC optimization cannot be used when
+# rotating the device.
+#
+ifeq ($(is_at_least_icecream_sandwich),1)
+PVR_ANDROID_HAS_WINDOW_TRANSFORM_HINT := 1
+endif
+
+##############################################################################
+# ICS requires that at least one driver EGLConfig advertises the
+# EGL_RECORDABLE_ANDROID attribute. The platform requires that surfaces
+# rendered with this config can be consumed by an OMX video encoder.
+#
+ifeq ($(is_at_least_icecream_sandwich),1)
+EGL_EXTENSION_ANDROID_RECORDABLE := 1
+endif
+
+##############################################################################
+# ICS added a new usage bit. USAGE_HW_COMPOSER indicates that a buffer might
+# be used with HWComposer. In practice this is all non-MM buffers.
+#
+ifeq ($(is_at_least_icecream_sandwich),1)
+PVR_ANDROID_HAS_GRALLOC_USAGE_HW_COMPOSER := 1
+endif
+
+##############################################################################
+# ICS added the EGL_ANDROID_blob_cache extension. Enable support for this
+# extension in EGL/GLESv2.
+#
+ifeq ($(is_at_least_icecream_sandwich),1)
+EGL_EXTENSION_ANDROID_BLOB_CACHE := 1
+endif
+
+##############################################################################
+# ICS MR1 added a new usage bit. USAGE_HW_VIDEO_ENCODER indicates that a
+# buffer might be used with the video encoder.
+#
+ifeq ($(is_at_least_icecream_sandwich_mr1),1)
+PVR_ANDROID_HAS_GRALLOC_USAGE_HW_VIDEO_ENCODER := 1
+endif
+
+##############################################################################
+# ICS and earlier should rate-limit composition by waiting for 3D renders
+# to complete in the compositor's eglSwapBuffers().
+#
+ifeq ($(is_at_least_jellybean),0)
+PVR_ANDROID_COMPOSITOR_WAIT_FOR_RENDER := 1
+endif
+
+# Placeholder for future version handling
+#
+ifeq ($(is_future_version),1)
+-include ../common/android/future_version.mk
+endif
diff --git a/pvr-source/eurasiacon/build/linux2/common/android/paths.mk b/pvr-source/eurasiacon/build/linux2/common/android/paths.mk
new file mode 100644
index 0000000..5c8f000
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/common/android/paths.mk
@@ -0,0 +1,53 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+TARGET_BUILD_TYPE ?= release
+
+OUT_DIR ?= $(ANDROID_ROOT)/out
+
+ifeq ($(TARGET_BUILD_TYPE),debug)
+TARGET_ROOT := $(OUT_DIR)/debug/target
+else
+TARGET_ROOT := $(OUT_DIR)/target
+endif
+
+TOOLCHAIN ?= $(TARGET_ROOT)/product/$(TARGET_PRODUCT)/obj
+
+LIBGCC := $(shell $(CROSS_COMPILE)gcc -print-libgcc-file-name)
diff --git a/pvr-source/eurasiacon/build/linux2/common/android/platform_version.mk b/pvr-source/eurasiacon/build/linux2/common/android/platform_version.mk
new file mode 100644
index 0000000..698efa3
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/common/android/platform_version.mk
@@ -0,0 +1,156 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# Figure out the version of Android we're building against.
+#
+PLATFORM_VERSION := $(shell \
+ if [ -f $(TARGET_ROOT)/product/$(TARGET_PRODUCT)/system/build.prop ]; then \
+ cat $(TARGET_ROOT)/product/$(TARGET_PRODUCT)/system/build.prop | \
+ grep ^ro.build.version.release | cut -f2 -d'=' | cut -f1 -d'-'; \
+ else \
+ echo 4.0.3; \
+ fi)
+
+define version-starts-with
+$(shell echo $(PLATFORM_VERSION) | grep -q ^$(1); \
+ [ "$$?" = "0" ] && echo 1 || echo 0)
+endef
+
+# ro.build.version.release contains the version number for release builds, or
+# the version codename otherwise. In this case we need to assume that the
+# version of Android we're building against has the features that are in the
+# final release of that version, so we set PLATFORM_VERSION to the
+# corresponding release number.
+#
+ifeq ($(call version-starts-with,Eclair),1)
+PLATFORM_VERSION := 2.0
+else ifeq ($(call version-starts-with,Froyo),1)
+PLATFORM_VERSION := 2.2
+else ifeq ($(call version-starts-with,Gingerbread),1)
+PLATFORM_VERSION := 2.3
+else ifeq ($(call version-starts-with,Honeycomb),1)
+PLATFORM_VERSION := 3.0
+else ifeq ($(call version-starts-with,IceCreamSandwichMR),1)
+PLATFORM_VERSION := 4.0.3
+else ifeq ($(call version-starts-with,IceCreamSandwich),1)
+PLATFORM_VERSION := 4.0
+else ifeq ($(call version-starts-with,JellyBean),1)
+PLATFORM_VERSION := 4.1
+else ifeq ($(shell echo $(PLATFORM_VERSION) | grep -qE "[A-Za-z]+"; echo $$?),0)
+PLATFORM_VERSION := 5.0
+endif
+
+PLATFORM_VERSION_MAJ := $(shell echo $(PLATFORM_VERSION) | cut -f1 -d'.')
+PLATFORM_VERSION_MIN := $(shell echo $(PLATFORM_VERSION) | cut -f2 -d'.')
+PLATFORM_VERSION_PATCH := $(shell echo $(PLATFORM_VERSION) | cut -f3 -d'.')
+
+# Not all versions have a patchlevel; fix that up here
+#
+ifeq ($(PLATFORM_VERSION_PATCH),)
+PLATFORM_VERSION_PATCH := 0
+endif
+
+# Macros to help categorize support for features and API_LEVEL for tests.
+#
+is_at_least_eclair := \
+ $(shell ( test $(PLATFORM_VERSION_MAJ) -gt 2 || \
+ ( test $(PLATFORM_VERSION_MAJ) -eq 2 && \
+ test $(PLATFORM_VERSION_MIN) -ge 0 ) ) && echo 1 || echo 0)
+is_at_least_froyo := \
+ $(shell ( test $(PLATFORM_VERSION_MAJ) -gt 2 || \
+ ( test $(PLATFORM_VERSION_MAJ) -eq 2 && \
+ test $(PLATFORM_VERSION_MIN) -ge 2 ) ) && echo 1 || echo 0)
+is_at_least_gingerbread := \
+ $(shell ( test $(PLATFORM_VERSION_MAJ) -gt 2 || \
+ ( test $(PLATFORM_VERSION_MAJ) -eq 2 && \
+ test $(PLATFORM_VERSION_MIN) -ge 3 ) ) && echo 1 || echo 0)
+is_at_least_honeycomb := \
+ $(shell test $(PLATFORM_VERSION_MAJ) -ge 3 && echo 1 || echo 0)
+is_at_least_icecream_sandwich := \
+ $(shell test $(PLATFORM_VERSION_MAJ) -ge 4 && echo 1 || echo 0)
+is_at_least_icecream_sandwich_mr1 := \
+ $(shell ( test $(PLATFORM_VERSION_MAJ) -gt 4 || \
+ ( test $(PLATFORM_VERSION_MAJ) -eq 4 && \
+ ( test $(PLATFORM_VERSION_MIN) -ge 1 || \
+ test $(PLATFORM_VERSION_PATCH) -ge 3 ) ) ) && echo 1 || echo 0)
+is_at_least_jellybean := \
+ $(shell ( test $(PLATFORM_VERSION_MAJ) -gt 4 || \
+ ( test $(PLATFORM_VERSION_MAJ) -eq 4 && \
+ test $(PLATFORM_VERSION_MIN) -ge 1 ) ) && echo 1 || echo 0)
+
+# FIXME: Assume "future versions" are >=5.0, but we don't really know
+is_future_version := \
+ $(shell ( test $(PLATFORM_VERSION_MAJ) -ge 5 ) && echo 1 || echo 0)
+
+# Picking an exact match of API_LEVEL for the platform we're building
+# against can avoid compatibility theming and affords better integration.
+#
+ifeq ($(is_future_version),1)
+API_LEVEL := 17
+else ifeq ($(is_at_least_jellybean),1)
+API_LEVEL := 16
+else ifeq ($(is_at_least_icecream_sandwich),1)
+# MR1 15
+API_LEVEL := 14
+else ifeq ($(is_at_least_honeycomb),1)
+# MR2 13
+# MR1 12
+API_LEVEL := 11
+else ifeq ($(is_at_least_gingerbread),1)
+# MR1 10
+API_LEVEL := 9
+else ifeq ($(is_at_least_froyo),1)
+API_LEVEL := 8
+else ifeq ($(is_at_least_eclair),1)
+# MR1 7
+# 2.0.1 6
+API_LEVEL := 5
+else
+$(error Must build against Android >= 2.0)
+endif
+
+# Each DDK is tested against only a single version of the platform.
+# Warn if a different platform version is used.
+#
+ifeq ($(is_future_version),1)
+$(info WARNING: Android version is newer than this DDK supports)
+else ifneq ($(is_at_least_icecream_sandwich),1)
+$(info WARNING: Android version is older than this DDK supports)
+endif
diff --git a/pvr-source/eurasiacon/build/linux2/common/dridrm.mk b/pvr-source/eurasiacon/build/linux2/common/dridrm.mk
new file mode 100644
index 0000000..5d0289f
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/common/dridrm.mk
@@ -0,0 +1,63 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+$(eval $(call TunableBothConfigC,SUPPORT_DRI_DRM,))
+$(eval $(call TunableBothConfigC,SUPPORT_DRI_DRM_EXT,))
+$(eval $(call TunableKernelConfigC,SUPPORT_DRI_DRM_PLUGIN,))
+
+
+$(eval $(call TunableBothConfigMake,SUPPORT_DRI_DRM,))
+
+ifeq ($(SUPPORT_DRI_DRM),1)
+ifeq ($(SUPPORT_DRI_DRM_NO_LIBDRM),1)
+endif
+$(eval $(call TunableKernelConfigC,PVR_SECURE_DRM_AUTH_EXPORT,))
+$(eval $(call TunableKernelConfigC,SUPPORT_DRM_MODESET,))
+endif
+
+$(eval $(call TunableKernelConfigC,PVR_DISPLAY_CONTROLLER_DRM_IOCTL,))
+
+$(eval $(call TunableBothConfigC,PVR_DRI_DRM_NOT_PCI))
+$(eval $(call TunableBothConfigMake,PVR_DRI_DRM_NOT_PCI))
+
+$(eval $(call TunableKernelConfigC,PVR_DRI_DRM_PLATFORM_DEV,))
+
+
+export EXTERNAL_3PDD_TARBALL
diff --git a/pvr-source/eurasiacon/build/linux2/common/omap4.mk b/pvr-source/eurasiacon/build/linux2/common/omap4.mk
new file mode 100644
index 0000000..153159a
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/common/omap4.mk
@@ -0,0 +1,43 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+$(eval $(call TunableKernelConfigC,PVR_NO_OMAP_TIMER,))
+$(eval $(call TunableKernelConfigC,PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY,))
+$(eval $(call TunableKernelConfigC,PVR_OMAPLFB_DRM_FB,))
diff --git a/pvr-source/eurasiacon/build/linux2/common/opencl.mk b/pvr-source/eurasiacon/build/linux2/common/opencl.mk
new file mode 100644
index 0000000..b5f84d4
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/common/opencl.mk
@@ -0,0 +1,40 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
diff --git a/pvr-source/eurasiacon/build/linux2/config/core.mk b/pvr-source/eurasiacon/build/linux2/config/core.mk
new file mode 100644
index 0000000..247d1e1
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/config/core.mk
@@ -0,0 +1,604 @@
+########################################################################### ###
+#@Title Root build configuration.
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# Configuration wrapper for new build system. This file deals with
+# configuration of the build. Add to this file anything that deals
+# with switching driver options on/off and altering the defines or
+# objects the build uses.
+#
+# At the end of this file is an exhaustive list of all variables
+# that are passed between the platform/config stage and the generic
+# build. PLEASE refrain from adding more variables than necessary
+# to this stage -- almost all options can go through config.h.
+#
+
+################################# MACROS ####################################
+
+# Write out a kernel GNU make option.
+#
+define KernelConfigMake
+$$(shell echo "override $(1) := $(2)" >>$(CONFIG_KERNEL_MK).new)
+endef
+
+# Write out a GNU make option for both user & kernel
+#
+define BothConfigMake
+$$(eval $$(call KernelConfigMake,$(1),$(2)))
+endef
+
+# Conditionally write out a kernel GNU make option
+#
+define TunableKernelConfigMake
+ifneq ($$($(1)),)
+ifneq ($$($(1)),0)
+$$(eval $$(call KernelConfigMake,$(1),$$($(1))))
+endif
+else
+ifneq ($(2),)
+$$(eval $$(call KernelConfigMake,$(1),$(2)))
+endif
+endif
+endef
+
+# Conditionally write out a GNU make option for both user & kernel
+#
+define TunableBothConfigMake
+$$(eval $$(call TunableKernelConfigMake,$(1),$(2)))
+endef
+
+# Write out a kernel-only option
+#
+define KernelConfigC
+$$(shell echo "#define $(1) $(2)" >>$(CONFIG_KERNEL_H).new)
+endef
+
+# Write out an option for both user & kernel
+#
+define BothConfigC
+$$(eval $$(call KernelConfigC,$(1),$(2)))
+endef
+
+# Conditionally write out a kernel-only option
+#
+define TunableKernelConfigC
+ifneq ($$($(1)),)
+ifneq ($$($(1)),0)
+ifeq ($$($(1)),1)
+$$(eval $$(call KernelConfigC,$(1),))
+else
+$$(eval $$(call KernelConfigC,$(1),$$($(1))))
+endif
+endif
+else
+ifneq ($(2),)
+ifeq ($(2),1)
+$$(eval $$(call KernelConfigC,$(1),))
+else
+$$(eval $$(call KernelConfigC,$(1),$(2)))
+endif
+endif
+endif
+endef
+
+# Conditionally write out an option for both user & kernel
+#
+define TunableBothConfigC
+$$(eval $$(call TunableKernelConfigC,$(1),$(2)))
+endef
+
+############################### END MACROS ##################################
+
+# Check we have a new enough version of GNU make.
+#
+need := 3.81
+ifeq ($(filter $(need),$(firstword $(sort $(MAKE_VERSION) $(need)))),)
+$(error A version of GNU make >= $(need) is required - this is version $(MAKE_VERSION))
+endif
+
+# Try to guess EURASIAROOT if it wasn't set. Check this location.
+#
+_GUESSED_EURASIAROOT := $(abspath ../../../..)
+ifneq ($(strip $(EURASIAROOT)),)
+# We don't want to warn about EURASIAROOT if it's empty: this might mean that
+# it's not set at all anywhere, but it could also mean that it's set like
+# "export EURASIAROOT=" or "make EURASIAROOT= sometarget". If it is set but
+# empty, we'll act as if it's unset and not warn.
+ifneq ($(strip $(EURASIAROOT)),$(_GUESSED_EURASIAROOT))
+nothing :=
+space := $(nothing) $(nothing)
+$(warning EURASIAROOT is set (via: $(origin EURASIAROOT)), but its value does not)
+$(warning match the root of this source tree, so it is being ignored)
+$(warning EURASIAROOT is set to: $(EURASIAROOT))
+$(warning $(space)The detected root is: $(_GUESSED_EURASIAROOT))
+$(warning To suppress this message, unset EURASIAROOT or set it empty)
+endif
+# else, EURASIAROOT matched the actual root of the source tree: don't warn
+endif
+override EURASIAROOT := $(_GUESSED_EURASIAROOT)
+TOP := $(EURASIAROOT)
+
+ifneq ($(words $(TOP)),1)
+$(warning This source tree is located in a path which contains whitespace,)
+$(warning which is not supported.)
+$(warning $(space)The root is: $(TOP))
+$(error Whitespace found in $$(TOP))
+endif
+
+$(call directory-must-exist,$(TOP))
+
+include ../defs.mk
+
+# Infer PVR_BUILD_DIR from the directory configuration is launched from.
+# Check anyway that such a directory exists.
+#
+PVR_BUILD_DIR := $(notdir $(abspath .))
+$(call directory-must-exist,$(TOP)/eurasiacon/build/linux2/$(PVR_BUILD_DIR))
+
+# Output directory for configuration, object code,
+# final programs/libraries, and install/rc scripts.
+#
+BUILD ?= release
+# TI: Added SGX type to binary build location so builds for different GPUs
+# with the same build directory are put in different places
+OUT ?= $(TOP)/eurasiacon/binary2_$(SGXCORE)_$(SGX_CORE_REV)_$(PVR_BUILD_DIR)_$(BUILD)
+override OUT := $(if $(filter /%,$(OUT)),$(OUT),$(TOP)/$(OUT))
+
+CONFIG_MK := $(OUT)/config.mk
+CONFIG_H := $(OUT)/config.h
+CONFIG_KERNEL_MK := $(OUT)/config_kernel.mk
+CONFIG_KERNEL_H := $(OUT)/config_kernel.h
+
+# Create the OUT directory and delete any previous intermediary files
+#
+$(shell mkdir -p $(OUT))
+$(shell \
+ for file in $(CONFIG_MK).new $(CONFIG_H).new \
+ $(CONFIG_KERNEL_MK).new $(CONFIG_KERNEL_H).new; do \
+ rm -f $$file; \
+ done)
+
+# Some targets don't need information about any modules. If we only specify
+# these targets on the make command line, set INTERNAL_CLOBBER_ONLY to
+# indicate that toplevel.mk shouldn't read any makefiles
+CLOBBER_ONLY_TARGETS := clean clobber help install
+INTERNAL_CLOBBER_ONLY :=
+ifneq ($(strip $(MAKECMDGOALS)),)
+INTERNAL_CLOBBER_ONLY := \
+$(if \
+ $(strip $(foreach _cmdgoal,$(MAKECMDGOALS),\
+ $(if $(filter $(_cmdgoal),$(CLOBBER_ONLY_TARGETS)),,x))),,true)
+endif
+
+# For a clobber-only build, we shouldn't regenerate any config files, or
+# require things like SGXCORE to be set
+ifneq ($(INTERNAL_CLOBBER_ONLY),true)
+
+-include ../config/user-defs.mk
+
+# FIXME: Backwards compatibility remaps.
+#
+ifeq ($(SUPPORT_SLC),1)
+SGX_FEATURE_SYSTEM_CACHE := 1
+endif
+ifeq ($(BYPASS_SLC),1)
+SGX_BYPASS_SYSTEM_CACHE := 1
+endif
+ifeq ($(BYPASS_DCU),1)
+SGX_BYPASS_DCU := 1
+endif
+ifneq ($(SGXCOREREV),)
+SGX_CORE_REV := $(SGXCOREREV)
+endif
+
+# Core handling
+#
+ifeq ($(SGXCORE),)
+$(error Must specify SGXCORE)
+endif
+ifeq ($(SGX_CORE_REV),)
+override USE_SGX_CORE_REV_HEAD := 1
+else ifeq ($(SGX_CORE_REV),000)
+override USE_SGX_CORE_REV_HEAD := 1
+override SGX_CORE_REV :=
+else
+override USE_SGX_CORE_REV_HEAD := 0
+endif
+
+# Enforced dependencies. Move this to an include.
+#
+ifeq ($(SUPPORT_LINUX_USING_WORKQUEUES),1)
+override PVR_LINUX_USING_WORKQUEUES := 1
+override PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE := 1
+override PVR_LINUX_TIMERS_USING_WORKQUEUES := 1
+override SYS_CUSTOM_POWERLOCK_WRAP := 1
+else ifeq ($(SUPPORT_LINUX_USING_SHARED_WORKQUEUES),1)
+override PVR_LINUX_USING_WORKQUEUES := 1
+override PVR_LINUX_MISR_USING_WORKQUEUE := 1
+override PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE := 1
+override SYS_CUSTOM_POWERLOCK_WRAP := 1
+endif
+
+ifneq ($(PDUMP),1)
+override SUPPORT_PDUMP_MULTI_PROCESS := 0
+endif
+
+ifeq ($(SUPPORT_HYBRID_PB),1)
+override SUPPORT_SHARED_PB := 1
+override SUPPORT_PERCONTEXT_PB := 1
+else ifeq ($(SUPPORT_PERCONTEXT_PB),1)
+override SUPPORT_SHARED_PB := 0
+endif
+
+ifeq ($(NO_HARDWARE),1)
+override SYS_USING_INTERRUPTS := 0
+override SUPPORT_HW_RECOVERY := 0
+override SUPPORT_ACTIVE_POWER_MANAGEMENT := 0
+endif
+
+# We're bumping against USSE limits on older cores because the ukernel
+# is too large when building both SGX_DISABLE_VISTEST_SUPPORT=0 and
+# PVRSRV_USSE_EDM_STATUS_DEBUG=1.
+#
+# Automatically disable vistest support if debugging the ukernel to
+# prevent build failures.
+#
+ifneq ($(filter 520 530 531 535 540,$(SGXCORE)),)
+ifneq ($(SGX_DISABLE_VISTEST_SUPPORT),1)
+SGX_DISABLE_VISTEST_SUPPORT ?= not-overridden
+ifeq ($(SGX_DISABLE_VISTEST_SUPPORT),not-overridden)
+$(warning Setting SGX_DISABLE_VISTEST_SUPPORT=1 because PVRSRV_USSE_EDM_STATUS_DEBUG=1)
+SGX_DISABLE_VISTEST_SUPPORT := 1
+endif
+endif
+endif
+
+ifeq ($(SGXCORE),535)
+ifeq ($(PVRSRV_USSE_EDM_STATUS_DEBUG),1)
+SUPPORT_SGX_HWPERF ?= not-overridden
+ifeq ($(SUPPORT_SGX_HWPERF),not-overridden)
+$(warning Setting SUPPORT_SGX_HWPERF=0 because PVRSRV_USSE_EDM_STATUS_DEBUG=1)
+SUPPORT_SGX_HWPERF := 0
+endif
+endif
+PVR2D_ALT_2DHW ?= 0
+endif
+
+# Multi-core handling must be done separately to other options
+# Also do some sanity checks
+#
+ifeq ($(SGX_FEATURE_MP),1)
+ifeq ($(SGX_FEATURE_MP_CORE_COUNT),)
+ifeq ($(SGX_FEATURE_MP_CORE_COUNT_TA),)
+$(error Must specify SGX_FEATURE_MP_CORE_COUNT or both SGX_FEATURE_MP_CORE_COUNT_TA and SGX_FEATURE_MP_CORE_COUNT_3D with SGX_FEATURE_MP)
+else
+$(eval $(call BothConfigC,SGX_FEATURE_MP_CORE_COUNT_TA,$(SGX_FEATURE_MP_CORE_COUNT_TA)))
+endif
+ifeq ($(SGX_FEATURE_MP_CORE_COUNT_3D),)
+$(error Must specify SGX_FEATURE_MP_CORE_COUNT or both SGX_FEATURE_MP_CORE_COUNT_TA and SGX_FEATURE_MP_CORE_COUNT_3D with SGX_FEATURE_MP)
+else
+$(eval $(call BothConfigC,SGX_FEATURE_MP_CORE_COUNT_3D,$(SGX_FEATURE_MP_CORE_COUNT_3D)))
+endif
+else
+$(eval $(call BothConfigC,SGX_FEATURE_MP_CORE_COUNT,$(SGX_FEATURE_MP_CORE_COUNT)))
+endif
+endif
+
+# Rather than requiring the user to have to define two variables (one quoted,
+# one not), make PVRSRV_MODNAME a non-tunable and give it an overridable
+# default here.
+#
+PVRSRV_MODNAME ?= pvrsrvkm
+
+# The user didn't set CROSS_COMPILE. There's probably nothing wrong
+# with that, but we'll let them know anyway.
+#
+ifeq ($(CROSS_COMPILE),)
+$(warning CROSS_COMPILE is not set. Target components will be built with the host compiler)
+endif
+
+# The user is trying to set one of the old SUPPORT_ options on the
+# command line or in the environment. This isn't supported any more
+# and will often break the build. The user is generally only trying
+# to remove a component from the list of targets to build, so we'll
+# point them at the new way of doing this.
+define sanity-check-support-option-origin
+ifeq ($$(filter undefined file,$$(origin $(1))),)
+$$(warning *** Setting $(1) via $$(origin $(1)) is deprecated)
+$$(error If you are trying to disable a component, use e.g. EXCLUDED_APIS="opengles1 opengl")
+endif
+endef
+$(foreach _o,SYS_CFLAGS SYS_CXXFLAGS SYS_EXE_LDFLAGS SYS_LIB_LDFLAGS SUPPORT_EWS SUPPORT_OPENGLES1 SUPPORT_OPENGLES2 SUPPORT_OPENVG SUPPORT_OPENCL SUPPORT_OPENGL SUPPORT_UNITTESTS SUPPORT_XORG,$(eval $(call sanity-check-support-option-origin,$(_o))))
+
+# Check for words in EXCLUDED_APIS that aren't understood by the
+# common/apis/*.mk files. This should be kept in sync with all the tests on
+# EXCLUDED_APIS in those files
+_excludable_apis := opencl opengl opengles1 opengles2 openvg ews unittests xorg xorg_unittests scripts
+_unrecognised := $(strip $(filter-out $(_excludable_apis),$(EXCLUDED_APIS)))
+ifneq ($(_unrecognised),)
+$(warning *** Unrecognised entries in EXCLUDED_APIS: $(_unrecognised))
+$(warning *** EXCLUDED_APIS was set via: $(origin EXCLUDED_APIS))
+$(error Excludable APIs are: $(_excludable_apis))
+endif
+
+# Build's selected list of components
+#
+-include components.mk
+
+# PDUMP needs extra components
+#
+ifeq ($(PDUMP),1)
+ifneq ($(COMPONENTS),)
+COMPONENTS += pdump
+endif
+ifeq ($(SUPPORT_DRI_DRM),1)
+EXTRA_PVRSRVKM_COMPONENTS += dbgdrv
+else
+KERNEL_COMPONENTS += dbgdrv
+endif
+endif
+
+ifeq ($(SUPPORT_PVR_REMOTE),1)
+ifneq ($(filter pvr2d,$(COMPONENTS)),)
+COMPONENTS += null_pvr2d_remote
+endif
+COMPONENTS += pvrvncsrv
+endif
+
+# If KERNELDIR is set, write it out to the config.mk, with
+# KERNEL_COMPONENTS and KERNEL_ID
+#
+ifneq ($(strip $(KERNELDIR)),)
+include ../kernel_version.mk
+PVRSRV_MODULE_BASEDIR ?= /lib/modules/$(KERNEL_ID)/extra/
+$(eval $(call KernelConfigMake,KERNELDIR,$(KERNELDIR)))
+# Needed only by install script
+$(eval $(call KernelConfigMake,KERNEL_COMPONENTS,$(KERNEL_COMPONENTS)))
+$(eval $(call TunableKernelConfigMake,EXTRA_PVRSRVKM_COMPONENTS,))
+$(eval $(call TunableKernelConfigMake,EXTRA_KBUILD_SOURCE,))
+
+# If KERNEL_CROSS_COMPILE is set to "undef", this is magically
+# equivalent to being unset. If it is unset, we use CROSS_COMPILE
+# (which might also be unset). If it is set, use it directly.
+ifneq ($(KERNEL_CROSS_COMPILE),undef)
+KERNEL_CROSS_COMPILE ?= $(CROSS_COMPILE)
+$(eval $(call TunableBothConfigMake,KERNEL_CROSS_COMPILE,))
+endif
+
+# Check the KERNELDIR has a kernel built and also check that it is
+# not 64-bit, which we do not support.
+VMLINUX := $(strip $(wildcard $(KERNELDIR)/vmlinux))
+ifneq ($(VMLINUX),)
+VMLINUX_IS_64BIT := $(shell file $(VMLINUX) | grep -q 64-bit || echo false)
+ifneq ($(VMLINUX_IS_64BIT),false)
+$(warning $$(KERNELDIR)/vmlinux is 64-bit, which is not supported. Kbuild may fail.)
+endif
+else
+$(warning $$(KERNELDIR)/vmlinux does not exist. Kbuild may fail.)
+endif
+endif
+
+
+# Ideally configured by platform Makefiles, as necessary
+#
+
+# Invariant options for Linux
+#
+$(eval $(call BothConfigC,LINUX,))
+
+$(eval $(call BothConfigC,PVR_BUILD_DIR,"\"$(PVR_BUILD_DIR)\""))
+$(eval $(call BothConfigC,PVR_BUILD_TYPE,"\"$(BUILD)\""))
+$(eval $(call BothConfigC,PVRSRV_MODNAME,"\"$(PVRSRV_MODNAME)\""))
+
+$(eval $(call TunableBothConfigC,SGXCORE,))
+$(eval $(call BothConfigC,SGX$(SGXCORE),))
+$(eval $(call BothConfigC,SUPPORT_SGX$(SGXCORE),))
+
+$(eval $(call TunableBothConfigC,SUPPORT_SGX,1))
+$(eval $(call TunableBothConfigC,SGX_CORE_REV,))
+$(eval $(call TunableBothConfigC,USE_SGX_CORE_REV_HEAD,))
+
+$(eval $(call BothConfigC,TRANSFER_QUEUE,))
+$(eval $(call BothConfigC,PVR_SECURE_HANDLES,))
+
+ifneq ($(DISPLAY_CONTROLLER),)
+$(eval $(call BothConfigC,DISPLAY_CONTROLLER,$(DISPLAY_CONTROLLER)))
+endif
+
+PVR_LINUX_MEM_AREA_POOL_MAX_PAGES ?= 0
+ifneq ($(PVR_LINUX_MEM_AREA_POOL_MAX_PAGES),0)
+PVR_LINUX_MEM_AREA_USE_VMAP ?= 1
+include ../kernel_version.mk
+ifeq ($(call kernel-version-at-least,3,0),true)
+PVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK ?= 1
+endif
+endif
+$(eval $(call KernelConfigC,PVR_LINUX_MEM_AREA_POOL_MAX_PAGES,$(PVR_LINUX_MEM_AREA_POOL_MAX_PAGES)))
+$(eval $(call TunableKernelConfigC,PVR_LINUX_MEM_AREA_USE_VMAP,))
+$(eval $(call TunableKernelConfigC,PVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK,))
+
+
+$(eval $(call BothConfigMake,PVR_SYSTEM,$(PVR_SYSTEM)))
+
+
+# Build-type dependent options
+#
+$(eval $(call BothConfigMake,BUILD,$(BUILD)))
+
+ifeq ($(BUILD),debug)
+$(eval $(call BothConfigC,DEBUG,))
+$(eval $(call KernelConfigC,DEBUG_LINUX_MEMORY_ALLOCATIONS,))
+$(eval $(call KernelConfigC,DEBUG_LINUX_MEM_AREAS,))
+$(eval $(call KernelConfigC,DEBUG_LINUX_MMAP_AREAS,))
+$(eval $(call KernelConfigC,DEBUG_BRIDGE_KM,))
+else ifeq ($(BUILD),release)
+$(eval $(call BothConfigC,RELEASE,))
+$(eval $(call TunableBothConfigMake,DEBUGLINK,1))
+else ifeq ($(BUILD),timing)
+$(eval $(call BothConfigC,TIMING,))
+$(eval $(call TunableBothConfigMake,DEBUGLINK,1))
+else
+$(error BUILD= must be either debug, release or timing)
+endif
+
+# User-configurable options
+#
+$(eval $(call TunableBothConfigC,SUPPORT_PERCONTEXT_PB,1))
+$(eval $(call TunableBothConfigC,SUPPORT_SHARED_PB,))
+$(eval $(call TunableBothConfigC,SUPPORT_HYBRID_PB,))
+$(eval $(call TunableBothConfigC,SUPPORT_HW_RECOVERY,1))
+$(eval $(call TunableBothConfigC,SUPPORT_ACTIVE_POWER_MANAGEMENT,1))
+$(eval $(call TunableBothConfigC,SUPPORT_SGX_HWPERF,1))
+$(eval $(call TunableBothConfigC,SUPPORT_SGX_LOW_LATENCY_SCHEDULING,1))
+$(eval $(call TunableBothConfigC,SUPPORT_MEMINFO_IDS,))
+$(eval $(call TunableBothConfigC,SUPPORT_SGX_NEW_STATUS_VALS,1))
+$(eval $(call TunableBothConfigC,SUPPORT_PDUMP_MULTI_PROCESS,))
+$(eval $(call TunableBothConfigC,SUPPORT_DBGDRV_EVENT_OBJECTS,1))
+$(eval $(call TunableBothConfigC,SGX_FEATURE_SYSTEM_CACHE,))
+$(eval $(call TunableBothConfigC,SGX_BYPASS_SYSTEM_CACHE,))
+$(eval $(call TunableBothConfigC,SGX_BYPASS_DCU,))
+$(eval $(call TunableBothConfigC,SGX_FAST_DPM_INIT,))
+$(eval $(call TunableBothConfigC,SGX_FEATURE_MP,))
+$(eval $(call TunableBothConfigC,SGX_FEATURE_MP_PLUS,))
+$(eval $(call TunableBothConfigC,FPGA,))
+$(eval $(call TunableBothConfigC,PDUMP,))
+$(eval $(call TunableBothConfigC,NO_HARDWARE,))
+$(eval $(call TunableBothConfigC,PDUMP_DEBUG_OUTFILES,))
+$(eval $(call TunableBothConfigC,PVRSRV_USSE_EDM_STATUS_DEBUG,))
+$(eval $(call TunableBothConfigC,SGX_DISABLE_VISTEST_SUPPORT,))
+$(eval $(call TunableBothConfigC,PVRSRV_RESET_ON_HWTIMEOUT,))
+$(eval $(call TunableBothConfigC,SYS_USING_INTERRUPTS,1))
+$(eval $(call TunableBothConfigC,SUPPORT_EXTERNAL_SYSTEM_CACHE,))
+$(eval $(call TunableBothConfigC,PVRSRV_NEW_PVR_DPF,))
+$(eval $(call TunableBothConfigC,PVRSRV_NEED_PVR_DPF,))
+$(eval $(call TunableBothConfigC,PVRSRV_NEED_PVR_ASSERT,))
+$(eval $(call TunableBothConfigC,PVRSRV_NEED_PVR_TRACE,))
+$(eval $(call TunableBothConfigC,SUPPORT_SECURE_33657_FIX,))
+$(eval $(call TunableBothConfigC,SUPPORT_ION,))
+$(eval $(call TunableBothConfigC,SUPPORT_HWRECOVERY_TRACE_LIMIT,))
+$(eval $(call TunableBothConfigC,SUPPORT_PVRSRV_GET_DC_SYSTEM_BUFFER,1))
+$(eval $(call TunableBothConfigC,SUPPORT_NV12_FROM_2_HWADDRS,))
+
+$(eval $(call TunableKernelConfigC,SUPPORT_LINUX_X86_WRITECOMBINE,1))
+$(eval $(call TunableKernelConfigC,SUPPORT_LINUX_X86_PAT,1))
+$(eval $(call TunableKernelConfigC,SGX_DYNAMIC_TIMING_INFO,))
+$(eval $(call TunableKernelConfigC,SYS_SGX_ACTIVE_POWER_LATENCY_MS,))
+$(eval $(call TunableKernelConfigC,SYS_CUSTOM_POWERLOCK_WRAP,))
+$(eval $(call TunableKernelConfigC,PVR_LINUX_USING_WORKQUEUES,))
+$(eval $(call TunableKernelConfigC,PVR_LINUX_MISR_USING_WORKQUEUE,))
+$(eval $(call TunableKernelConfigC,PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE,))
+$(eval $(call TunableKernelConfigC,PVR_LINUX_TIMERS_USING_WORKQUEUES,))
+$(eval $(call TunableKernelConfigC,PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE,))
+$(eval $(call TunableKernelConfigC,LDM_PLATFORM,))
+$(eval $(call TunableKernelConfigC,PVR_LDM_PLATFORM_PRE_REGISTERED,))
+$(eval $(call TunableKernelConfigC,PVR_LDM_PLATFORM_PRE_REGISTERED_DEV,))
+$(eval $(call TunableKernelConfigC,PVR_LDM_DRIVER_REGISTRATION_NAME,"\"$(PVRSRV_MODNAME)\""))
+$(eval $(call TunableKernelConfigC,LDM_PCI,))
+$(eval $(call TunableKernelConfigC,PVRSRV_DUMP_MK_TRACE,))
+$(eval $(call TunableKernelConfigC,PVRSRV_DUMP_KERNEL_CCB,))
+$(eval $(call TunableKernelConfigC,PVRSRV_REFCOUNT_DEBUG,))
+$(eval $(call TunableKernelConfigC,PVRSRV_MMU_MAKE_READWRITE_ON_DEMAND,))
+$(eval $(call TunableKernelConfigC,HYBRID_SHARED_PB_SIZE,))
+$(eval $(call TunableKernelConfigC,SUPPORT_LARGE_GENERAL_HEAP,))
+$(eval $(call TunableKernelConfigC,TTRACE,))
+
+ifeq ($(BUILD),debug)
+$(eval $(call TunableKernelConfigC,CONFIG_PVR_PROC_FS,1))
+else
+$(eval $(call TunableKernelConfigC,CONFIG_PVR_PROC_FS,))
+endif
+
+$(eval $(call TunableKernelConfigC,CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG,))
+
+$(eval $(call TunableBothConfigMake,SUPPORT_ION,))
+
+
+$(eval $(call TunableBothConfigMake,OPTIM,))
+
+
+$(eval $(call TunableKernelConfigMake,TTRACE,))
+
+endif # INTERNAL_CLOBBER_ONLY
+
+export INTERNAL_CLOBBER_ONLY
+export TOP
+export OUT
+
+MAKE_ETC := -Rr --no-print-directory -C $(TOP) TOP=$(TOP) OUT=$(OUT) \
+ -f eurasiacon/build/linux2/toplevel.mk
+
+# This must match the default value of MAKECMDGOALS below, and the default
+# goal in toplevel.mk
+.DEFAULT_GOAL := build
+
+ifeq ($(MAKECMDGOALS),)
+MAKECMDGOALS := build
+else
+# We can't pass autogen to toplevel.mk
+MAKECMDGOALS := $(filter-out autogen,$(MAKECMDGOALS))
+endif
+
+.PHONY: autogen
+autogen:
+ifeq ($(INTERNAL_CLOBBER_ONLY),)
+ @$(MAKE) -s --no-print-directory -C $(EURASIAROOT) \
+ -f eurasiacon/build/linux2/prepare_tree.mk \
+ LDM_PCI=$(LDM_PCI) LDM_PLATFORM=$(LDM_PLATFORM)
+else
+ @:
+endif
+
+# This deletes built-in suffix rules. Otherwise the submake isn't run when
+# saying e.g. "make thingy.a"
+.SUFFIXES:
+
+# Because we have a match-anything rule below, we'll run the main build when
+# we're actually trying to remake various makefiles after they're read in.
+# These rules try to prevent that
+%.mk: ;
+Makefile%: ;
+Makefile: ;
+
+.PHONY: build kbuild install
+build kbuild install: autogen
+ @$(if $(MAKECMDGOALS),$(MAKE) $(MAKE_ETC) $(MAKECMDGOALS) $(eval MAKECMDGOALS :=),:)
+
+%: autogen
+ @$(if $(MAKECMDGOALS),$(MAKE) $(MAKE_ETC) $(MAKECMDGOALS) $(eval MAKECMDGOALS :=),:)
diff --git a/pvr-source/eurasiacon/build/linux2/defs.mk b/pvr-source/eurasiacon/build/linux2/defs.mk
new file mode 100644
index 0000000..621e03e
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/defs.mk
@@ -0,0 +1,140 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+define must-be-defined
+$(if $(filter undefined,$(origin $(1))),$(error In makefile $(THIS_MAKEFILE): $$($(1)) must be defined),)
+endef
+
+define must-be-nonempty
+$(if $(strip $($(1))),,$(error In makefile $(THIS_MAKEFILE): $$($(1)) must contain a value))
+endef
+
+define directory-must-exist
+$(if $(wildcard $(abspath $(1)/)),,$(error Directory $(1) must exist))
+endef
+
+define one-word-only
+$(if $(filter-out $(firstword $($(1))),$($(1))),$(error In makefile $(THIS_MAKEFILE): $$($(1)) must contain only one word),)
+endef
+
+define target-intermediates-of
+$(addprefix $(TARGET_OUT)/intermediates/$(1)/,$(2))
+endef
+
+define host-intermediates-of
+$(addprefix $(HOST_OUT)/intermediates/$(1)/,$(2))
+endef
+
+define module-library
+$(patsubst lib%.so,%,$(if $($(1)_target),$($(1)_target),$(1).so))
+endef
+
+# This is done to allow module type makefiles to use $(THIS_MAKEFILE)
+define register-module
+INTERNAL_MAKEFILE_FOR_MODULE_$(1) := $(THIS_MAKEFILE)
+endef
+
+define process-module
+THIS_MODULE := $(1)
+THIS_MAKEFILE := $(INTERNAL_MAKEFILE_FOR_MODULE_$(1))
+include $$(MAKE_TOP)/this_makefile.mk
+$$(call must-be-nonempty,THIS_MAKEFILE)
+$$(call must-be-nonempty,$(1)_type)
+MODULE_HOST_BUILD := $$(if $(filter host_%,$($(1)_type)),true,)
+include $$(MAKE_TOP)/moduledefs.mk
+include $$(MAKE_TOP)/$$(patsubst host_%,%,$($(1)_type)).mk
+INTERNAL_TARGETS_FOR_$(THIS_MODULE) := $(MODULE_TARGETS)
+endef
+
+# This can be used by module_type.mk files to indicate that they can't be
+# built as host_module_type
+define target-build-only
+$(if $(filter true,$(MODULE_HOST_BUILD)),$(error In makefile $(THIS_MAKEFILE): Module $(THIS_MODULE) attempted to build a host $(1), which is not supported))
+endef
+
+define relative-to-top
+$(patsubst $(TOP)/%,%,$(1))
+endef
+
+define cc-check
+$(shell \
+ CC_CHECK=$(patsubst @%,%,$(CC_CHECK)) && \
+ $(patsubst @%,%,$(CHMOD)) +x $$CC_CHECK && \
+ $$CC_CHECK --cc "$(1)" --out "$(2)" $(3))
+endef
+
+define cc-is-64bit
+$(call cc-check,$(1),$(OUT),--64)
+endef
+
+define cc-option
+$(call cc-check,$(patsubst @%,%,$(CC)),$(OUT),$(1))
+endef
+
+define cxx-option
+$(call cc-check,$(patsubst @%,%,$(CXX)),$(OUT),$(1))
+endef
+
+define host-cc-option
+$(call cc-check,$(patsubst @%,%,$(HOST_CC)),$(OUT),$(1))
+endef
+
+define kernel-cc-option
+$(call cc-check,$(KERNEL_CROSS_COMPILE)gcc,$(OUT),$(1))
+endef
+
+# Turn a particular warning on, or explicitly turn it off, depending on
+# the value of W. The "-W" or "-Wno-" part of the warning need not be
+# specified.
+define cc-optional-warning
+$(call cc-option,-W$(if $(W),,no-)$(patsubst -W%,%,$(patsubst -Wno-%,%,$(1))))
+endef
+
+define host-cc-optional-warning
+$(call host-cc-option,-W$(if $(W),,no-)$(patsubst -W%,%,$(patsubst -Wno-%,%,$(1))))
+endef
+
+define kernel-cc-optional-warning
+$(call kernel-cc-option,-W$(if $(W),,no-)$(patsubst -W%,%,$(patsubst -Wno-%,%,$(1))))
+endef
+
+define module-info-line
+$(if $(filter modules,$(D)),$(info $(1)),)
+endef
diff --git a/pvr-source/eurasiacon/build/linux2/kbuild/Makefile.template b/pvr-source/eurasiacon/build/linux2/kbuild/Makefile.template
new file mode 100644
index 0000000..9d88941
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/kbuild/Makefile.template
@@ -0,0 +1,92 @@
+########################################################################### ###
+#@Title Root kernel makefile
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# This top-level kbuild makefile builds all the Linux kernel modules in the
+# DDK. To run kbuild, this makefile is copied to $(TARGET_OUT)/kbuild/Makefile
+# and make is invoked in $(TARGET_OUT)/kbuild.
+
+# This makefile doesn't define any kbuild special variables apart from
+# ccflags-y and obj-m. The variables for objects are picked up by including
+# the kbuild makefile fragments named in $(INTERNAL_KBUILD_MAKEFILES). The
+# list of objects that these fragments make is collected in
+# $(INTERNAL_KBUILD_OBJECTS) and $(INTERNAL_EXTRA_KBUILD_OBJECTS). These
+# variables are set according to the build's $(KERNEL_COMPONENTS) and
+# $(EXTRA_PVRSRVKM_COMPONENTS). To add a new kernel module to the build, edit
+# these variables in the per-build Makefile.
+
+include $(OUT)/config_kernel.mk
+
+.SECONDARY:
+
+$(OUT)/target/kbuild/external/%.c: $(EXTRA_KBUILD_SOURCE)/%.c
+ @if [ ! -e $(dir $@) ]; then mkdir -p $(dir $@); fi
+ @if [ ! -h $@ ]; then ln -sf $< $@; fi
+
+$(OUT)/target/kbuild/%.c: $(TOP)/%.c
+ @if [ ! -e $(dir $@) ]; then mkdir -p $(dir $@); fi
+ @if [ ! -h $@ ]; then ln -sf $< $@; fi
+
+ccflags-y += -D__linux__ -include $(OUT)/config_kernel.h \
+ -DDEBUG_LOG_PATH_TRUNCATE="\"$(OUT)/target/kbuild\"" \
+ -I$(OUT)/include \
+ -I$(TOP)/include4 \
+ -I$(TOP)/services4/include \
+ -I$(TOP)/services4/system/$(PVR_SYSTEM) \
+ -I$(TOP)/services4/system/include \
+ -I$(TOP)/services4/srvkm/bridged \
+ -I$(TOP)/services4/srvkm/bridged/sgx \
+ -I$(TOP)/services4/srvkm/common \
+ -I$(TOP)/services4/srvkm/devices/sgx \
+ -I$(TOP)/services4/srvkm/env/linux \
+ -I$(TOP)/services4/srvkm/include
+
+ifeq ($(PVR_LOCAL_HWDEFS),)
+ccflags-y += -I$(TOP)/services4/srvkm/hwdefs
+else
+ccflags-y += -I$(TOP)/hwdefs
+endif
+
+include $(INTERNAL_KBUILD_MAKEFILES)
+
+$(if $(pvrsrvkm_sgx$(SGXCORE)_$(SGX_CORE_REV)-y),,$(error pvrsrvkm_sgx$(SGXCORE)_$(SGX_CORE_REV)-y was empty, which could mean that srvkm is missing from $$(KERNEL_COMPONENTS)))
+pvrsrvkm-y += $(foreach _m,$(INTERNAL_EXTRA_KBUILD_OBJECTS:.o=),$($(_m)-y))
+
+obj-m += $(INTERNAL_KBUILD_OBJECTS)
diff --git a/pvr-source/eurasiacon/build/linux2/kbuild/external_tarball.mk b/pvr-source/eurasiacon/build/linux2/kbuild/external_tarball.mk
new file mode 100644
index 0000000..d3aa147
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/kbuild/external_tarball.mk
@@ -0,0 +1,49 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+ifneq ($(EXTERNAL_3PDD_TARBALL),)
+TAR_OPT_STRIP_COMPONENTS ?= --strip-components
+prepare_tree: $(OUT)/target/kbuild/external
+$(OUT)/target/kbuild/external: eurasiacon/external/$(EXTERNAL_3PDD_TARBALL)
+ @echo "Extracting $<.."
+ @mkdir -p $@
+ @tar $(TAR_OPT_STRIP_COMPONENTS) 1 --touch -jxf $< -C $@
+ @touch $(OUT)/target/kbuild/external
+endif
diff --git a/pvr-source/eurasiacon/build/linux2/kbuild/kbuild.mk b/pvr-source/eurasiacon/build/linux2/kbuild/kbuild.mk
new file mode 100644
index 0000000..94e2100
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/kbuild/kbuild.mk
@@ -0,0 +1,91 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+$(if $(strip $(KERNELDIR)),,$(error KERNELDIR must be set))
+$(call directory-must-exist,$(KERNELDIR))
+
+$(TARGET_OUT)/kbuild/Makefile: $(MAKE_TOP)/kbuild/Makefile.template
+ @[ ! -e $(dir $@) ] && mkdir -p $(dir $@) || true
+ $(CP) -f $< $@
+
+# We need to make INTERNAL_KBUILD_MAKEFILES absolute because the files will be
+# read while chdir'd into $(KERNELDIR)
+INTERNAL_KBUILD_MAKEFILES := $(abspath $(foreach _m,$(KERNEL_COMPONENTS) $(EXTRA_PVRSRVKM_COMPONENTS),$(if $(INTERNAL_KBUILD_MAKEFILE_FOR_$(_m)),$(INTERNAL_KBUILD_MAKEFILE_FOR_$(_m)),$(error Unknown kbuild module "$(_m)"))))
+INTERNAL_KBUILD_OBJECTS := $(foreach _m,$(KERNEL_COMPONENTS),$(if $(INTERNAL_KBUILD_OBJECTS_FOR_$(_m)),$(INTERNAL_KBUILD_OBJECTS_FOR_$(_m)),$(error BUG: Unknown kbuild module "$(_m)" should have been caught earlier)))
+INTERNAL_EXTRA_KBUILD_OBJECTS := $(foreach _m,$(EXTRA_PVRSRVKM_COMPONENTS),$(if $(INTERNAL_KBUILD_OBJECTS_FOR_$(_m)),$(INTERNAL_KBUILD_OBJECTS_FOR_$(_m)),$(error BUG: Unknown kbuild module "$(_m)" should have been caught earlier)))
+.PHONY: kbuild kbuild_clean
+
+kbuild: $(TARGET_OUT)/kbuild/Makefile
+ @$(MAKE) -Rr --no-print-directory -C $(KERNELDIR) M=$(abspath $(TARGET_OUT)/kbuild) \
+ INTERNAL_KBUILD_MAKEFILES="$(INTERNAL_KBUILD_MAKEFILES)" \
+ INTERNAL_KBUILD_OBJECTS="$(INTERNAL_KBUILD_OBJECTS)" \
+ INTERNAL_EXTRA_KBUILD_OBJECTS="$(INTERNAL_EXTRA_KBUILD_OBJECTS)" \
+ EXTRA_KBUILD_SOURCE="$(EXTRA_KBUILD_SOURCE)" \
+ CROSS_COMPILE="$(KERNEL_CROSS_COMPILE)" \
+ EXTRA_CFLAGS="$(ALL_KBUILD_CFLAGS)" \
+ V=$(V) W=$(W) \
+ TOP=$(TOP)
+ @for kernel_module in $(addprefix $(TARGET_OUT)/kbuild/,$(INTERNAL_KBUILD_OBJECTS:.o=.ko)); do \
+ cp $$kernel_module $(TARGET_OUT); \
+ done
+
+kbuild_clean: $(TARGET_OUT)/kbuild/Makefile
+ @$(MAKE) -Rr --no-print-directory -C $(KERNELDIR) M=$(abspath $(TARGET_OUT)/kbuild) \
+ INTERNAL_KBUILD_MAKEFILES="$(INTERNAL_KBUILD_MAKEFILES)" \
+ INTERNAL_KBUILD_OBJECTS="$(INTERNAL_KBUILD_OBJECTS)" \
+ INTERNAL_EXTRA_KBUILD_OBJECTS="$(INTERNAL_EXTRA_KBUILD_OBJECTS)" \
+ EXTRA_KBUILD_SOURCE="$(EXTRA_KBUILD_SOURCE)" \
+ CROSS_COMPILE="$(KERNEL_CROSS_COMPILE)" \
+ EXTRA_CFLAGS="$(ALL_KBUILD_CFLAGS)" \
+ V=$(V) W=$(W) \
+ TOP=$(TOP) clean
+
+kbuild_install: $(TARGET_OUT)/kbuild/Makefile
+ @: $(if $(strip $(DISCIMAGE)),,$(error $$(DISCIMAGE) was empty or unset while trying to use it to set INSTALL_MOD_PATH for modules_install))
+ @$(MAKE) -Rr --no-print-directory -C $(KERNELDIR) M=$(abspath $(TARGET_OUT)/kbuild) \
+ INTERNAL_KBUILD_MAKEFILES="$(INTERNAL_KBUILD_MAKEFILES)" \
+ INTERNAL_KBUILD_OBJECTS="$(INTERNAL_KBUILD_OBJECTS)" \
+ INTERNAL_EXTRA_KBUILD_OBJECTS="$(INTERNAL_EXTRA_KBUILD_OBJECTS)" \
+ EXTRA_KBUILD_SOURCE="$(EXTRA_KBUILD_SOURCE)" \
+ CROSS_COMPILE="$(KERNEL_CROSS_COMPILE)" \
+ EXTRA_CFLAGS="$(ALL_KBUILD_CFLAGS)" \
+ INSTALL_MOD_PATH="$(DISCIMAGE)" \
+ V=$(V) W=$(W) \
+ TOP=$(TOP) modules_install
diff --git a/pvr-source/eurasiacon/build/linux2/kernel_module.mk b/pvr-source/eurasiacon/build/linux2/kernel_module.mk
new file mode 100644
index 0000000..a0a1289
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/kernel_module.mk
@@ -0,0 +1,75 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# Rules for making kernel modules with kbuild. This makefile doesn't define
+# any rules that build the modules, it only copies the kbuild Makefile into
+# the right place and then invokes kbuild to do the actual build
+
+$(call target-build-only,kernel module)
+
+MODULE_KBUILD_DIR := $(MODULE_OUT)/kbuild
+
+# $(THIS_MODULE)_makefile names the kbuild makefile fragment used to build
+# this module's objects
+$(call must-be-nonempty,$(THIS_MODULE)_makefile)
+MODULE_KBUILD_MAKEFILE := $($(THIS_MODULE)_makefile)
+$(if $(wildcard $(abspath $(MODULE_KBUILD_MAKEFILE))),,$(error In makefile $(THIS_MAKEFILE): Module $(THIS_MODULE) requires kbuild makefile $(MODULE_KBUILD_MAKEFILE), which is missing))
+
+# $(THIS_MODULE)_target specifies the name of the kernel module
+$(call must-be-nonempty,$(THIS_MODULE)_target)
+MODULE_KBUILD_OBJECTS := $($(THIS_MODULE)_target:.ko=.o)
+
+# Here we could maybe include $(MODULE_KBUILD_MAKEFILE) and look at
+# $(MODULE_KBUILD_OBJECTS)-y to see which source files might be built
+
+.PHONY: $(THIS_MODULE)
+$(THIS_MODULE): MODULE_KBUILD_MAKEFILE := $(MODULE_KBUILD_MAKEFILE)
+$(THIS_MODULE): MODULE_KBUILD_OBJECTS := $(MODULE_KBUILD_OBJECTS)
+$(THIS_MODULE):
+ @echo "kbuild module '$@'"
+ @echo " MODULE_KBUILD_MAKEFILE := $(MODULE_KBUILD_MAKEFILE)"
+ @echo " MODULE_KBUILD_OBJECTS := $(MODULE_KBUILD_OBJECTS)"
+ @echo ' Being built:' $(if $(filter $@,$(KERNEL_COMPONENTS)),"yes (separate module)",$(if $(filter $@,$(EXTRA_PVRSRVKM_COMPONENTS)),"yes (into pvrsrvkm)","no"))
+ @echo "Module $@ is a kbuild module. Run 'make kbuild' to make it"
+ @false
+
+ALL_KBUILD_MODULES += $(THIS_MODULE)
+INTERNAL_KBUILD_MAKEFILE_FOR_$(THIS_MODULE) := $(MODULE_KBUILD_MAKEFILE)
+INTERNAL_KBUILD_OBJECTS_FOR_$(THIS_MODULE) := $(MODULE_KBUILD_OBJECTS)
diff --git a/pvr-source/eurasiacon/build/linux2/kernel_version.mk b/pvr-source/eurasiacon/build/linux2/kernel_version.mk
new file mode 100644
index 0000000..35ecceb
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/kernel_version.mk
@@ -0,0 +1,100 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+$(if $(KERNELDIR),,$(error KERNELDIR must be set to obtain a version))
+
+override KERNEL_VERSION := \
+ $(shell grep "^VERSION = " $(KERNELDIR)/Makefile | cut -f3 -d' ')
+override KERNEL_PATCHLEVEL := \
+ $(shell grep "^PATCHLEVEL = " $(KERNELDIR)/Makefile | cut -f3 -d' ')
+override KERNEL_SUBLEVEL := \
+ $(shell grep "^SUBLEVEL = " $(KERNELDIR)/Makefile | cut -f3 -d' ')
+override KERNEL_EXTRAVERSION := \
+ $(shell grep "^EXTRAVERSION = " $(KERNELDIR)/Makefile | cut -f3 -d' ')
+
+# Break the kernel version up into a space separated list
+kernel_version_as_list := $(KERNEL_VERSION) \
+ $(KERNEL_PATCHLEVEL) \
+ $(KERNEL_SUBLEVEL) \
+ $(patsubst .%,%,$(KERNEL_EXTRAVERSION))
+
+# The base ID doesn't have to be accurate; we only use it for
+# feature checks which will not care about extraversion bits
+#
+override KERNEL_BASE_ID := \
+ $(KERNEL_VERSION).$(KERNEL_PATCHLEVEL).$(KERNEL_SUBLEVEL)
+
+# Try to get the kernel ID from the kernel.release file.
+#
+KERNEL_ID ?= \
+ $(shell cat $(KERNELDIR)/include/config/kernel.release 2>/dev/null)
+
+# If the kernel ID isn't set yet, try to set it from the UTS_RELEASE
+# macro.
+#
+ifeq ($(strip $(KERNEL_ID)),)
+KERNEL_ID := \
+ $(shell grep -h '\#define UTS_RELEASE' \
+ $(KERNELDIR)/include/linux/* | cut -f3 -d' ' | sed s/\"//g)
+endif
+
+ifeq ($(strip $(KERNEL_ID)),)
+KERNEL_ID := \
+ $(KERNEL_VERSION).$(KERNEL_PATCHLEVEL).$(KERNEL_SUBLEVEL)$(KERNEL_EXTRAVERSION)
+endif
+
+# Return 1 if the kernel version is at least the value passed to the
+# function, else return nothing.
+# Examples
+# $(call kernel-version-at-least,2,6,35)
+# $(call kernel-version-at-least,2,6,35,7)
+#
+define kernel-version-at-least
+$(shell set -- $(kernel_version_as_list) 0 0 0 0; \
+ Y=true; \
+ for D in $1 $2 $3 $4; \
+ do \
+ [ $$1 ] || break; \
+ [ $$1 -eq $$D ] && { shift; continue; };\
+ [ $$1 -lt $$D ] && Y=; \
+ break; \
+ done; \
+ echo $$Y)
+endef
diff --git a/pvr-source/eurasiacon/build/linux2/moduledefs.mk b/pvr-source/eurasiacon/build/linux2/moduledefs.mk
new file mode 100644
index 0000000..869026f
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/moduledefs.mk
@@ -0,0 +1,96 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+MODULE_TARGETS :=
+MODULE_CFLAGS := $(ALL_CFLAGS) $($(THIS_MODULE)_cflags)
+MODULE_CXXFLAGS := $(ALL_CXXFLAGS) $($(THIS_MODULE)_cxxflags)
+MODULE_HOST_CFLAGS := $(ALL_HOST_CFLAGS) $($(THIS_MODULE)_cflags)
+MODULE_HOST_CXXFLAGS := $(ALL_HOST_CXXFLAGS) $($(THIS_MODULE)_cxxflags)
+MODULE_LDFLAGS := $(ALL_LDFLAGS) $($(THIS_MODULE)_ldflags)
+MODULE_HOST_LDFLAGS := $(ALL_HOST_LDFLAGS) $($(THIS_MODULE)_ldflags)
+MODULE_BISON_FLAGS := $(ALL_BISON_FLAGS) $($(THIS_MODULE)_bisonflags)
+MODULE_FLEX_FLAGS := $(ALL_FLEX_FLAGS) $($(THIS_MODULE)_flexflags)
+
+# -L flags for library search dirs
+MODULE_LIBRARY_DIR_FLAGS := $(foreach _path,$($(THIS_MODULE)_libpaths),$(if $(filter /%,$(_path)),-L$(call relative-to-top,$(_path)),-L$(_path)))
+# -I flags for header search dirs
+MODULE_INCLUDE_FLAGS := $(foreach _path,$($(THIS_MODULE)_includes),$(if $(filter /%,$(_path)),-I$(call relative-to-top,$(_path)),-I$(_path)))
+
+# Variables used to differentiate between host/target builds
+MODULE_OUT := $(if $(MODULE_HOST_BUILD),$(HOST_OUT),$(TARGET_OUT))
+MODULE_INTERMEDIATES_DIR := $(if $(MODULE_HOST_BUILD),$(HOST_INTERMEDIATES)/$(THIS_MODULE),$(TARGET_INTERMEDIATES)/$(THIS_MODULE))
+
+.SECONDARY: $(MODULE_INTERMEDIATES_DIR)
+$(MODULE_INTERMEDIATES_DIR):
+ $(make-directory)
+
+Host_or_target := $(if $(MODULE_HOST_BUILD),Host,Target)
+
+# These define the rules for finding source files.
+# - If a name begins with a slash, we strip $(TOP) off the front if it begins
+# with $(TOP). This is so that we don't get really long error messages from
+# the compiler if the source tree is in a deeply nested directory, but we
+# still do get absolute paths if you say "make OUT=/tmp/somewhere"
+# - Otherwise, if a name contains a slash and begins with $(OUT), we leave it
+# as it is. This is so you can say "module_src :=
+# $(TARGET_INTERMEDIATES)/something/generated.c"
+# - Otherwise, we assume it's a path referring to somewhere under the
+# directory containing Linux.mk, and add $(THIS_DIR) to it
+_SOURCES_WITHOUT_SLASH := $(strip $(foreach _s,$($(THIS_MODULE)_src),$(if $(findstring /,$(_s)),,$(_s))))
+_SOURCES_WITH_SLASH := $(strip $(foreach _s,$($(THIS_MODULE)_src),$(if $(findstring /,$(_s)),$(_s),)))
+MODULE_SOURCES := $(addprefix $(THIS_DIR)/,$(_SOURCES_WITHOUT_SLASH))
+MODULE_SOURCES += $(call relative-to-top,$(filter /%,$(_SOURCES_WITH_SLASH)))
+_RELATIVE_SOURCES_WITH_SLASH := $(filter-out /%,$(_SOURCES_WITH_SLASH))
+_OUTDIR_RELATIVE_SOURCES_WITH_SLASH := $(filter $(RELATIVE_OUT)/%,$(_RELATIVE_SOURCES_WITH_SLASH))
+_THISDIR_RELATIVE_SOURCES_WITH_SLASH := $(filter-out $(RELATIVE_OUT)/%,$(_RELATIVE_SOURCES_WITH_SLASH))
+MODULE_SOURCES += $(_OUTDIR_RELATIVE_SOURCES_WITH_SLASH)
+MODULE_SOURCES += $(addprefix $(THIS_DIR)/,$(_THISDIR_RELATIVE_SOURCES_WITH_SLASH))
+MODULE_SOURCES += $(addprefix $(MODULE_OUT)/intermediates/,$($(THIS_MODULE)_gensrc))
+MODULE_GENERATED_HEADERS := $(addprefix $(MODULE_OUT)/intermediates/,$($(THIS_MODULE)_genheaders))
+
+# -l flags for each library
+MODULE_LIBRARY_FLAGS := $(addprefix -l, $($(THIS_MODULE)_staticlibs)) $(addprefix -l,$($(THIS_MODULE)_libs)) $(foreach _lib,$($(THIS_MODULE)_extlibs),$(if $(filter undefined,$(origin lib$(_lib)_ldflags)),-l$(_lib),$(lib$(_lib)_ldflags)))
+
+# pkg-config integration; primarily used by X.org
+# FIXME: We don't support arbitrary CFLAGS yet (just includes)
+$(foreach _package,$($(THIS_MODULE)_packages),\
+ $(eval MODULE_INCLUDE_FLAGS += `pkg-config --cflags-only-I $(_package)`)\
+ $(eval MODULE_LIBRARY_FLAGS += `pkg-config --libs-only-l $(_package)`)\
+ $(eval MODULE_LIBRARY_DIR_FLAGS += `pkg-config --libs-only-L $(_package)`))
diff --git a/pvr-source/eurasiacon/build/linux2/modules.mk b/pvr-source/eurasiacon/build/linux2/modules.mk
new file mode 100644
index 0000000..1576590
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/modules.mk
@@ -0,0 +1,49 @@
+########################################################################### ###
+#@Title Module processing
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# Bits for processing $(modules) after reading in each Linux.mk
+
+#$(info ---- $(modules) ----)
+$(call must-be-nonempty,modules)
+
+$(foreach _m,$(modules),$(if $(filter $(_m),$(ALL_MODULES)),$(error In makefile $(THIS_MAKEFILE): Duplicate module $(_m) (first seen in $(INTERNAL_MAKEFILE_FOR_MODULE_$(_m))) listed in $$(modules)),$(eval $(call register-module,$(_m)))))
+
+ALL_MODULES += $(modules)
diff --git a/pvr-source/eurasiacon/build/linux2/omap4430_android/Makefile b/pvr-source/eurasiacon/build/linux2/omap4430_android/Makefile
new file mode 100644
index 0000000..b034ea0
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/omap4430_android/Makefile
@@ -0,0 +1,185 @@
+########################################################################### ###
+#@Title Root makefile for omap4430 Android. Builds everything else.
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+ifeq ($(TARGET_SGX),544sc)
+ SGXCORE := 544
+ SGX_CORE_REV := 112
+else ifeq ($(TARGET_SGX),540)
+ SGXCORE := 540
+ SGX_CORE_REV := 120
+else ifeq ($(TARGET_SGX),544)
+ SGXCORE := 544
+ SGX_CORE_REV := 105
+ HAL_VARIANT := omap5
+ SGX_FEATURE_MP := 1
+ SGX_FEATURE_SYSTEM_CACHE := 1
+ SGX_FEATURE_MP_CORE_COUNT := 2
+else
+ #default config
+ SGXCORE := 540
+ SGX_CORE_REV := 120
+endif
+export SGXCORE
+export SGX_CORE_REV
+
+SGX_DYNAMIC_TIMING_INFO := 1
+
+SUPPORT_LINUX_USING_WORKQUEUES := 1
+
+DISPLAY_CONTROLLER := omaplfb
+
+PVR_SYSTEM := omap4
+HAL_VARIANT := $(PVR_SYSTEM)
+
+# We have more memory on OMAP platforms, so we can spare to make the
+# pool larger, and have higher resolutions which benefit from it.
+#
+PVR_LINUX_MEM_AREA_POOL_MAX_PAGES ?= 10800
+
+include ../common/android/paths.mk
+include ../common/android/armv7-a.mk
+include ../common/android/features.mk
+
+ifneq ($(strip $(KERNELDIR)),)
+ include ../kernel_version.mk
+ ifeq ($(call kernel-version-at-least,2,6,35),true)
+ PVR_NO_OMAP_TIMER := 1
+ endif
+ ifeq ($(call kernel-version-at-least,2,6,39),true)
+ ifeq ($(LDM_PLATFORM),1)
+ PVR_LDM_PLATFORM_PRE_REGISTERED := 1
+ PVR_LDM_PLATFORM_PRE_REGISTERED_DEV := "\"pvrsrvkm\""
+ endif
+ endif
+ ifeq ($(is_at_least_icecream_sandwich),1)
+ ifeq ($(call kernel-version-at-least,3,0),true)
+ SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED := 1
+ PVR_ANDROID_NEEDS_ACCUM_SYNC_WORKAROUND := 1
+ SYS_OMAP4_HAS_DVFS_FRAMEWORK := 1
+ endif
+ endif
+else
+ ifeq ($(is_at_least_icecream_sandwich),1)
+ $(warning "KERNELDIR is not set, so can't feature check DVFS or dsscomp.")
+ $(warning "Assuming we want DVFS and dsscomp support.")
+ SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED := 1
+ PVR_ANDROID_NEEDS_ACCUM_SYNC_WORKAROUND := 1
+ SYS_OMAP4_HAS_DVFS_FRAMEWORK := 1
+ endif
+endif
+
+ifneq ($(LDM_PLATFORM),1)
+SUPPORT_LINUX_USING_WORKQUEUES := 0
+SUPPORT_LINUX_USING_SHARED_WORKQUEUES := 1
+SUPPORT_ACTIVE_POWER_MANAGEMENT := 0
+DISPLAY_CONTROLLER := pvrlfb
+DISPLAY_CONTROLLER_COMPONENT := linux_framebuffer
+OMAP_NON_FLIP_DISPLAY := 1
+
+# The code for the omaplfb component is now hosted on a
+# different repository. No need to compile this now
+#
+# DISPLAY_CONTROLLER_COMPONENT := dc_omapfb3_linux
+
+endif
+
+ifeq ($(SUPPORT_DRI_DRM),1)
+ifeq ($(PVR_LDM_PLATFORM_PRE_REGISTERED),1)
+PVR_DRI_DRM_PLATFORM_DEV := 1
+PVR_DRI_DRM_STATIC_BUS_ID := 1
+PVR_DRI_DRM_DEV_BUS_ID := "\"platform:pvrsrvkm"\"
+else
+PVR_DRI_DRM_NOT_PCI := 1
+KERNEL_COMPONENTS += linux_drm
+endif
+EXTRA_PVRSRVKM_COMPONENTS += $(DISPLAY_CONTROLLER_COMPONENT)
+EXTRA_KBUILD_SOURCE := $(KERNELDIR)
+# FIXME: Only required for comparison with X's KM
+PVR_SECURE_DRM_AUTH_EXPORT := 1
+ifneq ($(OMAP_NON_FLIP_DISPLAY),1)
+PVR_DISPLAY_CONTROLLER_DRM_IOCTL := 1
+endif
+else
+KERNEL_COMPONENTS += $(DISPLAY_CONTROLLER_COMPONENT)
+endif
+
+SUPPORT_ANDROID_OMAP_NV12 := 1
+
+ifeq ($(is_at_least_icecream_sandwich),1)
+ifeq ($(SUPPORT_ANDROID_COMPOSER_HAL),1)
+PVR_ANDROID_USE_WINDOW_TRANSFORM_HINT := 1
+endif
+endif
+
+PVR_ANDROID_PLATFORM_HAS_LINUX_FBDEV := 1
+
+# FIXME: Remove this once vsync issues are resolved
+PVR_ANDROID_COMPOSITOR_WAIT_FOR_RENDER := 1
+
+ifeq ($(is_at_least_icecream_sandwich),1)
+-include products.mk
+endif
+
+ifeq ($(NO_HARDWARE),1)
+ifeq ($(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED),1)
+$(info WARNING: SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED=1 is incompatible with NO_HARDWARE=1)
+$(info WARNING: Setting SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED=0 and switching to dc_nohw)
+override SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED := 0
+override DISPLAY_CONTROLLER := dcnohw
+KERNEL_COMPONENTS += dc_nohw
+endif
+endif
+
+include ../config/core.mk
+include ../common/android/extra_config.mk
+include ../common/dridrm.mk
+include ../common/opencl.mk
+include ../common/omap4.mk
+
+# Not all OMAP4 kernels have a compatible DVFS framework
+#
+$(eval $(call TunableKernelConfigC,SYS_OMAP4_HAS_DVFS_FRAMEWORK,))
+
+# If set, services allows two flips to enter the processing queue,
+# and does not add read dependencies to the set of buffers last
+# flipped to. This is necessary for DSS composition on OMAP4.
+#
+$(eval $(call TunableKernelConfigC,SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED,))
diff --git a/pvr-source/eurasiacon/build/linux2/omap4430_android/products.mk b/pvr-source/eurasiacon/build/linux2/omap4430_android/products.mk
new file mode 100644
index 0000000..53073a9
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/omap4430_android/products.mk
@@ -0,0 +1,46 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+PVRSRV_USSE_EDM_STATUS_DEBUG ?= 1
+SGX_DISABLE_VISTEST_SUPPORT ?= 1
+PVRSRV_DUMP_MK_TRACE ?= 1
+PVRSRV_NEED_PVR_DPF ?= 1
+PVRSRV_NEED_PVR_TRACE ?= 1
+PVRSRV_NEED_PVR_ASSERT ?= 1
diff --git a/pvr-source/eurasiacon/build/linux2/prepare_tree.mk b/pvr-source/eurasiacon/build/linux2/prepare_tree.mk
new file mode 100644
index 0000000..05e4fe3
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/prepare_tree.mk
@@ -0,0 +1,60 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+.PHONY: prepare_tree
+
+-include eurasiacon/build/linux2/kbuild/external_tarball.mk
+
+# If there's no external tarball, there's nothing to do
+#
+prepare_tree:
+
+INTERNAL_INCLUDED_PREPARE_HEADERS :=
+-include eurasiacon/build/linux2/prepare_headers.mk
+ifneq ($(INTERNAL_INCLUDED_PREPARE_HEADERS),true)
+missing_headers := $(strip $(shell test ! -e include4/pvrversion.h && echo true))
+ifdef missing_headers
+$(info )
+$(info ** include4/pvrversion.h is missing, and cannot be rebuilt.)
+$(info ** Cannot continue.)
+$(info )
+$(error Missing headers)
+endif
+endif
diff --git a/pvr-source/eurasiacon/build/linux2/this_makefile.mk b/pvr-source/eurasiacon/build/linux2/this_makefile.mk
new file mode 100644
index 0000000..c312001
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/this_makefile.mk
@@ -0,0 +1,68 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# Find out the path of the Linux.mk makefile currently being processed, and
+# set paths used by the build rules
+
+# This magic is used so we can use this_makefile.mk twice: first when reading
+# in each Linux.mk, and then again when generating rules. There we set
+# $(THIS_MAKEFILE), and $(REMAINING_MAKEFILES) should be empty
+ifneq ($(strip $(REMAINING_MAKEFILES)),)
+
+# Absolute path to the Linux.mk being processed
+THIS_MAKEFILE := $(firstword $(REMAINING_MAKEFILES))
+
+# The list of makefiles left to process
+REMAINING_MAKEFILES := $(wordlist 2,$(words $(REMAINING_MAKEFILES)),$(REMAINING_MAKEFILES))
+
+else
+
+# When generating rules, we should have read in every Linux.mk
+$(if $(INTERNAL_INCLUDED_ALL_MAKEFILES),,$(error No makefiles left in $$(REMAINING_MAKEFILES), but $$(INTERNAL_INCLUDED_ALL_MAKEFILES) is not set))
+
+endif
+
+# Path to the directory containing Linux.mk
+THIS_DIR := $(patsubst %/,%,$(dir $(THIS_MAKEFILE)))
+ifeq ($(strip $(THIS_DIR)),)
+$(error Empty $$(THIS_DIR) for makefile "$(THIS_MAKEFILE)")
+endif
+
+modules :=
diff --git a/pvr-source/eurasiacon/build/linux2/tools/cc-check.sh b/pvr-source/eurasiacon/build/linux2/tools/cc-check.sh
new file mode 100755
index 0000000..6cef8fa
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/tools/cc-check.sh
@@ -0,0 +1,99 @@
+#!/bin/sh
+########################################################################### ###
+#@Title Test the nature of the C compiler.
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+LANG=C
+export LANG
+
+usage() {
+ echo "usage: $0 [--64] --cc CC --out OUT [cflag]"
+ exit 1
+}
+
+# NOTE: The program passed to the compiler is deliberately incorrect
+# (`return;' should be `return 0;') but we do this to emit a warning.
+#
+# Emitting a warning is necessary to get GCC to print out additional
+# warnings about any unsupported -Wno options, so we can handle these
+# as unsupported by the build.
+#
+do_cc() {
+ echo "int main(void){return;}" | $CC -W -Wall $3 -xc -c - -o $1 >$2 2>&1
+}
+
+while [ 1 ]; do
+ if [ "$1" = "--64" ]; then
+ BIT_CHECK=1
+ elif [ "$1" = "--cc" ]; then
+ [ "x$2" = "x" ] && usage
+ CC="$2" && shift
+ elif [ "$1" = "--out" ]; then
+ [ "x$2" = "x" ] && usage
+ OUT="$2" && shift
+ elif [ "${1#--}" != "$1" ]; then
+ usage
+ else
+ break
+ fi
+ shift
+done
+
+[ "x$CC" = "x" ] && usage
+[ "x$OUT" = "x" ] && usage
+ccof=$OUT/cc-sanity-check
+log=${ccof}.log
+
+if [ "x$BIT_CHECK" = "x1" ]; then
+ do_cc $ccof $log ""
+ file $ccof | grep 64-bit >/dev/null 2>&1
+ [ "$?" = "0" ] && echo true || echo false
+else
+ [ "x$1" = "x" ] && usage
+ do_cc $ccof $log $1
+ if [ "$?" = "0" ]; then
+ # compile passed, but was the warning unrecognized?
+ grep -q "^cc1: warning: unrecognized command line option \"$1\"" $log
+ [ "$?" = "1" ] && echo $1
+ fi
+fi
+
+rm -f $ccof $log
+exit 0
diff --git a/pvr-source/eurasiacon/build/linux2/toplevel.mk b/pvr-source/eurasiacon/build/linux2/toplevel.mk
new file mode 100644
index 0000000..26b1198
--- /dev/null
+++ b/pvr-source/eurasiacon/build/linux2/toplevel.mk
@@ -0,0 +1,226 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+# Define the default goal. This masks a previous definition of the default
+# goal in Makefile.config, which must match this one
+.PHONY: build
+build: components kbuild
+
+ifeq ($(OUT),)
+$(error "Must specify output directory with OUT=")
+endif
+
+ifeq ($(TOP),)
+$(error "Must specify root of source tree with TOP=")
+endif
+$(call directory-must-exist,$(TOP))
+
+# Output directory for configuration, object code,
+# final programs/libraries, and install/rc scripts.
+#
+
+# RELATIVE_OUT is relative only if it's under $(TOP)
+RELATIVE_OUT := $(patsubst $(TOP)/%,%,$(OUT))
+HOST_OUT := $(RELATIVE_OUT)/host
+TARGET_OUT := $(RELATIVE_OUT)/target
+CONFIG_MK := $(RELATIVE_OUT)/config.mk
+CONFIG_H := $(RELATIVE_OUT)/config.h
+CONFIG_KERNEL_MK := $(RELATIVE_OUT)/config_kernel.mk
+CONFIG_KERNEL_H := $(RELATIVE_OUT)/config_kernel.h
+MAKE_TOP := eurasiacon/build/linux2
+THIS_MAKEFILE := (top-level makefiles)
+
+# Convert commas to spaces in $(D). This is so you can say "make
+# D=config-changes,freeze-config" and have $(filter config-changes,$(D))
+# still work.
+comma := ,
+empty :=
+space := $(empty) $(empty)
+override D := $(subst $(comma),$(space),$(D))
+
+include $(MAKE_TOP)/defs.mk
+
+ifneq ($(INTERNAL_CLOBBER_ONLY),true)
+# Create the out directory
+#
+$(shell mkdir -p $(OUT))
+
+# Provide rules to create $(HOST_OUT) and $(TARGET_OUT)
+.SECONDARY: $(HOST_OUT) $(TARGET_OUT)
+$(HOST_OUT) $(TARGET_OUT):
+ $(make-directory)
+
+# If these generated files differ from any pre-existing ones,
+# replace them, causing affected parts of the driver to rebuild.
+#
+_want_config_diff := $(filter config-changes,$(D))
+_freeze_config := $(strip $(filter freeze-config,$(D)))
+_updated_config_files := $(shell \
+ $(if $(_want_config_diff),rm -f $(OUT)/config.diff;,) \
+ for file in $(CONFIG_MK) $(CONFIG_H) \
+ $(CONFIG_KERNEL_MK) $(CONFIG_KERNEL_H); do \
+ diff -U 0 $$file $$file.new \
+ >>$(if $(_want_config_diff),$(OUT)/config.diff,/dev/null) 2>/dev/null \
+ && rm -f $$file.new \
+ || echo $$file; \
+ done)
+
+ifneq ($(_want_config_diff),)
+# We send the diff to stderr so it isn't captured by $(shell)
+$(shell [ -s $(OUT)/config.diff ] && echo >&2 "Configuration changed in $(RELATIVE_OUT):" && cat >&2 $(OUT)/config.diff)
+endif
+
+ifneq ($(_freeze_config),)
+$(if $(_updated_config_files),$(error Configuration change in $(RELATIVE_OUT) prevented by D=freeze-config),)
+endif
+
+# Update the config, if changed
+$(foreach _f,$(_updated_config_files), \
+ $(shell mv -f $(_f).new $(_f) >/dev/null 2>/dev/null))
+
+endif # INTERNAL_CLOBBER_ONLY
+
+MAKEFLAGS := -Rr --no-print-directory
+
+ifneq ($(INTERNAL_CLOBBER_ONLY),true)
+
+# This is so you can say "find $(TOP) -name Linux.mk > /tmp/something; export
+# ALL_MAKEFILES=/tmp/something; make" and avoid having to run find. This is
+# handy if your source tree is mounted over NFS or something
+override ALL_MAKEFILES := $(call relative-to-top,$(if $(strip $(ALL_MAKEFILES)),$(shell cat $(ALL_MAKEFILES)),$(shell find $(TOP) -type f -name Linux.mk -print -o -type d -name '.*' -prune)))
+ifeq ($(strip $(ALL_MAKEFILES)),)
+$(info ** Unable to find any Linux.mk files under $$(TOP). This could mean that)
+$(info ** there are no makefiles, or that ALL_MAKEFILES is set in the environment)
+$(info ** and points to a nonexistent or empty file.)
+$(error No makefiles)
+endif
+
+else # clobber-only
+ALL_MAKEFILES :=
+endif
+
+unexport ALL_MAKEFILES
+
+REMAINING_MAKEFILES := $(ALL_MAKEFILES)
+ALL_MODULES :=
+INTERNAL_INCLUDED_ALL_MAKEFILES :=
+
+ifneq ($(INTERNAL_CLOBBER_ONLY),true)
+# Please do not change the format of the following lines
+-include $(CONFIG_KERNEL_MK)
+# These files may not exist in GPL km source packages
+-include $(MAKE_TOP)/xorgconf.mk
+-include $(MAKE_TOP)/llvm.mk
+endif
+
+include $(MAKE_TOP)/commands.mk
+include $(MAKE_TOP)/buildvars.mk
+
+HOST_INTERMEDIATES := $(HOST_OUT)/intermediates
+TARGET_INTERMEDIATES := $(TARGET_OUT)/intermediates
+
+# Include each Linux.mk, then include modules.mk to save some information
+# about each module
+include $(foreach _Linux.mk,$(ALL_MAKEFILES),$(MAKE_TOP)/this_makefile.mk $(_Linux.mk) $(MAKE_TOP)/modules.mk)
+
+ifeq ($(strip $(REMAINING_MAKEFILES)),)
+INTERNAL_INCLUDED_ALL_MAKEFILES := true
+else
+$(error Impossible: $(words $(REMAINING_MAKEFILES)) makefiles were mysteriously ignored when reading $$(ALL_MAKEFILES))
+endif
+
+# At this point, all Linux.mks have been included. Now generate rules to build
+# each module: for each module in $(ALL_MODULES), set per-makefile variables
+$(foreach _m,$(ALL_MODULES),$(eval $(call process-module,$(_m))))
+
+.PHONY: kbuild install
+kbuild install:
+
+ifneq ($(INTERNAL_CLOBBER_ONLY),true)
+-include $(MAKE_TOP)/scripts.mk
+-include $(MAKE_TOP)/kbuild/kbuild.mk
+else
+# We won't depend on 'build' here so that people can build subsets of
+# components and still have the install script attempt to install the
+# subset.
+install:
+ @if [ ! -d "$(DISCIMAGE)" ]; then \
+ echo; \
+ echo "** DISCIMAGE was not set or does not point to a valid directory."; \
+ echo "** Cannot continue with install."; \
+ echo; \
+ exit 1; \
+ fi
+ @if [ ! -f $(TARGET_OUT)/install.sh ]; then \
+ echo; \
+ echo "** install.sh not found in $(TARGET_OUT)."; \
+ echo "** Cannot continue with install."; \
+ echo; \
+ exit 1; \
+ fi
+ @cd $(TARGET_OUT) && ./install.sh
+endif
+
+# You can say 'make all_modules' to attempt to make everything, or 'make
+# components' to only make the things which are listed (in the per-build
+# makefiles) as components of the build.
+.PHONY: all_modules components
+all_modules: $(ALL_MODULES)
+components: $(COMPONENTS)
+
+# Cleaning
+.PHONY: clean clobber
+clean: MODULE_DIRS_TO_REMOVE := $(OUT)/host/intermediates $(OUT)/target/intermediates $(OUT)/target/kbuild
+clean:
+ $(clean-dirs)
+clobber: MODULE_DIRS_TO_REMOVE := $(OUT)
+clobber:
+ $(clean-dirs)
+
+# Saying 'make clean-MODULE' removes the intermediates for MODULE.
+# clobber-MODULE deletes the output files as well
+clean-%:
+ $(if $(V),,@echo " RM " $(call relative-to-top,$(OUT)/host/intermediates/$* $(OUT)/target/intermediates/$*))
+ $(RM) -rf $(OUT)/host/intermediates/$*/* $(OUT)/target/intermediates/$*/*
+clobber-%:
+ $(if $(V),,@echo " RM " $(call relative-to-top,$(OUT)/host/intermediates/$* $(OUT)/target/intermediates/$* $(INTERNAL_TARGETS_FOR_$*)))
+ $(RM) -rf $(OUT)/host/intermediates/$* $(OUT)/target/intermediates/$* $(INTERNAL_TARGETS_FOR_$*)
+
+include $(MAKE_TOP)/bits.mk
diff --git a/pvr-source/include4/dbgdrvif.h b/pvr-source/include4/dbgdrvif.h
new file mode 100644
index 0000000..753f8f2
--- /dev/null
+++ b/pvr-source/include4/dbgdrvif.h
@@ -0,0 +1,381 @@
+/*************************************************************************/ /*!
+@Title Debug driver
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Debug Driver Interface
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _DBGDRVIF_
+#define _DBGDRVIF_
+
+
+#if defined(__linux__)
+
+#define FILE_DEVICE_UNKNOWN 0
+#define METHOD_BUFFERED 0
+#define FILE_ANY_ACCESS 0
+
+#define CTL_CODE( DeviceType, Function, Method, Access ) (Function)
+#define MAKEIOCTLINDEX(i) ((i) & 0xFFF)
+
+#else
+
+#include "ioctldef.h"
+
+#endif
+
+/*****************************************************************************
+ Stream mode stuff.
+*****************************************************************************/
+#define DEBUG_CAPMODE_FRAMED 0x00000001UL
+#define DEBUG_CAPMODE_CONTINUOUS 0x00000002UL
+#define DEBUG_CAPMODE_HOTKEY 0x00000004UL
+
+#define DEBUG_OUTMODE_STANDARDDBG 0x00000001UL
+#define DEBUG_OUTMODE_MONO 0x00000002UL
+#define DEBUG_OUTMODE_STREAMENABLE 0x00000004UL
+#define DEBUG_OUTMODE_ASYNC 0x00000008UL
+#define DEBUG_OUTMODE_SGXVGA 0x00000010UL
+
+#define DEBUG_FLAGS_USE_NONPAGED_MEM 0x00000001UL
+#define DEBUG_FLAGS_NO_BUF_EXPANDSION 0x00000002UL
+#define DEBUG_FLAGS_ENABLESAMPLE 0x00000004UL
+#define DEBUG_FLAGS_READONLY 0x00000008UL
+#define DEBUG_FLAGS_WRITEONLY 0x00000010UL
+
+#define DEBUG_FLAGS_TEXTSTREAM 0x80000000UL
+
+/*****************************************************************************
+ Debug level control. Only bothered with the first 12 levels, I suspect you
+ get the idea...
+*****************************************************************************/
+#define DEBUG_LEVEL_0 0x00000001UL
+#define DEBUG_LEVEL_1 0x00000003UL
+#define DEBUG_LEVEL_2 0x00000007UL
+#define DEBUG_LEVEL_3 0x0000000FUL
+#define DEBUG_LEVEL_4 0x0000001FUL
+#define DEBUG_LEVEL_5 0x0000003FUL
+#define DEBUG_LEVEL_6 0x0000007FUL
+#define DEBUG_LEVEL_7 0x000000FFUL
+#define DEBUG_LEVEL_8 0x000001FFUL
+#define DEBUG_LEVEL_9 0x000003FFUL
+#define DEBUG_LEVEL_10 0x000007FFUL
+#define DEBUG_LEVEL_11 0x00000FFFUL
+
+#define DEBUG_LEVEL_SEL0 0x00000001UL
+#define DEBUG_LEVEL_SEL1 0x00000002UL
+#define DEBUG_LEVEL_SEL2 0x00000004UL
+#define DEBUG_LEVEL_SEL3 0x00000008UL
+#define DEBUG_LEVEL_SEL4 0x00000010UL
+#define DEBUG_LEVEL_SEL5 0x00000020UL
+#define DEBUG_LEVEL_SEL6 0x00000040UL
+#define DEBUG_LEVEL_SEL7 0x00000080UL
+#define DEBUG_LEVEL_SEL8 0x00000100UL
+#define DEBUG_LEVEL_SEL9 0x00000200UL
+#define DEBUG_LEVEL_SEL10 0x00000400UL
+#define DEBUG_LEVEL_SEL11 0x00000800UL
+
+/*****************************************************************************
+ IOCTL values.
+*****************************************************************************/
+#define DEBUG_SERVICE_IOCTL_BASE 0x800UL
+#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)
+#define DEBUG_SERVICE_SETCONNNOTIFY CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x19, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+
+typedef enum _DBG_EVENT_
+{
+ DBG_EVENT_STREAM_DATA = 1
+} DBG_EVENT;
+
+
+/*****************************************************************************
+ In/Out Structures
+*****************************************************************************/
+typedef struct _DBG_IN_CREATESTREAM_
+{
+ union
+ {
+ IMG_CHAR *pszName;
+ IMG_UINT64 ui64Name;
+ } u;
+ IMG_UINT32 ui32Pages;
+ IMG_UINT32 ui32CapMode;
+ IMG_UINT32 ui32OutMode;
+}DBG_IN_CREATESTREAM, *PDBG_IN_CREATESTREAM;
+
+typedef struct _DBG_IN_FINDSTREAM_
+{
+ union
+ {
+ IMG_CHAR *pszName;
+ IMG_UINT64 ui64Name;
+ }u;
+ IMG_BOOL bResetStream;
+}DBG_IN_FINDSTREAM, *PDBG_IN_FINDSTREAM;
+
+typedef struct _DBG_IN_WRITESTRING_
+{
+ union
+ {
+ IMG_CHAR *pszString;
+ IMG_UINT64 ui64String;
+ } u;
+ IMG_SID hStream;
+ IMG_UINT32 ui32Level;
+}DBG_IN_WRITESTRING, *PDBG_IN_WRITESTRING;
+
+typedef struct _DBG_IN_READSTRING_
+{
+ union
+ {
+ IMG_CHAR *pszString;
+ IMG_UINT64 ui64String;
+ } u;
+ IMG_SID hStream;
+ IMG_UINT32 ui32StringLen;
+} DBG_IN_READSTRING, *PDBG_IN_READSTRING;
+
+typedef struct _DBG_IN_SETDEBUGMODE_
+{
+ IMG_SID hStream;
+ IMG_UINT32 ui32Mode;
+ IMG_UINT32 ui32Start;
+ IMG_UINT32 ui32End;
+ IMG_UINT32 ui32SampleRate;
+} DBG_IN_SETDEBUGMODE, *PDBG_IN_SETDEBUGMODE;
+
+typedef struct _DBG_IN_SETDEBUGOUTMODE_
+{
+ IMG_SID hStream;
+ IMG_UINT32 ui32Mode;
+} DBG_IN_SETDEBUGOUTMODE, *PDBG_IN_SETDEBUGOUTMODE;
+
+typedef struct _DBG_IN_SETDEBUGLEVEL_
+{
+ IMG_SID hStream;
+ IMG_UINT32 ui32Level;
+} DBG_IN_SETDEBUGLEVEL, *PDBG_IN_SETDEBUGLEVEL;
+
+typedef struct _DBG_IN_SETFRAME_
+{
+ IMG_SID hStream;
+ IMG_UINT32 ui32Frame;
+} DBG_IN_SETFRAME, *PDBG_IN_SETFRAME;
+
+typedef struct _DBG_IN_WRITE_
+{
+ union
+ {
+ IMG_UINT8 *pui8InBuffer;
+ IMG_UINT64 ui64InBuffer;
+ } u;
+ IMG_SID hStream;
+ IMG_UINT32 ui32Level;
+ IMG_UINT32 ui32TransferSize;
+} DBG_IN_WRITE, *PDBG_IN_WRITE;
+
+typedef struct _DBG_IN_READ_
+{
+ union
+ {
+ IMG_UINT8 *pui8OutBuffer;
+ IMG_UINT64 ui64OutBuffer;
+ } u;
+ IMG_SID hStream;
+ IMG_BOOL bReadInitBuffer;
+ IMG_UINT32 ui32OutBufferSize;
+} DBG_IN_READ, *PDBG_IN_READ;
+
+typedef struct _DBG_IN_OVERRIDEMODE_
+{
+ IMG_SID hStream;
+ IMG_UINT32 ui32Mode;
+} DBG_IN_OVERRIDEMODE, *PDBG_IN_OVERRIDEMODE;
+
+typedef struct _DBG_IN_ISCAPTUREFRAME_
+{
+ IMG_SID hStream;
+ IMG_BOOL bCheckPreviousFrame;
+} DBG_IN_ISCAPTUREFRAME, *PDBG_IN_ISCAPTUREFRAME;
+
+typedef struct _DBG_IN_SETMARKER_
+{
+ IMG_SID hStream;
+ IMG_UINT32 ui32Marker;
+} DBG_IN_SETMARKER, *PDBG_IN_SETMARKER;
+
+typedef struct _DBG_IN_WRITE_LF_
+{
+ union
+ {
+ IMG_UINT8 *pui8InBuffer;
+ IMG_UINT64 ui64InBuffer;
+ } u;
+ IMG_UINT32 ui32Flags;
+ IMG_SID hStream;
+ IMG_UINT32 ui32Level;
+ IMG_UINT32 ui32BufferSize;
+} DBG_IN_WRITE_LF, *PDBG_IN_WRITE_LF;
+
+/*
+ Flags for above struct
+*/
+#define WRITELF_FLAGS_RESETBUF 0x00000001UL
+
+/*
+ Common control structure (don't duplicate control in main stream
+ and init phase stream).
+*/
+typedef struct _DBG_STREAM_CONTROL_
+{
+ IMG_BOOL bInitPhaseComplete; /*!< init phase has finished */
+ IMG_UINT32 ui32Flags; /*!< flags (see DEBUG_FLAGS above) */
+
+ IMG_UINT32 ui32CapMode; /*!< capturing mode framed/hot key */
+ IMG_UINT32 ui32OutMode; /*!< output mode, e.g. files */
+ IMG_UINT32 ui32DebugLevel;
+ IMG_UINT32 ui32DefaultMode;
+ IMG_UINT32 ui32Start; /*!< first capture frame */
+ IMG_UINT32 ui32End; /*!< last frame */
+ IMG_UINT32 ui32Current; /*!< current frame */
+ IMG_UINT32 ui32SampleRate; /*!< capture frequency */
+ IMG_UINT32 ui32Reserved;
+} DBG_STREAM_CONTROL, *PDBG_STREAM_CONTROL;
+/*
+ Per-buffer control structure.
+*/
+typedef struct _DBG_STREAM_
+{
+ struct _DBG_STREAM_ *psNext;
+ struct _DBG_STREAM_ *psInitStream;
+ DBG_STREAM_CONTROL *psCtrl;
+ IMG_BOOL bCircularAllowed;
+ IMG_PVOID pvBase;
+ IMG_UINT32 ui32Size;
+ IMG_UINT32 ui32RPtr;
+ IMG_UINT32 ui32WPtr;
+ IMG_UINT32 ui32DataWritten;
+ IMG_UINT32 ui32Marker; /*!< marker for file splitting */
+ IMG_UINT32 ui32InitPhaseWOff; /*!< snapshot offset for init phase end for follow-on pdump */
+ IMG_CHAR szName[30]; /* Give this a size, some compilers don't like [] */
+} DBG_STREAM,*PDBG_STREAM;
+
+/*
+ * Allows dbgdrv to notify services when events happen, e.g. pdump.exe starts.
+ * (better than resetting psDevInfo->psKernelCCBInfo->ui32CCBDumpWOff = 0
+ * in SGXGetClientInfoKM.)
+ */
+typedef struct _DBGKM_CONNECT_NOTIFIER_
+{
+ IMG_VOID (IMG_CALLCONV *pfnConnectNotifier) (IMG_VOID);
+} DBGKM_CONNECT_NOTIFIER, *PDBGKM_CONNECT_NOTIFIER;
+
+/*****************************************************************************
+ Kernel mode service table
+*****************************************************************************/
+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_BOOL (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_BOOL (IMG_CALLCONV *pfnIsLastCaptureFrame) (PDBG_STREAM psStream);
+ IMG_VOID (IMG_CALLCONV *pfnWaitForEvent) (DBG_EVENT eEvent);
+ IMG_VOID (IMG_CALLCONV *pfnSetConnectNotifier) (DBGKM_CONNECT_NOTIFIER fn_notifier);
+ IMG_UINT32 (IMG_CALLCONV *pfnWritePersist) (PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+} DBGKM_SERVICE_TABLE, *PDBGKM_SERVICE_TABLE;
+
+#if defined(__linux__)
+/*****************************************************************************
+ Function to export service table from debug driver to the PDUMP component.
+*****************************************************************************/
+IMG_VOID DBGDrvGetServiceTable(DBGKM_SERVICE_TABLE **fn_table);
+#endif
+
+
+#endif
+/*****************************************************************************
+ End of file (DBGDRVIF.H)
+*****************************************************************************/
diff --git a/pvr-source/include4/img_defs.h b/pvr-source/include4/img_defs.h
new file mode 100644
index 0000000..375ed99
--- /dev/null
+++ b/pvr-source/include4/img_defs.h
@@ -0,0 +1,153 @@
+/*************************************************************************/ /*!
+@Title Common header containing type definitions for portability
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Contains variable and structure definitions. Any platform
+ specific types should be defined in this file.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#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
+#if !defined(INLINE)
+ #define INLINE __inline
+#endif
+ #define FORCE_INLINE static __inline
+#endif
+#endif
+
+
+/* Use this in any file, or use attributes under GCC - see below */
+#ifndef PVR_UNREFERENCED_PARAMETER
+#define PVR_UNREFERENCED_PARAMETER(param) (param) = (param)
+#endif
+
+/* The best way to supress unused parameter warnings using GCC is to use a
+ * variable attribute. Place the unref__ between the type and name of an
+ * unused parameter in a function parameter list, eg `int unref__ var'. This
+ * should only be used in GCC build environments, for example, in files that
+ * compile only on Linux. Other files should use UNREFERENCED_PARAMETER */
+#ifdef __GNUC__
+#define unref__ __attribute__ ((unused))
+#else
+#define unref__
+#endif
+
+/*
+ Wide character definitions
+*/
+#ifndef _TCHAR_DEFINED
+#if defined(UNICODE)
+typedef unsigned short TCHAR, *PTCHAR, *PTSTR;
+#else /* #if defined(UNICODE) */
+typedef char TCHAR, *PTCHAR, *PTSTR;
+#endif /* #if defined(UNICODE) */
+#define _TCHAR_DEFINED
+#endif /* #ifndef _TCHAR_DEFINED */
+
+
+ #if defined(__linux__) || defined(__QNXNTO__) || defined(__METAG)
+
+ #define IMG_CALLCONV
+ #define IMG_INTERNAL __attribute__((visibility("hidden")))
+ #define IMG_EXPORT __attribute__((visibility("default")))
+ #define IMG_IMPORT
+ #define IMG_RESTRICT __restrict__
+
+ #else
+ #error("define an OS")
+ #endif
+
+// Use default definition if not overridden
+#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
+
+#if defined(__GNUC__)
+#define IMG_FORMAT_PRINTF(x,y) __attribute__((format(printf,x,y)))
+#else
+#define IMG_FORMAT_PRINTF(x,y)
+#endif
+
+/*
+ * Cleanup request defines
+ */
+#define CLEANUP_WITH_POLL IMG_FALSE
+#define FORCE_CLEANUP IMG_TRUE
+
+#if defined (_WIN64)
+#define IMG_UNDEF (~0ULL)
+#else
+#define IMG_UNDEF (~0UL)
+#endif
+
+#endif /* #if !defined (__IMG_DEFS_H__) */
+/*****************************************************************************
+ End of file (IMG_DEFS.H)
+*****************************************************************************/
diff --git a/pvr-source/include4/img_types.h b/pvr-source/include4/img_types.h
new file mode 100644
index 0000000..7f5137e
--- /dev/null
+++ b/pvr-source/include4/img_types.h
@@ -0,0 +1,214 @@
+/*************************************************************************/ /*!
+@Title Global types for use by IMG APIs
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Defines type aliases for use by IMG APIs.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef __IMG_TYPES_H__
+#define __IMG_TYPES_H__
+
+/* define all address space bit depths: */
+/* CPU virtual address space defaults to 32bits */
+#if !defined(IMG_ADDRSPACE_CPUVADDR_BITS)
+#define IMG_ADDRSPACE_CPUVADDR_BITS 32
+#endif
+
+/* Physical address space defaults to 32bits */
+#if !defined(IMG_ADDRSPACE_PHYSADDR_BITS)
+#define IMG_ADDRSPACE_PHYSADDR_BITS 32
+#endif
+
+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;
+#if !defined(IMG_UINT32_IS_ULONG)
+typedef unsigned int IMG_UINT32, *IMG_PUINT32;
+typedef signed int IMG_INT32, *IMG_PINT32;
+#else
+typedef unsigned long IMG_UINT32, *IMG_PUINT32;
+typedef signed long IMG_INT32, *IMG_PINT32;
+#endif
+#if !defined(IMG_UINT32_MAX)
+ #define IMG_UINT32_MAX 0xFFFFFFFFUL
+#endif
+
+#if defined(USE_CODE)
+
+typedef unsigned __int64 IMG_UINT64, *IMG_PUINT64;
+typedef __int64 IMG_INT64, *IMG_PINT64;
+
+#else
+ #if defined(LINUX) || defined(__METAG) || defined (__QNXNTO__)
+ typedef unsigned long long IMG_UINT64, *IMG_PUINT64;
+ typedef long long IMG_INT64, *IMG_PINT64;
+ #else
+ #error("define an OS")
+ #endif
+#endif
+
+#if !(defined(LINUX) && defined (__KERNEL__))
+/* Linux kernel mode does not use floating point */
+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;
+
+#if defined(_WIN64)
+ typedef unsigned __int64 IMG_UINTPTR_T;
+ typedef signed __int64 IMG_PTRDIFF_T;
+ typedef IMG_UINT64 IMG_SIZE_T;
+#else
+ typedef unsigned int IMG_UINTPTR_T;
+ typedef IMG_UINT32 IMG_SIZE_T;
+#endif
+
+typedef IMG_PVOID IMG_HANDLE;
+
+typedef void** IMG_HVOID, * IMG_PHVOID;
+
+#define IMG_NULL 0
+
+/* services/stream ID */
+typedef IMG_UINT32 IMG_SID;
+
+typedef IMG_UINT32 IMG_EVENTSID;
+
+/*
+ * Address types.
+ * All types used to refer to a block of memory are wrapped in structures
+ * to enforce some degree of type safety, i.e. a IMG_DEV_VIRTADDR cannot
+ * be assigned to a variable of type IMG_DEV_PHYADDR because they are not the
+ * same thing.
+ *
+ * There is an assumption that the system contains at most one non-cpu mmu,
+ * and a memory block is only mapped by the MMU once.
+ *
+ * Different devices could have offset views of the physical address space.
+ *
+ */
+
+
+/*
+ *
+ * +------------+ +------------+ +------------+ +------------+
+ * | CPU | | DEV | | DEV | | DEV |
+ * +------------+ +------------+ +------------+ +------------+
+ * | | | |
+ * | PVOID |IMG_DEV_VIRTADDR |IMG_DEV_VIRTADDR |
+ * | \-------------------/ |
+ * | | |
+ * +------------+ +------------+ |
+ * | MMU | | MMU | |
+ * +------------+ +------------+ |
+ * | | |
+ * | | |
+ * | | |
+ * +--------+ +---------+ +--------+
+ * | Offset | | (Offset)| | Offset |
+ * +--------+ +---------+ +--------+
+ * | | IMG_DEV_PHYADDR |
+ * | | |
+ * | | IMG_DEV_PHYADDR |
+ * +---------------------------------------------------------------------+
+ * | System Address bus |
+ * +---------------------------------------------------------------------+
+ *
+ */
+
+typedef IMG_PVOID IMG_CPU_VIRTADDR;
+
+/* device virtual address */
+typedef struct _IMG_DEV_VIRTADDR
+{
+ /* device virtual addresses are 32bit for now */
+ IMG_UINT32 uiAddr;
+#define IMG_CAST_TO_DEVVADDR_UINT(var) (IMG_UINT32)(var)
+
+} IMG_DEV_VIRTADDR;
+
+typedef IMG_UINT32 IMG_DEVMEM_SIZE_T;
+
+/* cpu physical address */
+typedef struct _IMG_CPU_PHYADDR
+{
+ /* variable sized type (32,64) */
+ IMG_UINTPTR_T uiAddr;
+} IMG_CPU_PHYADDR;
+
+/* device physical address */
+typedef struct _IMG_DEV_PHYADDR
+{
+#if IMG_ADDRSPACE_PHYSADDR_BITS == 32
+ /* variable sized type (32,64) */
+ IMG_UINTPTR_T uiAddr;
+#else
+ IMG_UINT32 uiAddr;
+ IMG_UINT32 uiHighAddr;
+#endif
+} IMG_DEV_PHYADDR;
+
+/* system physical address */
+typedef struct _IMG_SYS_PHYADDR
+{
+ /* variable sized type (32,64) */
+ IMG_UINTPTR_T uiAddr;
+} IMG_SYS_PHYADDR;
+
+#include "img_defs.h"
+
+#endif /* __IMG_TYPES_H__ */
+/******************************************************************************
+ End of file (img_types.h)
+******************************************************************************/
diff --git a/pvr-source/include4/pdumpdefs.h b/pvr-source/include4/pdumpdefs.h
new file mode 100644
index 0000000..112e9ee
--- /dev/null
+++ b/pvr-source/include4/pdumpdefs.h
@@ -0,0 +1,126 @@
+/*************************************************************************/ /*!
+@Title PDUMP definitions header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description PDUMP definitions header
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#if !defined (__PDUMPDEFS_H__)
+#define __PDUMPDEFS_H__
+
+typedef enum _PDUMP_PIXEL_FORMAT_
+{
+ PVRSRV_PDUMP_PIXEL_FORMAT_UNSUPPORTED = 0,
+ 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_RGBA8888 = 39,
+ PVRSRV_PDUMP_PIXEL_FORMAT_ABGR4444 = 40,
+ PVRSRV_PDUMP_PIXEL_FORMAT_RGBA4444 = 41,
+ PVRSRV_PDUMP_PIXEL_FORMAT_BGRA4444 = 42,
+ PVRSRV_PDUMP_PIXEL_FORMAT_ABGR1555 = 43,
+ PVRSRV_PDUMP_PIXEL_FORMAT_RGBA5551 = 44,
+ PVRSRV_PDUMP_PIXEL_FORMAT_BGRA5551 = 45,
+ PVRSRV_PDUMP_PIXEL_FORMAT_BGR565 = 46,
+ PVRSRV_PDUMP_PIXEL_FORMAT_A8 = 47,
+
+ 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 /* __PDUMPDEFS_H__ */
+
+/*****************************************************************************
+ End of file (pdumpdefs.h)
+*****************************************************************************/
diff --git a/pvr-source/include4/pvr_debug.h b/pvr-source/include4/pvr_debug.h
new file mode 100644
index 0000000..7e05666
--- /dev/null
+++ b/pvr-source/include4/pvr_debug.h
@@ -0,0 +1,235 @@
+/*************************************************************************/ /*!
+@Title PVR Debug Declarations
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Provides debug functionality
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#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)
+
+/* These are privately used by pvr_debug, use the PVR_DBG_ defines instead */
+#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_DBGDRV_MESSAGE 0x80UL
+
+#define DBGPRIV_DBGLEVEL_COUNT 8
+
+#if !defined(PVRSRV_NEED_PVR_ASSERT) && defined(DEBUG)
+#define PVRSRV_NEED_PVR_ASSERT
+#endif
+
+#if defined(PVRSRV_NEED_PVR_ASSERT) && !defined(PVRSRV_NEED_PVR_DPF)
+#define PVRSRV_NEED_PVR_DPF
+#endif
+
+#if !defined(PVRSRV_NEED_PVR_TRACE) && (defined(DEBUG) || defined(TIMING))
+#define PVRSRV_NEED_PVR_TRACE
+#endif
+
+/* PVR_ASSERT() and PVR_DBG_BREAK handling */
+
+#if defined(PVRSRV_NEED_PVR_ASSERT)
+
+#if defined(LINUX) && defined(__KERNEL__)
+/* In Linux kernel mode, use BUG() directly. This produces the correct
+ filename and line number in the panic message. */
+#define PVR_ASSERT(EXPR) do \
+ { \
+ if (!(EXPR)) \
+ { \
+ PVRSRVDebugPrintf(DBGPRIV_FATAL, __FILE__, __LINE__, \
+ "Debug assertion failed!"); \
+ BUG(); \
+ } \
+ } while (0)
+
+#else /* defined(LINUX) && defined(__KERNEL__) */
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVDebugAssertFail(const IMG_CHAR *pszFile,
+ IMG_UINT32 ui32Line);
+
+#if defined(LINUX)
+ #define PVR_ASSERT(EXPR) do \
+ { \
+ if (!(EXPR)) \
+ PVRSRVDebugAssertFail(__FILE__, __LINE__); \
+ } while (0)
+#else
+ #if defined (__QNXNTO__)
+ #define PVR_ASSERT(EXPR) if (!(EXPR)) PVRSRVDebugAssertFail(__FILE__, __LINE__);
+ #else
+ #define PVR_ASSERT(EXPR) if (!(EXPR)) PVRSRVDebugAssertFail(__FILE__, __LINE__)
+ #endif
+#endif
+
+#endif /* defined(LINUX) && defined(__KERNEL__) */
+
+
+ #if defined(LINUX) && defined(__KERNEL__)
+ #define PVR_DBG_BREAK BUG()
+ #else
+ #define PVR_DBG_BREAK PVRSRVDebugAssertFail(__FILE__, __LINE__)
+ #endif
+
+#else /* defined(PVRSRV_NEED_PVR_ASSERT) */
+
+ #define PVR_ASSERT(EXPR)
+ #define PVR_DBG_BREAK
+
+#endif /* defined(PVRSRV_NEED_PVR_ASSERT) */
+
+
+/* PVR_DPF() handling */
+
+#if defined(PVRSRV_NEED_PVR_DPF)
+
+#if defined(PVRSRV_NEW_PVR_DPF)
+
+ /* New logging mechanism */
+ #define PVR_DBG_FATAL DBGPRIV_FATAL
+ #define PVR_DBG_ERROR DBGPRIV_ERROR
+ #define PVR_DBG_WARNING DBGPRIV_WARNING
+ #define PVR_DBG_MESSAGE DBGPRIV_MESSAGE
+ #define PVR_DBG_VERBOSE DBGPRIV_VERBOSE
+ #define PVR_DBG_CALLTRACE DBGPRIV_CALLTRACE
+ #define PVR_DBG_ALLOC DBGPRIV_ALLOC
+ #define PVR_DBGDRIV_MESSAGE DBGPRIV_DBGDRV_MESSAGE
+
+ /* These levels are always on with PVRSRV_NEED_PVR_DPF */
+ #define __PVR_DPF_0x01UL(x...) PVRSRVDebugPrintf(DBGPRIV_FATAL, x)
+ #define __PVR_DPF_0x02UL(x...) PVRSRVDebugPrintf(DBGPRIV_ERROR, x)
+
+ /* Some are compiled out completely in release builds */
+#if defined(DEBUG)
+ #define __PVR_DPF_0x04UL(x...) PVRSRVDebugPrintf(DBGPRIV_WARNING, x)
+ #define __PVR_DPF_0x08UL(x...) PVRSRVDebugPrintf(DBGPRIV_MESSAGE, x)
+ #define __PVR_DPF_0x10UL(x...) PVRSRVDebugPrintf(DBGPRIV_VERBOSE, x)
+ #define __PVR_DPF_0x20UL(x...) PVRSRVDebugPrintf(DBGPRIV_CALLTRACE, x)
+ #define __PVR_DPF_0x40UL(x...) PVRSRVDebugPrintf(DBGPRIV_ALLOC, x)
+ #define __PVR_DPF_0x80UL(x...) PVRSRVDebugPrintf(DBGPRIV_DBGDRV_MESSAGE, x)
+#else
+ #define __PVR_DPF_0x04UL(x...)
+ #define __PVR_DPF_0x08UL(x...)
+ #define __PVR_DPF_0x10UL(x...)
+ #define __PVR_DPF_0x20UL(x...)
+ #define __PVR_DPF_0x40UL(x...)
+ #define __PVR_DPF_0x80UL(x...)
+#endif
+
+ /* Translate the different log levels to separate macros
+ * so they can each be compiled out.
+ */
+#if defined(DEBUG)
+ #define __PVR_DPF(lvl, x...) __PVR_DPF_ ## lvl (__FILE__, __LINE__, x)
+#else
+ #define __PVR_DPF(lvl, x...) __PVR_DPF_ ## lvl ("", 0, x)
+#endif
+
+ /* Get rid of the double bracketing */
+ #define PVR_DPF(x) __PVR_DPF x
+
+#else /* defined(PVRSRV_NEW_PVR_DPF) */
+
+ /* Old logging mechanism */
+ #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__
+ #define PVR_DBGDRIV_MESSAGE DBGPRIV_DBGDRV_MESSAGE, "", 0
+
+ #define PVR_DPF(X) PVRSRVDebugPrintf X
+
+#endif /* defined(PVRSRV_NEW_PVR_DPF) */
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVDebugPrintf(IMG_UINT32 ui32DebugLevel,
+ const IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32Line,
+ const IMG_CHAR *pszFormat,
+ ...) IMG_FORMAT_PRINTF(4, 5);
+
+#else /* defined(PVRSRV_NEED_PVR_DPF) */
+
+ #define PVR_DPF(X)
+
+#endif /* defined(PVRSRV_NEED_PVR_DPF) */
+
+
+/* PVR_TRACE() handling */
+
+#if defined(PVRSRV_NEED_PVR_TRACE)
+
+ #define PVR_TRACE(X) PVRSRVTrace X
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVTrace(const IMG_CHAR* pszFormat, ... )
+ IMG_FORMAT_PRINTF(1, 2);
+
+#else /* defined(PVRSRV_NEED_PVR_TRACE) */
+
+ #define PVR_TRACE(X)
+
+#endif /* defined(PVRSRV_NEED_PVR_TRACE) */
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* __PVR_DEBUG_H__ */
+
+/******************************************************************************
+ End of file (pvr_debug.h)
+******************************************************************************/
+
diff --git a/pvr-source/include4/pvrmodule.h b/pvr-source/include4/pvrmodule.h
new file mode 100644
index 0000000..267c7b6
--- /dev/null
+++ b/pvr-source/include4/pvrmodule.h
@@ -0,0 +1,48 @@
+/*************************************************************************/ /*!
+@Title Module Author and License.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _PVRMODULE_H_
+#define _PVRMODULE_H_
+
+MODULE_AUTHOR("Imagination Technologies Ltd. <gpl-support@imgtec.com>");
+MODULE_LICENSE("Dual MIT/GPL");
+
+#endif /* _PVRMODULE_H_ */
diff --git a/pvr-source/include4/pvrversion.h b/pvr-source/include4/pvrversion.h
new file mode 100644
index 0000000..820b25a
--- /dev/null
+++ b/pvr-source/include4/pvrversion.h
@@ -0,0 +1,69 @@
+/*************************************************************************/ /*!
+@File
+@Title Version numbers and strings.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Version numbers and strings for PVR Consumer services
+ components.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _PVRVERSION_H_
+#define _PVRVERSION_H_
+
+#define PVR_STR(X) #X
+#define PVR_STR2(X) PVR_STR(X)
+
+#define PVRVERSION_MAJ 1
+#define PVRVERSION_MIN 9
+#define PVRVERSION_BRANCH 19
+
+#define PVRVERSION_FAMILY "sgxddk"
+#define PVRVERSION_BRANCHNAME "1.9"
+#define PVRVERSION_BUILD 2166536
+#define PVRVERSION_BSCONTROL "SGX_DDK_Android"
+
+#define PVRVERSION_STRING "SGX_DDK_Android sgxddk 19 1.9@" PVR_STR2(PVRVERSION_BUILD)
+#define PVRVERSION_STRING_SHORT "1.9@" PVR_STR2(PVRVERSION_BUILD)
+
+#define COPYRIGHT_TXT "Copyright (c) Imagination Technologies Ltd. All Rights Reserved."
+
+#define PVRVERSION_BUILD_HI 216
+#define PVRVERSION_BUILD_LO 6536
+#define PVRVERSION_STRING_NUMERIC PVR_STR2(PVRVERSION_MAJ) "." PVR_STR2(PVRVERSION_MIN) "." PVR_STR2(PVRVERSION_BUILD_HI) "." PVR_STR2(PVRVERSION_BUILD_LO)
+
+#endif /* _PVRVERSION_H_ */
diff --git a/pvr-source/include4/services.h b/pvr-source/include4/services.h
new file mode 100644
index 0000000..bfa7fb0
--- /dev/null
+++ b/pvr-source/include4/services.h
@@ -0,0 +1,1870 @@
+/*************************************************************************/ /*!
+@Title Services API Header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Exported services API details
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __SERVICES_H__
+#define __SERVICES_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "img_defs.h"
+#include "servicesext.h"
+#include "pdumpdefs.h"
+
+
+/* The comment below is the front page for code-generated doxygen documentation */
+/*!
+ ******************************************************************************
+ @mainpage
+ This document details the APIs and implementation of the Consumer Services.
+ It is intended to be used in conjunction with the Consumer Services
+ Software Architectural Specification and the Consumer Services Software
+ Functional Specification.
+ *****************************************************************************/
+
+/******************************************************************************
+ * #defines
+ *****************************************************************************/
+
+/* 4k page size definition */
+#define PVRSRV_4K_PAGE_SIZE 4096UL
+
+#define PVRSRV_MAX_CMD_SIZE 1024/*!< max size in bytes of a command */
+
+#define PVRSRV_MAX_DEVICES 16 /*!< Largest supported number of devices on the system */
+
+#define EVENTOBJNAME_MAXLENGTH (50)
+
+/*
+ Flags associated with memory allocation
+ (bits 0-11)
+*/
+#define PVRSRV_MEM_READ (1U<<0)
+#define PVRSRV_MEM_WRITE (1U<<1)
+#define PVRSRV_MEM_CACHE_CONSISTENT (1U<<2)
+#define PVRSRV_MEM_NO_SYNCOBJ (1U<<3)
+#define PVRSRV_MEM_INTERLEAVED (1U<<4)
+#define PVRSRV_MEM_DUMMY (1U<<5)
+#define PVRSRV_MEM_EDM_PROTECT (1U<<6)
+#define PVRSRV_MEM_ZERO (1U<<7)
+#define PVRSRV_MEM_USER_SUPPLIED_DEVVADDR (1U<<8)
+#define PVRSRV_MEM_RAM_BACKED_ALLOCATION (1U<<9)
+#define PVRSRV_MEM_NO_RESMAN (1U<<10)
+#define PVRSRV_MEM_EXPORTED (1U<<11)
+
+
+/*
+ Heap Attribute flags
+ (bits 12-23)
+*/
+#define PVRSRV_HAP_CACHED (1U<<12)
+#define PVRSRV_HAP_UNCACHED (1U<<13)
+#define PVRSRV_HAP_WRITECOMBINE (1U<<14)
+#define PVRSRV_HAP_CACHETYPE_MASK (PVRSRV_HAP_CACHED|PVRSRV_HAP_UNCACHED|PVRSRV_HAP_WRITECOMBINE)
+#define PVRSRV_HAP_KERNEL_ONLY (1U<<15)
+#define PVRSRV_HAP_SINGLE_PROCESS (1U<<16)
+#define PVRSRV_HAP_MULTI_PROCESS (1U<<17)
+#define PVRSRV_HAP_FROM_EXISTING_PROCESS (1U<<18)
+#define PVRSRV_HAP_NO_CPU_VIRTUAL (1U<<19)
+#define PVRSRV_MAP_GC_MMU (1UL<<20)
+#define PVRSRV_HAP_GPU_PAGEABLE (1U<<21)
+#define PVRSRV_HAP_NO_GPU_VIRTUAL_ON_ALLOC (1U<<22)
+#define PVRSRV_HAP_MAPTYPE_MASK (PVRSRV_HAP_KERNEL_ONLY \
+ |PVRSRV_HAP_SINGLE_PROCESS \
+ |PVRSRV_HAP_MULTI_PROCESS \
+ |PVRSRV_HAP_FROM_EXISTING_PROCESS)
+#define PVRSRV_HAP_MAPPING_CTRL_MASK (PVRSRV_HAP_NO_CPU_VIRTUAL\
+ |PVRSRV_HAP_GPU_PAGEABLE \
+ |PVRSRV_HAP_NO_GPU_VIRTUAL_ON_ALLOC)
+
+/*
+ Allows user allocations to override heap attributes
+ (Bits shared with heap flags)
+*/
+#define PVRSRV_MEM_CACHED PVRSRV_HAP_CACHED
+#define PVRSRV_MEM_UNCACHED PVRSRV_HAP_UNCACHED
+#define PVRSRV_MEM_WRITECOMBINE PVRSRV_HAP_WRITECOMBINE
+
+/*
+ Backing store flags (defined internally)
+ (bits 24-26)
+*/
+#define PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT (24)
+
+/*
+ Per allocation/mapping flags
+ (bits 27-30)
+ */
+#define PVRSRV_MAP_NOUSERVIRTUAL (1UL<<27)
+#define PVRSRV_MEM_XPROC (1U<<28)
+#define PVRSRV_MEM_ION (1U<<29)
+#define PVRSRV_MEM_ALLOCATENONCACHEDMEM (1UL<<30)
+
+/*
+ Internal allocation/mapping flags
+ (bit 31)
+*/
+#define PVRSRV_MEM_SPARSE (1U<<31)
+
+
+/*
+ * How much context we lose on a (power) mode change
+ */
+#define PVRSRV_NO_CONTEXT_LOSS 0 /*!< Do not lose state on power down */
+#define PVRSRV_SEVERE_LOSS_OF_CONTEXT 1 /*!< lose state on power down */
+#define PVRSRV_PRE_STATE_CHANGE_MASK 0x80 /*!< power state change mask */
+
+
+/*
+ * Device cookie defines
+ */
+#define PVRSRV_DEFAULT_DEV_COOKIE (1) /*!< default device cookie */
+
+
+/*
+ * Misc Info. present flags
+ */
+#define PVRSRV_MISC_INFO_TIMER_PRESENT (1U<<0)
+#define PVRSRV_MISC_INFO_CLOCKGATE_PRESENT (1U<<1)
+#define PVRSRV_MISC_INFO_MEMSTATS_PRESENT (1U<<2)
+#define PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT (1U<<3)
+#define PVRSRV_MISC_INFO_DDKVERSION_PRESENT (1U<<4)
+#define PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT (1U<<5)
+#define PVRSRV_MISC_INFO_FREEMEM_PRESENT (1U<<6)
+#define PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT (1U<<7)
+#define PVRSRV_MISC_INFO_GET_PAGE_SIZE_PRESENT (1U<<8)
+#define PVRSRV_MISC_INFO_FORCE_SWAP_TO_SYSTEM_PRESENT (1U<<9)
+
+#define PVRSRV_MISC_INFO_RESET_PRESENT (1U<<31)
+
+/* PDUMP defines */
+#define PVRSRV_PDUMP_MAX_FILENAME_SIZE 20
+#define PVRSRV_PDUMP_MAX_COMMENT_SIZE 200
+
+
+/*
+ Flags for PVRSRVChangeDeviceMemoryAttributes call.
+*/
+#define PVRSRV_CHANGEDEVMEM_ATTRIBS_CACHECOHERENT 0x00000001
+
+/*
+ Flags for PVRSRVMapExtMemory and PVRSRVUnmapExtMemory
+ ALTERNATEVA - Used when mapping multiple virtual addresses to the same physical address. Set this flag on extra maps.
+ PHYSCONTIG - Physical pages are contiguous (unused)
+*/
+#define PVRSRV_MAPEXTMEMORY_FLAGS_ALTERNATEVA 0x00000001
+#define PVRSRV_MAPEXTMEMORY_FLAGS_PHYSCONTIG 0x00000002
+
+/*
+ Flags for PVRSRVModifySyncOps
+ WO_INC - Used to increment "WriteOpsPending/complete of sync info"
+ RO_INC - Used to increment "ReadOpsPending/complete of sync info"
+*/
+#define PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC 0x00000001
+#define PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC 0x00000002
+
+/*
+ Flags for Services connection.
+ Allows to define per-client policy for Services
+*/
+#define SRV_FLAGS_PERSIST 0x1
+#define SRV_FLAGS_PDUMP_ACTIVE 0x2
+
+/*
+ Pdump flags which are accessible to Services clients
+*/
+#define PVRSRV_PDUMP_FLAGS_CONTINUOUS 0x1
+
+/* Number of MM planes supported for the meminfo */
+#define PVRSRV_MAX_NUMBER_OF_MM_BUFFER_PLANES 3
+
+/* Invalid Device Virtual Address Value */
+#define PVRSRV_BAD_DEVICE_ADDRESS 0
+
+/* Maximum array size of the meminfo's when invoking
+ * PVRSRVMultiManageDevMem() in shared mode */
+#define PVRSRV_MULTI_MANAGE_DEV_MEM_MAX_SIZE 128
+
+/* Maximum array size of the meminfo's when invoking
+ * PVRSRVMultiManageDevMem() in direct (copy) mode */
+#define PVRSRV_MULTI_MANAGE_DEV_MEM_MAX_DIRECT_SIZE 8
+
+/******************************************************************************
+ * Enums
+ *****************************************************************************/
+
+/*!
+ ******************************************************************************
+ * List of known device types.
+ *****************************************************************************/
+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,
+
+ /* 3rd party devices take ext type */
+ 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 )
+
+/* common undefined heap ID define */
+#define PVRSRV_UNDEFINED_HEAP_ID (~0LU)
+
+/*!
+ ******************************************************************************
+ * User Module type
+ *****************************************************************************/
+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,
+#if defined(SUPPORT_GRAPHICS_HAL) || defined(SUPPORT_COMPOSER_HAL)
+ IMG_ANDROID_HAL = 0x0000000E,
+#endif
+#if defined(SUPPORT_OPENCL)
+ IMG_OPENCL = 0x0000000F,
+#endif
+
+} IMG_MODULE_ID;
+
+
+#define APPHINT_MAX_STRING_SIZE 256
+
+/*!
+ ******************************************************************************
+ * IMG data types
+ *****************************************************************************/
+typedef enum
+{
+ IMG_STRING_TYPE = 1,
+ IMG_FLOAT_TYPE ,
+ IMG_UINT_TYPE ,
+ IMG_INT_TYPE ,
+ IMG_FLAG_TYPE
+}IMG_DATA_TYPE;
+
+
+/******************************************************************************
+ * Structure definitions.
+ *****************************************************************************/
+
+/*!
+ * Forward declaration
+ */
+typedef struct _PVRSRV_DEV_DATA_ *PPVRSRV_DEV_DATA;
+
+/*!
+ ******************************************************************************
+ * Device identifier structure
+ *****************************************************************************/
+typedef struct _PVRSRV_DEVICE_IDENTIFIER_
+{
+ PVRSRV_DEVICE_TYPE eDeviceType; /*!< Identifies the type of the device */
+ PVRSRV_DEVICE_CLASS eDeviceClass; /*!< Identifies more general class of device - display/3d/mpeg etc */
+ IMG_UINT32 ui32DeviceIndex; /*!< Index of the device within the system */
+ IMG_CHAR *pszPDumpDevName; /*!< Pdump memory bank name */
+ IMG_CHAR *pszPDumpRegName; /*!< Pdump register bank name */
+
+} PVRSRV_DEVICE_IDENTIFIER;
+
+
+/******************************************************************************
+ * Client dev info
+ ******************************************************************************
+ */
+typedef struct _PVRSRV_CLIENT_DEV_DATA_
+{
+ IMG_UINT32 ui32NumDevices; /*!< Number of services-managed devices connected */
+ PVRSRV_DEVICE_IDENTIFIER asDevID[PVRSRV_MAX_DEVICES]; /*!< Device identifiers */
+ PVRSRV_ERROR (*apfnDevConnect[PVRSRV_MAX_DEVICES])(PPVRSRV_DEV_DATA); /*< device-specific connection callback */
+ PVRSRV_ERROR (*apfnDumpTrace[PVRSRV_MAX_DEVICES])(PPVRSRV_DEV_DATA); /*!< device-specific debug trace callback */
+
+} PVRSRV_CLIENT_DEV_DATA;
+
+
+/*!
+ ******************************************************************************
+ * Kernel Services connection structure
+ *****************************************************************************/
+typedef struct _PVRSRV_CONNECTION_
+{
+ IMG_HANDLE hServices; /*!< UM IOCTL handle */
+ IMG_UINT32 ui32ProcessID; /*!< Process ID for resource locking */
+ PVRSRV_CLIENT_DEV_DATA sClientDevData; /*!< Client device data */
+ IMG_UINT32 ui32SrvFlags; /*!< Per-client Services flags */
+}PVRSRV_CONNECTION;
+
+
+/*!
+ ******************************************************************************
+ * This structure allows the user mode glue code to have an OS independent
+ * set of prototypes.
+ *****************************************************************************/
+typedef struct _PVRSRV_DEV_DATA_
+{
+ IMG_CONST PVRSRV_CONNECTION *psConnection; /*!< Services connection info */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie; /*!< Dev cookie */
+#else
+ IMG_HANDLE hDevCookie; /*!< Dev cookie */
+#endif
+
+} PVRSRV_DEV_DATA;
+
+/*!
+ ******************************************************************************
+ * address:value update structure
+ *****************************************************************************/
+typedef struct _PVRSRV_MEMUPDATE_
+{
+ IMG_UINT32 ui32UpdateAddr; /*!< Address */
+ IMG_UINT32 ui32UpdateVal; /*!< value */
+} PVRSRV_MEMUPDATE;
+
+/*!
+ ******************************************************************************
+ * address:value register structure
+ *****************************************************************************/
+typedef struct _PVRSRV_HWREG_
+{
+ IMG_UINT32 ui32RegAddr; /*!< Address */
+ IMG_UINT32 ui32RegVal; /*!< value */
+} PVRSRV_HWREG;
+
+/*!
+ ******************************************************************************
+ * Implementation details for memory handling
+ *****************************************************************************/
+typedef struct _PVRSRV_MEMBLK_
+{
+ IMG_DEV_VIRTADDR sDevVirtAddr; /*!< Address of the memory in the IMG MMUs address space */
+ IMG_HANDLE hOSMemHandle; /*!< Stores the underlying memory allocation handle */
+ IMG_HANDLE hOSWrapMem; /*!< FIXME: better way to solve this problem */
+ IMG_HANDLE hBuffer; /*!< Stores the BM_HANDLE for the underlying memory management */
+ IMG_HANDLE hResItem; /*!< handle to resource item for allocate */
+ IMG_SYS_PHYADDR *psIntSysPAddr;
+
+} PVRSRV_MEMBLK;
+
+/*!
+ ******************************************************************************
+ * Memory Management (externel interface)
+ *****************************************************************************/
+typedef struct _PVRSRV_KERNEL_MEM_INFO_ *PPVRSRV_KERNEL_MEM_INFO;
+
+typedef struct _PVRSRV_CLIENT_MEM_INFO_
+{
+ /* CPU Virtual Address */
+ IMG_PVOID pvLinAddr;
+
+ /* CPU Virtual Address (for kernel mode) */
+ IMG_PVOID pvLinAddrKM;
+
+ /* Device Virtual Address */
+ IMG_DEV_VIRTADDR sDevVAddr;
+
+ /* allocation flags */
+ IMG_UINT32 ui32Flags;
+
+ /* client allocation flags */
+ IMG_UINT32 ui32ClientFlags;
+
+ /* allocation size in bytes */
+ IMG_SIZE_T uAllocSize;
+
+
+ /* ptr to associated client sync info - NULL if no sync */
+ struct _PVRSRV_CLIENT_SYNC_INFO_ *psClientSyncInfo;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ /* handle to client mapping data (OS specific) */
+ IMG_SID hMappingInfo;
+
+ /* handle to kernel mem info */
+ IMG_SID hKernelMemInfo;
+
+ /* resman handle for UM mapping clean-up */
+ IMG_SID hResItem;
+#else
+ /* handle to client mapping data (OS specific) */
+ IMG_HANDLE hMappingInfo;
+
+ /* handle to kernel mem info */
+ IMG_HANDLE hKernelMemInfo;
+
+ /* resman handle for UM mapping clean-up */
+ IMG_HANDLE hResItem;
+#endif
+
+#if defined(SUPPORT_MEMINFO_IDS)
+ #if !defined(USE_CODE)
+ /* Globally unique "stamp" for allocation (not re-used until wrap) */
+ IMG_UINT64 ui64Stamp;
+ #else /* !defined(USE_CODE) */
+ IMG_UINT32 dummy1;
+ IMG_UINT32 dummy2;
+ #endif /* !defined(USE_CODE) */
+#endif /* defined(SUPPORT_MEMINFO_IDS) */
+
+ /* Sub-system ID that allocated the buffer */
+ IMG_UINT64 uiSubSystem;
+
+ /*
+ ptr to next mem info
+ D3D uses psNext for mid-scene texture reload.
+ */
+ struct _PVRSRV_CLIENT_MEM_INFO_ *psNext;
+
+ /* Device Virtual Addresses for the YUV MM planes */
+ IMG_UINT32 planeOffsets[PVRSRV_MAX_NUMBER_OF_MM_BUFFER_PLANES];
+} PVRSRV_CLIENT_MEM_INFO, *PPVRSRV_CLIENT_MEM_INFO;
+
+/*
+ Multiple buffer device virtual mapping management
+*/
+typedef enum
+{
+ PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_INVALID = 0,
+ /* We may not have GPU virtual address */
+ PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_MAP = 1,
+ PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_LOCK_MAP,
+ PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_SWAP_MAP_FROM_PREV,
+ /* We have GPU virtual address */
+ PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_UNMAP,
+ PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_UNLOCK_MAP,
+ PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_SWAP_MAP_TO_NEXT,
+ PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_LAST = (IMG_UINT32)-1
+} PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_TYPE;
+
+typedef struct _PVRSRV_MANAGE_DEV_MEM_REQUEST
+{
+ PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_TYPE eReqType;
+ IMG_UINT32 ui32FieldSize; /* valid if equal to the size of the structure */
+ IMG_HANDLE hKernelMemInfo;
+ IMG_HANDLE hKernelSyncInfo;
+ PVRSRV_CLIENT_MEM_INFO *psClientMemInfo; /* Client side reference */
+ IMG_UINT32 ui32Hints;
+ IMG_UINT32 ui32Attribs;
+ IMG_SIZE_T uSize;
+ IMG_SIZE_T uAlignment;
+ IMG_PVOID pvLinAddr; /* CPU Virtual Address */
+ IMG_UINT32 ui32CpuMapRefCount;
+ IMG_DEV_VIRTADDR sDevVAddr; /* Device Virtual Address */
+ IMG_UINT32 ui32GpuMapRefCount;
+ IMG_UINT32 ui32TransferFromToReqSlotIndx; /* Transfer GPU virtual mapping from index */
+ IMG_UINT64 uiSubSystem;
+ PVRSRV_ERROR eError;
+}PVRSRV_MANAGE_DEV_MEM_REQUEST;
+
+typedef PVRSRV_MANAGE_DEV_MEM_REQUEST PVRSRV_MANAGE_DEV_MEM_RESPONSE;
+
+typedef struct _PVRSRV_MULTI_MANAGE_DEV_MEM_REQUESTS
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ #if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ /* handle to kernel shared memory */
+ IMG_SID hKernelMemInfo;
+ #else
+ IMG_HANDLE hDevCookie;
+ /* handle to kernel shared memory*/
+ IMG_HANDLE hKernelMemInfo;
+ #endif
+ PVRSRV_CLIENT_MEM_INFO *psSharedMemClientMemInfo; /* NULL if direct (not through shared) */
+ IMG_UINT32 ui32MaxNumberOfRequests; /* Must be <= PVRSRV_MULTI_MANAGE_DEV_MEM_MAX_DIRECT_SIZE for direct */
+ IMG_UINT32 ui32NumberOfValidRequests; /* Must be <= ui32MaxNumberOfRequests */
+ IMG_UINT32 ui32CtrlFlags;
+ IMG_UINT32 ui32StatusFlags;
+ PVRSRV_MANAGE_DEV_MEM_REQUEST sMemRequests[PVRSRV_MULTI_MANAGE_DEV_MEM_MAX_DIRECT_SIZE]; /* Memory Requests Array */
+}PVRSRV_MULTI_MANAGE_DEV_MEM_REQUESTS;
+
+/*!
+ ******************************************************************************
+ * Memory Heap Information
+ *****************************************************************************/
+#define PVRSRV_MAX_CLIENT_HEAPS (32)
+typedef struct _PVRSRV_HEAP_INFO_
+{
+ IMG_UINT32 ui32HeapID;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemHeap;
+#else
+ IMG_HANDLE hDevMemHeap;
+#endif
+ IMG_DEV_VIRTADDR sDevVAddrBase;
+ IMG_UINT32 ui32HeapByteSize;
+ IMG_UINT32 ui32Attribs;
+ IMG_UINT32 ui32XTileStride;
+}PVRSRV_HEAP_INFO;
+
+
+
+
+/*
+ Event Object information structure
+*/
+typedef struct _PVRSRV_EVENTOBJECT_
+{
+ /* globally unique name of the event object */
+ IMG_CHAR szName[EVENTOBJNAME_MAXLENGTH];
+ /* kernel specific handle for the event object */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hOSEventKM;
+#else
+ IMG_HANDLE hOSEventKM;
+#endif
+
+} PVRSRV_EVENTOBJECT;
+
+/*
+ Cache operation type
+*/
+typedef enum
+{
+ PVRSRV_MISC_INFO_CPUCACHEOP_NONE = 0,
+ PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN,
+ PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH
+} PVRSRV_MISC_INFO_CPUCACHEOP_TYPE;
+
+/*!
+ ******************************************************************************
+ * Structure to retrieve misc. information from services
+ *****************************************************************************/
+typedef struct _PVRSRV_MISC_INFO_
+{
+ IMG_UINT32 ui32StateRequest; /*!< requested State Flags */
+ IMG_UINT32 ui32StatePresent; /*!< Present/Valid State Flags */
+
+ /*!< SOC Timer register */
+ IMG_VOID *pvSOCTimerRegisterKM;
+ IMG_VOID *pvSOCTimerRegisterUM;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSOCTimerRegisterOSMemHandle;
+ IMG_SID hSOCTimerRegisterMappingInfo;
+#else
+ IMG_HANDLE hSOCTimerRegisterOSMemHandle;
+ IMG_HANDLE hSOCTimerRegisterMappingInfo;
+#endif
+
+ /*!< SOC Clock Gating registers */
+ IMG_VOID *pvSOCClockGateRegs;
+ IMG_UINT32 ui32SOCClockGateRegsSize;
+
+ /* Memory Stats/DDK version string depending on ui32StateRequest flags */
+ IMG_CHAR *pszMemoryStr;
+ IMG_UINT32 ui32MemoryStrLen;
+
+ /* global event object */
+ PVRSRV_EVENTOBJECT sGlobalEventObject;//FIXME: should be private to services
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_EVENTSID hOSGlobalEvent;
+#else
+ IMG_HANDLE hOSGlobalEvent;
+#endif
+
+ /* Note: add misc. items as required */
+ IMG_UINT32 aui32DDKVersion[4];
+
+ /*!< CPU cache flush controls: */
+ struct
+ {
+ /*!< Defer the CPU cache op to the next HW op to be submitted (else flush now) */
+ IMG_BOOL bDeferOp;
+
+ /*!< Type of cache operation to perform */
+ PVRSRV_MISC_INFO_CPUCACHEOP_TYPE eCacheOpType;
+
+ /* This union is a bit unsightly. We need it because we'll use the psMemInfo
+ * directly in the srvclient PVRSRVGetMiscInfo code, and then convert it
+ * to a kernel meminfo if required. Try to not waste space.
+ */
+#if !defined (SUPPORT_SID_INTERFACE)
+ union
+ {
+ /*!< Input client meminfo (UM side) */
+ PVRSRV_CLIENT_MEM_INFO *psClientMemInfo;
+
+ /*!< Output kernel meminfo (Bridge+KM side) */
+ struct _PVRSRV_KERNEL_MEM_INFO_ *psKernelMemInfo;
+ } u;
+#endif
+
+ /*!< Offset in MemInfo to start cache op */
+ IMG_VOID *pvBaseVAddr;
+
+ /*!< Length of range to perform cache op */
+ IMG_UINT32 ui32Length;
+ } sCacheOpCtl;
+
+ /*!< Meminfo refcount controls: */
+ struct
+ {
+ /* This union is a bit unsightly. We need it because we'll use the psMemInfo
+ * directly in the srvclient PVRSRVGetMiscInfo code, and then convert it
+ * to a kernel meminfo if required. Try to not waste space.
+ */
+#if !defined(SUPPORT_SID_INTERFACE)
+ union
+ {
+ /*!< Input client meminfo (UM side) */
+ PVRSRV_CLIENT_MEM_INFO *psClientMemInfo;
+
+ /*!< Output kernel meminfo (Bridge+KM side) */
+ struct _PVRSRV_KERNEL_MEM_INFO_ *psKernelMemInfo;
+ } u;
+#endif
+
+ /*!< Resulting refcount */
+ IMG_UINT32 ui32RefCount;
+ } sGetRefCountCtl;
+
+ IMG_UINT32 ui32PageSize;
+} PVRSRV_MISC_INFO;
+
+/*!
+ ******************************************************************************
+ * Synchronisation token
+ *****************************************************************************/
+typedef struct _PVRSRV_SYNC_TOKEN_
+{
+ /* This token is supposed to be passed around as an opaque object
+ - caller should not rely on the internal fields staying the same.
+ The fields are hidden in sPrivate in order to reinforce this. */
+ struct
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfo;
+#else
+ IMG_HANDLE hKernelSyncInfo;
+#endif
+ IMG_UINT32 ui32ReadOpsPendingSnapshot;
+ IMG_UINT32 ui32WriteOpsPendingSnapshot;
+ IMG_UINT32 ui32ReadOps2PendingSnapshot;
+ } sPrivate;
+} PVRSRV_SYNC_TOKEN;
+
+
+/******************************************************************************
+ * PVR Client Event handling in Services
+ *****************************************************************************/
+typedef enum _PVRSRV_CLIENT_EVENT_
+{
+ PVRSRV_CLIENT_EVENT_HWTIMEOUT = 0,
+} PVRSRV_CLIENT_EVENT;
+
+typedef IMG_VOID (*PFN_QUEUE_COMMAND_COMPLETE)(IMG_HANDLE hCallbackData);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVClientEvent(IMG_CONST PVRSRV_CLIENT_EVENT eEvent,
+ PVRSRV_DEV_DATA *psDevData,
+ IMG_PVOID pvData);
+
+/******************************************************************************
+ * PVR Services API prototypes.
+ *****************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVConnect(PVRSRV_CONNECTION **ppsConnection, IMG_UINT32 ui32SrvFlags);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDisconnect(IMG_CONST 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);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVPollForValue ( const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hOSEvent,
+#else
+ IMG_HANDLE hOSEvent,
+#endif
+ volatile IMG_UINT32 *pui32LinMemAddr,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ IMG_UINT32 ui32Waitus,
+ IMG_UINT32 ui32Tries);
+
+/* memory APIs */
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContext(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID *phDevMemContext,
+#else
+ IMG_HANDLE *phDevMemContext,
+#endif
+ IMG_UINT32 *pui32SharedHeapCount,
+ PVRSRV_HEAP_INFO *psHeapInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContext(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemContext
+#else
+ IMG_HANDLE hDevMemContext
+#endif
+ );
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfo(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemContext,
+#else
+ IMG_HANDLE hDevMemContext,
+#endif
+ IMG_UINT32 *pui32SharedHeapCount,
+ PVRSRV_HEAP_INFO *psHeapInfo);
+
+#if defined(PVRSRV_LOG_MEMORY_ALLOCS)
+ #define PVRSRVAllocDeviceMem_log(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo, logStr) \
+ (PVR_TRACE(("PVRSRVAllocDeviceMem(" #psDevData "," #hDevMemHeap "," #ui32Attribs "," #ui32Size "," #ui32Alignment "," #ppsMemInfo ")" \
+ ": " logStr " (size = 0x%lx)", ui32Size)), \
+ PVRSRVAllocDeviceMem(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo))
+#else
+ #define PVRSRVAllocDeviceMem_log(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo, logStr) \
+ PVRSRVAllocDeviceMem(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo)
+#endif
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocDeviceMem2(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemHeap,
+#else
+ IMG_HANDLE hDevMemHeap,
+#endif
+ IMG_UINT32 ui32Attribs,
+ IMG_SIZE_T ui32Size,
+ IMG_SIZE_T ui32Alignment,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ PVRSRV_CLIENT_MEM_INFO **ppsMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocDeviceMem(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemHeap,
+#else
+ IMG_HANDLE hDevMemHeap,
+#endif
+ IMG_UINT32 ui32Attribs,
+ IMG_SIZE_T ui32Size,
+ IMG_SIZE_T 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 PVRSRVMultiManageDevMem(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ IMG_UINT32 ui32ControlFlags, PVRSRV_MULTI_MANAGE_DEV_MEM_REQUESTS * psMultiMemDevRequest,
+ IMG_UINT32 *ui32StatusFlags, IMG_UINT32 *ui32IndexError);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVManageDevMem(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_TYPE eReq, PVRSRV_CLIENT_MEM_INFO *psMemInfo,
+ IMG_UINT32 *ui32StatusFlags);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVManageDevMemSwapGpuVirtAddr(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_CLIENT_MEM_INFO *psMemInfoSourceArray, PVRSRV_CLIENT_MEM_INFO *psMemInfoTargetArray,
+ IMG_UINT32 ui32NumBuff, IMG_UINT32 *ui32StatusFlags);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVExportDeviceMem(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_CLIENT_MEM_INFO *psMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID *phMemInfo
+#else
+ IMG_HANDLE *phMemInfo
+#endif
+ );
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVReserveDeviceVirtualMem(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemHeap,
+#else
+ IMG_HANDLE hDevMemHeap,
+#endif
+ IMG_DEV_VIRTADDR *psDevVAddr,
+ IMG_SIZE_T ui32Size,
+ IMG_SIZE_T 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo,
+ IMG_SID hDstDevMemHeap,
+#else
+ IMG_HANDLE hKernelMemInfo,
+ IMG_HANDLE hDstDevMemHeap,
+#endif
+ 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemContext,
+#else
+ IMG_HANDLE hDevMemContext,
+#endif
+ IMG_SIZE_T ui32ByteSize,
+ IMG_SIZE_T ui32PageOffset,
+ IMG_BOOL bPhysContig,
+ IMG_SYS_PHYADDR *psSysPAddr,
+ IMG_VOID *pvLinAddr,
+ IMG_UINT32 ui32Flags,
+ 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemContext,
+ IMG_SID hDeviceClassBuffer,
+#else
+ IMG_HANDLE hDevMemContext,
+ IMG_HANDLE hDeviceClassBuffer,
+#endif
+ 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);
+
+#if defined(LINUX)
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCloseExportedDeviceMemHanle(const PVRSRV_DEV_DATA *psDevData,
+ IMG_INT i32Fd);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVExportDeviceMem2(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_CLIENT_MEM_INFO *psMemInfo,
+ IMG_INT *iFd);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemory2(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ IMG_INT iFd,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDstDevMemHeap,
+#else
+ IMG_HANDLE hDstDevMemHeap,
+#endif
+ PVRSRV_CLIENT_MEM_INFO **ppsDstMemInfo);
+#endif /* defined(LINUX) */
+
+#if defined(SUPPORT_ION)
+PVRSRV_ERROR PVRSRVMapIonHandle(const PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemContext,
+#else
+ IMG_HANDLE hDevMemContext,
+#endif
+ IMG_INT32 uiFD,
+ IMG_UINT32 uiSize,
+ IMG_UINT32 ui32Attribs,
+ PVRSRV_CLIENT_MEM_INFO **ppsMemInfo);
+
+PVRSRV_ERROR PVRSRVUnmapIonHandle(const PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_CLIENT_MEM_INFO *psMemInfo);
+#endif /* defined (SUPPORT_ION) */
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocDeviceMemSparse(const PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemHeap,
+#else
+ IMG_HANDLE hDevMemHeap,
+#endif
+ IMG_UINT32 ui32Attribs,
+ IMG_SIZE_T uAlignment,
+ IMG_UINT32 ui32ChunkSize,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_BOOL *pabMapChunk,
+ PVRSRV_CLIENT_MEM_INFO **ppsMemInfo);
+
+/******************************************************************************
+ * PVR Allocation Synchronisation Functionality...
+ *****************************************************************************/
+
+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);
+
+
+/******************************************************************************
+ * Common Device Class Enumeration
+ *****************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDeviceClass(IMG_CONST PVRSRV_CONNECTION *psConnection,
+ PVRSRV_DEVICE_CLASS DeviceClass,
+ IMG_UINT32 *pui32DevCount,
+ IMG_UINT32 *pui32DevID);
+
+/******************************************************************************
+ * Display Device Class API definition
+ *****************************************************************************/
+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,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID *phBuffer
+#else
+ IMG_HANDLE *phBuffer
+#endif
+ );
+
+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,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID *phSwapChain
+#else
+ IMG_HANDLE *phSwapChain
+#endif
+ );
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDCSwapChain (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSwapChain
+#else
+ IMG_HANDLE hSwapChain
+#endif
+ );
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCDstRect (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSwapChain,
+#else
+ IMG_HANDLE hSwapChain,
+#endif
+ IMG_RECT *psDstRect);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCSrcRect (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSwapChain,
+#else
+ IMG_HANDLE hSwapChain,
+#endif
+ IMG_RECT *psSrcRect);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCDstColourKey (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSwapChain,
+#else
+ IMG_HANDLE hSwapChain,
+#endif
+ IMG_UINT32 ui32CKColour);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCSrcColourKey (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSwapChain,
+#else
+ IMG_HANDLE hSwapChain,
+#endif
+ IMG_UINT32 ui32CKColour);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCBuffers(IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSwapChain,
+ IMG_SID *phBuffer
+#else
+ IMG_HANDLE hSwapChain,
+ IMG_HANDLE *phBuffer
+#endif
+ );
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCBuffers2(IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSwapChain,
+ IMG_SID *phBuffer,
+#else
+ IMG_HANDLE hSwapChain,
+ IMG_HANDLE *phBuffer,
+#endif
+ IMG_SYS_PHYADDR *psPhyAddr);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSwapToDCBuffer (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hBuffer,
+#else
+ IMG_HANDLE hBuffer,
+#endif
+ IMG_UINT32 ui32ClipRectCount,
+ IMG_RECT *psClipRect,
+ IMG_UINT32 ui32SwapInterval,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hPrivateTag
+#else
+ IMG_HANDLE hPrivateTag
+#endif
+ );
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSwapToDCBuffer2 (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hBuffer,
+#else
+ IMG_HANDLE hBuffer,
+#endif
+ IMG_UINT32 ui32SwapInterval,
+ PVRSRV_CLIENT_MEM_INFO **ppsMemInfos,
+ IMG_UINT32 ui32NumMemInfos,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSwapToDCSystem (IMG_HANDLE hDevice,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSwapChain
+#else
+ IMG_HANDLE hSwapChain
+#endif
+ );
+
+/******************************************************************************
+ * Buffer Device Class API definition
+ *****************************************************************************/
+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,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID *phBuffer
+#else
+ IMG_HANDLE *phBuffer
+#endif
+ );
+
+
+/******************************************************************************
+ * PDUMP Function prototypes...
+ *****************************************************************************/
+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,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo,
+#else
+ PVRSRV_CLIENT_MEM_INFO *psMemInfo,
+#endif
+ IMG_UINT32 ui32Offset,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ PDUMP_POLL_OPERATOR eOperator,
+ IMG_UINT32 ui32Flags);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSyncPol(IMG_CONST PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfo,
+#else
+ PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo,
+#endif
+ IMG_BOOL bIsRead,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSyncPol2(IMG_CONST PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfo,
+#else
+ PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo,
+#endif
+ IMG_BOOL bIsRead);
+
+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_DEV_DATA *psDevData,
+ IMG_CHAR *pszRegRegion,
+ IMG_UINT32 ui32RegAddr,
+ IMG_UINT32 ui32RegValue,
+ IMG_UINT32 ui32Flags);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegPolWithFlags(const PVRSRV_DEV_DATA *psDevData,
+ IMG_CHAR *pszRegRegion,
+ IMG_UINT32 ui32RegAddr,
+ IMG_UINT32 ui32RegValue,
+ IMG_UINT32 ui32Mask,
+ IMG_UINT32 ui32Flags);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegPol(const PVRSRV_DEV_DATA *psDevData,
+ IMG_CHAR *pszRegRegion,
+ 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);
+
+#if !defined(USE_CODE)
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMemPages(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo,
+#else
+ IMG_HANDLE hKernelMemInfo,
+#endif
+ IMG_DEV_PHYADDR *pPages,
+ IMG_UINT32 ui32NumPages,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_UINT32 ui32Start,
+ IMG_UINT32 ui32Length,
+ IMG_UINT32 ui32Flags);
+#endif
+
+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, ...)
+#if !defined(USE_CODE)
+ IMG_FORMAT_PRINTF(3, 4)
+#endif
+;
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCommentWithFlagsf(IMG_CONST PVRSRV_CONNECTION *psConnection,
+ IMG_UINT32 ui32Flags,
+ IMG_CONST IMG_CHAR *pszFormat, ...)
+#if !defined(USE_CODE)
+ IMG_FORMAT_PRINTF(3, 4)
+#endif
+;
+
+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_DEV_DATA *psDevData,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_UINT32 ui32Width,
+ IMG_UINT32 ui32Height,
+ IMG_UINT32 ui32StrideInBytes,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemContext,
+#else
+ IMG_HANDLE hDevMemContext,
+#endif
+ IMG_UINT32 ui32Size,
+ PDUMP_PIXEL_FORMAT ePixelFormat,
+ PDUMP_MEM_FORMAT eMemFormat,
+ IMG_UINT32 ui32PDumpFlags);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegRead(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ IMG_CONST IMG_CHAR *pszRegRegion,
+ 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_DEV_DATA *psDevData,
+ 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);
+
+/******************************************************************************
+ * Memory API(s)
+ *****************************************************************************/
+
+/* Exported APIs */
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVAllocUserModeMem (IMG_SIZE_T ui32Size);
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVCallocUserModeMem (IMG_SIZE_T 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_SIZE_T ui32Size);
+IMG_IMPORT IMG_VOID PVRSRVMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_SIZE_T ui32Size);
+
+struct _PVRSRV_MUTEX_OPAQUE_STRUCT_;
+typedef struct _PVRSRV_MUTEX_OPAQUE_STRUCT_ *PVRSRV_MUTEX_HANDLE;
+
+
+#if defined(PVR_DEBUG_MUTEXES)
+
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateMutex(PVRSRV_MUTEX_HANDLE *phMutex,
+ IMG_CHAR pszMutexName[],
+ IMG_CHAR pszFilename[],
+ IMG_INT iLine);
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyMutex(PVRSRV_MUTEX_HANDLE hMutex,
+ IMG_CHAR pszMutexName[],
+ IMG_CHAR pszFilename[],
+ IMG_INT iLine);
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVLockMutex(PVRSRV_MUTEX_HANDLE hMutex,
+ IMG_CHAR pszMutexName[],
+ IMG_CHAR pszFilename[],
+ IMG_INT iLine);
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVUnlockMutex(PVRSRV_MUTEX_HANDLE hMutex,
+ IMG_CHAR pszMutexName[],
+ IMG_CHAR pszFilename[],
+ IMG_INT iLine);
+
+#define PVRSRVCreateMutex(phMutex) PVRSRVCreateMutex(phMutex, #phMutex, __FILE__, __LINE__)
+#define PVRSRVDestroyMutex(hMutex) PVRSRVDestroyMutex(hMutex, #hMutex, __FILE__, __LINE__)
+#define PVRSRVLockMutex(hMutex) PVRSRVLockMutex(hMutex, #hMutex, __FILE__, __LINE__)
+#define PVRSRVUnlockMutex(hMutex) PVRSRVUnlockMutex(hMutex, #hMutex, __FILE__, __LINE__)
+
+#else /* defined(PVR_DEBUG_MUTEXES) */
+
+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);
+
+#endif /* defined(PVR_DEBUG_MUTEXES) */
+
+
+struct _PVRSRV_RECMUTEX_OPAQUE_STRUCT_;
+typedef struct _PVRSRV_RECMUTEX_OPAQUE_STRUCT_ *PVRSRV_RECMUTEX_HANDLE;
+
+
+#if defined(PVR_DEBUG_MUTEXES)
+
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateRecursiveMutex(PVRSRV_RECMUTEX_HANDLE *phMutex,
+ IMG_CHAR pszMutexName[],
+ IMG_CHAR pszFilename[],
+ IMG_INT iLine);
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyRecursiveMutex(PVRSRV_RECMUTEX_HANDLE hMutex,
+ IMG_CHAR pszMutexName[],
+ IMG_CHAR pszFilename[],
+ IMG_INT iLine);
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVLockRecursiveMutex(PVRSRV_RECMUTEX_HANDLE hMutex,
+ IMG_CHAR pszMutexName[],
+ IMG_CHAR pszFilename[],
+ IMG_INT iLine);
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVUnlockRecursiveMutex(PVRSRV_RECMUTEX_HANDLE hMutex,
+ IMG_CHAR pszMutexName[],
+ IMG_CHAR pszFilename[],
+ IMG_INT iLine);
+
+#define PVRSRVCreateRecursiveMutex(phMutex) PVRSRVCreateRecursiveMutex(phMutex, #phMutex, __FILE__, __LINE__)
+#define PVRSRVDestroyRecursiveMutex(hMutex) PVRSRVDestroyRecursiveMutex(hMutex, #hMutex, __FILE__, __LINE__)
+#define PVRSRVLockRecursiveMutex(hMutex) PVRSRVLockRecursiveMutex(hMutex, #hMutex, __FILE__, __LINE__)
+#define PVRSRVUnlockRecursiveMutex(hMutex) PVRSRVUnlockRecursiveMutex(hMutex, #hMutex, __FILE__, __LINE__)
+
+#else /* defined(PVR_DEBUG_MUTEXES) */
+
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateRecursiveMutex(PVRSRV_RECMUTEX_HANDLE *phMutex);
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyRecursiveMutex(PVRSRV_RECMUTEX_HANDLE hMutex);
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVLockRecursiveMutex(PVRSRV_RECMUTEX_HANDLE hMutex);
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVUnlockRecursiveMutex(PVRSRV_RECMUTEX_HANDLE hMutex);
+
+#endif /* defined(PVR_DEBUG_MUTEXES) */
+
+/* Non-recursive coarse-grained mutex shared between all threads in a proccess */
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVLockProcessGlobalMutex(void);
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVUnlockProcessGlobalMutex(void);
+
+
+struct _PVRSRV_SEMAPHORE_OPAQUE_STRUCT_;
+typedef struct _PVRSRV_SEMAPHORE_OPAQUE_STRUCT_ *PVRSRV_SEMAPHORE_HANDLE;
+
+
+ #define IMG_SEMAPHORE_WAIT_INFINITE ((IMG_UINT64)0xFFFFFFFFFFFFFFFFull)
+
+
+#if !defined(USE_CODE)
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVCreateSemaphore)
+#endif
+static INLINE PVRSRV_ERROR PVRSRVCreateSemaphore(PVRSRV_SEMAPHORE_HANDLE *phSemaphore, IMG_INT iInitialCount)
+{
+ PVR_UNREFERENCED_PARAMETER(iInitialCount);
+ *phSemaphore = 0;
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVDestroySemaphore)
+#endif
+static INLINE PVRSRV_ERROR PVRSRVDestroySemaphore(PVRSRV_SEMAPHORE_HANDLE hSemaphore)
+{
+ PVR_UNREFERENCED_PARAMETER(hSemaphore);
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVWaitSemaphore)
+#endif
+static INLINE PVRSRV_ERROR PVRSRVWaitSemaphore(PVRSRV_SEMAPHORE_HANDLE hSemaphore, IMG_UINT64 ui64TimeoutMicroSeconds)
+{
+ PVR_UNREFERENCED_PARAMETER(hSemaphore);
+ PVR_UNREFERENCED_PARAMETER(ui64TimeoutMicroSeconds);
+ return PVRSRV_ERROR_INVALID_PARAMS;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVPostSemaphore)
+#endif
+static INLINE IMG_VOID PVRSRVPostSemaphore(PVRSRV_SEMAPHORE_HANDLE hSemaphore, IMG_INT iPostCount)
+{
+ PVR_UNREFERENCED_PARAMETER(hSemaphore);
+ PVR_UNREFERENCED_PARAMETER(iPostCount);
+}
+
+#endif /* !defined(USE_CODE) */
+
+
+/* Non-exported APIs */
+#if defined(DEBUG) && (defined(__linux__) || defined(__QNXNTO__) )
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVAllocUserModeMemTracking(IMG_SIZE_T ui32Size, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber);
+
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVCallocUserModeMemTracking(IMG_SIZE_T ui32Size, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber);
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVFreeUserModeMemTracking(IMG_VOID *pvMem);
+
+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVReallocUserModeMemTracking(IMG_VOID *pvMem, IMG_SIZE_T ui32NewSize,
+ IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber);
+#endif
+
+/******************************************************************************
+ * PVR Event Object API(s)
+ *****************************************************************************/
+
+IMG_IMPORT PVRSRV_ERROR PVRSRVEventObjectWait(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_EVENTSID hOSEvent
+#else
+ IMG_HANDLE hOSEvent
+#endif
+ );
+
+/*!
+ ******************************************************************************
+
+ @Function PVRSRVCreateSyncInfoModObj
+
+ @Description Creates an empty Modification object to be later used by PVRSRVModifyPendingSyncOps
+
+ ******************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateSyncInfoModObj(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID *phKernelSyncInfoModObj
+#else
+ IMG_HANDLE *phKernelSyncInfoModObj
+#endif
+ );
+
+/*!
+ ******************************************************************************
+
+ @Function PVRSRVDestroySyncInfoModObj
+
+ @Description Destroys a Modification object. Must be empty.
+
+ ******************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroySyncInfoModObj(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfoModObj
+#else
+ IMG_HANDLE hKernelSyncInfoModObj
+#endif
+ );
+
+
+
+/*!
+ ******************************************************************************
+
+ @Function PVRSRVModifyPendingSyncOps
+
+ @Description Returns PRE-INCREMENTED sync op values. Performs thread safe increment
+ of sync ops values as specified by ui32ModifyFlags.
+
+ PVRSRV_ERROR_RETRY is returned if the supplied modification object
+ is not empty. This is on the assumption that a different thread
+ will imminently call PVRSRVModifyCompleteSyncOps. This thread should
+ sleep before retrying. It should be regarded as an error if no such
+ other thread exists.
+
+ Note that this API has implied locking semantics, as follows:
+
+ PVRSRVModifyPendingSyncOps()
+ - announces an operation on the buffer is "pending", and
+ conceptually takes a ticket to represent your place in the queue.
+ - NB: ** exclusive access to the resource is _NOT_ granted at this time **
+ PVRSRVSyncOpsFlushToModObj()
+ - ensures you have exclusive access to the resource (conceptually, a LOCK)
+ - the previously "pending" operation can now be regarded as "in progress"
+ PVRSRVModifyCompleteSyncOps()
+ - declares that the previously "in progress" operation is now complete. (UNLOCK)
+
+
+ ******************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVModifyPendingSyncOps(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfoModObj,
+#else
+ IMG_HANDLE hKernelSyncInfoModObj,
+#endif
+ PVRSRV_CLIENT_SYNC_INFO *psSyncInfo,
+ IMG_UINT32 ui32ModifyFlags,
+ IMG_UINT32 *pui32ReadOpsPending,
+ IMG_UINT32 *pui32WriteOpsPending);
+
+/*!
+ ******************************************************************************
+
+ @Function PVRSRVModifyCompleteSyncOps
+
+ @Description Performs thread safe increment of sync ops values as specified
+ by the ui32ModifyFlags that were given to PVRSRVModifyPendingSyncOps.
+ The supplied Modification Object will become empty.
+
+ Note that this API has implied locking semantics, as
+ described above in PVRSRVModifyPendingSyncOps
+
+ ******************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVModifyCompleteSyncOps(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfoModObj
+#else
+ IMG_HANDLE hKernelSyncInfoModObj
+#endif
+ );
+
+/*!
+ ******************************************************************************
+
+ @Function PVRSRVSyncOpsTakeToken
+
+ @Description Takes a "deli-counter" style token for future use with
+ PVRSRVSyncOpsFlushToToken(). In practice this means
+ recording a snapshot of the current "pending" values. A
+ future PVRSRVSyncOpsFlushToToken() will ensure that all
+ operations that were pending at the time of this
+ PVRSRVSyncOpsTakeToken() call will be flushed.
+ Operations may be subsequently queued after this call
+ and would not be flushed. The caller is required to
+ provide storage for the token. The token is disposable
+ - i.e. the caller can simply let the token go out of
+ scope without telling us... in particular, there is no
+ obligation to call PVRSRVSyncOpsFlushToToken().
+ Multiple tokens may be taken. There is no implied
+ locking with this API.
+
+ ******************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSyncOpsTakeToken(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ const IMG_SID hKernelSyncInfo,
+#else
+ const PVRSRV_CLIENT_SYNC_INFO *psSyncInfo,
+#endif
+ PVRSRV_SYNC_TOKEN *psSyncToken);
+/*!
+ ******************************************************************************
+
+ @Function PVRSRVSyncOpsFlushToToken
+
+ @Description Tests whether the dependencies for a pending sync op modification
+ have been satisfied. If this function returns PVRSRV_OK, then the
+ "complete" counts have caught up with the snapshot of the "pending"
+ values taken when PVRSRVSyncOpsTakeToken() was called.
+ In the event that the dependencies are not (yet) met,
+ this call will auto-retry if bWait is specified, otherwise, it will
+ return PVRSRV_ERROR_RETRY. (Not really an "error")
+
+ (auto-retry behaviour not implemented)
+
+ ******************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSyncOpsFlushToToken(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ const IMG_SID hKernelSyncInfo,
+#else
+ const PVRSRV_CLIENT_SYNC_INFO *psSyncInfo,
+#endif
+ const PVRSRV_SYNC_TOKEN *psSyncToken,
+ IMG_BOOL bWait);
+/*!
+ ******************************************************************************
+
+ @Function PVRSRVSyncOpsFlushToModObj
+
+ @Description Tests whether the dependencies for a pending sync op modification
+ have been satisfied. If this function returns PVRSRV_OK, then the
+ "complete" counts have caught up with the snapshot of the "pending"
+ values taken when PVRSRVModifyPendingSyncOps() was called.
+ PVRSRVModifyCompleteSyncOps() can then be called without risk of
+ stalling. In the event that the dependencies are not (yet) met,
+ this call will auto-retry if bWait is specified, otherwise, it will
+ return PVRSRV_ERROR_RETRY. (Not really an "error")
+
+ Note that this API has implied locking semantics, as
+ described above in PVRSRVModifyPendingSyncOps
+
+ ******************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSyncOpsFlushToModObj(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfoModObj,
+#else
+ IMG_HANDLE hKernelSyncInfoModObj,
+#endif
+ IMG_BOOL bWait);
+
+/*!
+ ******************************************************************************
+
+ @Function PVRSRVSyncOpsFlushToDelta
+
+ @Description Compares the number of outstanding operations (pending count minus
+ complete count) with the limit specified. If no more than ui32Delta
+ operations are outstanding, this function returns PVRSRV_OK.
+ In the event that there are too many outstanding operations,
+ this call will auto-retry if bWait is specified, otherwise, it will
+ return PVRSRV_ERROR_RETRY. (Not really an "error")
+
+ ******************************************************************************/
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSyncOpsFlushToDelta(const PVRSRV_CONNECTION *psConnection,
+ PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo,
+ IMG_UINT32 ui32Delta,
+ IMG_BOOL bWait);
+
+/*!
+ ******************************************************************************
+
+ @Function PVRSRVAllocSyncInfo
+
+ @Description Creates a Sync Object. Unlike the sync objects created
+ automatically with "PVRSRVAllocDeviceMem", the sync objects
+ returned by this function do _not_ have a UM mapping to the
+ sync data and they do _not_ have the device virtual address
+ of the "opscomplete" fields. These data are to be deprecated.
+
+ ******************************************************************************/
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfo(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_CLIENT_SYNC_INFO **ppsSyncInfo);
+
+/*!
+ ******************************************************************************
+
+ @Function PVRSRVFreeSyncInfo
+
+ @Description Destroys a Sync Object created via
+ PVRSRVAllocSyncInfo.
+
+ ******************************************************************************/
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeSyncInfo(IMG_CONST PVRSRV_DEV_DATA *psDevData,
+ PVRSRV_CLIENT_SYNC_INFO *psSyncInfo);
+
+/*!
+ ******************************************************************************
+
+ @Function PVRSRVGetErrorString
+
+ @Description Returns a text string relating to the PVRSRV_ERROR enum.
+
+ ******************************************************************************/
+IMG_IMPORT
+const IMG_CHAR *PVRSRVGetErrorString(PVRSRV_ERROR eError);
+
+
+/*!
+ ******************************************************************************
+
+ @Function PVRSRVCacheInvalidate
+
+ @Description Invalidate the CPU cache for a specified memory
+ area. Note that PVRSRVGetMiscInfo provides similar cpu
+ cache flush/invalidate functionality for some platforms.
+
+ ******************************************************************************/
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCacheInvalidate(const PVRSRV_CONNECTION *psConnection,
+ IMG_PVOID pvLinearAddress,
+ IMG_UINT32 ui32Size);
+
+/******************************************************************************
+ Time wrapping macro
+******************************************************************************/
+#define TIME_NOT_PASSED_UINT32(a,b,c) (((a) - (b)) < (c))
+
+#if defined (__cplusplus)
+}
+#endif
+#endif /* __SERVICES_H__ */
+
+/******************************************************************************
+ End of file (services.h)
+******************************************************************************/
diff --git a/pvr-source/include4/servicesext.h b/pvr-source/include4/servicesext.h
new file mode 100644
index 0000000..80df117
--- /dev/null
+++ b/pvr-source/include4/servicesext.h
@@ -0,0 +1,965 @@
+/*************************************************************************/ /*!
+@Title Services definitions required by external drivers
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Provides services data structures, defines and prototypes
+ required by external drivers.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined (__SERVICESEXT_H__)
+#define __SERVICESEXT_H__
+
+/*
+ * Lock buffer read/write flags
+ */
+#define PVRSRV_LOCKFLG_READONLY (1) /*!< The locking process will only read the locked surface */
+
+/*!
+ *****************************************************************************
+ * Error values
+ *
+ * NOTE: If you change this, make sure you update the error texts in
+ * services4/include/pvrsrv_errors.h to match.
+ *
+ *****************************************************************************/
+typedef enum _PVRSRV_ERROR_
+{
+ PVRSRV_OK = 0,
+ PVRSRV_ERROR_OUT_OF_MEMORY,
+ PVRSRV_ERROR_TOO_FEW_BUFFERS,
+ PVRSRV_ERROR_INVALID_PARAMS,
+ PVRSRV_ERROR_INIT_FAILURE,
+ PVRSRV_ERROR_CANT_REGISTER_CALLBACK,
+ PVRSRV_ERROR_INVALID_DEVICE,
+ PVRSRV_ERROR_NOT_OWNER,
+ PVRSRV_ERROR_BAD_MAPPING,
+ PVRSRV_ERROR_TIMEOUT,
+ PVRSRV_ERROR_FLIP_CHAIN_EXISTS,
+ PVRSRV_ERROR_INVALID_SWAPINTERVAL,
+ PVRSRV_ERROR_SCENE_INVALID,
+ PVRSRV_ERROR_STREAM_ERROR,
+ PVRSRV_ERROR_FAILED_DEPENDENCIES,
+ PVRSRV_ERROR_CMD_NOT_PROCESSED,
+ PVRSRV_ERROR_CMD_TOO_BIG,
+ PVRSRV_ERROR_DEVICE_REGISTER_FAILED,
+ PVRSRV_ERROR_TOOMANYBUFFERS,
+ PVRSRV_ERROR_NOT_SUPPORTED,
+ PVRSRV_ERROR_PROCESSING_BLOCKED,
+
+ PVRSRV_ERROR_CANNOT_FLUSH_QUEUE,
+ PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE,
+ PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS,
+ PVRSRV_ERROR_RETRY,
+
+ PVRSRV_ERROR_DDK_VERSION_MISMATCH,
+ PVRSRV_ERROR_BUILD_MISMATCH,
+ PVRSRV_ERROR_CORE_REVISION_MISMATCH,
+
+ PVRSRV_ERROR_UPLOAD_TOO_BIG,
+
+ PVRSRV_ERROR_INVALID_FLAGS,
+ PVRSRV_ERROR_FAILED_TO_REGISTER_PROCESS,
+
+ PVRSRV_ERROR_UNABLE_TO_LOAD_LIBRARY,
+ PVRSRV_ERROR_UNABLE_GET_FUNC_ADDR,
+ PVRSRV_ERROR_UNLOAD_LIBRARY_FAILED,
+
+ PVRSRV_ERROR_BRIDGE_CALL_FAILED,
+ PVRSRV_ERROR_IOCTL_CALL_FAILED,
+
+ PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND,
+ PVRSRV_ERROR_BUFFER_DEVICE_NOT_FOUND,
+ PVRSRV_ERROR_BUFFER_DEVICE_ALREADY_PRESENT,
+
+ PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND,
+ PVRSRV_ERROR_PCI_CALL_FAILED,
+ PVRSRV_ERROR_PCI_REGION_TOO_SMALL,
+ PVRSRV_ERROR_PCI_REGION_UNAVAILABLE,
+ PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH,
+
+ PVRSRV_ERROR_REGISTER_BASE_NOT_SET,
+
+ PVRSRV_ERROR_BM_BAD_SHAREMEM_HANDLE,
+
+ PVRSRV_ERROR_FAILED_TO_ALLOC_USER_MEM,
+ PVRSRV_ERROR_FAILED_TO_ALLOC_VP_MEMORY,
+ PVRSRV_ERROR_FAILED_TO_MAP_SHARED_PBDESC,
+ PVRSRV_ERROR_FAILED_TO_GET_PHYS_ADDR,
+
+ PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY,
+ PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY,
+
+ PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES,
+ PVRSRV_ERROR_FAILED_TO_FREE_PAGES,
+ PVRSRV_ERROR_FAILED_TO_COPY_PAGES,
+ PVRSRV_ERROR_UNABLE_TO_LOCK_PAGES,
+ PVRSRV_ERROR_UNABLE_TO_UNLOCK_PAGES,
+ PVRSRV_ERROR_STILL_MAPPED,
+ PVRSRV_ERROR_MAPPING_NOT_FOUND,
+ PVRSRV_ERROR_PHYS_ADDRESS_EXCEEDS_32BIT,
+ PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE,
+
+ PVRSRV_ERROR_INVALID_SEGMENT_BLOCK,
+ PVRSRV_ERROR_INVALID_SGXDEVDATA,
+ PVRSRV_ERROR_INVALID_DEVINFO,
+ PVRSRV_ERROR_INVALID_MEMINFO,
+ PVRSRV_ERROR_INVALID_MISCINFO,
+ PVRSRV_ERROR_UNKNOWN_IOCTL,
+ PVRSRV_ERROR_INVALID_CONTEXT,
+ PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT,
+ PVRSRV_ERROR_INVALID_HEAP,
+ PVRSRV_ERROR_INVALID_KERNELINFO,
+ PVRSRV_ERROR_UNKNOWN_POWER_STATE,
+ PVRSRV_ERROR_INVALID_HANDLE_TYPE,
+ PVRSRV_ERROR_INVALID_WRAP_TYPE,
+ PVRSRV_ERROR_INVALID_PHYS_ADDR,
+ PVRSRV_ERROR_INVALID_CPU_ADDR,
+ PVRSRV_ERROR_INVALID_HEAPINFO,
+ PVRSRV_ERROR_INVALID_PERPROC,
+ PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO,
+ PVRSRV_ERROR_INVALID_MAP_REQUEST,
+ PVRSRV_ERROR_INVALID_UNMAP_REQUEST,
+ PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP,
+ PVRSRV_ERROR_MAPPING_STILL_IN_USE,
+
+ PVRSRV_ERROR_EXCEEDED_HW_LIMITS,
+ PVRSRV_ERROR_NO_STAGING_BUFFER_ALLOCATED,
+
+ PVRSRV_ERROR_UNABLE_TO_CREATE_PERPROC_AREA,
+ PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT,
+ PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT,
+ PVRSRV_ERROR_UNABLE_TO_REGISTER_EVENT,
+ PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT,
+ PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD,
+ PVRSRV_ERROR_UNABLE_TO_CLOSE_THREAD,
+ PVRSRV_ERROR_THREAD_READ_ERROR,
+ PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER,
+ PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR,
+ PVRSRV_ERROR_UNABLE_TO_UNINSTALL_ISR,
+ PVRSRV_ERROR_ISR_ALREADY_INSTALLED,
+ PVRSRV_ERROR_ISR_NOT_INSTALLED,
+ PVRSRV_ERROR_UNABLE_TO_INITIALISE_INTERRUPT,
+ PVRSRV_ERROR_UNABLE_TO_RETRIEVE_INFO,
+ PVRSRV_ERROR_UNABLE_TO_DO_BACKWARDS_BLIT,
+ PVRSRV_ERROR_UNABLE_TO_CLOSE_SERVICES,
+ PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT,
+ PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE,
+ PVRSRV_ERROR_UNABLE_TO_CLOSE_HANDLE,
+
+ PVRSRV_ERROR_INVALID_CCB_COMMAND,
+
+ PVRSRV_ERROR_UNABLE_TO_LOCK_RESOURCE,
+ PVRSRV_ERROR_INVALID_LOCK_ID,
+ PVRSRV_ERROR_RESOURCE_NOT_LOCKED,
+
+ PVRSRV_ERROR_FLIP_FAILED,
+ PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED,
+
+ PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE,
+
+ PVRSRV_ERROR_CREATE_RENDER_CONTEXT_FAILED,
+ PVRSRV_ERROR_UNKNOWN_PRIMARY_FRAG,
+ PVRSRV_ERROR_UNEXPECTED_SECONDARY_FRAG,
+ PVRSRV_ERROR_UNEXPECTED_PRIMARY_FRAG,
+
+ PVRSRV_ERROR_UNABLE_TO_INSERT_FENCE_ID,
+
+ PVRSRV_ERROR_BLIT_SETUP_FAILED,
+
+ PVRSRV_ERROR_PDUMP_NOT_AVAILABLE,
+ PVRSRV_ERROR_PDUMP_BUFFER_FULL,
+ PVRSRV_ERROR_PDUMP_BUF_OVERFLOW,
+ PVRSRV_ERROR_PDUMP_NOT_ACTIVE,
+ PVRSRV_ERROR_INCOMPLETE_LINE_OVERLAPS_PAGES,
+
+ PVRSRV_ERROR_MUTEX_DESTROY_FAILED,
+ PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR,
+
+ PVRSRV_ERROR_INSUFFICIENT_SCRIPT_SPACE,
+ PVRSRV_ERROR_INSUFFICIENT_SPACE_FOR_COMMAND,
+
+ PVRSRV_ERROR_PROCESS_NOT_INITIALISED,
+ PVRSRV_ERROR_PROCESS_NOT_FOUND,
+ PVRSRV_ERROR_SRV_CONNECT_FAILED,
+ PVRSRV_ERROR_SRV_DISCONNECT_FAILED,
+ PVRSRV_ERROR_DEINT_PHASE_FAILED,
+ PVRSRV_ERROR_INIT2_PHASE_FAILED,
+
+ PVRSRV_ERROR_UNABLE_TO_FIND_RESOURCE,
+
+ PVRSRV_ERROR_NO_DC_DEVICES_FOUND,
+ PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE,
+ PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE,
+ PVRSRV_ERROR_NO_DEVICEDATA_FOUND,
+ PVRSRV_ERROR_NO_DEVICENODE_FOUND,
+ PVRSRV_ERROR_NO_CLIENTNODE_FOUND,
+ PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE,
+
+ PVRSRV_ERROR_UNABLE_TO_INIT_TASK,
+ PVRSRV_ERROR_UNABLE_TO_SCHEDULE_TASK,
+ PVRSRV_ERROR_UNABLE_TO_KILL_TASK,
+
+ PVRSRV_ERROR_UNABLE_TO_ENABLE_TIMER,
+ PVRSRV_ERROR_UNABLE_TO_DISABLE_TIMER,
+ PVRSRV_ERROR_UNABLE_TO_REMOVE_TIMER,
+
+ PVRSRV_ERROR_UNKNOWN_PIXEL_FORMAT,
+ PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION,
+
+ PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE,
+ PVRSRV_ERROR_HANDLE_NOT_ALLOCATED,
+ PVRSRV_ERROR_HANDLE_TYPE_MISMATCH,
+ PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE,
+ PVRSRV_ERROR_HANDLE_NOT_SHAREABLE,
+ PVRSRV_ERROR_HANDLE_NOT_FOUND,
+ PVRSRV_ERROR_INVALID_SUBHANDLE,
+ PVRSRV_ERROR_HANDLE_BATCH_IN_USE,
+ PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE,
+
+ PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE,
+ PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED,
+
+ PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE,
+ PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP,
+
+ PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE,
+
+ PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE,
+ PVRSRV_ERROR_INVALID_DEVICEID,
+ PVRSRV_ERROR_DEVICEID_NOT_FOUND,
+
+ PVRSRV_ERROR_MEMORY_TEST_FAILED,
+ PVRSRV_ERROR_CPUPADDR_TEST_FAILED,
+ PVRSRV_ERROR_COPY_TEST_FAILED,
+
+ PVRSRV_ERROR_SEMAPHORE_NOT_INITIALISED,
+
+ PVRSRV_ERROR_UNABLE_TO_RELEASE_CLOCK,
+ PVRSRV_ERROR_CLOCK_REQUEST_FAILED,
+ PVRSRV_ERROR_DISABLE_CLOCK_FAILURE,
+ PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE,
+ PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE,
+ PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK,
+ PVRSRV_ERROR_UNABLE_TO_GET_CLOCK,
+ PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK,
+ PVRSRV_ERROR_UNABLE_TO_GET_SYSTEM_CLOCK,
+
+ PVRSRV_ERROR_UNKNOWN_SGL_ERROR,
+
+ PVRSRV_ERROR_SYSTEM_POWER_CHANGE_FAILURE,
+ PVRSRV_ERROR_DEVICE_POWER_CHANGE_FAILURE,
+
+ PVRSRV_ERROR_BAD_SYNC_STATE,
+
+ PVRSRV_ERROR_CACHEOP_FAILED,
+
+ PVRSRV_ERROR_CACHE_INVALIDATE_FAILED,
+
+ PVRSRV_ERROR_FORCE_I32 = 0x7fffffff
+
+} PVRSRV_ERROR;
+
+
+/*!
+ *****************************************************************************
+ * List of known device classes.
+ *****************************************************************************/
+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;
+
+
+/*!
+ *****************************************************************************
+ * States for power management
+ *****************************************************************************/
+typedef enum _PVRSRV_SYS_POWER_STATE_
+{
+ PVRSRV_SYS_POWER_STATE_Unspecified = -1, /*!< Unspecified : Uninitialised */
+ PVRSRV_SYS_POWER_STATE_D0 = 0, /*!< On */
+ PVRSRV_SYS_POWER_STATE_D1 = 1, /*!< User Idle */
+ PVRSRV_SYS_POWER_STATE_D2 = 2, /*!< System Idle / sleep */
+ PVRSRV_SYS_POWER_STATE_D3 = 3, /*!< Suspend / Hibernate */
+ PVRSRV_SYS_POWER_STATE_D4 = 4, /*!< shutdown */
+
+ PVRSRV_SYS_POWER_STATE_FORCE_I32 = 0x7fffffff
+
+} PVRSRV_SYS_POWER_STATE, *PPVRSRV_SYS_POWER_STATE;
+
+
+typedef enum _PVRSRV_DEV_POWER_STATE_
+{
+ PVRSRV_DEV_POWER_STATE_DEFAULT = -1, /*!< Default state for the device */
+ PVRSRV_DEV_POWER_STATE_ON = 0, /*!< Running */
+ PVRSRV_DEV_POWER_STATE_IDLE = 1, /*!< Powered but operation paused */
+ PVRSRV_DEV_POWER_STATE_OFF = 2, /*!< Unpowered */
+
+ PVRSRV_DEV_POWER_STATE_FORCE_I32 = 0x7fffffff
+
+} PVRSRV_DEV_POWER_STATE, *PPVRSRV_DEV_POWER_STATE; /* PRQA S 3205 */
+
+
+/* Power transition handler prototypes */
+typedef PVRSRV_ERROR (*PFN_PRE_POWER) (IMG_HANDLE hDevHandle,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+typedef PVRSRV_ERROR (*PFN_POST_POWER) (IMG_HANDLE hDevHandle,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+
+/* Clock speed handler prototypes */
+typedef PVRSRV_ERROR (*PFN_PRE_CLOCKSPEED_CHANGE) (IMG_HANDLE hDevHandle,
+ IMG_BOOL bIdleDevice,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+typedef PVRSRV_ERROR (*PFN_POST_CLOCKSPEED_CHANGE) (IMG_HANDLE hDevHandle,
+ IMG_BOOL bIdleDevice,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+
+
+/*****************************************************************************
+ * Enumeration of all possible pixel types. Where applicable, Ordering of name
+ * is in reverse order of memory bytes (i.e. as a word in little endian).
+ * e.g. A8R8G8B8 is in memory as 4 bytes in order: BB GG RR AA
+ *
+ * NOTE: When modifying this structure please update the client driver format
+ * tables located in %WORKROOT%/eurasia/codegen/pixfmts using the tool
+ * located in %WORKROOT%/eurasia/tools/intern/TextureFormatParser.
+ *
+ *****************************************************************************/
+typedef enum _PVRSRV_PIXEL_FORMAT_ {
+ /* Basic types */
+ PVRSRV_PIXEL_FORMAT_UNKNOWN = 0,
+ PVRSRV_PIXEL_FORMAT_RGB565 = 1,
+ PVRSRV_PIXEL_FORMAT_RGB555 = 2,
+ PVRSRV_PIXEL_FORMAT_RGB888 = 3, /*!< 24bit */
+ PVRSRV_PIXEL_FORMAT_BGR888 = 4, /*!< 24bit */
+ 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 = 26,
+ PVRSRV_PIXEL_FORMAT_XBGR8888 = 27,
+ PVRSRV_PIXEL_FORMAT_BGRA8888 = 28,
+ PVRSRV_PIXEL_FORMAT_XRGB4444 = 29,
+ PVRSRV_PIXEL_FORMAT_ARGB8332 = 30,
+ PVRSRV_PIXEL_FORMAT_A2RGB10 = 31, /*!< 32bpp, 10 bits for R, G, B, 2 bits for A */
+ PVRSRV_PIXEL_FORMAT_A2BGR10 = 32, /*!< 32bpp, 10 bits for B, G, R, 2 bits for A */
+ PVRSRV_PIXEL_FORMAT_P8 = 33,
+ PVRSRV_PIXEL_FORMAT_L8 = 34,
+ PVRSRV_PIXEL_FORMAT_A8L8 = 35,
+ PVRSRV_PIXEL_FORMAT_A4L4 = 36,
+ PVRSRV_PIXEL_FORMAT_L16 = 37,
+ PVRSRV_PIXEL_FORMAT_L6V5U5 = 38,
+ PVRSRV_PIXEL_FORMAT_V8U8 = 39,
+ PVRSRV_PIXEL_FORMAT_V16U16 = 40,
+ PVRSRV_PIXEL_FORMAT_QWVU8888 = 41,
+ PVRSRV_PIXEL_FORMAT_XLVU8888 = 42,
+ PVRSRV_PIXEL_FORMAT_QWVU16 = 43,
+ PVRSRV_PIXEL_FORMAT_D16 = 44,
+ PVRSRV_PIXEL_FORMAT_D24S8 = 45,
+ PVRSRV_PIXEL_FORMAT_D24X8 = 46,
+
+ /* Added to ensure TQ build */
+ PVRSRV_PIXEL_FORMAT_ABGR16 = 47,
+ PVRSRV_PIXEL_FORMAT_ABGR16F = 48,
+ PVRSRV_PIXEL_FORMAT_ABGR32 = 49,
+ PVRSRV_PIXEL_FORMAT_ABGR32F = 50,
+ PVRSRV_PIXEL_FORMAT_B10GR11 = 51,
+ PVRSRV_PIXEL_FORMAT_GR88 = 52,
+ PVRSRV_PIXEL_FORMAT_BGR32 = 53,
+ PVRSRV_PIXEL_FORMAT_GR32 = 54,
+ PVRSRV_PIXEL_FORMAT_E5BGR9 = 55,
+
+ /* reserved types */
+ PVRSRV_PIXEL_FORMAT_RESERVED1 = 56,
+ PVRSRV_PIXEL_FORMAT_RESERVED2 = 57,
+ PVRSRV_PIXEL_FORMAT_RESERVED3 = 58,
+ PVRSRV_PIXEL_FORMAT_RESERVED4 = 59,
+ PVRSRV_PIXEL_FORMAT_RESERVED5 = 60,
+
+ /* RGB space packed formats */
+ PVRSRV_PIXEL_FORMAT_R8G8_B8G8 = 61,
+ PVRSRV_PIXEL_FORMAT_G8R8_G8B8 = 62,
+
+ /* YUV space planar formats */
+ PVRSRV_PIXEL_FORMAT_NV11 = 63,
+ PVRSRV_PIXEL_FORMAT_NV12 = 64,
+
+ /* YUV space packed formats */
+ PVRSRV_PIXEL_FORMAT_YUY2 = 65,
+ PVRSRV_PIXEL_FORMAT_YUV420 = 66,
+ PVRSRV_PIXEL_FORMAT_YUV444 = 67,
+ PVRSRV_PIXEL_FORMAT_VUY444 = 68,
+ PVRSRV_PIXEL_FORMAT_YUYV = 69,
+ PVRSRV_PIXEL_FORMAT_YVYU = 70,
+ PVRSRV_PIXEL_FORMAT_UYVY = 71,
+ PVRSRV_PIXEL_FORMAT_VYUY = 72,
+
+ PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY = 73, /*!< See http://www.fourcc.org/yuv.php#UYVY */
+ PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YUYV = 74, /*!< See http://www.fourcc.org/yuv.php#YUYV */
+ PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YVYU = 75, /*!< See http://www.fourcc.org/yuv.php#YVYU */
+ PVRSRV_PIXEL_FORMAT_FOURCC_ORG_VYUY = 76, /*!< No fourcc.org link */
+ PVRSRV_PIXEL_FORMAT_FOURCC_ORG_AYUV = 77, /*!< See http://www.fourcc.org/yuv.php#AYUV */
+
+ /* 4 component, 32 bits per component types */
+ PVRSRV_PIXEL_FORMAT_A32B32G32R32 = 78, /*!< type unspecified */
+ PVRSRV_PIXEL_FORMAT_A32B32G32R32F = 79, /*!< float type */
+ PVRSRV_PIXEL_FORMAT_A32B32G32R32_UINT = 80, /*!< uint type */
+ PVRSRV_PIXEL_FORMAT_A32B32G32R32_SINT = 81, /*!< sint type */
+
+ /* 3 component, 32 bits per component types */
+ PVRSRV_PIXEL_FORMAT_B32G32R32 = 82, /*!< type unspecified */
+ PVRSRV_PIXEL_FORMAT_B32G32R32F = 83, /*!< float data */
+ PVRSRV_PIXEL_FORMAT_B32G32R32_UINT = 84, /*!< uint data */
+ PVRSRV_PIXEL_FORMAT_B32G32R32_SINT = 85, /*!< signed int data */
+
+ /* 2 component, 32 bits per component types */
+ PVRSRV_PIXEL_FORMAT_G32R32 = 86, /*!< type unspecified */
+ PVRSRV_PIXEL_FORMAT_G32R32F = 87, /*!< float */
+ PVRSRV_PIXEL_FORMAT_G32R32_UINT = 88, /*!< uint */
+ PVRSRV_PIXEL_FORMAT_G32R32_SINT = 89, /*!< signed int */
+
+ /* 1 component, 32 bits per component types */
+ PVRSRV_PIXEL_FORMAT_D32F = 90, /*!< float depth */
+ PVRSRV_PIXEL_FORMAT_R32 = 91, /*!< type unspecified */
+ PVRSRV_PIXEL_FORMAT_R32F = 92, /*!< float type */
+ PVRSRV_PIXEL_FORMAT_R32_UINT = 93, /*!< unsigned int type */
+ PVRSRV_PIXEL_FORMAT_R32_SINT = 94, /*!< signed int type */
+
+ /* 4 component, 16 bits per component types */
+ PVRSRV_PIXEL_FORMAT_A16B16G16R16 = 95, /*!< type unspecified */
+ PVRSRV_PIXEL_FORMAT_A16B16G16R16F = 96, /*!< type float */
+ PVRSRV_PIXEL_FORMAT_A16B16G16R16_SINT = 97, /*!< signed ints */
+ PVRSRV_PIXEL_FORMAT_A16B16G16R16_SNORM = 98, /*!< signed normalised int */
+ PVRSRV_PIXEL_FORMAT_A16B16G16R16_UINT = 99, /*!< unsigned ints */
+ PVRSRV_PIXEL_FORMAT_A16B16G16R16_UNORM = 100, /*!< normalised unsigned int */
+
+ /* 2 component, 16 bits per component types */
+ PVRSRV_PIXEL_FORMAT_G16R16 = 101, /*!< unspecified type */
+ PVRSRV_PIXEL_FORMAT_G16R16F = 102, /*!< float type */
+ PVRSRV_PIXEL_FORMAT_G16R16_UINT = 103, /*!< unsigned int type */
+ PVRSRV_PIXEL_FORMAT_G16R16_UNORM = 104, /*!< unsigned normalised */
+ PVRSRV_PIXEL_FORMAT_G16R16_SINT = 105, /*!< signed int */
+ PVRSRV_PIXEL_FORMAT_G16R16_SNORM = 106, /*!< signed normalised */
+
+ /* 1 component, 16 bits per component types */
+ PVRSRV_PIXEL_FORMAT_R16 = 107, /*!< type unspecified */
+ PVRSRV_PIXEL_FORMAT_R16F = 108, /*!< float type */
+ PVRSRV_PIXEL_FORMAT_R16_UINT = 109, /*!< unsigned int type */
+ PVRSRV_PIXEL_FORMAT_R16_UNORM = 110, /*!< unsigned normalised int type */
+ PVRSRV_PIXEL_FORMAT_R16_SINT = 111, /*!< signed int type */
+ PVRSRV_PIXEL_FORMAT_R16_SNORM = 112, /*!< signed normalised int type */
+
+ /* 4 component, 8 bits per component types */
+ PVRSRV_PIXEL_FORMAT_X8R8G8B8 = 113, /*!< type unspecified */
+ PVRSRV_PIXEL_FORMAT_X8R8G8B8_UNORM = 114, /*!< normalised unsigned int */
+ PVRSRV_PIXEL_FORMAT_X8R8G8B8_UNORM_SRGB = 115, /*!< normalised uint with sRGB */
+
+ PVRSRV_PIXEL_FORMAT_A8R8G8B8 = 116, /*!< type unspecified */
+ PVRSRV_PIXEL_FORMAT_A8R8G8B8_UNORM = 117, /*!< normalised unsigned int */
+ PVRSRV_PIXEL_FORMAT_A8R8G8B8_UNORM_SRGB = 118, /*!< normalised uint with sRGB */
+
+ PVRSRV_PIXEL_FORMAT_A8B8G8R8 = 119, /*!< type unspecified */
+ PVRSRV_PIXEL_FORMAT_A8B8G8R8_UINT = 120, /*!< unsigned int */
+ PVRSRV_PIXEL_FORMAT_A8B8G8R8_UNORM = 121, /*!< normalised unsigned int */
+ PVRSRV_PIXEL_FORMAT_A8B8G8R8_UNORM_SRGB = 122, /*!< normalised unsigned int */
+ PVRSRV_PIXEL_FORMAT_A8B8G8R8_SINT = 123, /*!< signed int */
+ PVRSRV_PIXEL_FORMAT_A8B8G8R8_SNORM = 124, /*!< normalised signed int */
+
+ /* 2 component, 8 bits per component types */
+ PVRSRV_PIXEL_FORMAT_G8R8 = 125, /*!< type unspecified */
+ PVRSRV_PIXEL_FORMAT_G8R8_UINT = 126, /*!< unsigned int type */
+ PVRSRV_PIXEL_FORMAT_G8R8_UNORM = 127, /*!< unsigned int normalised */
+ PVRSRV_PIXEL_FORMAT_G8R8_SINT = 128, /*!< signed int type */
+ PVRSRV_PIXEL_FORMAT_G8R8_SNORM = 129, /*!< signed int normalised */
+
+ /* 1 component, 8 bits per component types */
+ PVRSRV_PIXEL_FORMAT_A8 = 130, /*!< type unspecified, alpha channel */
+ PVRSRV_PIXEL_FORMAT_R8 = 131, /*!< type unspecified */
+ PVRSRV_PIXEL_FORMAT_R8_UINT = 132, /*!< unsigned int */
+ PVRSRV_PIXEL_FORMAT_R8_UNORM = 133, /*!< unsigned normalised int */
+ PVRSRV_PIXEL_FORMAT_R8_SINT = 134, /*!< signed int */
+ PVRSRV_PIXEL_FORMAT_R8_SNORM = 135, /*!< signed normalised int */
+
+ /* A2RGB10 types */
+ PVRSRV_PIXEL_FORMAT_A2B10G10R10 = 136, /*!< Type unspecified */
+ PVRSRV_PIXEL_FORMAT_A2B10G10R10_UNORM = 137, /*!< normalised unsigned int */
+ PVRSRV_PIXEL_FORMAT_A2B10G10R10_UINT = 138, /*!< unsigned int */
+
+ /* F11F11F10 types */
+ PVRSRV_PIXEL_FORMAT_B10G11R11 = 139, /*!< type unspecified */
+ PVRSRV_PIXEL_FORMAT_B10G11R11F = 140, /*!< float type */
+
+ /* esoteric types */
+ PVRSRV_PIXEL_FORMAT_X24G8R32 = 141, /*!< 64 bit, type unspecified (Usually typed to D32S8 style) */
+ PVRSRV_PIXEL_FORMAT_G8R24 = 142, /*!< 32 bit, type unspecified (Usually typed to D24S8 style) */
+ PVRSRV_PIXEL_FORMAT_X8R24 = 143,
+ PVRSRV_PIXEL_FORMAT_E5B9G9R9 = 144, /*!< 32 bit, shared exponent (RGBE). */
+ PVRSRV_PIXEL_FORMAT_R1 = 145, /*!< 1 bit monochrome */
+
+ PVRSRV_PIXEL_FORMAT_RESERVED6 = 146,
+ PVRSRV_PIXEL_FORMAT_RESERVED7 = 147,
+ PVRSRV_PIXEL_FORMAT_RESERVED8 = 148,
+ PVRSRV_PIXEL_FORMAT_RESERVED9 = 149,
+ PVRSRV_PIXEL_FORMAT_RESERVED10 = 150,
+ PVRSRV_PIXEL_FORMAT_RESERVED11 = 151,
+ PVRSRV_PIXEL_FORMAT_RESERVED12 = 152,
+ PVRSRV_PIXEL_FORMAT_RESERVED13 = 153,
+ PVRSRV_PIXEL_FORMAT_RESERVED14 = 154,
+ PVRSRV_PIXEL_FORMAT_RESERVED15 = 155,
+ PVRSRV_PIXEL_FORMAT_RESERVED16 = 156,
+ PVRSRV_PIXEL_FORMAT_RESERVED17 = 157,
+ PVRSRV_PIXEL_FORMAT_RESERVED18 = 158,
+ PVRSRV_PIXEL_FORMAT_RESERVED19 = 159,
+ PVRSRV_PIXEL_FORMAT_RESERVED20 = 160,
+
+ /* DXLegacy vertex types */
+ PVRSRV_PIXEL_FORMAT_UBYTE4 = 161, /*!< 4 channels, 1 byte per channel, normalised */
+ PVRSRV_PIXEL_FORMAT_SHORT4 = 162, /*!< 4 signed channels, 16 bits each, unnormalised */
+ PVRSRV_PIXEL_FORMAT_SHORT4N = 163, /*!< 4 signed channels, 16 bits each, normalised */
+ PVRSRV_PIXEL_FORMAT_USHORT4N = 164, /*!< 4 unsigned channels, 16 bits each, normalised */
+ PVRSRV_PIXEL_FORMAT_SHORT2N = 165, /*!< 2 signed channels, 16 bits each, normalised */
+ PVRSRV_PIXEL_FORMAT_SHORT2 = 166, /*!< 2 signed channels, 16 bits each, unnormalised */
+ PVRSRV_PIXEL_FORMAT_USHORT2N = 167, /*!< 2 unsigned channels, 16 bits each, normalised */
+ PVRSRV_PIXEL_FORMAT_UDEC3 = 168, /*!< 3 10-bit channels, unnormalised, unsigned*/
+ PVRSRV_PIXEL_FORMAT_DEC3N = 169, /*!< 3 10-bit channels, signed normalised */
+ PVRSRV_PIXEL_FORMAT_F16_2 = 170, /*!< 2 F16 channels */
+ PVRSRV_PIXEL_FORMAT_F16_4 = 171, /*!< 4 F16 channels */
+
+ /* misc float types */
+ PVRSRV_PIXEL_FORMAT_L_F16 = 172,
+ PVRSRV_PIXEL_FORMAT_L_F16_REP = 173,
+ PVRSRV_PIXEL_FORMAT_L_F16_A_F16 = 174,
+ PVRSRV_PIXEL_FORMAT_A_F16 = 175,
+ PVRSRV_PIXEL_FORMAT_B16G16R16F = 176,
+
+ PVRSRV_PIXEL_FORMAT_L_F32 = 177,
+ PVRSRV_PIXEL_FORMAT_A_F32 = 178,
+ PVRSRV_PIXEL_FORMAT_L_F32_A_F32 = 179,
+
+ /* powervr types */
+ PVRSRV_PIXEL_FORMAT_PVRTC2 = 180,
+ PVRSRV_PIXEL_FORMAT_PVRTC4 = 181,
+ PVRSRV_PIXEL_FORMAT_PVRTCII2 = 182,
+ PVRSRV_PIXEL_FORMAT_PVRTCII4 = 183,
+ PVRSRV_PIXEL_FORMAT_PVRTCIII = 184,
+ PVRSRV_PIXEL_FORMAT_PVRO8 = 185,
+ PVRSRV_PIXEL_FORMAT_PVRO88 = 186,
+ PVRSRV_PIXEL_FORMAT_PT1 = 187,
+ PVRSRV_PIXEL_FORMAT_PT2 = 188,
+ PVRSRV_PIXEL_FORMAT_PT4 = 189,
+ PVRSRV_PIXEL_FORMAT_PT8 = 190,
+ PVRSRV_PIXEL_FORMAT_PTW = 191,
+ PVRSRV_PIXEL_FORMAT_PTB = 192,
+ PVRSRV_PIXEL_FORMAT_MONO8 = 193,
+ PVRSRV_PIXEL_FORMAT_MONO16 = 194,
+
+ /* additional YUV types */
+ PVRSRV_PIXEL_FORMAT_C0_YUYV = 195,
+ PVRSRV_PIXEL_FORMAT_C0_UYVY = 196,
+ PVRSRV_PIXEL_FORMAT_C0_YVYU = 197,
+ PVRSRV_PIXEL_FORMAT_C0_VYUY = 198,
+ PVRSRV_PIXEL_FORMAT_C1_YUYV = 199,
+ PVRSRV_PIXEL_FORMAT_C1_UYVY = 200,
+ PVRSRV_PIXEL_FORMAT_C1_YVYU = 201,
+ PVRSRV_PIXEL_FORMAT_C1_VYUY = 202,
+
+ /* planar YUV types */
+ PVRSRV_PIXEL_FORMAT_C0_YUV420_2P_UV = 203,
+ PVRSRV_PIXEL_FORMAT_C0_YUV420_2P_VU = 204,
+ PVRSRV_PIXEL_FORMAT_C0_YUV420_3P = 205,
+ PVRSRV_PIXEL_FORMAT_C1_YUV420_2P_UV = 206,
+ PVRSRV_PIXEL_FORMAT_C1_YUV420_2P_VU = 207,
+ PVRSRV_PIXEL_FORMAT_C1_YUV420_3P = 208,
+
+ PVRSRV_PIXEL_FORMAT_A2B10G10R10F = 209,
+ PVRSRV_PIXEL_FORMAT_B8G8R8_SINT = 210,
+ PVRSRV_PIXEL_FORMAT_PVRF32SIGNMASK = 211,
+
+ PVRSRV_PIXEL_FORMAT_ABGR4444 = 212,
+ PVRSRV_PIXEL_FORMAT_ABGR1555 = 213,
+ PVRSRV_PIXEL_FORMAT_BGR565 = 214,
+
+ /* 4k aligned planar YUV */
+ PVRSRV_PIXEL_FORMAT_C0_4KYUV420_2P_UV = 215,
+ PVRSRV_PIXEL_FORMAT_C0_4KYUV420_2P_VU = 216,
+ PVRSRV_PIXEL_FORMAT_C1_4KYUV420_2P_UV = 217,
+ PVRSRV_PIXEL_FORMAT_C1_4KYUV420_2P_VU = 218,
+ PVRSRV_PIXEL_FORMAT_P208 = 219,
+ PVRSRV_PIXEL_FORMAT_A8P8 = 220,
+
+ PVRSRV_PIXEL_FORMAT_A4 = 221,
+ PVRSRV_PIXEL_FORMAT_AYUV8888 = 222,
+ PVRSRV_PIXEL_FORMAT_RAW256 = 223,
+ PVRSRV_PIXEL_FORMAT_RAW512 = 224,
+ PVRSRV_PIXEL_FORMAT_RAW1024 = 225,
+
+ PVRSRV_PIXEL_FORMAT_FORCE_I32 = 0x7fffffff
+
+} PVRSRV_PIXEL_FORMAT;
+
+/*!
+ *****************************************************************************
+ * Enumeration of possible alpha types.
+ *****************************************************************************/
+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;
+
+/*!
+ *****************************************************************************
+ * Enumeration of possible alpha types.
+ *****************************************************************************/
+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;
+
+
+/*
+ * Drawable orientation (in degrees clockwise).
+ * Opposite sense from WSEGL.
+ */
+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;
+
+/*!
+ * Flags for DisplayClassCreateSwapChain.
+ */
+#define PVRSRV_CREATE_SWAPCHAIN_SHARED (1<<0)
+#define PVRSRV_CREATE_SWAPCHAIN_QUERY (1<<1)
+#define PVRSRV_CREATE_SWAPCHAIN_OEMOVERLAY (1<<2)
+
+/*!
+ *****************************************************************************
+ * Structure providing implementation details for serialisation and
+ * synchronisation of operations. This is the fundamental unit on which operations
+ * are synced, and would typically be included in any data structures that require
+ * serialised accesses etc. e.g. MEM_INFO structures
+ *
+ *****************************************************************************/
+/*
+ Sync Data to be shared/mapped between user/kernel
+*/
+typedef struct _PVRSRV_SYNC_DATA_
+{
+ /* CPU accessible WriteOp Info */
+ IMG_UINT32 ui32WriteOpsPending;
+ volatile IMG_UINT32 ui32WriteOpsComplete;
+
+ /* CPU accessible ReadOp Info */
+ IMG_UINT32 ui32ReadOpsPending;
+ volatile IMG_UINT32 ui32ReadOpsComplete;
+
+ /* CPU accessible ReadOp2 Info */
+ IMG_UINT32 ui32ReadOps2Pending;
+ volatile IMG_UINT32 ui32ReadOps2Complete;
+
+ /* pdump specific value */
+ IMG_UINT32 ui32LastOpDumpVal;
+ IMG_UINT32 ui32LastReadOpDumpVal;
+
+ /* Last write oprtation on this sync */
+ IMG_UINT64 ui64LastWrite;
+
+} PVRSRV_SYNC_DATA;
+
+/*
+ Client Sync Info structure
+*/
+typedef struct _PVRSRV_CLIENT_SYNC_INFO_
+{
+ /* mapping of the kernel sync data */
+ PVRSRV_SYNC_DATA *psSyncData;
+
+ /* Device accessible WriteOp Info */
+ IMG_DEV_VIRTADDR sWriteOpsCompleteDevVAddr;
+
+ /* Device accessible ReadOp Info */
+ IMG_DEV_VIRTADDR sReadOpsCompleteDevVAddr;
+
+ /* Device accessible ReadOp2 Info */
+ IMG_DEV_VIRTADDR sReadOps2CompleteDevVAddr;
+
+ /* handle to client mapping data (OS specific) */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMappingInfo;
+
+ /* handle to kernel sync info */
+ IMG_SID hKernelSyncInfo;
+#else
+ IMG_HANDLE hMappingInfo;
+
+ /* handle to kernel sync info */
+ IMG_HANDLE hKernelSyncInfo;
+#endif
+
+} PVRSRV_CLIENT_SYNC_INFO, *PPVRSRV_CLIENT_SYNC_INFO;
+
+/*!
+ *****************************************************************************
+ * Resource locking structure
+ *****************************************************************************/
+typedef struct PVRSRV_RESOURCE_TAG
+{
+ volatile IMG_UINT32 ui32Lock;
+ IMG_UINT32 ui32ID;
+}PVRSRV_RESOURCE;
+typedef PVRSRV_RESOURCE PVRSRV_RES_HANDLE;
+
+
+/* command complete callback pfn prototype */
+typedef IMG_VOID (*PFN_CMD_COMPLETE) (IMG_HANDLE);
+typedef IMG_VOID (**PPFN_CMD_COMPLETE) (IMG_HANDLE);
+
+/* private command handler prototype */
+typedef IMG_BOOL (*PFN_CMD_PROC) (IMG_HANDLE, IMG_UINT32, IMG_VOID*);
+typedef IMG_BOOL (**PPFN_CMD_PROC) (IMG_HANDLE, IMG_UINT32, IMG_VOID*);
+
+
+/*
+ rectangle structure required by Lock API
+*/
+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;
+
+
+/* common pfn between BC/DC */
+typedef PVRSRV_ERROR (*PFN_GET_BUFFER_ADDR)(IMG_HANDLE,
+ IMG_HANDLE,
+ IMG_SYS_PHYADDR**,
+ IMG_SIZE_T*,
+ IMG_VOID**,
+ IMG_HANDLE*,
+ IMG_BOOL*,
+ IMG_UINT32*);
+
+
+/*
+ Display dimension structure definition
+*/
+typedef struct DISPLAY_DIMS_TAG
+{
+ IMG_UINT32 ui32ByteStride;
+ IMG_UINT32 ui32Width;
+ IMG_UINT32 ui32Height;
+} DISPLAY_DIMS;
+
+
+/*
+ Display format structure definition
+*/
+typedef struct DISPLAY_FORMAT_TAG
+{
+ /* pixel format type */
+ PVRSRV_PIXEL_FORMAT pixelformat;
+} DISPLAY_FORMAT;
+
+/*
+ Display Surface Attributes structure definition
+*/
+typedef struct DISPLAY_SURF_ATTRIBUTES_TAG
+{
+ /* pixel format type */
+ PVRSRV_PIXEL_FORMAT pixelformat;
+ /* dimensions information structure array */
+ DISPLAY_DIMS sDims;
+} DISPLAY_SURF_ATTRIBUTES;
+
+
+/*
+ Display Mode information structure definition
+*/
+typedef struct DISPLAY_MODE_INFO_TAG
+{
+ /* pixel format type */
+ PVRSRV_PIXEL_FORMAT pixelformat;
+ /* dimensions information structure array */
+ DISPLAY_DIMS sDims;
+ /* refresh rate of the display */
+ IMG_UINT32 ui32RefreshHZ;
+ /* OEM specific flags */
+ IMG_UINT32 ui32OEMFlags;
+} DISPLAY_MODE_INFO;
+
+
+
+#define MAX_DISPLAY_NAME_SIZE (50) /* arbitrary choice! */
+
+/*
+ Display info structure definition
+*/
+typedef struct DISPLAY_INFO_TAG
+{
+ /* max swapchains supported */
+ IMG_UINT32 ui32MaxSwapChains;
+ /* max buffers in a swapchain */
+ IMG_UINT32 ui32MaxSwapChainBuffers;
+ /* min swap interval supported */
+ IMG_UINT32 ui32MinSwapInterval;
+ /* max swap interval supported */
+ IMG_UINT32 ui32MaxSwapInterval;
+ /* physical dimensions of the display required for DPI calc. */
+ IMG_UINT32 ui32PhysicalWidthmm;
+ IMG_UINT32 ui32PhysicalHeightmm;
+ /* display name */
+ IMG_CHAR szDisplayName[MAX_DISPLAY_NAME_SIZE];
+#if defined(SUPPORT_HW_CURSOR)
+ /* cursor dimensions */
+ IMG_UINT16 ui32CursorWidth;
+ IMG_UINT16 ui32CursorHeight;
+#endif
+} DISPLAY_INFO;
+
+typedef struct ACCESS_INFO_TAG
+{
+ IMG_UINT32 ui32Size;
+ IMG_UINT32 ui32FBPhysBaseAddress;
+ IMG_UINT32 ui32FBMemAvailable; /* size of usable FB memory */
+ IMG_UINT32 ui32SysPhysBaseAddress;
+ IMG_UINT32 ui32SysSize;
+ IMG_UINT32 ui32DevIRQ;
+}ACCESS_INFO;
+
+
+
+#if defined(PDUMP_SUSPEND_IS_PER_THREAD)
+/** Present only on WinMobile 6.5 */
+
+typedef struct {
+ IMG_UINT32 threadId;
+ IMG_INT suspendCount;
+} PVRSRV_THREAD_SUSPEND_COUNT;
+
+#define PVRSRV_PDUMP_SUSPEND_Q_NAME "PVRSRVPDumpSuspendMsgQ"
+#define PVRSRV_PDUMP_SUSPEND_Q_LENGTH 8
+
+#endif /* defined(PDUMP_SUSPEND_IS_PER_THREAD) */
+
+
+/*!
+ *****************************************************************************
+ * This structure is used for OS independent registry (profile) access
+ *****************************************************************************/
+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)
+
+#define MAX_BUFFER_DEVICE_NAME_SIZE (50) /* arbitrary choice! */
+
+/* buffer information structure */
+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;
+ IMG_CHAR szDeviceName[MAX_BUFFER_DEVICE_NAME_SIZE];
+} BUFFER_INFO;
+
+typedef enum _OVERLAY_DEINTERLACE_MODE_
+{
+ WEAVE=0x0,
+ BOB_ODD,
+ BOB_EVEN,
+ BOB_EVEN_NONINTERLEAVED
+} OVERLAY_DEINTERLACE_MODE;
+
+#endif /* __SERVICESEXT_H__ */
+/*****************************************************************************
+ End of file (servicesext.h)
+*****************************************************************************/
diff --git a/pvr-source/include4/sgx_options.h b/pvr-source/include4/sgx_options.h
new file mode 100644
index 0000000..b64cd39
--- /dev/null
+++ b/pvr-source/include4/sgx_options.h
@@ -0,0 +1,258 @@
+/*************************************************************************/ /*!
+@Title
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/* Each build option listed here is packed into a dword which
+ * provides up to 32 flags (or up to 28 flags plus a numeric
+ * value in the range 0-15 which corresponds to the number of
+ * cores minus one if SGX_FEATURE_MP is defined). The corresponding
+ * bit is set if the build option was enabled at compile time.
+ *
+ * In order to extract the enabled build flags the INTERNAL_TEST
+ * switch should be enabled in a client program which includes this
+ * header. Then the client can test specific build flags by reading
+ * the bit value at ##OPTIONNAME##_SET_OFFSET in SGX_BUILD_OPTIONS.
+ *
+ * IMPORTANT: add new options to unused bits or define a new dword
+ * (e.g. SGX_BUILD_OPTIONS2) so that the bitfield remains backwards
+ * compatible.
+ */
+
+
+#if defined(DEBUG) || defined (INTERNAL_TEST)
+#define DEBUG_SET_OFFSET OPTIONS_BIT0
+#define OPTIONS_BIT0 0x1U
+#else
+#define OPTIONS_BIT0 0x0
+#endif /* DEBUG */
+
+#if defined(PDUMP) || defined (INTERNAL_TEST)
+#define PDUMP_SET_OFFSET OPTIONS_BIT1
+#define OPTIONS_BIT1 (0x1U << 1)
+#else
+#define OPTIONS_BIT1 0x0
+#endif /* PDUMP */
+
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) || defined (INTERNAL_TEST)
+#define PVRSRV_USSE_EDM_STATUS_DEBUG_SET_OFFSET OPTIONS_BIT2
+#define OPTIONS_BIT2 (0x1U << 2)
+#else
+#define OPTIONS_BIT2 0x0
+#endif /* PVRSRV_USSE_EDM_STATUS_DEBUG */
+
+#if defined(SUPPORT_HW_RECOVERY) || defined (INTERNAL_TEST)
+#define SUPPORT_HW_RECOVERY_SET_OFFSET OPTIONS_BIT3
+#define OPTIONS_BIT3 (0x1U << 3)
+#else
+#define OPTIONS_BIT3 0x0
+#endif /* SUPPORT_HW_RECOVERY */
+
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+#define PVR_SECURE_HANDLES_SET_OFFSET OPTIONS_BIT4
+#define OPTIONS_BIT4 (0x1U << 4)
+#else
+#if defined(PVR_SECURE_HANDLES) || defined (INTERNAL_TEST)
+#define PVR_SECURE_HANDLES_SET_OFFSET OPTIONS_BIT4
+#define OPTIONS_BIT4 (0x1U << 4)
+#else
+#define OPTIONS_BIT4 0x0
+#endif /* PVR_SECURE_HANDLES */
+#endif
+
+#if defined(SGX_BYPASS_SYSTEM_CACHE) || defined (INTERNAL_TEST)
+#define SGX_BYPASS_SYSTEM_CACHE_SET_OFFSET OPTIONS_BIT5
+#define OPTIONS_BIT5 (0x1U << 5)
+#else
+#define OPTIONS_BIT5 0x0
+#endif /* SGX_BYPASS_SYSTEM_CACHE */
+
+#if defined(SGX_DMS_AGE_ENABLE) || defined (INTERNAL_TEST)
+#define SGX_DMS_AGE_ENABLE_SET_OFFSET OPTIONS_BIT6
+#define OPTIONS_BIT6 (0x1U << 6)
+#else
+#define OPTIONS_BIT6 0x0
+#endif /* SGX_DMS_AGE_ENABLE */
+
+#if defined(SGX_FAST_DPM_INIT) || defined (INTERNAL_TEST)
+#define SGX_FAST_DPM_INIT_SET_OFFSET OPTIONS_BIT8
+#define OPTIONS_BIT8 (0x1U << 8)
+#else
+#define OPTIONS_BIT8 0x0
+#endif /* SGX_FAST_DPM_INIT */
+
+#if defined(SGX_FEATURE_WRITEBACK_DCU) || defined (INTERNAL_TEST)
+#define SGX_FEATURE_DCU_SET_OFFSET OPTIONS_BIT9
+#define OPTIONS_BIT9 (0x1U << 9)
+#else
+#define OPTIONS_BIT9 0x0
+#endif /* SGX_FEATURE_WRITEBACK_DCU */
+
+#if defined(SGX_FEATURE_MP) || defined (INTERNAL_TEST)
+#define SGX_FEATURE_MP_SET_OFFSET OPTIONS_BIT10
+#define OPTIONS_BIT10 (0x1U << 10)
+#else
+#define OPTIONS_BIT10 0x0
+#endif /* SGX_FEATURE_MP */
+
+#define OPTIONS_BIT11 0x0
+
+#define OPTIONS_BIT12 0x0
+
+
+#if defined(SGX_FEATURE_SYSTEM_CACHE) || defined (INTERNAL_TEST)
+#define SGX_FEATURE_SYSTEM_CACHE_SET_OFFSET OPTIONS_BIT13
+#define OPTIONS_BIT13 (0x1U << 13)
+#else
+#define OPTIONS_BIT13 0x0
+#endif /* SGX_FEATURE_SYSTEM_CACHE */
+
+#if defined(SGX_SUPPORT_HWPROFILING) || defined (INTERNAL_TEST)
+#define SGX_SUPPORT_HWPROFILING_SET_OFFSET OPTIONS_BIT14
+#define OPTIONS_BIT14 (0x1U << 14)
+#else
+#define OPTIONS_BIT14 0x0
+#endif /* SGX_SUPPORT_HWPROFILING */
+
+
+
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) || defined (INTERNAL_TEST)
+#define SUPPORT_ACTIVE_POWER_MANAGEMENT_SET_OFFSET OPTIONS_BIT15
+#define OPTIONS_BIT15 (0x1U << 15)
+#else
+#define OPTIONS_BIT15 0x0
+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */
+
+#if defined(SUPPORT_DISPLAYCONTROLLER_TILING) || defined (INTERNAL_TEST)
+#define SUPPORT_DISPLAYCONTROLLER_TILING_SET_OFFSET OPTIONS_BIT16
+#define OPTIONS_BIT16 (0x1U << 16)
+#else
+#define OPTIONS_BIT16 0x0
+#endif /* SUPPORT_DISPLAYCONTROLLER_TILING */
+
+#if defined(SUPPORT_PERCONTEXT_PB) || defined (INTERNAL_TEST)
+#define SUPPORT_PERCONTEXT_PB_SET_OFFSET OPTIONS_BIT17
+#define OPTIONS_BIT17 (0x1U << 17)
+#else
+#define OPTIONS_BIT17 0x0
+#endif /* SUPPORT_PERCONTEXT_PB */
+
+#if defined(SUPPORT_SGX_HWPERF) || defined (INTERNAL_TEST)
+#define SUPPORT_SGX_HWPERF_SET_OFFSET OPTIONS_BIT18
+#define OPTIONS_BIT18 (0x1U << 18)
+#else
+#define OPTIONS_BIT18 0x0
+#endif /* SUPPORT_SGX_HWPERF */
+
+
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) || defined (INTERNAL_TEST)
+#define SUPPORT_SGX_MMU_DUMMY_PAGE_SET_OFFSET OPTIONS_BIT19
+#define OPTIONS_BIT19 (0x1U << 19)
+#else
+#define OPTIONS_BIT19 0x0
+#endif /* SUPPORT_SGX_MMU_DUMMY_PAGE */
+
+#if defined(SUPPORT_SGX_PRIORITY_SCHEDULING) || defined (INTERNAL_TEST)
+#define SUPPORT_SGX_PRIORITY_SCHEDULING_SET_OFFSET OPTIONS_BIT20
+#define OPTIONS_BIT20 (0x1U << 20)
+#else
+#define OPTIONS_BIT20 0x0
+#endif /* SUPPORT_SGX_PRIORITY_SCHEDULING */
+
+#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) || defined (INTERNAL_TEST)
+#define SUPPORT_SGX_LOW_LATENCY_SCHEDULING_SET_OFFSET OPTIONS_BIT21
+#define OPTIONS_BIT21 (0x1U << 21)
+#else
+#define OPTIONS_BIT21 0x0
+#endif /* SUPPORT_SGX_LOW_LATENCY_SCHEDULING */
+
+#if defined(USE_SUPPORT_NO_TA3D_OVERLAP) || defined (INTERNAL_TEST)
+#define USE_SUPPORT_NO_TA3D_OVERLAP_SET_OFFSET OPTIONS_BIT22
+#define OPTIONS_BIT22 (0x1U << 22)
+#else
+#define OPTIONS_BIT22 0x0
+#endif /* USE_SUPPORT_NO_TA3D_OVERLAP */
+
+#if defined(SGX_FEATURE_MP) || defined (INTERNAL_TEST)
+#if defined(SGX_FEATURE_MP_CORE_COUNT)
+#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 (((SGX_FEATURE_MP_CORE_COUNT_TA-1) << SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET) |\
+ ((SGX_FEATURE_MP_CORE_COUNT_3D-1) << SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET_3D))
+#define SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET 24UL
+#define SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET_3D 28UL
+#define SGX_FEATURE_MP_CORE_COUNT_SET_MASK 0xFF
+#endif
+#else /* SGX_FEATURE_MP */
+#define OPTIONS_HIGHBYTE 0x0
+#endif /* SGX_FEATURE_MP */
+
+
+
+#define SGX_BUILD_OPTIONS \
+ OPTIONS_BIT0 |\
+ OPTIONS_BIT1 |\
+ OPTIONS_BIT2 |\
+ OPTIONS_BIT3 |\
+ OPTIONS_BIT4 |\
+ OPTIONS_BIT5 |\
+ OPTIONS_BIT6 |\
+ 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/pvr-source/include4/sgxapi_km.h b/pvr-source/include4/sgxapi_km.h
new file mode 100644
index 0000000..bb8776a
--- /dev/null
+++ b/pvr-source/include4/sgxapi_km.h
@@ -0,0 +1,524 @@
+/*************************************************************************/ /*!
+@Title SGX KM API Header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Exported SGX API details
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __SGXAPI_KM_H__
+#define __SGXAPI_KM_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "sgxdefs.h"
+
+#if (defined(__linux__) || defined(__QNXNTO__)) && !defined(USE_CODE)
+ #if defined(__KERNEL__)
+ #include <asm/unistd.h>
+ #else
+ #include <unistd.h>
+ #endif
+#endif
+
+/******************************************************************************
+ Some defines...
+******************************************************************************/
+
+/* SGX Heap IDs, note: not all heaps are available to clients */
+#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_SHARED_3DPARAMETERS_HEAP_ID 9
+#define SGX_PERCONTEXT_3DPARAMETERS_HEAP_ID 10
+#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+#define SGX_GENERAL_MAPPING_HEAP_ID 11
+#endif
+#if defined(SGX_FEATURE_2D_HARDWARE)
+#define SGX_2D_HEAP_ID 12
+#endif
+#if defined(SUPPORT_MEMORY_TILING)
+#define SGX_VPB_TILED_HEAP_ID 14
+#endif
+#if defined(SUPPORT_ION)
+#define SGX_ION_HEAP_ID 15
+#endif
+
+#define SGX_MAX_HEAP_ID 16
+
+/*
+ * Keep SGX_3DPARAMETERS_HEAP_ID as TQ full custom
+ * shaders need it to select which heap to write
+ * their ISP controll stream to.
+ */
+#if (defined(SUPPORT_PERCONTEXT_PB) || defined(SUPPORT_HYBRID_PB))
+#define SGX_3DPARAMETERS_HEAP_ID SGX_PERCONTEXT_3DPARAMETERS_HEAP_ID
+#else
+#define SGX_3DPARAMETERS_HEAP_ID SGX_SHARED_3DPARAMETERS_HEAP_ID
+#endif
+/* Define for number of bytes between consecutive code base registers */
+#if defined(SGX543) || defined(SGX544) || defined(SGX554)
+#define SGX_USE_CODE_SEGMENT_RANGE_BITS 23
+#else
+#define SGX_USE_CODE_SEGMENT_RANGE_BITS 19
+#endif
+
+#define SGX_MAX_TA_STATUS_VALS 32
+#define SGX_MAX_3D_STATUS_VALS 4
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+/* sync info structure array size */
+#define SGX_MAX_TA_DST_SYNCS 1
+#define SGX_MAX_TA_SRC_SYNCS 1
+#define SGX_MAX_3D_SRC_SYNCS 4
+/* note: there is implicitly 1 3D Dst Sync */
+#else
+/* sync info structure array size */
+#define SGX_MAX_SRC_SYNCS_TA 32
+#define SGX_MAX_DST_SYNCS_TA 1
+/* note: there is implicitly 1 3D Dst Sync */
+#define SGX_MAX_SRC_SYNCS_TQ 8
+#define SGX_MAX_DST_SYNCS_TQ 1
+#endif
+
+
+#if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS)
+#define PVRSRV_SGX_HWPERF_NUM_COUNTERS 8
+#define PVRSRV_SGX_HWPERF_NUM_MISC_COUNTERS 11
+#else
+#define PVRSRV_SGX_HWPERF_NUM_COUNTERS 9
+#define PVRSRV_SGX_HWPERF_NUM_MISC_COUNTERS 8
+#endif /* SGX543 */
+
+#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_POWER 0x6
+#define PVRSRV_SGX_HWPERF_PERIODIC 0x7
+#define PVRSRV_SGX_HWPERF_3DSPM 0x8
+
+#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_MK_TRANSFER_DUMMY 0x105
+#define PVRSRV_SGX_HWPERF_MK_TA_DUMMY 0x106
+#define PVRSRV_SGX_HWPERF_MK_3D_DUMMY 0x107
+#define PVRSRV_SGX_HWPERF_MK_2D_DUMMY 0x108
+#define PVRSRV_SGX_HWPERF_MK_TA_LOCKUP 0x109
+#define PVRSRV_SGX_HWPERF_MK_3D_LOCKUP 0x10A
+#define PVRSRV_SGX_HWPERF_MK_2D_LOCKUP 0x10B
+
+#define PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT 28
+#define PVRSRV_SGX_HWPERF_TYPE_OP_MASK ((1UL << PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT) - 1)
+#define PVRSRV_SGX_HWPERF_TYPE_OP_START (0UL << PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT)
+#define PVRSRV_SGX_HWPERF_TYPE_OP_END (1Ul << 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_POWER_START (PVRSRV_SGX_HWPERF_POWER | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_POWER_END (PVRSRV_SGX_HWPERF_POWER | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_PERIODIC (PVRSRV_SGX_HWPERF_PERIODIC)
+#define PVRSRV_SGX_HWPERF_TYPE_3DSPM_START (PVRSRV_SGX_HWPERF_3DSPM | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_3DSPM_END (PVRSRV_SGX_HWPERF_3DSPM | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_TRANSFER_DUMMY_START (PVRSRV_SGX_HWPERF_MK_TRANSFER_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_TRANSFER_DUMMY_END (PVRSRV_SGX_HWPERF_MK_TRANSFER_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_DUMMY_START (PVRSRV_SGX_HWPERF_MK_TA_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_DUMMY_END (PVRSRV_SGX_HWPERF_MK_TA_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_DUMMY_START (PVRSRV_SGX_HWPERF_MK_3D_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_DUMMY_END (PVRSRV_SGX_HWPERF_MK_3D_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_DUMMY_START (PVRSRV_SGX_HWPERF_MK_2D_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_START)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_DUMMY_END (PVRSRV_SGX_HWPERF_MK_2D_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_END)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_LOCKUP (PVRSRV_SGX_HWPERF_MK_TA_LOCKUP)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_LOCKUP (PVRSRV_SGX_HWPERF_MK_3D_LOCKUP)
+#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_LOCKUP (PVRSRV_SGX_HWPERF_MK_2D_LOCKUP)
+
+#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_STATUS_OFF (0x0)
+#define PVRSRV_SGX_HWPERF_STATUS_RESET_COUNTERS (1UL << 0)
+#define PVRSRV_SGX_HWPERF_STATUS_GRAPHICS_ON (1UL << 1)
+#define PVRSRV_SGX_HWPERF_STATUS_PERIODIC_ON (1UL << 2)
+#define PVRSRV_SGX_HWPERF_STATUS_MK_EXECUTION_ON (1UL << 3)
+
+
+/*!
+ *****************************************************************************
+ * One entry in the HWPerf Circular Buffer.
+ *****************************************************************************/
+typedef struct _PVRSRV_SGX_HWPERF_CB_ENTRY_
+{
+ IMG_UINT32 ui32FrameNo;
+ IMG_UINT32 ui32PID;
+ IMG_UINT32 ui32RTData;
+ IMG_UINT32 ui32Type;
+ IMG_UINT32 ui32Ordinal;
+ IMG_UINT32 ui32Info;
+ IMG_UINT32 ui32Clocksx16;
+ /* NOTE: There should always be at least as many 3D cores as TA cores. */
+ IMG_UINT32 ui32Counters[SGX_FEATURE_MP_CORE_COUNT_3D][PVRSRV_SGX_HWPERF_NUM_COUNTERS];
+ IMG_UINT32 ui32MiscCounters[SGX_FEATURE_MP_CORE_COUNT_3D][PVRSRV_SGX_HWPERF_NUM_MISC_COUNTERS];
+} PVRSRV_SGX_HWPERF_CB_ENTRY;
+
+
+/*
+ Status values control structure
+*/
+typedef struct _CTL_STATUS_
+{
+ IMG_DEV_VIRTADDR sStatusDevAddr;
+ IMG_UINT32 ui32StatusValue;
+} CTL_STATUS;
+
+
+/*!
+ List of possible requests/commands to SGXGetMiscInfo()
+*/
+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_EDM_MEMORY_DEBUG)
+ SGX_MISC_INFO_REQUEST_MEMREAD,
+ SGX_MISC_INFO_REQUEST_MEMCOPY,
+#endif /* SUPPORT_SGX_EDM_MEMORY_DEBUG */
+ SGX_MISC_INFO_REQUEST_SET_HWPERF_STATUS,
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+ SGX_MISC_INFO_REQUEST_SET_BREAKPOINT,
+ SGX_MISC_INFO_REQUEST_POLL_BREAKPOINT,
+ SGX_MISC_INFO_REQUEST_RESUME_BREAKPOINT,
+#endif /* SGX_FEATURE_DATA_BREAKPOINTS */
+ SGX_MISC_INFO_DUMP_DEBUG_INFO,
+ SGX_MISC_INFO_DUMP_DEBUG_INFO_FORCE_REGS,
+ SGX_MISC_INFO_PANIC,
+ SGX_MISC_INFO_REQUEST_SPM,
+ SGX_MISC_INFO_REQUEST_ACTIVEPOWER,
+ SGX_MISC_INFO_REQUEST_LOCKUPS,
+ SGX_MISC_INFO_REQUEST_FORCE_I16 = 0x7fff
+} SGX_MISC_INFO_REQUEST;
+
+
+/******************************************************************************
+ * Struct for passing SGX core rev/features from ukernel to driver.
+ * This is accessed from the kernel part of the driver and microkernel; it is
+ * only accessed in user space during buffer allocation in srvinit.
+ ******************************************************************************/
+typedef struct _PVRSRV_SGX_MISCINFO_FEATURES
+{
+ IMG_UINT32 ui32CoreRev; /*!< SGX Core revision from HW register */
+ IMG_UINT32 ui32CoreID; /*!< SGX Core ID from HW register */
+ IMG_UINT32 ui32DDKVersion; /*!< software DDK version */
+ IMG_UINT32 ui32DDKBuild; /*!< software DDK build no. */
+ IMG_UINT32 ui32CoreIdSW; /*!< software core version (ID), e.g. SGX535, SGX540 */
+ IMG_UINT32 ui32CoreRevSW; /*!< software core revision */
+ IMG_UINT32 ui32BuildOptions; /*!< build options bit-field */
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+ IMG_UINT32 ui32DeviceMemValue; /*!< device mem value read from ukernel */
+#endif
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+ IMG_DEV_VIRTADDR sDevVAEDMStatusBuffer; /*!< DevVAddr of the EDM status buffer */
+ IMG_PVOID pvEDMStatusBuffer; /*!< CPUVAddr of the EDM status buffer */
+#endif
+} PVRSRV_SGX_MISCINFO_FEATURES;
+
+
+/******************************************************************************
+ * Struct for getting lock-up stats from the kernel driver
+ ******************************************************************************/
+typedef struct _PVRSRV_SGX_MISCINFO_LOCKUPS
+{
+ IMG_UINT32 ui32HostDetectedLockups; /*!< Host timer detected lockups */
+ IMG_UINT32 ui32uKernelDetectedLockups; /*!< Microkernel detected lockups */
+} PVRSRV_SGX_MISCINFO_LOCKUPS;
+
+
+/******************************************************************************
+ * Struct for getting lock-up stats from the kernel driver
+ ******************************************************************************/
+typedef struct _PVRSRV_SGX_MISCINFO_ACTIVEPOWER
+{
+ IMG_UINT32 ui32NumActivePowerEvents; /*!< active power events */
+} PVRSRV_SGX_MISCINFO_ACTIVEPOWER;
+
+
+/******************************************************************************
+ * Struct for getting SPM stats fro the kernel driver
+ ******************************************************************************/
+typedef struct _PVRSRV_SGX_MISCINFO_SPM
+{
+ IMG_HANDLE hRTDataSet; /*!< render target data set handle returned from SGXAddRenderTarget */
+ IMG_UINT32 ui32NumOutOfMemSignals; /*!< Number of Out of Mem Signals */
+ IMG_UINT32 ui32NumSPMRenders; /*!< Number of SPM renders */
+} PVRSRV_SGX_MISCINFO_SPM;
+
+
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+/*!
+ ******************************************************************************
+ * Structure for SGX break points control
+ *****************************************************************************/
+typedef struct _SGX_BREAKPOINT_INFO
+{
+ /* set/clear BP boolean */
+ IMG_BOOL bBPEnable;
+ /* Index of BP to set */
+ IMG_UINT32 ui32BPIndex;
+ /* On which DataMaster(s) should the breakpoint fire? */
+ IMG_UINT32 ui32DataMasterMask;
+ /* DevVAddr of BP to set */
+ IMG_DEV_VIRTADDR sBPDevVAddr, sBPDevVAddrEnd;
+ /* Whether or not the desired breakpoint will be trapped */
+ IMG_BOOL bTrapped;
+ /* Will the requested breakpoint fire for reads? */
+ IMG_BOOL bRead;
+ /* Will the requested breakpoint fire for writes? */
+ IMG_BOOL bWrite;
+ /* Has a breakpoint been trapped? */
+ IMG_BOOL bTrappedBP;
+ /* Extra information recorded about a trapped breakpoint */
+ IMG_UINT32 ui32CoreNum;
+ IMG_DEV_VIRTADDR sTrappedBPDevVAddr;
+ IMG_UINT32 ui32TrappedBPBurstLength;
+ IMG_BOOL bTrappedBPRead;
+ IMG_UINT32 ui32TrappedBPDataMaster;
+ IMG_UINT32 ui32TrappedBPTag;
+} SGX_BREAKPOINT_INFO;
+#endif /* SGX_FEATURE_DATA_BREAKPOINTS */
+
+
+/*!
+ ******************************************************************************
+ * Structure for setting the hardware performance status
+ *****************************************************************************/
+typedef struct _PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS
+{
+ /* See PVRSRV_SGX_HWPERF_STATUS_* */
+ IMG_UINT32 ui32NewHWPerfStatus;
+
+ #if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS)
+ /* Specifies the HW's active group selectors */
+ IMG_UINT32 aui32PerfGroup[PVRSRV_SGX_HWPERF_NUM_COUNTERS];
+ /* Specifies the HW's active bit selectors */
+ IMG_UINT32 aui32PerfBit[PVRSRV_SGX_HWPERF_NUM_COUNTERS];
+ /* Specifies the HW's counter bit selectors */
+ IMG_UINT32 ui32PerfCounterBitSelect;
+ /* Specifies the HW's sum_mux selectors */
+ IMG_UINT32 ui32PerfSumMux;
+ #else
+ /* Specifies the HW's active group */
+ IMG_UINT32 ui32PerfGroup;
+ #endif /* SGX_FEATURE_EXTENDED_PERF_COUNTERS */
+} PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS;
+
+
+/*!
+ ******************************************************************************
+ * Structure for misc SGX commands in services
+ *****************************************************************************/
+typedef struct _SGX_MISC_INFO_
+{
+ SGX_MISC_INFO_REQUEST eRequest; /*!< Command request to SGXGetMiscInfo() */
+ IMG_UINT32 ui32Padding;
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+ IMG_DEV_VIRTADDR sDevVAddrSrc; /*!< dev virtual addr for mem read */
+ IMG_DEV_VIRTADDR sDevVAddrDest; /*!< dev virtual addr for mem write */
+ IMG_HANDLE hDevMemContext; /*!< device memory context for mem debug */
+#endif
+ union
+ {
+ IMG_UINT32 reserved; /*!< Unused: ensures valid code in the case everything else is compiled out */
+ PVRSRV_SGX_MISCINFO_FEATURES sSGXFeatures;
+ IMG_UINT32 ui32SGXClockSpeed;
+ PVRSRV_SGX_MISCINFO_ACTIVEPOWER sActivePower;
+ PVRSRV_SGX_MISCINFO_LOCKUPS sLockups;
+ PVRSRV_SGX_MISCINFO_SPM sSPM;
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+ SGX_BREAKPOINT_INFO sSGXBreakpointInfo;
+#endif
+ PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS sSetHWPerfStatus;
+ } uData;
+} SGX_MISC_INFO;
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+/*
+ * The largest number of source sync objects that can be associated with a blit
+ * command. Allows for src, pattern, and mask
+ */
+#define PVRSRV_MAX_BLT_SRC_SYNCS 3
+#endif
+
+
+#define SGX_KICKTA_DUMPBITMAP_MAX_NAME_LENGTH 256
+
+/*
+ Structure for dumping bitmaps
+*/
+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)
+
+/*!
+ ******************************************************************************
+ * Data required only when dumping parameters
+ *****************************************************************************/
+typedef struct _PVRSRV_SGX_PDUMP_CONTEXT_
+{
+ /* cache control word for micro kernel cache flush/invalidates */
+ IMG_UINT32 ui32CacheControl;
+
+} PVRSRV_SGX_PDUMP_CONTEXT;
+
+
+#if !defined (SUPPORT_SID_INTERFACE)
+typedef struct _SGX_KICKTA_DUMP_ROFF_
+{
+ IMG_HANDLE hKernelMemInfo; /*< Buffer handle */
+ IMG_UINT32 uiAllocIndex; /*< Alloc index for LDDM */
+ IMG_UINT32 ui32Offset; /*< Byte offset to value to dump */
+ IMG_UINT32 ui32Value; /*< Actual value to dump */
+ IMG_PCHAR pszName; /*< Name of buffer */
+} SGX_KICKTA_DUMP_ROFF, *PSGX_KICKTA_DUMP_ROFF;
+#endif
+
+#if defined (SUPPORT_SID_INTERFACE)
+typedef struct _SGX_KICKTA_DUMP_BUFFER_KM_
+#else
+typedef struct _SGX_KICKTA_DUMP_BUFFER_
+#endif
+{
+ IMG_UINT32 ui32SpaceUsed;
+ IMG_UINT32 ui32Start; /*< Byte offset of start to dump */
+ IMG_UINT32 ui32End; /*< Byte offset of end of dump (non-inclusive) */
+ IMG_UINT32 ui32BufferSize; /*< Size of buffer */
+ IMG_UINT32 ui32BackEndLength; /*< Size of back end portion, if End < Start */
+ IMG_UINT32 uiAllocIndex;
+ IMG_HANDLE hKernelMemInfo; /*< MemInfo handle for the circular buffer */
+ IMG_PVOID pvLinAddr;
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+ IMG_HANDLE hCtrlKernelMemInfo; /*< MemInfo handle for the control structure of the
+ circular buffer */
+ IMG_DEV_VIRTADDR sCtrlDevVAddr; /*< Device virtual address of the memory in the
+ control structure to be checked */
+#endif
+ IMG_PCHAR pszName; /*< Name of buffer */
+
+#if defined (__QNXNTO__)
+ IMG_UINT32 ui32NameLength; /*< Number of characters in buffer name */
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+} SGX_KICKTA_DUMP_BUFFER_KM, *PSGX_KICKTA_DUMP_BUFFER_KM;
+#else
+} SGX_KICKTA_DUMP_BUFFER, *PSGX_KICKTA_DUMP_BUFFER;
+#endif
+
+#if !defined (SUPPORT_SID_INTERFACE)
+#ifdef PDUMP
+/*
+ PDUMP version of above kick structure
+*/
+typedef struct _SGX_KICKTA_PDUMP_
+{
+ // Bitmaps to dump
+ PSGX_KICKTA_DUMPBITMAP psPDumpBitmapArray;
+ IMG_UINT32 ui32PDumpBitmapSize;
+
+ // Misc buffers to dump (e.g. TA, PDS etc..)
+ PSGX_KICKTA_DUMP_BUFFER psBufferArray;
+ IMG_UINT32 ui32BufferArraySize;
+
+ // Roffs to dump
+ PSGX_KICKTA_DUMP_ROFF psROffArray;
+ IMG_UINT32 ui32ROffArraySize;
+} SGX_KICKTA_PDUMP, *PSGX_KICKTA_PDUMP;
+#endif /* PDUMP */
+#endif /* #if !defined (SUPPORT_SID_INTERFACE) */
+
+#if defined(TRANSFER_QUEUE)
+#if defined(SGX_FEATURE_2D_HARDWARE)
+/* Maximum size of ctrl stream for 2d blit command (in 32 bit words) */
+#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 /* __SGXAPI_KM_H__ */
+
+/******************************************************************************
+ End of file (sgxapi_km.h)
+******************************************************************************/
diff --git a/pvr-source/include4/sgxscript.h b/pvr-source/include4/sgxscript.h
new file mode 100644
index 0000000..46b89d2
--- /dev/null
+++ b/pvr-source/include4/sgxscript.h
@@ -0,0 +1,99 @@
+/*************************************************************************/ /*!
+@Title SGX kernel services structues/functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description SGX initialisation script definitions.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#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,
+ SGX_INIT_OP_READ_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;
+ struct {
+ SGX_INIT_OPERATION eOp;
+ IMG_UINT32 ui32Offset;
+ } sReadHWReg;
+#if defined(PDUMP)
+ struct {
+ SGX_INIT_OPERATION eOp;
+ IMG_UINT32 ui32Offset;
+ IMG_UINT32 ui32Value;
+ } sPDumpHWReg;
+#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 /* __SGXSCRIPT_H__ */
+
+/*****************************************************************************
+ End of file (sgxscript.h)
+*****************************************************************************/
diff --git a/pvr-source/services4/3rdparty/dc_nohw/Kbuild.mk b/pvr-source/services4/3rdparty/dc_nohw/Kbuild.mk
new file mode 100644
index 0000000..4bbcfd0
--- /dev/null
+++ b/pvr-source/services4/3rdparty/dc_nohw/Kbuild.mk
@@ -0,0 +1,47 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+ccflags-y += \
+ -I$(TOP)/services4/3rdparty/dc_nohw \
+ -DDC_NOHW_DISCONTIG_BUFFERS -DDC_NOHW_GET_BUFFER_DIMENSIONS
+
+dcnohw-y += \
+ services4/3rdparty/dc_nohw/dc_nohw_displayclass.o \
+ services4/3rdparty/dc_nohw/dc_nohw_linux.o
diff --git a/pvr-source/services4/3rdparty/dc_nohw/Linux.mk b/pvr-source/services4/3rdparty/dc_nohw/Linux.mk
new file mode 100644
index 0000000..9bd3e01
--- /dev/null
+++ b/pvr-source/services4/3rdparty/dc_nohw/Linux.mk
@@ -0,0 +1,45 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+modules := dc_nohw
+
+dc_nohw_type := kernel_module
+dc_nohw_target := dcnohw.ko
+dc_nohw_makefile := $(THIS_DIR)/Kbuild.mk
diff --git a/pvr-source/services4/3rdparty/dc_nohw/dc_nohw.h b/pvr-source/services4/3rdparty/dc_nohw/dc_nohw.h
new file mode 100644
index 0000000..403361f
--- /dev/null
+++ b/pvr-source/services4/3rdparty/dc_nohw/dc_nohw.h
@@ -0,0 +1,288 @@
+/*************************************************************************/ /*!
+@Title Dummy 3rd party display driver structures and prototypes
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/**************************************************************************
+ The 3rd party driver is a specification of an API to integrate the
+ IMG PowerVR Services driver with 3rd Party display hardware.
+ It is NOT a specification for a display controller driver, rather a
+ specification to extend the API for a pre-existing driver for the display hardware.
+
+ The 3rd party driver interface provides IMG PowerVR client drivers (e.g. PVR2D)
+ with an API abstraction of the system's underlying display hardware, allowing
+ the client drivers to indirectly control the display hardware and access its
+ associated memory.
+
+ Functions of the API include
+
+ - query primary surface attributes (width, height, stride, pixel format,
+ CPU physical and virtual address)
+ - swap/flip chain creation and subsequent query of surface attributes
+ - asynchronous display surface flipping, taking account of asynchronous
+ read (flip) and write (render) operations to the display surface
+
+ Note: having queried surface attributes the client drivers are able to map
+ the display memory to any IMG PowerVR Services device by calling
+ PVRSRVMapDeviceClassMemory with the display surface handle.
+
+ This code is intended to be an example of how a pre-existing display driver
+ may be extended to support the 3rd Party Display interface to
+ PowerVR Services - IMG is not providing a display driver implementation
+ **************************************************************************/
+
+#ifndef __DC_NOHW_H__
+#define __DC_NOHW_H__
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if defined(USE_BASE_VIDEO_FRAMEBUFFER)
+#if defined (ENABLE_DISPLAY_MODE_TRACKING)
+#error Cannot have both USE_BASE_VIDEO_FRAMEBUFFER and ENABLE_DISPLAY_MODE_TRACKING defined
+#endif
+#endif
+
+#if !defined(DC_NOHW_BUFFER_WIDTH) && !defined(DC_NOHW_BUFFER_HEIGHT)
+/* Default buffer size */
+#define DC_NOHW_BUFFER_WIDTH 320
+#define DC_NOHW_BUFFER_HEIGHT 240
+#endif
+
+#define DC_NOHW_BUFFER_BIT_DEPTH 32
+#define DC_NOHW_BUFFER_PIXEL_FORMAT PVRSRV_PIXEL_FORMAT_ARGB8888
+
+#define DC_NOHW_DEPTH_BITS_PER_BYTE 8
+
+#define dc_nohw_byte_depth_from_bit_depth(bit_depth) (((IMG_UINT32)(bit_depth) + DC_NOHW_DEPTH_BITS_PER_BYTE - 1)/DC_NOHW_DEPTH_BITS_PER_BYTE)
+#define dc_nohw_bit_depth_from_byte_depth(byte_depth) ((IMG_UINT32)(byte_depth) * DC_NOHW_DEPTH_BITS_PER_BYTE)
+#define dc_nohw_roundup_bit_depth(bd) dc_nohw_bit_depth_from_byte_depth(dc_nohw_byte_depth_from_bit_depth(bd))
+
+#define dc_nohw_byte_stride(width, bit_depth) ((IMG_UINT32)(width) * dc_nohw_byte_depth_from_bit_depth(bit_depth))
+
+#if defined(DC_NOHW_GET_BUFFER_DIMENSIONS)
+IMG_BOOL GetBufferDimensions(IMG_UINT32 *pui32Width, IMG_UINT32 *pui32Height, PVRSRV_PIXEL_FORMAT *pePixelFormat, IMG_UINT32 *pui32Stride);
+#else
+#define DC_NOHW_BUFFER_BYTE_STRIDE dc_nohw_byte_stride(DC_NOHW_BUFFER_WIDTH, DC_NOHW_BUFFER_BIT_DEPTH)
+#endif
+
+extern IMG_BOOL IMG_IMPORT PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable);
+
+#define DC_NOHW_MAXFORMATS (1)
+#define DC_NOHW_MAXDIMS (1)
+#define DC_NOHW_MAX_BACKBUFFERS (3)
+
+
+typedef void * DC_HANDLE;
+
+typedef struct DC_NOHW_BUFFER_TAG
+{
+ DC_HANDLE hSwapChain;
+ DC_HANDLE hMemChunk;
+
+ /* member using IMG structures to minimise API function code */
+ /* replace with own structures where necessary */
+#if defined(DC_NOHW_DISCONTIG_BUFFERS)
+ IMG_SYS_PHYADDR *psSysAddr;
+#else
+ IMG_SYS_PHYADDR sSysAddr;
+#endif
+ IMG_DEV_VIRTADDR sDevVAddr;
+ IMG_CPU_VIRTADDR sCPUVAddr;
+ PVRSRV_SYNC_DATA* psSyncData;
+
+ struct DC_NOHW_BUFFER_TAG *psNext;
+} DC_NOHW_BUFFER;
+
+
+/* DC_NOHW buffer structure */
+typedef struct DC_NOHW_SWAPCHAIN_TAG
+{
+ unsigned long ulBufferCount;
+ DC_NOHW_BUFFER *psBuffer;
+} DC_NOHW_SWAPCHAIN;
+
+
+/* kernel device information structure */
+typedef struct DC_NOHW_DEVINFO_TAG
+{
+ unsigned int uiDeviceID;
+
+ /* system surface info */
+ DC_NOHW_BUFFER sSystemBuffer;
+
+ /* number of supported display formats */
+ unsigned long ulNumFormats;
+
+ /* number of supported display dims */
+ unsigned long ulNumDims;
+
+ /* jump table into PVR services */
+ PVRSRV_DC_DISP2SRV_KMJTABLE sPVRJTable;
+
+ /* jump table into DC */
+ PVRSRV_DC_SRV2DISP_KMJTABLE sDCJTable;
+
+ /*
+ handle for connection to kernel services
+ - OS specific - may not be required
+ */
+ DC_HANDLE hPVRServices;
+
+ /* back buffer info */
+ DC_NOHW_BUFFER asBackBuffers[DC_NOHW_MAX_BACKBUFFERS];
+
+ /* ref count */
+ unsigned long ulRefCount;
+
+ DC_NOHW_SWAPCHAIN *psSwapChain;
+
+ /* member using IMG structures to minimise API function code */
+ /* replace with own structures where necessary */
+ DISPLAY_INFO sDisplayInfo;
+
+ /* system surface info */
+ DISPLAY_FORMAT sSysFormat;
+ DISPLAY_DIMS sSysDims;
+ IMG_UINT32 ui32BufferSize;
+
+ /* list of supported display formats */
+ DISPLAY_FORMAT asDisplayFormatList[DC_NOHW_MAXFORMATS];
+
+ /* list of supported display formats */
+ DISPLAY_DIMS asDisplayDimList[DC_NOHW_MAXDIMS];
+
+ /* back buffer info */
+ DISPLAY_FORMAT sBackBufferFormat[DC_NOHW_MAXFORMATS];
+
+} DC_NOHW_DEVINFO;
+
+
+/*!
+ *****************************************************************************
+ * Error values
+ *****************************************************************************/
+typedef enum _DC_ERROR_
+{
+ DC_OK = 0,
+ DC_ERROR_GENERIC = 1,
+ DC_ERROR_OUT_OF_MEMORY = 2,
+ DC_ERROR_TOO_FEW_BUFFERS = 3,
+ DC_ERROR_INVALID_PARAMS = 4,
+ DC_ERROR_INIT_FAILURE = 5,
+ DC_ERROR_CANT_REGISTER_CALLBACK = 6,
+ DC_ERROR_INVALID_DEVICE = 7,
+ DC_ERROR_DEVICE_REGISTER_FAILED = 8
+} DC_ERROR;
+
+
+#ifndef UNREFERENCED_PARAMETER
+#define UNREFERENCED_PARAMETER(param) (param) = (param)
+#endif
+
+DC_ERROR Init(void);
+DC_ERROR Deinit(void);
+
+#if defined(USE_BASE_VIDEO_FRAMEBUFFER) || defined (ENABLE_DISPLAY_MODE_TRACKING)
+DC_ERROR OpenMiniport(void);
+DC_ERROR CloseMiniport(void);
+#endif /* #if defined(USE_BASE_VIDEO_FRAMEBUFFER) || defined (ENABLE_DISPLAY_MODE_TRACKING) */
+
+#if defined(USE_BASE_VIDEO_FRAMEBUFFER)
+PVRSRV_ERROR SetupDevInfo (DC_NOHW_DEVINFO *psDevInfo);
+PVRSRV_ERROR FreeBackBuffers (DC_NOHW_DEVINFO *psDevInfo);
+#endif
+
+#if defined (ENABLE_DISPLAY_MODE_TRACKING)
+DC_ERROR Shadow_Desktop_Resolution(DC_NOHW_DEVINFO *psDevInfo);
+#endif /* #if defined (ENABLE_DISPLAY_MODE_TRACKING) */
+
+#if !defined(DC_NOHW_DISCONTIG_BUFFERS) && !defined(USE_BASE_VIDEO_FRAMEBUFFER)
+IMG_SYS_PHYADDR CpuPAddrToSysPAddr(IMG_CPU_PHYADDR cpu_paddr);
+IMG_CPU_PHYADDR SysPAddrToCpuPAddr(IMG_SYS_PHYADDR sys_paddr);
+#endif
+
+/* OS Specific APIs */
+DC_ERROR OpenPVRServices (DC_HANDLE *phPVRServices);
+DC_ERROR ClosePVRServices (DC_HANDLE hPVRServices);
+
+#if defined(DC_NOHW_DISCONTIG_BUFFERS)
+DC_ERROR AllocDiscontigMemory(unsigned long ulSize,
+ DC_HANDLE * phMemChunk,
+ IMG_CPU_VIRTADDR *pLinAddr,
+ IMG_SYS_PHYADDR **pPhysAddr);
+
+void FreeDiscontigMemory(unsigned long ulSize,
+ DC_HANDLE hMemChunk,
+ IMG_CPU_VIRTADDR LinAddr,
+ IMG_SYS_PHYADDR *pPhysAddr);
+#else
+
+
+
+DC_ERROR AllocContigMemory(unsigned long ulSize,
+ DC_HANDLE * phMemHandle,
+ IMG_CPU_VIRTADDR *pLinAddr,
+ IMG_CPU_PHYADDR *pPhysAddr);
+
+void FreeContigMemory(unsigned long ulSize,
+ DC_HANDLE hMemChunk,
+ IMG_CPU_VIRTADDR LinAddr,
+ IMG_CPU_PHYADDR PhysAddr);
+
+
+#endif
+
+void *AllocKernelMem(unsigned long ulSize);
+void FreeKernelMem (void *pvMem);
+
+DC_ERROR GetLibFuncAddr (DC_HANDLE hExtDrv, char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __DC_NOHW_H__ */
+
+/******************************************************************************
+ End of file (dc_nohw.h)
+******************************************************************************/
+
diff --git a/pvr-source/services4/3rdparty/dc_nohw/dc_nohw_displayclass.c b/pvr-source/services4/3rdparty/dc_nohw/dc_nohw_displayclass.c
new file mode 100644
index 0000000..d47a171
--- /dev/null
+++ b/pvr-source/services4/3rdparty/dc_nohw/dc_nohw_displayclass.c
@@ -0,0 +1,982 @@
+/*************************************************************************/ /*!
+@Title NOHW display driver display-specific functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/**************************************************************************
+ The 3rd party driver is a specification of an API to integrate the IMG POWERVR
+ Services driver with 3rd Party display hardware. It is NOT a specification for
+ a display controller driver, rather a specification to extend the API for a
+ pre-existing driver for the display hardware.
+
+ The 3rd party driver interface provides IMG POWERVR client drivers (e.g. PVR2D)
+ with an API abstraction of the system's underlying display hardware, allowing
+ the client drivers to indirectly control the display hardware and access its
+ associated memory.
+
+ Functions of the API include
+ - query primary surface attributes (width, height, stride, pixel format, CPU
+ physical and virtual address)
+ - swap/flip chain creation and subsequent query of surface attributes
+ - asynchronous display surface flipping, taking account of asynchronous read
+ (flip) and write (render) operations to the display surface
+
+ Note: having queried surface attributes the client drivers are able to map the
+ display memory to any IMG POWERVR Services device by calling
+ PVRSRVMapDeviceClassMemory with the display surface handle.
+
+ This code is intended to be an example of how a pre-existing display driver may
+ be extended to support the 3rd Party Display interface to POWERVR Services
+ - IMG is not providing a display driver implementation.
+ **************************************************************************/
+
+#if defined(__linux__)
+#include <linux/string.h>
+#else
+#include <string.h>
+#endif
+
+/* IMG services headers */
+#include "img_defs.h"
+#include "servicesext.h"
+#include "kerneldisplay.h"
+
+#include "dc_nohw.h"
+
+#define DISPLAY_DEVICE_NAME "DC_NOHW"
+
+#define DC_NOHW_COMMAND_COUNT 1
+
+/* top level 'hook ptr' */
+static void *gpvAnchor = 0;
+static PFN_DC_GET_PVRJTABLE pfnGetPVRJTable = 0;
+
+
+
+
+/*
+ Kernel services is a kernel module and must be loaded first.
+ The display controller driver is also a kernel module and must be loaded after the pvr services module.
+ The display controller driver should be able to retrieve the
+ address of the services PVRGetDisplayClassJTable from (the already loaded)
+ kernel services module.
+*/
+
+/* returns anchor pointer */
+static DC_NOHW_DEVINFO * GetAnchorPtr(void)
+{
+ return (DC_NOHW_DEVINFO *)gpvAnchor;
+}
+
+/* sets anchor pointer */
+static void SetAnchorPtr(DC_NOHW_DEVINFO *psDevInfo)
+{
+ gpvAnchor = (void *)psDevInfo;
+}
+
+#if !defined(DC_NOHW_DISCONTIG_BUFFERS) && !defined(USE_BASE_VIDEO_FRAMEBUFFER)
+IMG_SYS_PHYADDR CpuPAddrToSysPAddr(IMG_CPU_PHYADDR cpu_paddr)
+{
+ IMG_SYS_PHYADDR sys_paddr;
+
+ /* This would only be an inequality if the CPU's MMU did not point to sys address 0,
+ ie. multi CPU system */
+ sys_paddr.uiAddr = cpu_paddr.uiAddr;
+ return sys_paddr;
+}
+
+IMG_CPU_PHYADDR SysPAddrToCpuPAddr(IMG_SYS_PHYADDR sys_paddr)
+{
+ IMG_CPU_PHYADDR cpu_paddr;
+
+ /* This would only be an inequality if the CPU's MMU did not point to sys address 0,
+ ie. multi CPU system */
+ cpu_paddr.uiAddr = sys_paddr.uiAddr;
+ return cpu_paddr;
+}
+#endif
+
+
+static PVRSRV_ERROR OpenDCDevice(IMG_UINT32 ui32DeviceID,
+ IMG_HANDLE *phDevice,
+ PVRSRV_SYNC_DATA* psSystemBufferSyncData)
+{
+ DC_NOHW_DEVINFO *psDevInfo;
+ PVR_UNREFERENCED_PARAMETER(ui32DeviceID);
+
+ psDevInfo = GetAnchorPtr();
+
+#if defined (ENABLE_DISPLAY_MODE_TRACKING)
+ if (Shadow_Desktop_Resolution(psDevInfo) != DC_OK)
+ {
+ return (PVRSRV_ERROR_NOT_SUPPORTED);
+ }
+#endif
+
+ /* store the system surface sync data */
+ psDevInfo->asBackBuffers[0].psSyncData = psSystemBufferSyncData;
+
+ /* return handle to the devinfo */
+ *phDevice = (IMG_HANDLE)psDevInfo;
+
+#if defined(USE_BASE_VIDEO_FRAMEBUFFER)
+ return (SetupDevInfo(psDevInfo));
+#else
+ return (PVRSRV_OK);
+#endif
+}
+
+
+static PVRSRV_ERROR CloseDCDevice(IMG_HANDLE hDevice)
+{
+ UNREFERENCED_PARAMETER(hDevice);
+
+#if defined(USE_BASE_VIDEO_FRAMEBUFFER)
+ FreeBackBuffers(GetAnchorPtr());
+#endif
+
+ return (PVRSRV_OK);
+}
+
+
+static PVRSRV_ERROR EnumDCFormats(IMG_HANDLE hDevice,
+ IMG_UINT32 *pui32NumFormats,
+ DISPLAY_FORMAT *psFormat)
+{
+ DC_NOHW_DEVINFO *psDevInfo;
+
+ if(!hDevice || !pui32NumFormats)
+ {
+ return (PVRSRV_ERROR_INVALID_PARAMS);
+ }
+
+ psDevInfo = (DC_NOHW_DEVINFO *)hDevice;
+
+ *pui32NumFormats = (IMG_UINT32)psDevInfo->ulNumFormats;
+
+ if(psFormat != IMG_NULL)
+ {
+ unsigned long i;
+
+ for(i=0; i<psDevInfo->ulNumFormats; i++)
+ {
+ psFormat[i] = psDevInfo->asDisplayFormatList[i];
+ }
+ }
+
+ return (PVRSRV_OK);
+}
+
+
+static PVRSRV_ERROR EnumDCDims(IMG_HANDLE hDevice,
+ DISPLAY_FORMAT *psFormat,
+ IMG_UINT32 *pui32NumDims,
+ DISPLAY_DIMS *psDim)
+{
+ DC_NOHW_DEVINFO *psDevInfo;
+
+ if(!hDevice || !psFormat || !pui32NumDims)
+ {
+ return (PVRSRV_ERROR_INVALID_PARAMS);
+ }
+
+ psDevInfo = (DC_NOHW_DEVINFO *)hDevice;
+
+ *pui32NumDims = (IMG_UINT32)psDevInfo->ulNumDims;
+
+ /* given psFormat return the available Dims */
+
+ if(psDim != IMG_NULL)
+ {
+ unsigned long i;
+
+ for(i=0; i<psDevInfo->ulNumDims; i++)
+ {
+ psDim[i] = psDevInfo->asDisplayDimList[i];
+ }
+ }
+
+ return (PVRSRV_OK);
+}
+
+
+static PVRSRV_ERROR GetDCSystemBuffer(IMG_HANDLE hDevice, IMG_HANDLE *phBuffer)
+{
+ DC_NOHW_DEVINFO *psDevInfo;
+
+ if(!hDevice || !phBuffer)
+ {
+ return (PVRSRV_ERROR_INVALID_PARAMS);
+ }
+
+ psDevInfo = (DC_NOHW_DEVINFO *)hDevice;
+
+ *phBuffer = (IMG_HANDLE)&psDevInfo->asBackBuffers[0];
+
+ return (PVRSRV_OK);
+}
+
+
+static PVRSRV_ERROR GetDCInfo(IMG_HANDLE hDevice, DISPLAY_INFO *psDCInfo)
+{
+ DC_NOHW_DEVINFO *psDevInfo;
+
+ if(!hDevice || !psDCInfo)
+ {
+ return (PVRSRV_ERROR_INVALID_PARAMS);
+ }
+
+ psDevInfo = (DC_NOHW_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,
+ IMG_UINT32 *pui32TilingStride)
+{
+ DC_NOHW_DEVINFO *psDevInfo;
+ DC_NOHW_BUFFER *psBuffer;
+
+ if(!hDevice || !hBuffer || !ppsSysAddr || !pui32ByteSize)
+ {
+ return (PVRSRV_ERROR_INVALID_PARAMS);
+ }
+
+ psDevInfo = (DC_NOHW_DEVINFO *)hDevice;
+
+ psBuffer = (DC_NOHW_BUFFER*)hBuffer;
+
+ *ppvCpuVAddr = psBuffer->sCPUVAddr;
+
+ *pui32ByteSize = (IMG_UINT32)(psDevInfo->asDisplayDimList[0].ui32Height * psDevInfo->asDisplayDimList[0].ui32ByteStride);
+ *phOSMapInfo = IMG_NULL;
+
+#if defined(DC_NOHW_DISCONTIG_BUFFERS)
+ *ppsSysAddr = psBuffer->psSysAddr;
+ *pbIsContiguous = IMG_FALSE;
+#else
+ *ppsSysAddr = &psBuffer->sSysAddr;
+ *pbIsContiguous = IMG_TRUE;
+#endif
+
+#if defined(SUPPORT_MEMORY_TILING)
+ {
+ IMG_UINT32 ui32Stride = psDevInfo->asDisplayDimList[0].ui32ByteStride;
+ IMG_UINT32 ui32NumBits = 0, ui32StrideTopBit, n;
+
+ // How many bits for x?
+ for(n = 0; n < 32; n++)
+ {
+ if(ui32Stride & (1<<n))
+ {
+ ui32NumBits = n+1;
+ }
+ }
+
+ // clamp to the minimum..
+ if(ui32NumBits < 10)
+ {
+ ui32NumBits = 10;
+ }
+
+ // Subtract one to make this a range limit..
+ ui32StrideTopBit = ui32NumBits - 1;
+
+ // Subtract 9 to prepare it for the HW..
+ ui32StrideTopBit -= 9;
+
+ *pui32TilingStride = ui32StrideTopBit;
+ }
+#else
+ UNREFERENCED_PARAMETER(pui32TilingStride);
+#endif /* defined(SUPPORT_MEMORY_TILING) */
+
+ 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)
+{
+ DC_NOHW_DEVINFO *psDevInfo;
+ DC_NOHW_SWAPCHAIN *psSwapChain;
+ DC_NOHW_BUFFER *psBuffer;
+ IMG_UINT32 i;
+
+ UNREFERENCED_PARAMETER(ui32OEMFlags);
+ UNREFERENCED_PARAMETER(pui32SwapChainID);
+
+ /* check parameters */
+ if(!hDevice
+ || !psDstSurfAttrib
+ || !psSrcSurfAttrib
+ || !ppsSyncData
+ || !phSwapChain)
+ {
+ return (PVRSRV_ERROR_INVALID_PARAMS);
+ }
+
+ psDevInfo = (DC_NOHW_DEVINFO*)hDevice;
+
+ /* the dc_nohw only supports a single swapchain */
+ if(psDevInfo->psSwapChain)
+ {
+ return (PVRSRV_ERROR_FLIP_CHAIN_EXISTS);
+ }
+
+ /* check the buffer count */
+ if(ui32BufferCount > DC_NOHW_MAX_BACKBUFFERS)
+ {
+ return (PVRSRV_ERROR_TOOMANYBUFFERS);
+ }
+
+ /*
+ verify the DST/SRC attributes
+ - SRC/DST must match the current display mode config
+ */
+ if(psDstSurfAttrib->pixelformat != psDevInfo->sSysFormat.pixelformat
+ || psDstSurfAttrib->sDims.ui32ByteStride != psDevInfo->sSysDims.ui32ByteStride
+ || psDstSurfAttrib->sDims.ui32Width != psDevInfo->sSysDims.ui32Width
+ || psDstSurfAttrib->sDims.ui32Height != psDevInfo->sSysDims.ui32Height)
+ {
+ /* DST doesn't match the current mode */
+ 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)
+ {
+ /* DST doesn't match the SRC */
+ return (PVRSRV_ERROR_INVALID_PARAMS);
+ }
+
+ /* INTEGRATION_POINT: check the flags */
+ UNREFERENCED_PARAMETER(ui32Flags);
+
+ /* create a swapchain structure */
+ psSwapChain = (DC_NOHW_SWAPCHAIN*)AllocKernelMem(sizeof(DC_NOHW_SWAPCHAIN));
+ if(!psSwapChain)
+ {
+ return (PVRSRV_ERROR_OUT_OF_MEMORY);
+ }
+
+ psBuffer = (DC_NOHW_BUFFER*)AllocKernelMem(sizeof(DC_NOHW_BUFFER) * ui32BufferCount);
+ if(!psBuffer)
+ {
+ FreeKernelMem(psSwapChain);
+ return (PVRSRV_ERROR_OUT_OF_MEMORY);
+ }
+
+ /* initialise allocations */
+ memset(psSwapChain, 0, sizeof(DC_NOHW_SWAPCHAIN));
+ memset(psBuffer, 0, sizeof(DC_NOHW_BUFFER) * ui32BufferCount);
+
+ psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount;
+ psSwapChain->psBuffer = psBuffer;
+
+ /* link the buffers */
+ for(i=0; i<ui32BufferCount-1; i++)
+ {
+ psBuffer[i].psNext = &psBuffer[i+1];
+ }
+ /* and link last to first */
+ psBuffer[i].psNext = &psBuffer[0];
+
+ /* populate the buffers */
+ for(i=0; i<ui32BufferCount; i++)
+ {
+ psBuffer[i].psSyncData = ppsSyncData[i];
+#if defined(DC_NOHW_DISCONTIG_BUFFERS)
+ psBuffer[i].psSysAddr = psDevInfo->asBackBuffers[i].psSysAddr;
+#else
+ psBuffer[i].sSysAddr = psDevInfo->asBackBuffers[i].sSysAddr;
+#endif
+ psBuffer[i].sDevVAddr = psDevInfo->asBackBuffers[i].sDevVAddr;
+ psBuffer[i].sCPUVAddr = psDevInfo->asBackBuffers[i].sCPUVAddr;
+ psBuffer[i].hSwapChain = (DC_HANDLE)psSwapChain;
+ }
+
+ /* mark swapchain's existence */
+ psDevInfo->psSwapChain = psSwapChain;
+
+ /* return swapchain handle */
+ *phSwapChain = (IMG_HANDLE)psSwapChain;
+
+ /* INTEGRATION_POINT: enable Vsync ISR */
+
+ return (PVRSRV_OK);
+}
+
+
+static PVRSRV_ERROR DestroyDCSwapChain(IMG_HANDLE hDevice,
+ IMG_HANDLE hSwapChain)
+{
+ DC_NOHW_DEVINFO *psDevInfo;
+ DC_NOHW_SWAPCHAIN *psSwapChain;
+
+ /* check parameters */
+ if(!hDevice
+ || !hSwapChain)
+ {
+ return (PVRSRV_ERROR_INVALID_PARAMS);
+ }
+
+ psDevInfo = (DC_NOHW_DEVINFO*)hDevice;
+ psSwapChain = (DC_NOHW_SWAPCHAIN*)hSwapChain;
+
+ /* free resources */
+ FreeKernelMem(psSwapChain->psBuffer);
+ FreeKernelMem(psSwapChain);
+
+ /* mark swapchain as not existing */
+ psDevInfo->psSwapChain = 0;
+
+ /* INTEGRATION_POINT: disable Vsync ISR */
+
+ 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)
+{
+/* DC_NOHW_DEVINFO *psDevInfo; */
+ DC_NOHW_SWAPCHAIN *psSwapChain;
+ unsigned long i;
+
+ /* check parameters */
+ if(!hDevice
+ || !hSwapChain
+ || !pui32BufferCount
+ || !phBuffer)
+ {
+ return (PVRSRV_ERROR_INVALID_PARAMS);
+ }
+
+/* psDevInfo = (DC_NOHW_DEVINFO*)hDevice; */
+ psSwapChain = (DC_NOHW_SWAPCHAIN*)hSwapChain;
+
+ /* return the buffer count */
+ *pui32BufferCount = (IMG_UINT32)psSwapChain->ulBufferCount;
+
+ /* return the buffers */
+ 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)
+{
+ UNREFERENCED_PARAMETER(ui32SwapInterval);
+ UNREFERENCED_PARAMETER(hPrivateTag);
+ UNREFERENCED_PARAMETER(psClipRect);
+
+ if(!hDevice
+ || !hBuffer
+ || (ui32ClipRectCount != 0))
+ {
+ return (PVRSRV_ERROR_INVALID_PARAMS);
+ }
+
+ /* nothing to do for no hw */
+ return (PVRSRV_OK);
+}
+
+
+static DC_ERROR Flip(DC_NOHW_DEVINFO *psDevInfo,
+ DC_NOHW_BUFFER *psBuffer)
+{
+ /* check parameters */
+ if(!psDevInfo || !psBuffer)
+ {
+ return (DC_ERROR_INVALID_PARAMS);
+ }
+ /* to be implemented */
+
+ return (DC_OK);
+}
+
+
+static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie,
+ IMG_UINT32 ui32DataSize,
+ IMG_VOID *pvData)
+{
+ DC_ERROR eError;
+ DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
+ DC_NOHW_DEVINFO *psDevInfo;
+ DC_NOHW_BUFFER *psBuffer;
+
+ /* check parameters */
+ if(!hCmdCookie)
+ {
+ return (IMG_FALSE);
+ }
+
+ /* validate data packet */
+ psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)pvData;
+ if (psFlipCmd == IMG_NULL || sizeof(DISPLAYCLASS_FLIP_COMMAND) != ui32DataSize)
+ {
+ return (IMG_FALSE);
+ }
+
+ /* setup some useful pointers */
+ psDevInfo = (DC_NOHW_DEVINFO*)psFlipCmd->hExtDevice;
+
+ psBuffer = (DC_NOHW_BUFFER*)psFlipCmd->hExtBuffer;
+
+ /* flip the display */
+ eError = Flip(psDevInfo, psBuffer);
+ if(eError != DC_OK)
+ {
+ return (IMG_FALSE);
+ }
+
+ /* call command complete Callback */
+ psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete(hCmdCookie, IMG_FALSE);
+
+ return (IMG_TRUE);
+}
+
+
+DC_ERROR Init(void)
+{
+ DC_NOHW_DEVINFO *psDevInfo;
+ DC_ERROR eError;
+ unsigned long ulBBuf;
+ unsigned long ulNBBuf;
+ /*
+ - connect to services
+ - register with services
+ - allocate and setup private data structure
+ */
+
+
+ /*
+ in kernel driver, data structures must be anchored to something for subsequent retrieval
+ this may be a single global pointer or TLS or something else - up to you
+ call API to retrieve this ptr
+ */
+
+ /*
+ get the anchor pointer
+ */
+ psDevInfo = GetAnchorPtr();
+
+ if (psDevInfo == 0)
+ {
+ PFN_CMD_PROC pfnCmdProcList[DC_NOHW_COMMAND_COUNT];
+ IMG_UINT32 aui32SyncCountList[DC_NOHW_COMMAND_COUNT][2];
+
+ /* allocate device info. structure */
+ psDevInfo = (DC_NOHW_DEVINFO *)AllocKernelMem(sizeof(*psDevInfo));
+
+ if(!psDevInfo)
+ {
+ eError = DC_ERROR_OUT_OF_MEMORY;/* failure */
+ goto ExitError;
+ }
+
+ /* initialise allocation */
+ memset(psDevInfo, 0, sizeof(*psDevInfo));
+
+ /* set the top-level anchor */
+ SetAnchorPtr((void*)psDevInfo);
+
+ /* set ref count */
+ psDevInfo->ulRefCount = 0UL;
+
+ if(OpenPVRServices(&psDevInfo->hPVRServices) != DC_OK)
+ {
+ eError = DC_ERROR_INIT_FAILURE;
+ goto ExitFreeDevInfo;
+ }
+ if(GetLibFuncAddr (psDevInfo->hPVRServices, "PVRGetDisplayClassJTable", &pfnGetPVRJTable) != DC_OK)
+ {
+ eError = DC_ERROR_INIT_FAILURE;
+ goto ExitCloseServices;
+ }
+
+ /* got the kernel services function table */
+ if((*pfnGetPVRJTable)(&psDevInfo->sPVRJTable) == IMG_FALSE)
+ {
+ eError = DC_ERROR_INIT_FAILURE;
+ goto ExitCloseServices;
+ }
+
+ /*
+ Setup the devinfo
+ */
+ psDevInfo->psSwapChain = 0;
+ psDevInfo->sDisplayInfo.ui32MinSwapInterval = 0UL;
+ psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 1UL;
+ psDevInfo->sDisplayInfo.ui32MaxSwapChains = 1UL;
+ psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = DC_NOHW_MAX_BACKBUFFERS;
+ strncpy(psDevInfo->sDisplayInfo.szDisplayName, DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE);
+
+ psDevInfo->ulNumFormats = 1UL;
+
+ psDevInfo->ulNumDims = 1UL;
+
+#if defined(DC_NOHW_GET_BUFFER_DIMENSIONS)
+ if (!GetBufferDimensions(&psDevInfo->asDisplayDimList[0].ui32Width,
+ &psDevInfo->asDisplayDimList[0].ui32Height,
+ &psDevInfo->asDisplayFormatList[0].pixelformat,
+ &psDevInfo->asDisplayDimList[0].ui32ByteStride))
+ {
+ eError = DC_ERROR_INIT_FAILURE;
+ goto ExitCloseServices;
+ }
+#else /* defined(DC_NOHW_GET_BUFFER_DIMENSIONS) */
+ #if defined (ENABLE_DISPLAY_MODE_TRACKING)
+ // Set sizes to zero to force re-alloc on display mode change.
+ psDevInfo->asDisplayFormatList[0].pixelformat = DC_NOHW_BUFFER_PIXEL_FORMAT;
+ psDevInfo->asDisplayDimList[0].ui32Width = 0;
+ psDevInfo->asDisplayDimList[0].ui32Height = 0;
+ psDevInfo->asDisplayDimList[0].ui32ByteStride = 0;
+ #else
+ psDevInfo->asDisplayFormatList[0].pixelformat = DC_NOHW_BUFFER_PIXEL_FORMAT;
+ psDevInfo->asDisplayDimList[0].ui32Width = DC_NOHW_BUFFER_WIDTH;
+ psDevInfo->asDisplayDimList[0].ui32Height = DC_NOHW_BUFFER_HEIGHT;
+ psDevInfo->asDisplayDimList[0].ui32ByteStride = DC_NOHW_BUFFER_BYTE_STRIDE;
+ #endif
+#endif /* defined(DC_NOHW_GET_BUFFER_DIMENSIONS) */
+
+ psDevInfo->sSysFormat = psDevInfo->asDisplayFormatList[0];
+ psDevInfo->sSysDims.ui32Width = psDevInfo->asDisplayDimList[0].ui32Width;
+ psDevInfo->sSysDims.ui32Height = psDevInfo->asDisplayDimList[0].ui32Height;
+ psDevInfo->sSysDims.ui32ByteStride = psDevInfo->asDisplayDimList[0].ui32ByteStride;
+ psDevInfo->ui32BufferSize = psDevInfo->sSysDims.ui32Height * psDevInfo->sSysDims.ui32ByteStride;
+
+
+ /* setup swapchain details */
+ for(ulBBuf=0; ulBBuf<DC_NOHW_MAX_BACKBUFFERS; ulBBuf++)
+ {
+#if defined(USE_BASE_VIDEO_FRAMEBUFFER) || defined (ENABLE_DISPLAY_MODE_TRACKING)
+ psDevInfo->asBackBuffers[ulBBuf].sSysAddr.uiAddr = IMG_NULL;
+ psDevInfo->asBackBuffers[ulBBuf].sCPUVAddr = IMG_NULL;
+#else
+#if defined(DC_NOHW_DISCONTIG_BUFFERS)
+ if (AllocDiscontigMemory(psDevInfo->ui32BufferSize,
+ &psDevInfo->asBackBuffers[ulBBuf].hMemChunk,
+ &psDevInfo->asBackBuffers[ulBBuf].sCPUVAddr,
+ &psDevInfo->asBackBuffers[ulBBuf].psSysAddr) != DC_OK)
+ {
+ eError = DC_ERROR_INIT_FAILURE;
+ goto ExitFreeMem;
+ }
+#else
+ IMG_CPU_PHYADDR sBufferCPUPAddr;
+
+ if (AllocContigMemory(psDevInfo->ui32BufferSize,
+ &psDevInfo->asBackBuffers[ulBBuf].hMemChunk,
+ &psDevInfo->asBackBuffers[ulBBuf].sCPUVAddr,
+ &sBufferCPUPAddr) != DC_OK)
+ {
+ eError = DC_ERROR_INIT_FAILURE;
+ goto ExitFreeMem;
+ }
+
+ psDevInfo->asBackBuffers[ulBBuf].sSysAddr = CpuPAddrToSysPAddr(sBufferCPUPAddr);
+#endif
+#endif /* #if defined(USE_BASE_VIDEO_FRAMEBUFFER) */
+ /* sDevVAddr not meaningful for nohw */
+ psDevInfo->asBackBuffers[ulBBuf].sDevVAddr.uiAddr = 0UL;
+ psDevInfo->asBackBuffers[ulBBuf].hSwapChain = 0;
+ psDevInfo->asBackBuffers[ulBBuf].psSyncData = 0;
+ psDevInfo->asBackBuffers[ulBBuf].psNext = 0;
+ }
+
+ /*
+ setup the DC Jtable so SRVKM can call into this driver
+ */
+ 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.pfnSetDCState = IMG_NULL;
+
+ /* register device with services and retrieve device index */
+ if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice (&psDevInfo->sDCJTable,
+ &psDevInfo->uiDeviceID ) != PVRSRV_OK)
+ {
+ eError = DC_ERROR_DEVICE_REGISTER_FAILED;
+ goto ExitFreeMem;
+ }
+
+ /*
+ setup private command processing function table
+ */
+ pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip;
+
+ /*
+ and associated sync count(s)
+ */
+ aui32SyncCountList[DC_FLIP_COMMAND][0] = 0UL;/* no writes */
+ aui32SyncCountList[DC_FLIP_COMMAND][1] = 2UL;/* 2 reads: To / From */
+
+ /*
+ register private command processing functions with
+ the Command Queue Manager and setup the general
+ command complete function in the devinfo
+ */
+ if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList(psDevInfo->uiDeviceID,
+ &pfnCmdProcList[0],
+ aui32SyncCountList,
+ DC_NOHW_COMMAND_COUNT) != PVRSRV_OK)
+ {
+ eError = DC_ERROR_CANT_REGISTER_CALLBACK;
+ goto ExitRemoveDevice;
+ }
+ }
+
+ /* increment the ref count */
+ psDevInfo->ulRefCount++;
+
+ /* return success */
+ return (DC_OK);
+
+ExitRemoveDevice:
+ (IMG_VOID) psDevInfo->sPVRJTable.pfnPVRSRVRemoveDCDevice(psDevInfo->uiDeviceID);
+
+ExitFreeMem:
+ ulNBBuf = ulBBuf;
+ for(ulBBuf=0; ulBBuf<ulNBBuf; ulBBuf++)
+ {
+#if defined(DC_NOHW_DISCONTIG_BUFFERS)
+ FreeDiscontigMemory(psDevInfo->ui32BufferSize,
+ psDevInfo->asBackBuffers[ulBBuf].hMemChunk,
+ psDevInfo->asBackBuffers[ulBBuf].sCPUVAddr,
+ psDevInfo->asBackBuffers[ulBBuf].psSysAddr);
+#else
+#if !defined(USE_BASE_VIDEO_FRAMEBUFFER)
+
+ FreeContigMemory(psDevInfo->ui32BufferSize,
+ psDevInfo->asBackBuffers[ulBBuf].hMemChunk,
+ psDevInfo->asBackBuffers[ulBBuf].sCPUVAddr,
+ SysPAddrToCpuPAddr(psDevInfo->asBackBuffers[ulBBuf].sSysAddr));
+
+
+#endif /* #if defined(USE_BASE_VIDEO_FRAMEBUFFER) */
+#endif /* #if defined(DC_NOHW_DISCONTIG_BUFFERS) */
+ }
+
+ExitCloseServices:
+ (void)ClosePVRServices(psDevInfo->hPVRServices);
+
+ExitFreeDevInfo:
+ FreeKernelMem(psDevInfo);
+ SetAnchorPtr(0);
+
+ExitError:
+ return eError;
+}
+
+
+
+/*
+ * Deinit
+ */
+DC_ERROR Deinit(void)
+{
+ DC_NOHW_DEVINFO *psDevInfo, *psDevFirst;
+#if !defined(USE_BASE_VIDEO_FRAMEBUFFER)
+ unsigned long i;
+#endif
+
+ psDevFirst = GetAnchorPtr();
+ psDevInfo = psDevFirst;
+
+ /* check DevInfo has been setup */
+ if (psDevInfo == 0)
+ {
+ return (DC_ERROR_GENERIC);/* failure */
+ }
+
+ /* decrement ref count */
+ psDevInfo->ulRefCount--;
+
+ if (psDevInfo->ulRefCount == 0UL)
+ {
+ /* all references gone - de-init device information */
+ PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable = &psDevInfo->sPVRJTable;
+
+ /* Remove display class device from kernel services device register */
+ if (psJTable->pfnPVRSRVRemoveDCDevice((IMG_UINT32)psDevInfo->uiDeviceID) != PVRSRV_OK)
+ {
+ return (DC_ERROR_GENERIC);/* failure */
+ }
+
+ if (psDevInfo->sPVRJTable.pfnPVRSRVRemoveCmdProcList(psDevInfo->uiDeviceID,
+ DC_NOHW_COMMAND_COUNT) != PVRSRV_OK)
+ {
+ return (DC_ERROR_GENERIC);/* failure */
+ }
+
+ if (ClosePVRServices(psDevInfo->hPVRServices) != DC_OK)
+ {
+ psDevInfo->hPVRServices = 0;
+ return (DC_ERROR_GENERIC);/* failure */
+ }
+
+#if !defined(USE_BASE_VIDEO_FRAMEBUFFER)
+ for(i=0; i<DC_NOHW_MAX_BACKBUFFERS; i++)
+ {
+ if (psDevInfo->asBackBuffers[i].sCPUVAddr)
+ {
+ #if defined(DC_NOHW_DISCONTIG_BUFFERS)
+ FreeDiscontigMemory(psDevInfo->ui32BufferSize,
+ psDevInfo->asBackBuffers[i].hMemChunk,
+ psDevInfo->asBackBuffers[i].sCPUVAddr,
+ psDevInfo->asBackBuffers[i].psSysAddr);
+ #else
+
+ FreeContigMemory(psDevInfo->ui32BufferSize,
+ psDevInfo->asBackBuffers[i].hMemChunk,
+ psDevInfo->asBackBuffers[i].sCPUVAddr,
+ SysPAddrToCpuPAddr(psDevInfo->asBackBuffers[i].sSysAddr));
+ #endif
+ }
+ }
+#endif /* #if !defined(USE_BASE_VIDEO_FRAMEBUFFER) */
+
+ /* de-allocate data structure */
+ FreeKernelMem(psDevInfo);
+ }
+
+#if defined (ENABLE_DISPLAY_MODE_TRACKING)
+ CloseMiniport();
+#endif
+ /* clear the top-level anchor */
+ SetAnchorPtr(0);
+
+ /* return success */
+ return (DC_OK);
+}
+
+/******************************************************************************
+ End of file (dc_nohw_displayclass.c)
+******************************************************************************/
diff --git a/pvr-source/services4/3rdparty/dc_nohw/dc_nohw_linux.c b/pvr-source/services4/3rdparty/dc_nohw/dc_nohw_linux.c
new file mode 100644
index 0000000..2f603ea
--- /dev/null
+++ b/pvr-source/services4/3rdparty/dc_nohw/dc_nohw_linux.c
@@ -0,0 +1,376 @@
+/*************************************************************************/ /*!
+@Title Dummy 3rd party driver linux specific declarations.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/**************************************************************************
+ The 3rd party driver is a specification of an API to integrate the
+ IMG PowerVR Services driver with 3rd Party display hardware.
+ It is NOT a specification for a display controller driver, rather a
+ specification to extend the API for a pre-existing driver for the display hardware.
+
+ The 3rd party driver interface provides IMG PowerVR client drivers (e.g. PVR2D)
+ with an API abstraction of the system's underlying display hardware, allowing
+ the client drivers to indirectly control the display hardware and access its
+ associated memory.
+
+ Functions of the API include
+
+ - query primary surface attributes (width, height, stride, pixel format,
+ CPU physical and virtual address)
+ - swap/flip chain creation and subsequent query of surface attributes
+ - asynchronous display surface flipping, taking account of asynchronous
+ read (flip) and write (render) operations to the display surface
+
+ Note: having queried surface attributes the client drivers are able to map
+ the display memory to any IMG PowerVR Services device by calling
+ PVRSRVMapDeviceClassMemory with the display surface handle.
+
+ This code is intended to be an example of how a pre-existing display driver
+ may be extended to support the 3rd Party Display interface to
+ PowerVR Services - IMG is not providing a display driver implementation
+ **************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+
+#if defined(SUPPORT_DRI_DRM)
+#include <drm/drmP.h>
+#endif
+
+#if defined(DC_NOHW_DISCONTIG_BUFFERS)
+#include <linux/vmalloc.h>
+#include <asm/page.h>
+#else
+#include <asm/dma-mapping.h>
+#endif
+
+#include "img_defs.h"
+#include "servicesext.h"
+#include "kerneldisplay.h"
+#include "dc_nohw.h"
+#include "pvrmodule.h"
+
+#if defined(SUPPORT_DRI_DRM)
+#include "pvr_drm.h"
+#endif
+
+#if defined(DC_USE_SET_MEMORY)
+ #undef DC_USE_SET_MEMORY
+#endif
+
+#if !defined(DC_NOHW_DISCONTIG_BUFFERS)
+ #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 DC_USE_SET_MEMORY
+ #endif
+#endif /* defined(DC_NOHW_DISCONTIG_BUFFERS) */
+
+#define DRVNAME "dcnohw"
+
+#if !defined(SUPPORT_DRI_DRM)
+MODULE_SUPPORTED_DEVICE(DRVNAME);
+#endif
+
+#define unref__ __attribute__ ((unused))
+
+#if defined(DC_NOHW_GET_BUFFER_DIMENSIONS)
+static unsigned long width = DC_NOHW_BUFFER_WIDTH;
+static unsigned long height = DC_NOHW_BUFFER_HEIGHT;
+static unsigned long depth = DC_NOHW_BUFFER_BIT_DEPTH;
+
+module_param(width, ulong, S_IRUGO);
+module_param(height, ulong, S_IRUGO);
+module_param(depth, ulong, S_IRUGO);
+
+IMG_BOOL GetBufferDimensions(IMG_UINT32 *pui32Width, IMG_UINT32 *pui32Height, PVRSRV_PIXEL_FORMAT *pePixelFormat, IMG_UINT32 *pui32Stride)
+{
+ if (width == 0 || height == 0 || depth == 0 ||
+ depth != dc_nohw_roundup_bit_depth(depth))
+ {
+ printk(KERN_WARNING DRVNAME ": Illegal module parameters (width %lu, height %lu, depth %lu)\n", width, height, depth);
+ return IMG_FALSE;
+ }
+
+ *pui32Width = (IMG_UINT32)width;
+ *pui32Height = (IMG_UINT32)height;
+
+ switch(depth)
+ {
+ case 32:
+ *pePixelFormat = PVRSRV_PIXEL_FORMAT_ARGB8888;
+ break;
+ case 16:
+ *pePixelFormat = PVRSRV_PIXEL_FORMAT_RGB565;
+ break;
+ default:
+ printk(KERN_WARNING DRVNAME ": Display depth %lu not supported\n", depth);
+ *pePixelFormat = PVRSRV_PIXEL_FORMAT_UNKNOWN;
+ return IMG_FALSE;
+ }
+
+ *pui32Stride = dc_nohw_byte_stride(width, depth);
+
+#if defined(DEBUG)
+ printk(KERN_INFO DRVNAME " Width: %lu\n", (unsigned long)*pui32Width);
+ printk(KERN_INFO DRVNAME " Height: %lu\n", (unsigned long)*pui32Height);
+ printk(KERN_INFO DRVNAME " Depth: %lu bits\n", depth);
+ printk(KERN_INFO DRVNAME " Stride: %lu bytes\n", (unsigned long)*pui32Stride);
+#endif /* defined(DEBUG) */
+
+ return IMG_TRUE;
+}
+#endif /* defined(DC_NOHW_GET_BUFFER_DIMENSIONS) */
+
+/*****************************************************************************
+ Function Name: DC_NOHW_Init
+ Description : Insert the driver into the kernel.
+
+ __init places the function in a special memory section that
+ the kernel frees once the function has been run. Refer also
+ to module_init() macro call below.
+
+*****************************************************************************/
+#if defined(SUPPORT_DRI_DRM)
+int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Init)(struct drm_device unref__ *dev)
+#else
+static int __init DC_NOHW_Init(void)
+#endif
+{
+ if(Init() != DC_OK)
+ {
+ return -ENODEV;
+ }
+
+ return 0;
+} /*DC_NOHW_Init*/
+
+/*****************************************************************************
+ Function Name: DC_NOHW_Cleanup
+ Description : Remove the driver from the kernel.
+
+ __exit places the function in a special memory section that
+ the kernel frees once the function has been run. Refer also
+ to module_exit() macro call below.
+
+*****************************************************************************/
+#if defined(SUPPORT_DRI_DRM)
+void PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Cleanup)(struct drm_device unref__ *dev)
+#else
+static void __exit DC_NOHW_Cleanup(void)
+#endif
+{
+ if(Deinit() != DC_OK)
+ {
+ printk (KERN_INFO DRVNAME ": DC_NOHW_Cleanup: can't deinit device\n");
+ }
+} /*DC_NOHW_Cleanup*/
+
+
+void *AllocKernelMem(unsigned long ulSize)
+{
+ return kmalloc(ulSize, GFP_KERNEL);
+}
+
+void FreeKernelMem(void *pvMem)
+{
+ kfree(pvMem);
+}
+
+#if defined(DC_NOHW_DISCONTIG_BUFFERS)
+
+#define RANGE_TO_PAGES(range) (((range) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)
+#define VMALLOC_TO_PAGE_PHYS(vAddr) page_to_phys(vmalloc_to_page(vAddr))
+
+DC_ERROR AllocDiscontigMemory(unsigned long ulSize,
+ DC_HANDLE unref__ *phMemHandle,
+ IMG_CPU_VIRTADDR *pLinAddr,
+ IMG_SYS_PHYADDR **ppPhysAddr)
+{
+ unsigned long ulPages = RANGE_TO_PAGES(ulSize);
+ IMG_SYS_PHYADDR *pPhysAddr;
+ unsigned long ulPage;
+ IMG_CPU_VIRTADDR LinAddr;
+
+ LinAddr = __vmalloc(ulSize, GFP_KERNEL | __GFP_HIGHMEM, pgprot_noncached(PAGE_KERNEL));
+ if (!LinAddr)
+ {
+ return DC_ERROR_OUT_OF_MEMORY;
+ }
+
+ pPhysAddr = kmalloc(ulPages * sizeof(IMG_SYS_PHYADDR), GFP_KERNEL);
+ if (!pPhysAddr)
+ {
+ vfree(LinAddr);
+ return DC_ERROR_OUT_OF_MEMORY;
+ }
+
+ *pLinAddr = LinAddr;
+
+ for (ulPage = 0; ulPage < ulPages; ulPage++)
+ {
+ pPhysAddr[ulPage].uiAddr = VMALLOC_TO_PAGE_PHYS(LinAddr);
+
+ LinAddr += PAGE_SIZE;
+ }
+
+ *ppPhysAddr = pPhysAddr;
+
+ return DC_OK;
+}
+
+void FreeDiscontigMemory(unsigned long ulSize,
+ DC_HANDLE unref__ hMemHandle,
+ IMG_CPU_VIRTADDR LinAddr,
+ IMG_SYS_PHYADDR *pPhysAddr)
+{
+ kfree(pPhysAddr);
+
+ vfree(LinAddr);
+}
+#else /* defined(DC_NOHW_DISCONTIG_BUFFERS) */
+DC_ERROR AllocContigMemory(unsigned long ulSize,
+ DC_HANDLE unref__ *phMemHandle,
+ IMG_CPU_VIRTADDR *pLinAddr,
+ IMG_CPU_PHYADDR *pPhysAddr)
+{
+#if defined(DC_USE_SET_MEMORY)
+ void *pvLinAddr;
+ unsigned long ulAlignedSize = PAGE_ALIGN(ulSize);
+ int iPages = (int)(ulAlignedSize >> PAGE_SHIFT);
+ int iError;
+
+ pvLinAddr = kmalloc(ulAlignedSize, GFP_KERNEL);
+ iError = set_memory_wc((unsigned long)pvLinAddr, iPages);
+ if (iError != 0)
+ {
+ printk(KERN_ERR DRVNAME ": AllocContigMemory: set_memory_wc failed (%d)\n", iError);
+
+ return DC_ERROR_OUT_OF_MEMORY;
+ }
+
+ pPhysAddr->uiAddr = virt_to_phys(pvLinAddr);
+ *pLinAddr = pvLinAddr;
+
+ return DC_OK;
+#else /* DC_USE_SET_MEMORY */
+ dma_addr_t dma;
+ IMG_VOID *pvLinAddr;
+
+ pvLinAddr = dma_alloc_coherent(NULL, ulSize, &dma, GFP_KERNEL);
+
+ if (pvLinAddr == NULL)
+ {
+ return DC_ERROR_OUT_OF_MEMORY;
+ }
+
+ pPhysAddr->uiAddr = dma;
+ *pLinAddr = pvLinAddr;
+
+ return DC_OK;
+#endif /* DC_USE_SET_MEMORY */
+}
+
+void FreeContigMemory(unsigned long ulSize,
+ DC_HANDLE unref__ hMemHandle,
+ IMG_CPU_VIRTADDR LinAddr,
+ IMG_CPU_PHYADDR PhysAddr)
+{
+#if defined(DC_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 ": FreeContigMemory: set_memory_wb failed (%d)\n", iError);
+ }
+ kfree(LinAddr);
+#else /* DC_USE_SET_MEMORY */
+ dma_free_coherent(NULL, ulSize, LinAddr, (dma_addr_t)PhysAddr.uiAddr);
+#endif /* DC_USE_SET_MEMORY */
+}
+#endif /* defined(DC_NOHW_DISCONTIG_BUFFERS) */
+
+DC_ERROR OpenPVRServices (DC_HANDLE *phPVRServices)
+{
+ /* Nothing to do - we have already checked services module insertion */
+ *phPVRServices = 0;
+ return DC_OK;
+}
+
+DC_ERROR ClosePVRServices (DC_HANDLE unref__ hPVRServices)
+{
+ /* Nothing to do */
+ return DC_OK;
+}
+
+DC_ERROR GetLibFuncAddr (DC_HANDLE unref__ hExtDrv, char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable)
+{
+ if(strcmp("PVRGetDisplayClassJTable", szFunctionName) != 0)
+ {
+ return DC_ERROR_INVALID_PARAMS;
+ }
+
+ /* Nothing to do - should be exported from pvrsrv.ko */
+ *ppfnFuncTable = PVRGetDisplayClassJTable;
+
+ return DC_OK;
+}
+
+#if !defined(SUPPORT_DRI_DRM)
+/*
+ These macro calls define the initialisation and removal functions of the
+ driver. Although they are prefixed `module_', they apply when compiling
+ statically as well; in both cases they define the function the kernel will
+ run to start/stop the driver.
+*/
+module_init(DC_NOHW_Init);
+module_exit(DC_NOHW_Cleanup);
+#endif
diff --git a/pvr-source/services4/3rdparty/dc_omapfb3_linux/Kbuild.mk b/pvr-source/services4/3rdparty/dc_omapfb3_linux/Kbuild.mk
new file mode 100644
index 0000000..7f4fd99
--- /dev/null
+++ b/pvr-source/services4/3rdparty/dc_omapfb3_linux/Kbuild.mk
@@ -0,0 +1,48 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+ccflags-y += \
+ -I$(TOP)/services4/3rdparty/dc_omapfb3_linux \
+ -I$(KERNELDIR)/drivers/video/omap2 \
+ -I$(KERNELDIR)/arch/arm/plat-omap/include
+
+omaplfb-y += \
+ services4/3rdparty/dc_omapfb3_linux/omaplfb_displayclass.o \
+ services4/3rdparty/dc_omapfb3_linux/omaplfb_linux.o
diff --git a/pvr-source/services4/3rdparty/dc_omapfb3_linux/Linux.mk b/pvr-source/services4/3rdparty/dc_omapfb3_linux/Linux.mk
new file mode 100644
index 0000000..75d11a9
--- /dev/null
+++ b/pvr-source/services4/3rdparty/dc_omapfb3_linux/Linux.mk
@@ -0,0 +1,45 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+modules := dc_omapfb3_linux
+
+dc_omapfb3_linux_type := kernel_module
+dc_omapfb3_linux_target := omaplfb.ko
+dc_omapfb3_linux_makefile := $(THIS_DIR)/Kbuild.mk
diff --git a/pvr-source/services4/3rdparty/dc_omapfb3_linux/omaplfb.h b/pvr-source/services4/3rdparty/dc_omapfb3_linux/omaplfb.h
new file mode 100644
index 0000000..804695b
--- /dev/null
+++ b/pvr-source/services4/3rdparty/dc_omapfb3_linux/omaplfb.h
@@ -0,0 +1,323 @@
+/*************************************************************************/ /*!
+@Title OMAP Linux display driver structures and prototypes
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef __OMAPLFB_H__
+#define __OMAPLFB_H__
+
+#include <linux/version.h>
+
+#include <asm/atomic.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/mutex.h>
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
+#define OMAPLFB_CONSOLE_LOCK() console_lock()
+#define OMAPLFB_CONSOLE_UNLOCK() console_unlock()
+#else
+#define OMAPLFB_CONSOLE_LOCK() acquire_console_sem()
+#define OMAPLFB_CONSOLE_UNLOCK() release_console_sem()
+#endif
+
+#define unref__ __attribute__ ((unused))
+
+typedef void * OMAPLFB_HANDLE;
+
+typedef bool OMAPLFB_BOOL, *OMAPLFB_PBOOL;
+#define OMAPLFB_FALSE false
+#define OMAPLFB_TRUE true
+
+typedef atomic_t OMAPLFB_ATOMIC_BOOL;
+
+typedef atomic_t OMAPLFB_ATOMIC_INT;
+
+/* OMAPLFB buffer structure */
+typedef struct OMAPLFB_BUFFER_TAG
+{
+ struct OMAPLFB_BUFFER_TAG *psNext;
+ struct OMAPLFB_DEVINFO_TAG *psDevInfo;
+
+ struct work_struct sWork;
+
+ /* Position of this buffer in the virtual framebuffer */
+ unsigned long ulYOffset;
+
+ /* IMG structures used, to minimise API function code */
+ /* replace with own structures where necessary */
+ IMG_SYS_PHYADDR sSysAddr;
+ IMG_CPU_VIRTADDR sCPUVAddr;
+ PVRSRV_SYNC_DATA *psSyncData;
+
+ OMAPLFB_HANDLE hCmdComplete;
+ unsigned long ulSwapInterval;
+} OMAPLFB_BUFFER;
+
+/* OMAPLFB swapchain structure */
+typedef struct OMAPLFB_SWAPCHAIN_TAG
+{
+ /* Swap chain ID */
+ unsigned int uiSwapChainID;
+
+ /* number of buffers in swapchain */
+ unsigned long ulBufferCount;
+
+ /* list of buffers in the swapchain */
+ OMAPLFB_BUFFER *psBuffer;
+
+ /* Swap chain work queue */
+ struct workqueue_struct *psWorkQueue;
+
+ /*
+ * Set if we didn't manage to wait for VSync on last swap,
+ * or if we think we need to wait for VSync on the next flip.
+ * The flag helps to avoid jitter when the screen is
+ * unblanked, by forcing an extended wait for VSync before
+ * attempting the next flip.
+ */
+ OMAPLFB_BOOL bNotVSynced;
+
+ /* Previous number of blank events */
+ int iBlankEvents;
+
+ /* Framebuffer Device ID for messages (e.g. printk) */
+ unsigned int uiFBDevID;
+} 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;
+ unsigned long ulPhysicalWidthmm;
+ unsigned long ulPhysicalHeightmm;
+
+ /* IMG structures used, to minimise API function code */
+ /* replace with own structures where necessary */
+ IMG_SYS_PHYADDR sSysAddr;//system physical address
+ IMG_CPU_VIRTADDR sCPUVAddr;
+
+ /* pixelformat of system/primary surface */
+ PVRSRV_PIXEL_FORMAT ePixelFormat;
+
+#if defined(CONFIG_DSSCOMP)
+ OMAPLFB_BOOL bIs2D;
+ IMG_SYS_PHYADDR *psPageList;
+ struct ion_handle *psIONHandle;
+ IMG_UINT32 uiBytesPerPixel;
+#endif
+} OMAPLFB_FBINFO;
+
+/* kernel device information structure */
+typedef struct OMAPLFB_DEVINFO_TAG
+{
+ /* Framebuffer Device ID */
+ unsigned int uiFBDevID;
+
+ /* PVR Device ID */
+ unsigned int uiPVRDevID;
+
+ /* Swapchain create/destroy mutex */
+ struct mutex sCreateSwapChainMutex;
+
+ /* system surface info */
+ OMAPLFB_BUFFER sSystemBuffer;
+
+ /* jump table into PVR services */
+ PVRSRV_DC_DISP2SRV_KMJTABLE sPVRJTable;
+
+ /* jump table into DC */
+ PVRSRV_DC_SRV2DISP_KMJTABLE sDCJTable;
+
+ /* fb info structure */
+ OMAPLFB_FBINFO sFBInfo;
+
+ /* Only one swapchain supported by this device so hang it here */
+ OMAPLFB_SWAPCHAIN *psSwapChain;
+
+ /* Swap chain ID */
+ unsigned int uiSwapChainID;
+
+ /* True if PVR Services is flushing its command queues */
+ OMAPLFB_ATOMIC_BOOL sFlushCommands;
+
+ /* pointer to linux frame buffer information structure */
+ struct fb_info *psLINFBInfo;
+
+ /* Linux Framebuffer event notification block */
+ struct notifier_block sLINNotifBlock;
+
+ /* IMG structures used, to minimise API function code */
+ /* replace with own structures where necessary */
+
+ /* Address of the surface being displayed */
+ IMG_DEV_VIRTADDR sDisplayDevVAddr;
+
+ DISPLAY_INFO sDisplayInfo;
+
+ /* Display format */
+ DISPLAY_FORMAT sDisplayFormat;
+
+ /* Display dimensions */
+ DISPLAY_DIMS sDisplayDim;
+
+ /* True if screen is blanked */
+ OMAPLFB_ATOMIC_BOOL sBlanked;
+
+ /* Number of blank/unblank events */
+ OMAPLFB_ATOMIC_INT sBlankEvents;
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ /* Set by early suspend */
+ OMAPLFB_ATOMIC_BOOL sEarlySuspendFlag;
+
+ struct early_suspend sEarlySuspend;
+#endif
+
+#if defined(SUPPORT_DRI_DRM)
+ OMAPLFB_ATOMIC_BOOL sLeaveVT;
+#endif
+
+} OMAPLFB_DEVINFO;
+
+#define OMAPLFB_PAGE_SIZE 4096
+
+/* DEBUG only printk */
+#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
+
+/*!
+ *****************************************************************************
+ * Error values
+ *****************************************************************************/
+typedef enum _OMAPLFB_ERROR_
+{
+ OMAPLFB_OK = 0,
+ OMAPLFB_ERROR_GENERIC = 1,
+ OMAPLFB_ERROR_OUT_OF_MEMORY = 2,
+ OMAPLFB_ERROR_TOO_FEW_BUFFERS = 3,
+ OMAPLFB_ERROR_INVALID_PARAMS = 4,
+ OMAPLFB_ERROR_INIT_FAILURE = 5,
+ OMAPLFB_ERROR_CANT_REGISTER_CALLBACK = 6,
+ OMAPLFB_ERROR_INVALID_DEVICE = 7,
+ OMAPLFB_ERROR_DEVICE_REGISTER_FAILED = 8,
+ OMAPLFB_ERROR_SET_UPDATE_MODE_FAILED = 9
+} OMAPLFB_ERROR;
+
+typedef enum _OMAPLFB_UPDATE_MODE_
+{
+ OMAPLFB_UPDATE_MODE_UNDEFINED = 0,
+ OMAPLFB_UPDATE_MODE_MANUAL = 1,
+ OMAPLFB_UPDATE_MODE_AUTO = 2,
+ OMAPLFB_UPDATE_MODE_DISABLED = 3
+} OMAPLFB_UPDATE_MODE;
+
+#ifndef UNREFERENCED_PARAMETER
+#define UNREFERENCED_PARAMETER(param) (param) = (param)
+#endif
+
+OMAPLFB_ERROR OMAPLFBInit(void);
+OMAPLFB_ERROR OMAPLFBDeInit(void);
+
+/* OS Specific APIs */
+OMAPLFB_DEVINFO *OMAPLFBGetDevInfoPtr(unsigned uiFBDevID);
+unsigned OMAPLFBMaxFBDevIDPlusOne(void);
+void *OMAPLFBAllocKernelMem(unsigned long ulSize);
+void OMAPLFBFreeKernelMem(void *pvMem);
+OMAPLFB_ERROR OMAPLFBGetLibFuncAddr(char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable);
+OMAPLFB_ERROR OMAPLFBCreateSwapQueue (OMAPLFB_SWAPCHAIN *psSwapChain);
+void OMAPLFBDestroySwapQueue(OMAPLFB_SWAPCHAIN *psSwapChain);
+void OMAPLFBInitBufferForSwap(OMAPLFB_BUFFER *psBuffer);
+void OMAPLFBSwapHandler(OMAPLFB_BUFFER *psBuffer);
+void OMAPLFBQueueBufferForSwap(OMAPLFB_SWAPCHAIN *psSwapChain, OMAPLFB_BUFFER *psBuffer);
+void OMAPLFBFlip(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_BUFFER *psBuffer);
+OMAPLFB_UPDATE_MODE OMAPLFBGetUpdateMode(OMAPLFB_DEVINFO *psDevInfo);
+OMAPLFB_BOOL OMAPLFBSetUpdateMode(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_UPDATE_MODE eMode);
+OMAPLFB_BOOL OMAPLFBWaitForVSync(OMAPLFB_DEVINFO *psDevInfo);
+OMAPLFB_BOOL OMAPLFBManualSync(OMAPLFB_DEVINFO *psDevInfo);
+OMAPLFB_BOOL OMAPLFBCheckModeAndSync(OMAPLFB_DEVINFO *psDevInfo);
+OMAPLFB_ERROR OMAPLFBUnblankDisplay(OMAPLFB_DEVINFO *psDevInfo);
+OMAPLFB_ERROR OMAPLFBEnableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo);
+OMAPLFB_ERROR OMAPLFBDisableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo);
+void OMAPLFBCreateSwapChainLockInit(OMAPLFB_DEVINFO *psDevInfo);
+void OMAPLFBCreateSwapChainLockDeInit(OMAPLFB_DEVINFO *psDevInfo);
+void OMAPLFBCreateSwapChainLock(OMAPLFB_DEVINFO *psDevInfo);
+void OMAPLFBCreateSwapChainUnLock(OMAPLFB_DEVINFO *psDevInfo);
+void OMAPLFBAtomicBoolInit(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal);
+void OMAPLFBAtomicBoolDeInit(OMAPLFB_ATOMIC_BOOL *psAtomic);
+void OMAPLFBAtomicBoolSet(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal);
+OMAPLFB_BOOL OMAPLFBAtomicBoolRead(OMAPLFB_ATOMIC_BOOL *psAtomic);
+void OMAPLFBAtomicIntInit(OMAPLFB_ATOMIC_INT *psAtomic, int iVal);
+void OMAPLFBAtomicIntDeInit(OMAPLFB_ATOMIC_INT *psAtomic);
+void OMAPLFBAtomicIntSet(OMAPLFB_ATOMIC_INT *psAtomic, int iVal);
+int OMAPLFBAtomicIntRead(OMAPLFB_ATOMIC_INT *psAtomic);
+void OMAPLFBAtomicIntInc(OMAPLFB_ATOMIC_INT *psAtomic);
+
+#if defined(DEBUG)
+void OMAPLFBPrintInfo(OMAPLFB_DEVINFO *psDevInfo);
+#else
+#define OMAPLFBPrintInfo(psDevInfo)
+#endif
+
+#endif /* __OMAPLFB_H__ */
+
+/******************************************************************************
+ End of file (omaplfb.h)
+******************************************************************************/
+
diff --git a/pvr-source/services4/3rdparty/dc_omapfb3_linux/omaplfb_displayclass.c b/pvr-source/services4/3rdparty/dc_omapfb3_linux/omaplfb_displayclass.c
new file mode 100644
index 0000000..ebca814
--- /dev/null
+++ b/pvr-source/services4/3rdparty/dc_omapfb3_linux/omaplfb_displayclass.c
@@ -0,0 +1,1722 @@
+/*************************************************************************/ /*!
+@Title OMAP common display driver components
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/**************************************************************************
+ The 3rd party driver is a specification of an API to integrate the IMG POWERVR
+ Services driver with 3rd Party display hardware. It is NOT a specification for
+ a display controller driver, rather a specification to extend the API for a
+ pre-existing driver for the display hardware.
+
+ The 3rd party driver interface provides IMG POWERVR client drivers (e.g. PVR2D)
+ with an API abstraction of the system's underlying display hardware, allowing
+ the client drivers to indirectly control the display hardware and access its
+ associated memory.
+
+ Functions of the API include
+ - query primary surface attributes (width, height, stride, pixel format, CPU
+ physical and virtual address)
+ - swap/flip chain creation and subsequent query of surface attributes
+ - asynchronous display surface flipping, taking account of asynchronous read
+ (flip) and write (render) operations to the display surface
+
+ Note: having queried surface attributes the client drivers are able to map the
+ display memory to any IMG POWERVR Services device by calling
+ PVRSRVMapDeviceClassMemory with the display surface handle.
+
+ This code is intended to be an example of how a pre-existing display driver may
+ be extended to support the 3rd Party Display interface to POWERVR Services
+ - IMG is not providing a display driver implementation.
+ **************************************************************************/
+
+/*
+ * OMAP Linux 3rd party display driver.
+ * This is based on the Generic PVR Linux Framebuffer 3rd party display
+ * driver, with OMAP specific extensions to support flipping.
+ */
+
+#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>
+
+/* IMG services headers */
+#include "img_defs.h"
+#include "servicesext.h"
+#include "kerneldisplay.h"
+#include "omaplfb.h"
+
+#if defined(CONFIG_DSSCOMP)
+
+#if !defined(CONFIG_ION_OMAP)
+#error CONFIG_DSSCOMP support requires CONFIG_ION_OMAP
+#endif
+
+#include <linux/ion.h>
+#include <linux/omap_ion.h>
+
+extern struct ion_client *gpsIONClient;
+
+#include <mach/tiler.h>
+#include <video/dsscomp.h>
+#include <plat/dsscomp.h>
+
+#endif /* defined(CONFIG_DSSCOMP) */
+
+#define OMAPLFB_COMMAND_COUNT 1
+
+#define OMAPLFB_VSYNC_SETTLE_COUNT 5
+
+#define OMAPLFB_MAX_NUM_DEVICES FB_MAX
+#if (OMAPLFB_MAX_NUM_DEVICES > FB_MAX)
+#error "OMAPLFB_MAX_NUM_DEVICES must not be greater than FB_MAX"
+#endif
+
+static OMAPLFB_DEVINFO *gapsDevInfo[OMAPLFB_MAX_NUM_DEVICES];
+
+/* Top level 'hook ptr' */
+static PFN_DC_GET_PVRJTABLE gpfnGetPVRJTable = NULL;
+
+/* Round x up to a multiple of y */
+static inline unsigned long RoundUpToMultiple(unsigned long x, unsigned long y)
+{
+ unsigned long div = x / y;
+ unsigned long rem = x % y;
+
+ return (div + ((rem == 0) ? 0 : 1)) * y;
+}
+
+/* Greatest common divisor of x and y */
+static unsigned long GCD(unsigned long x, unsigned long y)
+{
+ while (y != 0)
+ {
+ unsigned long r = x % y;
+ x = y;
+ y = r;
+ }
+
+ return x;
+}
+
+/* Least common multiple of x and y */
+static unsigned long LCM(unsigned long x, unsigned long y)
+{
+ unsigned long gcd = GCD(x, y);
+
+ return (gcd == 0) ? 0 : ((x / gcd) * y);
+}
+
+unsigned OMAPLFBMaxFBDevIDPlusOne(void)
+{
+ return OMAPLFB_MAX_NUM_DEVICES;
+}
+
+/* Returns DevInfo pointer for a given device */
+OMAPLFB_DEVINFO *OMAPLFBGetDevInfoPtr(unsigned uiFBDevID)
+{
+ WARN_ON(uiFBDevID >= OMAPLFBMaxFBDevIDPlusOne());
+
+ if (uiFBDevID >= OMAPLFB_MAX_NUM_DEVICES)
+ {
+ return NULL;
+ }
+
+ return gapsDevInfo[uiFBDevID];
+}
+
+/* Sets the DevInfo pointer for a given device */
+static inline void OMAPLFBSetDevInfoPtr(unsigned uiFBDevID, OMAPLFB_DEVINFO *psDevInfo)
+{
+ WARN_ON(uiFBDevID >= OMAPLFB_MAX_NUM_DEVICES);
+
+ if (uiFBDevID < OMAPLFB_MAX_NUM_DEVICES)
+ {
+ gapsDevInfo[uiFBDevID] = psDevInfo;
+ }
+}
+
+static inline OMAPLFB_BOOL SwapChainHasChanged(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_SWAPCHAIN *psSwapChain)
+{
+ return (psDevInfo->psSwapChain != psSwapChain) ||
+ (psDevInfo->uiSwapChainID != psSwapChain->uiSwapChainID);
+}
+
+/* Don't wait for vertical sync */
+static inline OMAPLFB_BOOL DontWaitForVSync(OMAPLFB_DEVINFO *psDevInfo)
+{
+ OMAPLFB_BOOL bDontWait;
+
+ bDontWait = OMAPLFBAtomicBoolRead(&psDevInfo->sBlanked) ||
+ OMAPLFBAtomicBoolRead(&psDevInfo->sFlushCommands);
+
+#if defined(CONFIG_HAS_EARLYSUSPEND)
+ bDontWait = bDontWait || OMAPLFBAtomicBoolRead(&psDevInfo->sEarlySuspendFlag);
+#endif
+#if defined(SUPPORT_DRI_DRM)
+ bDontWait = bDontWait || OMAPLFBAtomicBoolRead(&psDevInfo->sLeaveVT);
+#endif
+ return bDontWait;
+}
+
+/*
+ * SetDCState
+ * Called from services.
+ */
+static IMG_VOID SetDCState(IMG_HANDLE hDevice, IMG_UINT32 ui32State)
+{
+ OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)hDevice;
+
+ switch (ui32State)
+ {
+ case DC_STATE_FLUSH_COMMANDS:
+ OMAPLFBAtomicBoolSet(&psDevInfo->sFlushCommands, OMAPLFB_TRUE);
+ break;
+ case DC_STATE_NO_FLUSH_COMMANDS:
+ OMAPLFBAtomicBoolSet(&psDevInfo->sFlushCommands, OMAPLFB_FALSE);
+ break;
+ case DC_STATE_FORCE_SWAP_TO_SYSTEM:
+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer);
+ break;
+ default:
+ break;
+ }
+}
+
+/*
+ * OpenDCDevice
+ * Called from services.
+ */
+static PVRSRV_ERROR OpenDCDevice(IMG_UINT32 uiPVRDevID,
+ IMG_HANDLE *phDevice,
+ PVRSRV_SYNC_DATA* psSystemBufferSyncData)
+{
+ OMAPLFB_DEVINFO *psDevInfo;
+ OMAPLFB_ERROR eError;
+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne();
+ unsigned i;
+
+ for (i = 0; i < uiMaxFBDevIDPlusOne; i++)
+ {
+ psDevInfo = OMAPLFBGetDevInfoPtr(i);
+ if (psDevInfo != NULL && psDevInfo->uiPVRDevID == uiPVRDevID)
+ {
+ break;
+ }
+ }
+ if (i == uiMaxFBDevIDPlusOne)
+ {
+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX
+ ": %s: PVR Device %u not found\n", __FUNCTION__, uiPVRDevID));
+ return PVRSRV_ERROR_INVALID_DEVICE;
+ }
+
+ /* store the system surface sync data */
+ psDevInfo->sSystemBuffer.psSyncData = psSystemBufferSyncData;
+
+ eError = OMAPLFBUnblankDisplay(psDevInfo);
+ if (eError != OMAPLFB_OK)
+ {
+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX
+ ": %s: Device %u: OMAPLFBUnblankDisplay failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, eError));
+ return PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED;
+ }
+
+ /* return handle to the devinfo */
+ *phDevice = (IMG_HANDLE)psDevInfo;
+
+ return PVRSRV_OK;
+}
+
+/*
+ * CloseDCDevice
+ * Called from services.
+ */
+static PVRSRV_ERROR CloseDCDevice(IMG_HANDLE hDevice)
+{
+#if defined(SUPPORT_DRI_DRM)
+ OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)hDevice;
+
+ OMAPLFBAtomicBoolSet(&psDevInfo->sLeaveVT, OMAPLFB_FALSE);
+ (void) OMAPLFBUnblankDisplay(psDevInfo);
+#else
+ UNREFERENCED_PARAMETER(hDevice);
+#endif
+ return PVRSRV_OK;
+}
+
+/*
+ * EnumDCFormats
+ * Called from services.
+ */
+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;
+}
+
+/*
+ * EnumDCDims
+ * Called from services.
+ */
+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;
+
+ /* No need to look at psFormat; there is only one */
+ if(psDim)
+ {
+ psDim[0] = psDevInfo->sDisplayDim;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+/*
+ * GetDCSystemBuffer
+ * Called from services.
+ */
+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;
+}
+
+
+/*
+ * GetDCInfo
+ * Called from services.
+ */
+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;
+}
+
+/*
+ * GetDCBufferAddr
+ * Called from services.
+ */
+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,
+ IMG_UINT32 *pui32TilingStride)
+{
+ OMAPLFB_DEVINFO *psDevInfo;
+ OMAPLFB_BUFFER *psSystemBuffer;
+
+ UNREFERENCED_PARAMETER(pui32TilingStride);
+
+ if(!hDevice)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if(!hBuffer)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if (!ppsSysAddr)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if (!pui32ByteSize)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
+
+ psSystemBuffer = (OMAPLFB_BUFFER *)hBuffer;
+
+ *ppsSysAddr = &psSystemBuffer->sSysAddr;
+
+ *pui32ByteSize = (IMG_UINT32)psDevInfo->sFBInfo.ulBufferSize;
+
+ if (ppvCpuVAddr)
+ {
+#if defined(CONFIG_DSSCOMP)
+ *ppvCpuVAddr = psDevInfo->sFBInfo.bIs2D ? NULL : psSystemBuffer->sCPUVAddr;
+#else
+ *ppvCpuVAddr = psSystemBuffer->sCPUVAddr;
+#endif
+ }
+
+ if (phOSMapInfo)
+ {
+ *phOSMapInfo = (IMG_HANDLE)0;
+ }
+
+ if (pbIsContiguous)
+ {
+#if defined(CONFIG_DSSCOMP)
+ *pbIsContiguous = !psDevInfo->sFBInfo.bIs2D;
+#else
+ *pbIsContiguous = IMG_TRUE;
+#endif
+ }
+
+#if defined(CONFIG_DSSCOMP)
+ if (psDevInfo->sFBInfo.bIs2D)
+ {
+ int i = (psSystemBuffer->sSysAddr.uiAddr - psDevInfo->sFBInfo.psPageList->uiAddr) >> PAGE_SHIFT;
+ *ppsSysAddr = psDevInfo->sFBInfo.psPageList + psDevInfo->sFBInfo.ulHeight * i;
+ }
+#endif
+
+ return PVRSRV_OK;
+}
+
+/*
+ * CreateDCSwapChain
+ * Called from services.
+ */
+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;
+ IMG_UINT32 i;
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32BuffersToSkip;
+
+ UNREFERENCED_PARAMETER(ui32OEMFlags);
+
+ /* Check parameters */
+ if(!hDevice
+ || !psDstSurfAttrib
+ || !psSrcSurfAttrib
+ || !ppsSyncData
+ || !phSwapChain)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
+
+ /* Do we support swap chains? */
+ if (psDevInfo->sDisplayInfo.ui32MaxSwapChains == 0)
+ {
+ return PVRSRV_ERROR_NOT_SUPPORTED;
+ }
+
+ OMAPLFBCreateSwapChainLock(psDevInfo);
+
+ /* The driver only supports a single swapchain */
+ if(psDevInfo->psSwapChain != NULL)
+ {
+ eError = PVRSRV_ERROR_FLIP_CHAIN_EXISTS;
+ goto ExitUnLock;
+ }
+
+ /* Check the buffer count */
+ if(ui32BufferCount > psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers)
+ {
+ eError = PVRSRV_ERROR_TOOMANYBUFFERS;
+ goto ExitUnLock;
+ }
+
+ if ((psDevInfo->sFBInfo.ulRoundedBufferSize * (unsigned long)ui32BufferCount) > psDevInfo->sFBInfo.ulFBSize)
+ {
+ eError = PVRSRV_ERROR_TOOMANYBUFFERS;
+ goto ExitUnLock;
+ }
+
+ /*
+ * We will allocate the swap chain buffers at the back of the frame
+ * buffer area. This preserves the front portion, which may be being
+ * used by other Linux Framebuffer based applications.
+ */
+ ui32BuffersToSkip = psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers - ui32BufferCount;
+
+ /*
+ * Verify the DST/SRC attributes,
+ * SRC/DST must match the current display mode config
+ */
+ if(psDstSurfAttrib->pixelformat != psDevInfo->sDisplayFormat.pixelformat
+ || psDstSurfAttrib->sDims.ui32ByteStride != psDevInfo->sDisplayDim.ui32ByteStride
+ || psDstSurfAttrib->sDims.ui32Width != psDevInfo->sDisplayDim.ui32Width
+ || psDstSurfAttrib->sDims.ui32Height != psDevInfo->sDisplayDim.ui32Height)
+ {
+ /* DST doesn't match the current mode */
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ goto ExitUnLock;
+ }
+
+ if(psDstSurfAttrib->pixelformat != psSrcSurfAttrib->pixelformat
+ || psDstSurfAttrib->sDims.ui32ByteStride != psSrcSurfAttrib->sDims.ui32ByteStride
+ || psDstSurfAttrib->sDims.ui32Width != psSrcSurfAttrib->sDims.ui32Width
+ || psDstSurfAttrib->sDims.ui32Height != psSrcSurfAttrib->sDims.ui32Height)
+ {
+ /* DST doesn't match the SRC */
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ goto ExitUnLock;
+ }
+
+ /* check flags if implementation requires them */
+ UNREFERENCED_PARAMETER(ui32Flags);
+
+#if defined(PVR_OMAPFB3_UPDATE_MODE)
+ if (!OMAPLFBSetUpdateMode(psDevInfo, PVR_OMAPFB3_UPDATE_MODE))
+ {
+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't set frame buffer update mode %d\n", __FUNCTION__, psDevInfo->uiFBDevID, PVR_OMAPFB3_UPDATE_MODE);
+ }
+#endif
+ /* create a swapchain structure */
+ psSwapChain = (OMAPLFB_SWAPCHAIN*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_SWAPCHAIN));
+ if(!psSwapChain)
+ {
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto ExitUnLock;
+ }
+
+ psBuffer = (OMAPLFB_BUFFER*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_BUFFER) * ui32BufferCount);
+ if(!psBuffer)
+ {
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto ErrorFreeSwapChain;
+ }
+
+ psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount;
+ psSwapChain->psBuffer = psBuffer;
+ psSwapChain->bNotVSynced = OMAPLFB_TRUE;
+ psSwapChain->uiFBDevID = psDevInfo->uiFBDevID;
+
+ /* Link the buffers */
+ for(i=0; i<ui32BufferCount-1; i++)
+ {
+ psBuffer[i].psNext = &psBuffer[i+1];
+ }
+ /* and link last to first */
+ psBuffer[i].psNext = &psBuffer[0];
+
+ /* Configure the swapchain buffers */
+ for(i=0; i<ui32BufferCount; i++)
+ {
+ IMG_UINT32 ui32SwapBuffer = i + ui32BuffersToSkip;
+ IMG_UINT32 ui32BufferOffset = ui32SwapBuffer * (IMG_UINT32)psDevInfo->sFBInfo.ulRoundedBufferSize;
+
+#if defined(CONFIG_DSSCOMP)
+ if (psDevInfo->sFBInfo.bIs2D)
+ {
+ ui32BufferOffset = 0;
+ }
+#endif /* defined(CONFIG_DSSCOMP) */
+
+ psBuffer[i].psSyncData = ppsSyncData[i];
+
+ psBuffer[i].sSysAddr.uiAddr = psDevInfo->sFBInfo.sSysAddr.uiAddr + ui32BufferOffset;
+ psBuffer[i].sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr + ui32BufferOffset;
+ psBuffer[i].ulYOffset = ui32BufferOffset / psDevInfo->sFBInfo.ulByteStride;
+ psBuffer[i].psDevInfo = psDevInfo;
+
+#if defined(CONFIG_DSSCOMP)
+ if (psDevInfo->sFBInfo.bIs2D)
+ {
+ psBuffer[i].sSysAddr.uiAddr += ui32SwapBuffer *
+ ALIGN((IMG_UINT32)psDevInfo->sFBInfo.ulWidth * psDevInfo->sFBInfo.uiBytesPerPixel, PAGE_SIZE);
+ }
+#endif /* defined(CONFIG_DSSCOMP) */
+
+ OMAPLFBInitBufferForSwap(&psBuffer[i]);
+ }
+
+ if (OMAPLFBCreateSwapQueue(psSwapChain) != OMAPLFB_OK)
+ {
+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Failed to create workqueue\n", __FUNCTION__, psDevInfo->uiFBDevID);
+ eError = PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR;
+ goto ErrorFreeBuffers;
+ }
+
+ if (OMAPLFBEnableLFBEventNotification(psDevInfo)!= OMAPLFB_OK)
+ {
+ eError = PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT;
+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't enable framebuffer event notification\n", __FUNCTION__, psDevInfo->uiFBDevID);
+ goto ErrorDestroySwapQueue;
+ }
+
+ psDevInfo->uiSwapChainID++;
+ if (psDevInfo->uiSwapChainID == 0)
+ {
+ psDevInfo->uiSwapChainID++;
+ }
+
+ psSwapChain->uiSwapChainID = psDevInfo->uiSwapChainID;
+
+ psDevInfo->psSwapChain = psSwapChain;
+
+ *pui32SwapChainID = psDevInfo->uiSwapChainID;
+
+ *phSwapChain = (IMG_HANDLE)psSwapChain;
+
+ eError = PVRSRV_OK;
+ goto ExitUnLock;
+
+ErrorDestroySwapQueue:
+ OMAPLFBDestroySwapQueue(psSwapChain);
+ErrorFreeBuffers:
+ OMAPLFBFreeKernelMem(psBuffer);
+ErrorFreeSwapChain:
+ OMAPLFBFreeKernelMem(psSwapChain);
+ExitUnLock:
+ OMAPLFBCreateSwapChainUnLock(psDevInfo);
+ return eError;
+}
+
+/*
+ * DestroyDCSwapChain
+ * Called from services.
+ */
+static PVRSRV_ERROR DestroyDCSwapChain(IMG_HANDLE hDevice,
+ IMG_HANDLE hSwapChain)
+{
+ OMAPLFB_DEVINFO *psDevInfo;
+ OMAPLFB_SWAPCHAIN *psSwapChain;
+ OMAPLFB_ERROR eError;
+
+ /* Check parameters */
+ if(!hDevice || !hSwapChain)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
+ psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain;
+
+ OMAPLFBCreateSwapChainLock(psDevInfo);
+
+ if (SwapChainHasChanged(psDevInfo, psSwapChain))
+ {
+ printk(KERN_WARNING DRIVER_PREFIX
+ ": %s: Device %u: Swap chain mismatch\n", __FUNCTION__, psDevInfo->uiFBDevID);
+
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ goto ExitUnLock;
+ }
+
+ /* The swap queue is flushed before being destroyed */
+ OMAPLFBDestroySwapQueue(psSwapChain);
+
+ eError = OMAPLFBDisableLFBEventNotification(psDevInfo);
+ if (eError != OMAPLFB_OK)
+ {
+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't disable framebuffer event notification\n", __FUNCTION__, psDevInfo->uiFBDevID);
+ }
+
+ /* Free resources */
+ OMAPLFBFreeKernelMem(psSwapChain->psBuffer);
+ OMAPLFBFreeKernelMem(psSwapChain);
+
+ psDevInfo->psSwapChain = NULL;
+
+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer);
+ (void) OMAPLFBCheckModeAndSync(psDevInfo);
+
+ eError = PVRSRV_OK;
+
+ExitUnLock:
+ OMAPLFBCreateSwapChainUnLock(psDevInfo);
+
+ return eError;
+}
+
+/*
+ * SetDCDstRect
+ * Called from services.
+ */
+static PVRSRV_ERROR SetDCDstRect(IMG_HANDLE hDevice,
+ IMG_HANDLE hSwapChain,
+ IMG_RECT *psRect)
+{
+ UNREFERENCED_PARAMETER(hDevice);
+ UNREFERENCED_PARAMETER(hSwapChain);
+ UNREFERENCED_PARAMETER(psRect);
+
+ /* Only full display swapchains on this device */
+
+ return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+/*
+ * SetDCSrcRect
+ * Called from services.
+ */
+static PVRSRV_ERROR SetDCSrcRect(IMG_HANDLE hDevice,
+ IMG_HANDLE hSwapChain,
+ IMG_RECT *psRect)
+{
+ UNREFERENCED_PARAMETER(hDevice);
+ UNREFERENCED_PARAMETER(hSwapChain);
+ UNREFERENCED_PARAMETER(psRect);
+
+ /* Only full display swapchains on this device */
+
+ return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+/*
+ * SetDCDstColourKey
+ * Called from services.
+ */
+static PVRSRV_ERROR SetDCDstColourKey(IMG_HANDLE hDevice,
+ IMG_HANDLE hSwapChain,
+ IMG_UINT32 ui32CKColour)
+{
+ UNREFERENCED_PARAMETER(hDevice);
+ UNREFERENCED_PARAMETER(hSwapChain);
+ UNREFERENCED_PARAMETER(ui32CKColour);
+
+ /* Don't support DST CK on this device */
+
+ return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+/*
+ * SetDCSrcColourKey
+ * Called from services.
+ */
+static PVRSRV_ERROR SetDCSrcColourKey(IMG_HANDLE hDevice,
+ IMG_HANDLE hSwapChain,
+ IMG_UINT32 ui32CKColour)
+{
+ UNREFERENCED_PARAMETER(hDevice);
+ UNREFERENCED_PARAMETER(hSwapChain);
+ UNREFERENCED_PARAMETER(ui32CKColour);
+
+ /* Don't support SRC CK on this device */
+
+ return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+/*
+ * GetDCBuffers
+ * Called from services.
+ */
+static PVRSRV_ERROR GetDCBuffers(IMG_HANDLE hDevice,
+ IMG_HANDLE hSwapChain,
+ IMG_UINT32 *pui32BufferCount,
+ IMG_HANDLE *phBuffer)
+{
+ OMAPLFB_DEVINFO *psDevInfo;
+ OMAPLFB_SWAPCHAIN *psSwapChain;
+ PVRSRV_ERROR eError;
+ unsigned i;
+
+ /* Check parameters */
+ if(!hDevice
+ || !hSwapChain
+ || !pui32BufferCount
+ || !phBuffer)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice;
+ psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain;
+
+ OMAPLFBCreateSwapChainLock(psDevInfo);
+
+ if (SwapChainHasChanged(psDevInfo, psSwapChain))
+ {
+ printk(KERN_WARNING DRIVER_PREFIX
+ ": %s: Device %u: Swap chain mismatch\n", __FUNCTION__, psDevInfo->uiFBDevID);
+
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ goto Exit;
+ }
+
+ /* Return the buffer count */
+ *pui32BufferCount = (IMG_UINT32)psSwapChain->ulBufferCount;
+
+ /* Return the buffers */
+ for(i=0; i<psSwapChain->ulBufferCount; i++)
+ {
+ phBuffer[i] = (IMG_HANDLE)&psSwapChain->psBuffer[i];
+ }
+
+ eError = PVRSRV_OK;
+
+Exit:
+ OMAPLFBCreateSwapChainUnLock(psDevInfo);
+
+ return eError;
+}
+
+/*
+ * SwapToDCBuffer
+ * Called from services.
+ */
+static PVRSRV_ERROR SwapToDCBuffer(IMG_HANDLE hDevice,
+ IMG_HANDLE hBuffer,
+ IMG_UINT32 ui32SwapInterval,
+ IMG_HANDLE hPrivateTag,
+ IMG_UINT32 ui32ClipRectCount,
+ IMG_RECT *psClipRect)
+{
+ UNREFERENCED_PARAMETER(hDevice);
+ UNREFERENCED_PARAMETER(hBuffer);
+ UNREFERENCED_PARAMETER(ui32SwapInterval);
+ UNREFERENCED_PARAMETER(hPrivateTag);
+ UNREFERENCED_PARAMETER(ui32ClipRectCount);
+ UNREFERENCED_PARAMETER(psClipRect);
+
+ /* * Nothing to do since Services common code does the work */
+
+ return PVRSRV_OK;
+}
+
+/*
+ * Called after the screen has unblanked, or after any other occasion
+ * when we didn't wait for vsync, but now need to. Not doing this after
+ * unblank leads to screen jitter on some screens.
+ * Returns true if the screen has been deemed to have settled.
+ */
+static OMAPLFB_BOOL WaitForVSyncSettle(OMAPLFB_DEVINFO *psDevInfo)
+{
+ unsigned i;
+ for(i = 0; i < OMAPLFB_VSYNC_SETTLE_COUNT; i++)
+ {
+ if (DontWaitForVSync(psDevInfo) || !OMAPLFBWaitForVSync(psDevInfo))
+ {
+ return OMAPLFB_FALSE;
+ }
+ }
+
+ return OMAPLFB_TRUE;
+}
+
+/*
+ * Swap handler.
+ * Called from the swap chain work queue handler.
+ * There is no need to take the swap chain creation lock in here, or use
+ * some other method of stopping the swap chain from being destroyed.
+ * This is because the swap chain creation lock is taken when queueing work,
+ * and the work queue is flushed before the swap chain is destroyed.
+ */
+void OMAPLFBSwapHandler(OMAPLFB_BUFFER *psBuffer)
+{
+ OMAPLFB_DEVINFO *psDevInfo = psBuffer->psDevInfo;
+ OMAPLFB_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain;
+ OMAPLFB_BOOL bPreviouslyNotVSynced;
+
+#if defined(SUPPORT_DRI_DRM)
+ if (!OMAPLFBAtomicBoolRead(&psDevInfo->sLeaveVT))
+#endif
+ {
+ OMAPLFBFlip(psDevInfo, psBuffer);
+ }
+
+ bPreviouslyNotVSynced = psSwapChain->bNotVSynced;
+ psSwapChain->bNotVSynced = OMAPLFB_TRUE;
+
+
+ if (!DontWaitForVSync(psDevInfo))
+ {
+ OMAPLFB_UPDATE_MODE eMode = OMAPLFBGetUpdateMode(psDevInfo);
+ int iBlankEvents = OMAPLFBAtomicIntRead(&psDevInfo->sBlankEvents);
+
+ switch(eMode)
+ {
+ case OMAPLFB_UPDATE_MODE_AUTO:
+ psSwapChain->bNotVSynced = OMAPLFB_FALSE;
+
+ if (bPreviouslyNotVSynced || psSwapChain->iBlankEvents != iBlankEvents)
+ {
+ psSwapChain->iBlankEvents = iBlankEvents;
+ psSwapChain->bNotVSynced = !WaitForVSyncSettle(psDevInfo);
+ } else if (psBuffer->ulSwapInterval != 0)
+ {
+ psSwapChain->bNotVSynced = !OMAPLFBWaitForVSync(psDevInfo);
+ }
+ break;
+#if defined(PVR_OMAPFB3_MANUAL_UPDATE_SYNC_IN_SWAP)
+ case OMAPLFB_UPDATE_MODE_MANUAL:
+ if (psBuffer->ulSwapInterval != 0)
+ {
+ (void) OMAPLFBManualSync(psDevInfo);
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+ }
+
+ psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete((IMG_HANDLE)psBuffer->hCmdComplete, IMG_TRUE);
+}
+
+/* Triggered by PVRSRVSwapToDCBuffer */
+static IMG_BOOL ProcessFlipV1(IMG_HANDLE hCmdCookie,
+ OMAPLFB_DEVINFO *psDevInfo,
+ OMAPLFB_SWAPCHAIN *psSwapChain,
+ OMAPLFB_BUFFER *psBuffer,
+ unsigned long ulSwapInterval)
+{
+ OMAPLFBCreateSwapChainLock(psDevInfo);
+
+ /* The swap chain has been destroyed */
+ if (SwapChainHasChanged(psDevInfo, psSwapChain))
+ {
+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX
+ ": %s: Device %u (PVR Device ID %u): The swap chain has been destroyed\n",
+ __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID));
+ }
+ else
+ {
+ psBuffer->hCmdComplete = (OMAPLFB_HANDLE)hCmdCookie;
+ psBuffer->ulSwapInterval = ulSwapInterval;
+#if defined(CONFIG_DSSCOMP)
+ if (is_tiler_addr(psBuffer->sSysAddr.uiAddr))
+ {
+ IMG_UINT32 w = psBuffer->psDevInfo->sDisplayDim.ui32Width;
+ IMG_UINT32 h = psBuffer->psDevInfo->sDisplayDim.ui32Height;
+ struct dsscomp_setup_dispc_data comp = {
+ .num_mgrs = 1,
+ .mgrs[0].alpha_blending = 1,
+ .num_ovls = 1,
+ .ovls[0].cfg =
+ {
+ .width = w,
+ .win.w = w,
+ .crop.w = w,
+ .height = h,
+ .win.h = h,
+ .crop.h = h,
+ .stride = psBuffer->psDevInfo->sDisplayDim.ui32ByteStride,
+ .color_mode = OMAP_DSS_COLOR_ARGB32,
+ .enabled = 1,
+ .global_alpha = 255,
+ },
+ .mode = DSSCOMP_SETUP_DISPLAY,
+ };
+ struct tiler_pa_info *pas[1] = { NULL };
+ comp.ovls[0].ba = (u32) psBuffer->sSysAddr.uiAddr;
+ dsscomp_gralloc_queue(&comp, pas, true,
+ (void *) psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete,
+ (void *) psBuffer->hCmdComplete);
+ }
+ else
+#endif /* defined(CONFIG_DSSCOMP) */
+ {
+ OMAPLFBQueueBufferForSwap(psSwapChain, psBuffer);
+ }
+ }
+
+ OMAPLFBCreateSwapChainUnLock(psDevInfo);
+
+ return IMG_TRUE;
+}
+
+#if defined(CONFIG_DSSCOMP)
+
+/* Triggered by PVRSRVSwapToDCBuffer2 */
+static IMG_BOOL ProcessFlipV2(IMG_HANDLE hCmdCookie,
+ OMAPLFB_DEVINFO *psDevInfo,
+ PDC_MEM_INFO *ppsMemInfos,
+ IMG_UINT32 ui32NumMemInfos,
+ struct dsscomp_setup_dispc_data *psDssData,
+ IMG_UINT32 ui32DssDataLength)
+{
+ struct tiler_pa_info *apsTilerPAs[5];
+ IMG_UINT32 i, k;
+
+ if(ui32DssDataLength != sizeof(*psDssData))
+ {
+ WARN(1, "invalid size of private data (%d vs %d)",
+ ui32DssDataLength, sizeof(*psDssData));
+ return IMG_FALSE;
+ }
+
+ if(psDssData->num_ovls == 0 || ui32NumMemInfos == 0)
+ {
+ WARN(1, "must have at least one layer");
+ return IMG_FALSE;
+ }
+
+ for(i = k = 0; i < ui32NumMemInfos && k < ARRAY_SIZE(apsTilerPAs); i++, k++)
+ {
+ struct tiler_pa_info *psTilerInfo;
+ IMG_CPU_VIRTADDR virtAddr;
+ IMG_CPU_PHYADDR phyAddr;
+ IMG_UINT32 ui32NumPages;
+ IMG_SIZE_T uByteSize;
+ int j;
+
+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetByteSize(ppsMemInfos[i], &uByteSize);
+ ui32NumPages = (uByteSize + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+ apsTilerPAs[k] = NULL;
+
+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuPAddr(ppsMemInfos[i], 0, &phyAddr);
+
+ /* NV12 buffers are already mapped to tiler */
+ if(psDssData->ovls[k].cfg.color_mode == OMAP_DSS_COLOR_NV12)
+ {
+ psDssData->ovls[k].ba = (u32)phyAddr.uiAddr;
+
+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuPAddr(ppsMemInfos[i], (uByteSize * 2) / 3, &phyAddr);
+ psDssData->ovls[k].uv = (u32)phyAddr.uiAddr;
+ continue;
+ }
+
+ /* Other kinds of buffer may also already be mapped to tiler */
+ if(is_tiler_addr((u32)phyAddr.uiAddr))
+ {
+ psDssData->ovls[k].ba = (u32)phyAddr.uiAddr;
+ continue;
+ }
+
+ psTilerInfo = kzalloc(sizeof(*psTilerInfo), GFP_KERNEL);
+ if(!psTilerInfo)
+ {
+ continue;
+ }
+
+ psTilerInfo->mem = kzalloc(sizeof(*psTilerInfo->mem) * ui32NumPages, GFP_KERNEL);
+ if(!psTilerInfo->mem)
+ {
+ kfree(psTilerInfo);
+ continue;
+ }
+
+ psTilerInfo->num_pg = ui32NumPages;
+ psTilerInfo->memtype = TILER_MEM_USING;
+
+ for(j = 0; j < ui32NumPages; j++)
+ {
+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuPAddr(ppsMemInfos[i], j << PAGE_SHIFT, &phyAddr);
+ psTilerInfo->mem[j] = (u32)phyAddr.uiAddr;
+ }
+
+ /* Need base address for in-page offset */
+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuVAddr(ppsMemInfos[i], &virtAddr);
+ psDssData->ovls[k].ba = (u32)virtAddr;
+ apsTilerPAs[k] = psTilerInfo;
+ }
+
+ /* Set up cloned layer addresses (but don't duplicate tiler_pas) */
+ for(i = k; i < psDssData->num_ovls && i < ARRAY_SIZE(apsTilerPAs); i++)
+ {
+ unsigned int ix = psDssData->ovls[i].ba;
+ if(ix >= ARRAY_SIZE(apsTilerPAs))
+ {
+ WARN(1, "Invalid clone layer (%u); skipping all cloned layers", ix);
+ psDssData->num_ovls = k;
+ break;
+ }
+ apsTilerPAs[i] = apsTilerPAs[ix];
+ psDssData->ovls[i].ba = psDssData->ovls[ix].ba;
+ psDssData->ovls[i].uv = psDssData->ovls[ix].uv;
+ }
+
+ dsscomp_gralloc_queue(psDssData, apsTilerPAs, false,
+ (void *)psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete,
+ (void *)hCmdCookie);
+
+ for(i = 0; i < k; i++)
+ {
+ tiler_pa_free(apsTilerPAs[i]);
+ }
+
+ return IMG_TRUE;
+}
+
+#endif /* defined(CONFIG_DSSCOMP) */
+
+/* Command processing flip handler function. Called from services. */
+static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie,
+ IMG_UINT32 ui32DataSize,
+ IMG_VOID *pvData)
+{
+ DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
+ OMAPLFB_DEVINFO *psDevInfo;
+
+ /* Check parameters */
+ if(!hCmdCookie || !pvData)
+ {
+ return IMG_FALSE;
+ }
+
+ /* Validate data packet */
+ psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)pvData;
+
+ if (psFlipCmd == IMG_NULL)
+ {
+ return IMG_FALSE;
+ }
+
+ psDevInfo = (OMAPLFB_DEVINFO*)psFlipCmd->hExtDevice;
+
+ if(psFlipCmd->hExtBuffer)
+ {
+ return ProcessFlipV1(hCmdCookie,
+ psDevInfo,
+ psFlipCmd->hExtSwapChain,
+ psFlipCmd->hExtBuffer,
+ psFlipCmd->ui32SwapInterval);
+ }
+ else
+ {
+#if defined(CONFIG_DSSCOMP)
+ DISPLAYCLASS_FLIP_COMMAND2 *psFlipCmd2;
+ psFlipCmd2 = (DISPLAYCLASS_FLIP_COMMAND2 *)pvData;
+ return ProcessFlipV2(hCmdCookie,
+ psDevInfo,
+ psFlipCmd2->ppsMemInfos,
+ psFlipCmd2->ui32NumMemInfos,
+ psFlipCmd2->pvPrivData,
+ psFlipCmd2->ui32PrivDataLength);
+#else
+ BUG();
+#endif
+ }
+}
+
+/*!
+******************************************************************************
+
+ @Function OMAPLFBInitFBDev
+
+ @Description specifies devices in the systems memory map
+
+ @Input psSysData - sys data
+
+ @Return OMAPLFB_ERROR :
+
+******************************************************************************/
+static OMAPLFB_ERROR OMAPLFBInitFBDev(OMAPLFB_DEVINFO *psDevInfo)
+{
+ struct fb_info *psLINFBInfo;
+ struct module *psLINFBOwner;
+ OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo;
+ OMAPLFB_ERROR eError = OMAPLFB_ERROR_GENERIC;
+ unsigned long FBSize;
+ unsigned long ulLCM;
+ unsigned uiFBDevID = psDevInfo->uiFBDevID;
+
+ OMAPLFB_CONSOLE_LOCK();
+
+ psLINFBInfo = registered_fb[uiFBDevID];
+ if (psLINFBInfo == NULL)
+ {
+ eError = OMAPLFB_ERROR_INVALID_DEVICE;
+ goto ErrorRelSem;
+ }
+
+ FBSize = (psLINFBInfo->screen_size) != 0 ?
+ psLINFBInfo->screen_size :
+ psLINFBInfo->fix.smem_len;
+
+ /*
+ * Try and filter out invalid FB info structures (a problem
+ * seen on some OMAP3 systems).
+ */
+ if (FBSize == 0 || psLINFBInfo->fix.line_length == 0)
+ {
+ eError = OMAPLFB_ERROR_INVALID_DEVICE;
+ goto ErrorRelSem;
+ }
+
+ psLINFBOwner = psLINFBInfo->fbops->owner;
+ if (!try_module_get(psLINFBOwner))
+ {
+ printk(KERN_INFO DRIVER_PREFIX
+ ": %s: Device %u: Couldn't get framebuffer module\n", __FUNCTION__, uiFBDevID);
+
+ goto ErrorRelSem;
+ }
+
+ if (psLINFBInfo->fbops->fb_open != NULL)
+ {
+ int res;
+
+ res = psLINFBInfo->fbops->fb_open(psLINFBInfo, 0);
+ if (res != 0)
+ {
+ printk(KERN_INFO DRIVER_PREFIX
+ " %s: Device %u: Couldn't open framebuffer(%d)\n", __FUNCTION__, uiFBDevID, res);
+
+ goto ErrorModPut;
+ }
+ }
+
+ psDevInfo->psLINFBInfo = psLINFBInfo;
+
+ ulLCM = LCM(psLINFBInfo->fix.line_length, OMAPLFB_PAGE_SIZE);
+
+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
+ ": Device %u: Framebuffer physical address: 0x%lx\n",
+ psDevInfo->uiFBDevID, psLINFBInfo->fix.smem_start));
+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
+ ": Device %u: Framebuffer virtual address: 0x%lx\n",
+ psDevInfo->uiFBDevID, (unsigned long)psLINFBInfo->screen_base));
+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
+ ": Device %u: Framebuffer size: %lu\n",
+ psDevInfo->uiFBDevID, FBSize));
+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
+ ": Device %u: Framebuffer virtual width: %u\n",
+ psDevInfo->uiFBDevID, psLINFBInfo->var.xres_virtual));
+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
+ ": Device %u: Framebuffer virtual height: %u\n",
+ psDevInfo->uiFBDevID, psLINFBInfo->var.yres_virtual));
+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
+ ": Device %u: Framebuffer width: %u\n",
+ psDevInfo->uiFBDevID, psLINFBInfo->var.xres));
+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
+ ": Device %u: Framebuffer height: %u\n",
+ psDevInfo->uiFBDevID, psLINFBInfo->var.yres));
+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
+ ": Device %u: Framebuffer stride: %u\n",
+ psDevInfo->uiFBDevID, psLINFBInfo->fix.line_length));
+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
+ ": Device %u: LCM of stride and page size: %lu\n",
+ psDevInfo->uiFBDevID, ulLCM));
+
+ /* Additional implementation specific information */
+ OMAPLFBPrintInfo(psDevInfo);
+
+#if defined(CONFIG_DSSCOMP)
+ {
+ /* for some reason we need at least 3 buffers in the swap chain */
+ int n = FBSize / RoundUpToMultiple(psLINFBInfo->fix.line_length * psLINFBInfo->var.yres, ulLCM);
+ int res;
+ int i, x, y, w;
+ ion_phys_addr_t phys;
+ size_t size;
+ struct tiler_view_t view;
+
+ struct omap_ion_tiler_alloc_data sAllocData =
+ {
+ /* TILER will align width to 128-bytes */
+ /* however, SGX must have full page width */
+ .w = ALIGN(psLINFBInfo->var.xres, PAGE_SIZE / (psLINFBInfo->var.bits_per_pixel / 8)),
+ .h = psLINFBInfo->var.yres,
+ .fmt = psLINFBInfo->var.bits_per_pixel == 16 ? TILER_PIXEL_FMT_16BIT : TILER_PIXEL_FMT_32BIT,
+ .flags = 0,
+ };
+
+ printk(KERN_DEBUG DRIVER_PREFIX
+ " %s: Device %u: Requesting %d TILER 2D framebuffers\n",
+ __FUNCTION__, uiFBDevID, n);
+
+ /* INTEGRATION_POINT: limit to MAX 3 FBs to save TILER container space */
+ if (n != 3)
+ n = 3;
+
+ sAllocData.w *= n;
+
+ psPVRFBInfo->uiBytesPerPixel = psLINFBInfo->var.bits_per_pixel >> 3;
+ psPVRFBInfo->bIs2D = OMAPLFB_TRUE;
+
+ res = omap_ion_tiler_alloc(gpsIONClient, &sAllocData);
+ psPVRFBInfo->psIONHandle = sAllocData.handle;
+ if (res < 0)
+ {
+ printk(KERN_ERR DRIVER_PREFIX
+ " %s: Device %u: Could not allocate 2D framebuffer(%d)\n",
+ __FUNCTION__, uiFBDevID, res);
+ goto ErrorModPut;
+ }
+
+ psLINFBInfo->fix.smem_start = ion_phys(gpsIONClient, sAllocData.handle, &phys, &size);
+
+ psPVRFBInfo->sSysAddr.uiAddr = phys;
+ psPVRFBInfo->sCPUVAddr = 0;
+ psPVRFBInfo->ulWidth = psLINFBInfo->var.xres;
+ psPVRFBInfo->ulHeight = psLINFBInfo->var.yres;
+
+ psPVRFBInfo->ulByteStride = PAGE_ALIGN(psPVRFBInfo->ulWidth * psPVRFBInfo->uiBytesPerPixel);
+ w = psPVRFBInfo->ulByteStride >> PAGE_SHIFT;
+
+ /* this is an "effective" FB size to get correct number of buffers */
+ psPVRFBInfo->ulFBSize = sAllocData.h * n * psPVRFBInfo->ulByteStride;
+ psPVRFBInfo->psPageList = kzalloc(w * n * psPVRFBInfo->ulHeight * sizeof(*psPVRFBInfo->psPageList), GFP_KERNEL);
+ if (!psPVRFBInfo->psPageList)
+ {
+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Could not allocate page list\n", __FUNCTION__, psDevInfo->uiFBDevID);
+ ion_free(gpsIONClient, sAllocData.handle);
+ goto ErrorModPut;
+ }
+
+ tilview_create(&view, phys, psDevInfo->sFBInfo.ulWidth, psDevInfo->sFBInfo.ulHeight);
+ for(i = 0; i < n; i++)
+ {
+ for(y = 0; y < psDevInfo->sFBInfo.ulHeight; y++)
+ {
+ for(x = 0; x < w; x++)
+ {
+ psPVRFBInfo->psPageList[i * psDevInfo->sFBInfo.ulHeight * w + y * w + x].uiAddr =
+ phys + view.v_inc * y + ((x + i * w) << PAGE_SHIFT);
+ }
+ }
+ }
+ }
+#else /* defined(CONFIG_DSSCOMP) */
+ /* System Surface */
+ psPVRFBInfo->sSysAddr.uiAddr = psLINFBInfo->fix.smem_start;
+ psPVRFBInfo->sCPUVAddr = psLINFBInfo->screen_base;
+
+ psPVRFBInfo->ulWidth = psLINFBInfo->var.xres;
+ psPVRFBInfo->ulHeight = psLINFBInfo->var.yres;
+ psPVRFBInfo->ulByteStride = psLINFBInfo->fix.line_length;
+ psPVRFBInfo->ulFBSize = FBSize;
+#endif /* defined(CONFIG_DSSCOMP) */
+
+ psPVRFBInfo->ulBufferSize = psPVRFBInfo->ulHeight * psPVRFBInfo->ulByteStride;
+
+ /* Round the buffer size up to a multiple of the number of pages
+ * and the byte stride.
+ * This is used internally, to ensure buffers start on page
+ * boundaries, for the benefit of PVR Services.
+ */
+ psPVRFBInfo->ulRoundedBufferSize = RoundUpToMultiple(psPVRFBInfo->ulBufferSize, ulLCM);
+
+ 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(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID);
+ }
+ }
+ 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))
+ {
+ psPVRFBInfo->ePixelFormat = PVRSRV_PIXEL_FORMAT_ARGB8888;
+ }
+ else
+ {
+ printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID);
+ }
+ }
+ else
+ {
+ printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID);
+ }
+
+ psDevInfo->sFBInfo.ulPhysicalWidthmm =
+ ((int)psLINFBInfo->var.width > 0) ? psLINFBInfo->var.width : 90;
+
+ psDevInfo->sFBInfo.ulPhysicalHeightmm =
+ ((int)psLINFBInfo->var.height > 0) ? psLINFBInfo->var.height : 54;
+
+ /* System Surface */
+ psDevInfo->sFBInfo.sSysAddr.uiAddr = psPVRFBInfo->sSysAddr.uiAddr;
+ psDevInfo->sFBInfo.sCPUVAddr = psPVRFBInfo->sCPUVAddr;
+
+ eError = OMAPLFB_OK;
+ goto ErrorRelSem;
+
+ErrorModPut:
+ module_put(psLINFBOwner);
+ErrorRelSem:
+ OMAPLFB_CONSOLE_UNLOCK();
+
+ return eError;
+}
+
+static void OMAPLFBDeInitFBDev(OMAPLFB_DEVINFO *psDevInfo)
+{
+ struct fb_info *psLINFBInfo = psDevInfo->psLINFBInfo;
+ struct module *psLINFBOwner;
+
+ OMAPLFB_CONSOLE_LOCK();
+
+#if defined(CONFIG_DSSCOMP)
+ {
+ OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo;
+ kfree(psPVRFBInfo->psPageList);
+ if (psPVRFBInfo->psIONHandle)
+ {
+ ion_free(gpsIONClient, psPVRFBInfo->psIONHandle);
+ }
+ }
+#endif /* defined(CONFIG_DSSCOMP) */
+
+ psLINFBOwner = psLINFBInfo->fbops->owner;
+
+ if (psLINFBInfo->fbops->fb_release != NULL)
+ {
+ (void) psLINFBInfo->fbops->fb_release(psLINFBInfo, 0);
+ }
+
+ module_put(psLINFBOwner);
+
+ OMAPLFB_CONSOLE_UNLOCK();
+}
+
+static OMAPLFB_DEVINFO *OMAPLFBInitDev(unsigned uiFBDevID)
+{
+ PFN_CMD_PROC pfnCmdProcList[OMAPLFB_COMMAND_COUNT];
+ IMG_UINT32 aui32SyncCountList[OMAPLFB_COMMAND_COUNT][2];
+ OMAPLFB_DEVINFO *psDevInfo = NULL;
+
+ /* Allocate device info. structure */
+ psDevInfo = (OMAPLFB_DEVINFO *)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_DEVINFO));
+
+ if(psDevInfo == NULL)
+ {
+ printk(KERN_ERR DRIVER_PREFIX
+ ": %s: Device %u: Couldn't allocate device information structure\n", __FUNCTION__, uiFBDevID);
+
+ goto ErrorExit;
+ }
+
+ /* Any fields not set will be zero */
+ memset(psDevInfo, 0, sizeof(OMAPLFB_DEVINFO));
+
+ psDevInfo->uiFBDevID = uiFBDevID;
+
+ /* Get the kernel services function table */
+ if(!(*gpfnGetPVRJTable)(&psDevInfo->sPVRJTable))
+ {
+ goto ErrorFreeDevInfo;
+ }
+
+ /* Save private fbdev information structure in the dev. info. */
+ if(OMAPLFBInitFBDev(psDevInfo) != OMAPLFB_OK)
+ {
+ /*
+ * Leave it to OMAPLFBInitFBDev to print an error message, if
+ * required. The function may have failed because
+ * there is no Linux framebuffer device corresponding
+ * to the device ID.
+ */
+ goto ErrorFreeDevInfo;
+ }
+
+ psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = (IMG_UINT32)(psDevInfo->sFBInfo.ulFBSize / psDevInfo->sFBInfo.ulRoundedBufferSize);
+ if (psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers != 0)
+ {
+ psDevInfo->sDisplayInfo.ui32MaxSwapChains = 1;
+ psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 1;
+ }
+
+ psDevInfo->sDisplayInfo.ui32PhysicalWidthmm = psDevInfo->sFBInfo.ulPhysicalWidthmm;
+ psDevInfo->sDisplayInfo.ui32PhysicalHeightmm = psDevInfo->sFBInfo.ulPhysicalHeightmm;
+
+ 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
+ ": Device %u: Maximum number of swap chain buffers: %u\n",
+ psDevInfo->uiFBDevID, psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers));
+
+ /* Setup system buffer */
+ psDevInfo->sSystemBuffer.sSysAddr = psDevInfo->sFBInfo.sSysAddr;
+ psDevInfo->sSystemBuffer.sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr;
+ psDevInfo->sSystemBuffer.psDevInfo = psDevInfo;
+
+ OMAPLFBInitBufferForSwap(&psDevInfo->sSystemBuffer);
+
+ /*
+ Setup the DC Jtable so SRVKM can call into this driver
+ */
+ 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.pfnSetDCState = SetDCState;
+
+ /* Register device with services and retrieve device index */
+ if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice(
+ &psDevInfo->sDCJTable,
+ &psDevInfo->uiPVRDevID) != PVRSRV_OK)
+ {
+ printk(KERN_ERR DRIVER_PREFIX
+ ": %s: Device %u: PVR Services device registration failed\n", __FUNCTION__, uiFBDevID);
+
+ goto ErrorDeInitFBDev;
+ }
+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
+ ": Device %u: PVR Device ID: %u\n",
+ psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID));
+
+ /* Setup private command processing function table ... */
+ pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip;
+
+ /* ... and associated sync count(s) */
+ aui32SyncCountList[DC_FLIP_COMMAND][0] = 0; /* writes */
+ aui32SyncCountList[DC_FLIP_COMMAND][1] = 10; /* reads */
+
+ /*
+ Register private command processing functions with
+ the Command Queue Manager and setup the general
+ command complete function in the devinfo.
+ */
+ if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList(psDevInfo->uiPVRDevID,
+ &pfnCmdProcList[0],
+ aui32SyncCountList,
+ OMAPLFB_COMMAND_COUNT) != PVRSRV_OK)
+ {
+ printk(KERN_ERR DRIVER_PREFIX
+ ": %s: Device %u: Couldn't register command processing functions with PVR Services\n", __FUNCTION__, uiFBDevID);
+ goto ErrorUnregisterDevice;
+ }
+
+ OMAPLFBCreateSwapChainLockInit(psDevInfo);
+
+ OMAPLFBAtomicBoolInit(&psDevInfo->sBlanked, OMAPLFB_FALSE);
+ OMAPLFBAtomicIntInit(&psDevInfo->sBlankEvents, 0);
+ OMAPLFBAtomicBoolInit(&psDevInfo->sFlushCommands, OMAPLFB_FALSE);
+#if defined(CONFIG_HAS_EARLYSUSPEND)
+ OMAPLFBAtomicBoolInit(&psDevInfo->sEarlySuspendFlag, OMAPLFB_FALSE);
+#endif
+#if defined(SUPPORT_DRI_DRM)
+ OMAPLFBAtomicBoolInit(&psDevInfo->sLeaveVT, OMAPLFB_FALSE);
+#endif
+ return psDevInfo;
+
+ErrorUnregisterDevice:
+ (void)psDevInfo->sPVRJTable.pfnPVRSRVRemoveDCDevice(psDevInfo->uiPVRDevID);
+ErrorDeInitFBDev:
+ OMAPLFBDeInitFBDev(psDevInfo);
+ErrorFreeDevInfo:
+ OMAPLFBFreeKernelMem(psDevInfo);
+ErrorExit:
+ return NULL;
+}
+
+OMAPLFB_ERROR OMAPLFBInit(void)
+{
+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne();
+ unsigned i;
+ unsigned uiDevicesFound = 0;
+
+ if(OMAPLFBGetLibFuncAddr ("PVRGetDisplayClassJTable", &gpfnGetPVRJTable) != OMAPLFB_OK)
+ {
+ return OMAPLFB_ERROR_INIT_FAILURE;
+ }
+
+ /*
+ * We search for frame buffer devices backwards, as the last device
+ * registered with PVR Services will be the first device enumerated
+ * by PVR Services.
+ */
+ for(i = uiMaxFBDevIDPlusOne; i-- != 0;)
+ {
+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBInitDev(i);
+
+ if (psDevInfo != NULL)
+ {
+ /* Set the top-level anchor */
+ OMAPLFBSetDevInfoPtr(psDevInfo->uiFBDevID, psDevInfo);
+ uiDevicesFound++;
+ }
+ }
+
+ return (uiDevicesFound != 0) ? OMAPLFB_OK : OMAPLFB_ERROR_INIT_FAILURE;
+}
+
+/*
+ * OMAPLFBDeInitDev
+ * DeInitialises one device
+ */
+static OMAPLFB_BOOL OMAPLFBDeInitDev(OMAPLFB_DEVINFO *psDevInfo)
+{
+ PVRSRV_DC_DISP2SRV_KMJTABLE *psPVRJTable = &psDevInfo->sPVRJTable;
+
+ OMAPLFBCreateSwapChainLockDeInit(psDevInfo);
+
+ OMAPLFBAtomicBoolDeInit(&psDevInfo->sBlanked);
+ OMAPLFBAtomicIntDeInit(&psDevInfo->sBlankEvents);
+ OMAPLFBAtomicBoolDeInit(&psDevInfo->sFlushCommands);
+#if defined(CONFIG_HAS_EARLYSUSPEND)
+ OMAPLFBAtomicBoolDeInit(&psDevInfo->sEarlySuspendFlag);
+#endif
+#if defined(SUPPORT_DRI_DRM)
+ OMAPLFBAtomicBoolDeInit(&psDevInfo->sLeaveVT);
+#endif
+ psPVRJTable = &psDevInfo->sPVRJTable;
+
+ if (psPVRJTable->pfnPVRSRVRemoveCmdProcList (psDevInfo->uiPVRDevID, OMAPLFB_COMMAND_COUNT) != PVRSRV_OK)
+ {
+ printk(KERN_ERR DRIVER_PREFIX
+ ": %s: Device %u: PVR Device %u: Couldn't unregister command processing functions\n", __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID);
+ return OMAPLFB_FALSE;
+ }
+
+ /*
+ * Remove display class device from kernel services device
+ * register.
+ */
+ if (psPVRJTable->pfnPVRSRVRemoveDCDevice(psDevInfo->uiPVRDevID) != PVRSRV_OK)
+ {
+ printk(KERN_ERR DRIVER_PREFIX
+ ": %s: Device %u: PVR Device %u: Couldn't remove device from PVR Services\n", __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID);
+ return OMAPLFB_FALSE;
+ }
+
+ OMAPLFBDeInitFBDev(psDevInfo);
+
+ OMAPLFBSetDevInfoPtr(psDevInfo->uiFBDevID, NULL);
+
+ /* De-allocate data structure */
+ OMAPLFBFreeKernelMem(psDevInfo);
+
+ return OMAPLFB_TRUE;
+}
+
+/*
+ * OMAPLFBDeInit
+ * Deinitialises the display class device component of the FBDev
+ */
+OMAPLFB_ERROR OMAPLFBDeInit(void)
+{
+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne();
+ unsigned i;
+ OMAPLFB_BOOL bError = OMAPLFB_FALSE;
+
+ for(i = 0; i < uiMaxFBDevIDPlusOne; i++)
+ {
+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i);
+
+ if (psDevInfo != NULL)
+ {
+ bError |= !OMAPLFBDeInitDev(psDevInfo);
+ }
+ }
+
+ return (bError) ? OMAPLFB_ERROR_INIT_FAILURE : OMAPLFB_OK;
+}
+
+/******************************************************************************
+ End of file (omaplfb_displayclass.c)
+******************************************************************************/
+
diff --git a/pvr-source/services4/3rdparty/dc_omapfb3_linux/omaplfb_linux.c b/pvr-source/services4/3rdparty/dc_omapfb3_linux/omaplfb_linux.c
new file mode 100644
index 0000000..82c7fce
--- /dev/null
+++ b/pvr-source/services4/3rdparty/dc_omapfb3_linux/omaplfb_linux.c
@@ -0,0 +1,1165 @@
+/*************************************************************************/ /*!
+@Title OMAP linux display driver components
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/**************************************************************************
+ The 3rd party driver is a specification of an API to integrate the IMG POWERVR
+ Services driver with 3rd Party display hardware. It is NOT a specification for
+ a display controller driver, rather a specification to extend the API for a
+ pre-existing driver for the display hardware.
+
+ The 3rd party driver interface provides IMG POWERVR client drivers (e.g. PVR2D)
+ with an API abstraction of the system's underlying display hardware, allowing
+ the client drivers to indirectly control the display hardware and access its
+ associated memory.
+
+ Functions of the API include
+ - query primary surface attributes (width, height, stride, pixel format, CPU
+ physical and virtual address)
+ - swap/flip chain creation and subsequent query of surface attributes
+ - asynchronous display surface flipping, taking account of asynchronous read
+ (flip) and write (render) operations to the display surface
+
+ Note: having queried surface attributes the client drivers are able to map the
+ display memory to any IMG POWERVR Services device by calling
+ PVRSRVMapDeviceClassMemory with the display surface handle.
+
+ This code is intended to be an example of how a pre-existing display driver may
+ be extended to support the 3rd Party Display interface to POWERVR Services
+ - IMG is not providing a display driver implementation.
+ **************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <asm/atomic.h>
+
+#if defined(SUPPORT_DRI_DRM)
+#include <drm/drmP.h>
+#else
+#include <linux/module.h>
+#endif
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/hardirq.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <linux/omapfb.h>
+#include <linux/mutex.h>
+
+#if defined(PVR_OMAPLFB_DRM_FB)
+#include <plat/display.h>
+#include <linux/omap_gpu.h>
+#else /* defined(PVR_OMAPLFB_DRM_FB) */
+/* OmapZoom.org OMAP3 2.6.29 kernel tree - Needs mach/vrfb.h
+ * OmapZoom.org OMAP3 2.6.32 kernel tree - No additional header required
+ * OmapZoom.org OMAP4 2.6.33 kernel tree - No additional header required
+ * OmapZoom.org OMAP4 2.6.34 kernel tree - Needs plat/vrfb.h
+ * Sholes 2.6.32 kernel tree - Needs plat/vrfb.h
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
+#define PVR_OMAPFB3_NEEDS_PLAT_VRFB_H
+#endif
+
+#if defined(PVR_OMAPFB3_NEEDS_PLAT_VRFB_H)
+#include <plat/vrfb.h>
+#else
+#if defined(PVR_OMAPFB3_NEEDS_MACH_VRFB_H)
+#include <mach/vrfb.h>
+#endif
+#endif
+
+#if defined(DEBUG)
+#define PVR_DEBUG DEBUG
+#undef DEBUG
+#endif
+#include <omapfb/omapfb.h>
+#if defined(DEBUG)
+#undef DEBUG
+#endif
+#if defined(PVR_DEBUG)
+#define DEBUG PVR_DEBUG
+#undef PVR_DEBUG
+#endif
+#endif /* defined(PVR_OMAPLFB_DRM_FB) */
+
+#if defined(CONFIG_DSSCOMP)
+#include <mach/tiler.h>
+#include <video/dsscomp.h>
+#include <plat/dsscomp.h>
+#endif /* defined(CONFIG_DSSCOMP) */
+
+#include "img_defs.h"
+#include "servicesext.h"
+#include "kerneldisplay.h"
+#include "omaplfb.h"
+#include "pvrmodule.h"
+#if defined(SUPPORT_DRI_DRM)
+#include "pvr_drm.h"
+#include "3rdparty_dc_drm_shared.h"
+#endif
+
+#if !defined(PVR_LINUX_USING_WORKQUEUES)
+#error "PVR_LINUX_USING_WORKQUEUES must be defined"
+#endif
+
+MODULE_SUPPORTED_DEVICE(DEVNAME);
+
+#if !defined(PVR_OMAPLFB_DRM_FB)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
+#define OMAP_DSS_DRIVER(drv, dev) struct omap_dss_driver *drv = (dev) != NULL ? (dev)->driver : NULL
+#define OMAP_DSS_MANAGER(man, dev) struct omap_overlay_manager *man = (dev) != NULL ? (dev)->manager : NULL
+#define WAIT_FOR_VSYNC(man) ((man)->wait_for_vsync)
+#else
+#define OMAP_DSS_DRIVER(drv, dev) struct omap_dss_device *drv = (dev)
+#define OMAP_DSS_MANAGER(man, dev) struct omap_dss_device *man = (dev)
+#define WAIT_FOR_VSYNC(man) ((man)->wait_vsync)
+#endif
+#endif /* !defined(PVR_OMAPLFB_DRM_FB) */
+
+void *OMAPLFBAllocKernelMem(unsigned long ulSize)
+{
+ return kmalloc(ulSize, GFP_KERNEL);
+}
+
+void OMAPLFBFreeKernelMem(void *pvMem)
+{
+ kfree(pvMem);
+}
+
+void OMAPLFBCreateSwapChainLockInit(OMAPLFB_DEVINFO *psDevInfo)
+{
+ mutex_init(&psDevInfo->sCreateSwapChainMutex);
+}
+
+void OMAPLFBCreateSwapChainLockDeInit(OMAPLFB_DEVINFO *psDevInfo)
+{
+ mutex_destroy(&psDevInfo->sCreateSwapChainMutex);
+}
+
+void OMAPLFBCreateSwapChainLock(OMAPLFB_DEVINFO *psDevInfo)
+{
+ mutex_lock(&psDevInfo->sCreateSwapChainMutex);
+}
+
+void OMAPLFBCreateSwapChainUnLock(OMAPLFB_DEVINFO *psDevInfo)
+{
+ mutex_unlock(&psDevInfo->sCreateSwapChainMutex);
+}
+
+void OMAPLFBAtomicBoolInit(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal)
+{
+ atomic_set(psAtomic, (int)bVal);
+}
+
+void OMAPLFBAtomicBoolDeInit(OMAPLFB_ATOMIC_BOOL *psAtomic)
+{
+}
+
+void OMAPLFBAtomicBoolSet(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal)
+{
+ atomic_set(psAtomic, (int)bVal);
+}
+
+OMAPLFB_BOOL OMAPLFBAtomicBoolRead(OMAPLFB_ATOMIC_BOOL *psAtomic)
+{
+ return (OMAPLFB_BOOL)atomic_read(psAtomic);
+}
+
+void OMAPLFBAtomicIntInit(OMAPLFB_ATOMIC_INT *psAtomic, int iVal)
+{
+ atomic_set(psAtomic, iVal);
+}
+
+void OMAPLFBAtomicIntDeInit(OMAPLFB_ATOMIC_INT *psAtomic)
+{
+}
+
+void OMAPLFBAtomicIntSet(OMAPLFB_ATOMIC_INT *psAtomic, int iVal)
+{
+ atomic_set(psAtomic, iVal);
+}
+
+int OMAPLFBAtomicIntRead(OMAPLFB_ATOMIC_INT *psAtomic)
+{
+ return atomic_read(psAtomic);
+}
+
+void OMAPLFBAtomicIntInc(OMAPLFB_ATOMIC_INT *psAtomic)
+{
+ atomic_inc(psAtomic);
+}
+
+OMAPLFB_ERROR OMAPLFBGetLibFuncAddr (char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable)
+{
+ if(strcmp("PVRGetDisplayClassJTable", szFunctionName) != 0)
+ {
+ return (OMAPLFB_ERROR_INVALID_PARAMS);
+ }
+
+ /* Nothing to do - should be exported from pvrsrv.ko */
+ *ppfnFuncTable = PVRGetDisplayClassJTable;
+
+ return (OMAPLFB_OK);
+}
+
+/* Inset a swap buffer into the swap chain work queue */
+void OMAPLFBQueueBufferForSwap(OMAPLFB_SWAPCHAIN *psSwapChain, OMAPLFB_BUFFER *psBuffer)
+{
+ int res = queue_work(psSwapChain->psWorkQueue, &psBuffer->sWork);
+
+ if (res == 0)
+ {
+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Buffer already on work queue\n", __FUNCTION__, psSwapChain->uiFBDevID);
+ }
+}
+
+/* Process an item on a swap chain work queue */
+static void WorkQueueHandler(struct work_struct *psWork)
+{
+ OMAPLFB_BUFFER *psBuffer = container_of(psWork, OMAPLFB_BUFFER, sWork);
+
+ OMAPLFBSwapHandler(psBuffer);
+}
+
+/* Create a swap chain work queue */
+OMAPLFB_ERROR OMAPLFBCreateSwapQueue(OMAPLFB_SWAPCHAIN *psSwapChain)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,37))
+#define WQ_FREEZABLE WQ_FREEZEABLE
+#endif
+ /*
+ * Calling alloc_ordered_workqueue with the WQ_FREEZABLE and
+ * WQ_MEM_RECLAIM flags set, (currently) has the same effect as
+ * calling create_freezable_workqueue. None of the other WQ
+ * flags are valid. Setting WQ_MEM_RECLAIM should allow the
+ * workqueue to continue to service the swap chain in low memory
+ * conditions, preventing the driver from holding on to
+ * resources longer than it needs to.
+ */
+ psSwapChain->psWorkQueue = alloc_ordered_workqueue(DEVNAME, WQ_FREEZABLE | WQ_MEM_RECLAIM);
+#else
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36))
+ psSwapChain->psWorkQueue = create_freezable_workqueue(DEVNAME);
+#else
+ /*
+ * Create a single-threaded, freezable, rt-prio workqueue.
+ * Such workqueues are frozen with user threads when a system
+ * suspends, before driver suspend entry points are called.
+ * This ensures this driver will not call into the Linux
+ * framebuffer driver after the latter is suspended.
+ */
+ psSwapChain->psWorkQueue = __create_workqueue(DEVNAME, 1, 1, 1);
+#endif
+#endif
+ if (psSwapChain->psWorkQueue == NULL)
+ {
+ printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: Couldn't create workqueue\n", __FUNCTION__, psSwapChain->uiFBDevID);
+
+ return (OMAPLFB_ERROR_INIT_FAILURE);
+ }
+
+ return (OMAPLFB_OK);
+}
+
+/* Prepare buffer for insertion into a swap chain work queue */
+void OMAPLFBInitBufferForSwap(OMAPLFB_BUFFER *psBuffer)
+{
+ INIT_WORK(&psBuffer->sWork, WorkQueueHandler);
+}
+
+/* Destroy a swap chain work queue */
+void OMAPLFBDestroySwapQueue(OMAPLFB_SWAPCHAIN *psSwapChain)
+{
+ destroy_workqueue(psSwapChain->psWorkQueue);
+}
+
+/* Flip display to given buffer */
+void OMAPLFBFlip(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_BUFFER *psBuffer)
+{
+ struct fb_var_screeninfo sFBVar;
+ int res;
+ unsigned long ulYResVirtual;
+
+ OMAPLFB_CONSOLE_LOCK();
+
+ sFBVar = psDevInfo->psLINFBInfo->var;
+
+ sFBVar.xoffset = 0;
+ sFBVar.yoffset = psBuffer->ulYOffset;
+
+ ulYResVirtual = psBuffer->ulYOffset + sFBVar.yres;
+
+#if defined(CONFIG_DSSCOMP)
+ {
+ /*
+ * If using DSSCOMP, we need to use dsscomp queuing for normal
+ * framebuffer updates, so that previously used overlays get
+ * automatically disabled, and manager gets dirtied. We can
+ * do that because DSSCOMP takes ownership of all pipelines on
+ * a manager.
+ */
+ struct fb_fix_screeninfo sFBFix = psDevInfo->psLINFBInfo->fix;
+ struct dsscomp_setup_dispc_data d =
+ {
+ .num_ovls = 1,
+ .num_mgrs = 1,
+ .mgrs[0].alpha_blending = 1,
+ .ovls[0] =
+ {
+ .cfg =
+ {
+ .win.w = sFBVar.xres,
+ .win.h = sFBVar.yres,
+ .crop.x = sFBVar.xoffset,
+ .crop.y = sFBVar.yoffset,
+ .crop.w = sFBVar.xres,
+ .crop.h = sFBVar.yres,
+ .width = sFBVar.xres_virtual,
+ .height = sFBVar.yres_virtual,
+ .stride = sFBFix.line_length,
+ .enabled = 1,
+ .global_alpha = 255,
+ },
+ },
+ };
+
+ /* do not map buffer into TILER1D as it is contiguous */
+ struct tiler_pa_info *pas[] = { NULL };
+
+ d.ovls[0].ba = sFBFix.smem_start;
+ omapfb_mode_to_dss_mode(&sFBVar, &d.ovls[0].cfg.color_mode);
+
+ res = dsscomp_gralloc_queue(&d, pas, true, NULL, NULL);
+ }
+#else /* defined(CONFIG_DSSCOMP) */
+ /*
+ * PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY should be defined to work
+ * around flipping problems seen with the Taal LCDs on Blaze.
+ * The work around is safe to use with other types of screen on Blaze
+ * (e.g. HDMI) and on other platforms (e.g. Panda board).
+ */
+#if !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY)
+ /*
+ * Attempt to change the virtual screen resolution if it is too
+ * small. Note that fb_set_var also pans the display.
+ */
+ if (sFBVar.xres_virtual != sFBVar.xres || sFBVar.yres_virtual < ulYResVirtual)
+#endif /* !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) */
+ {
+ sFBVar.xres_virtual = sFBVar.xres;
+ sFBVar.yres_virtual = ulYResVirtual;
+
+ sFBVar.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
+
+ res = fb_set_var(psDevInfo->psLINFBInfo, &sFBVar);
+ if (res != 0)
+ {
+ printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: fb_set_var failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res);
+ }
+ }
+#if !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY)
+ else
+ {
+ res = fb_pan_display(psDevInfo->psLINFBInfo, &sFBVar);
+ if (res != 0)
+ {
+ printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: fb_pan_display failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res);
+ }
+ }
+#endif /* !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) */
+#endif /* defined(CONFIG_DSSCOMP) */
+
+ OMAPLFB_CONSOLE_UNLOCK();
+}
+
+#if !defined(PVR_OMAPLFB_DRM_FB) || defined(DEBUG)
+static OMAPLFB_BOOL OMAPLFBValidateDSSUpdateMode(enum omap_dss_update_mode eMode)
+{
+ switch (eMode)
+ {
+ case OMAP_DSS_UPDATE_AUTO:
+ case OMAP_DSS_UPDATE_MANUAL:
+ case OMAP_DSS_UPDATE_DISABLED:
+ return OMAPLFB_TRUE;
+ default:
+ break;
+ }
+
+ return OMAPLFB_FALSE;
+}
+
+static OMAPLFB_UPDATE_MODE OMAPLFBFromDSSUpdateMode(enum omap_dss_update_mode eMode)
+{
+ switch (eMode)
+ {
+ case OMAP_DSS_UPDATE_AUTO:
+ return OMAPLFB_UPDATE_MODE_AUTO;
+ case OMAP_DSS_UPDATE_MANUAL:
+ return OMAPLFB_UPDATE_MODE_MANUAL;
+ case OMAP_DSS_UPDATE_DISABLED:
+ return OMAPLFB_UPDATE_MODE_DISABLED;
+ default:
+ break;
+ }
+
+ return OMAPLFB_UPDATE_MODE_UNDEFINED;
+}
+#endif
+
+static OMAPLFB_BOOL OMAPLFBValidateUpdateMode(OMAPLFB_UPDATE_MODE eMode)
+{
+ switch(eMode)
+ {
+ case OMAPLFB_UPDATE_MODE_AUTO:
+ case OMAPLFB_UPDATE_MODE_MANUAL:
+ case OMAPLFB_UPDATE_MODE_DISABLED:
+ return OMAPLFB_TRUE;
+ default:
+ break;
+ }
+
+ return OMAPLFB_FALSE;
+}
+
+static enum omap_dss_update_mode OMAPLFBToDSSUpdateMode(OMAPLFB_UPDATE_MODE eMode)
+{
+ switch(eMode)
+ {
+ case OMAPLFB_UPDATE_MODE_AUTO:
+ return OMAP_DSS_UPDATE_AUTO;
+ case OMAPLFB_UPDATE_MODE_MANUAL:
+ return OMAP_DSS_UPDATE_MANUAL;
+ case OMAPLFB_UPDATE_MODE_DISABLED:
+ return OMAP_DSS_UPDATE_DISABLED;
+ default:
+ break;
+ }
+
+ return -1;
+}
+
+#if defined(DEBUG)
+static const char *OMAPLFBUpdateModeToString(OMAPLFB_UPDATE_MODE eMode)
+{
+ switch(eMode)
+ {
+ case OMAPLFB_UPDATE_MODE_AUTO:
+ return "Auto Update Mode";
+ case OMAPLFB_UPDATE_MODE_MANUAL:
+ return "Manual Update Mode";
+ case OMAPLFB_UPDATE_MODE_DISABLED:
+ return "Update Mode Disabled";
+ case OMAPLFB_UPDATE_MODE_UNDEFINED:
+ return "Update Mode Undefined";
+ default:
+ break;
+ }
+
+ return "Unknown Update Mode";
+}
+
+static const char *OMAPLFBDSSUpdateModeToString(enum omap_dss_update_mode eMode)
+{
+ if (!OMAPLFBValidateDSSUpdateMode(eMode))
+ {
+ return "Unknown Update Mode";
+ }
+
+ return OMAPLFBUpdateModeToString(OMAPLFBFromDSSUpdateMode(eMode));
+}
+
+void OMAPLFBPrintInfo(OMAPLFB_DEVINFO *psDevInfo)
+{
+#if defined(PVR_OMAPLFB_DRM_FB)
+ struct drm_connector *psConnector;
+ unsigned uConnectors;
+ unsigned uConnector;
+
+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: DRM framebuffer\n", psDevInfo->uiFBDevID));
+
+ for (psConnector = NULL, uConnectors = 0;
+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;)
+ {
+ uConnectors++;
+ }
+
+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: Number of screens (DRM connectors): %u\n", psDevInfo->uiFBDevID, uConnectors));
+
+ if (uConnectors == 0)
+ {
+ return;
+ }
+
+ for (psConnector = NULL, uConnector = 0;
+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL; uConnector++)
+ {
+ enum omap_dss_update_mode eMode = omap_connector_get_update_mode(psConnector);
+
+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: Screen %u: %s (%d)\n", psDevInfo->uiFBDevID, uConnector, OMAPLFBDSSUpdateModeToString(eMode), (int)eMode));
+
+ }
+#else /* defined(PVR_OMAPLFB_DRM_FB) */
+ OMAPLFB_UPDATE_MODE eMode = OMAPLFBGetUpdateMode(psDevInfo);
+
+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: non-DRM framebuffer\n", psDevInfo->uiFBDevID));
+
+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: %s\n", psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode)));
+#endif /* defined(PVR_OMAPLFB_DRM_FB) */
+}
+#endif /* defined(DEBUG) */
+
+/*
+ * Get display update mode.
+ * If the mode is AUTO, we can wait for VSync, if desired.
+ */
+OMAPLFB_UPDATE_MODE OMAPLFBGetUpdateMode(OMAPLFB_DEVINFO *psDevInfo)
+{
+#if defined(PVR_OMAPLFB_DRM_FB)
+ struct drm_connector *psConnector;
+ OMAPLFB_UPDATE_MODE eMode = OMAPLFB_UPDATE_MODE_UNDEFINED;
+
+ /*
+ * There may be multiple displays connected. If at least one
+ * display is manual update mode, report all screens as being
+ * in that mode.
+ */
+ for (psConnector = NULL;
+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;)
+ {
+ switch(omap_connector_get_update_mode(psConnector))
+ {
+ case OMAP_DSS_UPDATE_MANUAL:
+ eMode = OMAPLFB_UPDATE_MODE_MANUAL;
+ break;
+ case OMAP_DSS_UPDATE_DISABLED:
+ if (eMode == OMAPLFB_UPDATE_MODE_UNDEFINED)
+ {
+ eMode = OMAPLFB_UPDATE_MODE_DISABLED;
+ }
+ break;
+ case OMAP_DSS_UPDATE_AUTO:
+ /* Fall through to default case */
+ default:
+ /* Asssume auto update is possible */
+ if (eMode != OMAPLFB_UPDATE_MODE_MANUAL)
+ {
+ eMode = OMAPLFB_UPDATE_MODE_AUTO;
+ }
+ break;
+ }
+ }
+
+ return eMode;
+#else /* defined(PVR_OMAPLFB_DRM_FB) */
+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo);
+ OMAP_DSS_DRIVER(psDSSDrv, psDSSDev);
+
+ enum omap_dss_update_mode eMode;
+
+ if (psDSSDrv == NULL)
+ {
+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: No DSS device\n", __FUNCTION__, psDevInfo->uiFBDevID));
+ return OMAPLFB_UPDATE_MODE_UNDEFINED;
+ }
+
+ if (psDSSDrv->get_update_mode == NULL)
+ {
+ if (strcmp(psDSSDev->name, "hdmi") == 0)
+ {
+ return OMAPLFB_UPDATE_MODE_AUTO;
+ }
+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: No get_update_mode function\n", __FUNCTION__, psDevInfo->uiFBDevID));
+ return OMAPLFB_UPDATE_MODE_UNDEFINED;
+ }
+
+ eMode = psDSSDrv->get_update_mode(psDSSDev);
+ if (!OMAPLFBValidateDSSUpdateMode(eMode))
+ {
+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Unknown update mode (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, (int)eMode));
+ }
+
+ return OMAPLFBFromDSSUpdateMode(eMode);
+#endif /* defined(PVR_OMAPLFB_DRM_FB) */
+}
+
+/* Set display update mode */
+OMAPLFB_BOOL OMAPLFBSetUpdateMode(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_UPDATE_MODE eMode)
+{
+#if defined(PVR_OMAPLFB_DRM_FB)
+ struct drm_connector *psConnector;
+ enum omap_dss_update_mode eDSSMode;
+ OMAPLFB_BOOL bSuccess = OMAPLFB_FALSE;
+ OMAPLFB_BOOL bFailure = OMAPLFB_FALSE;
+
+ if (!OMAPLFBValidateUpdateMode(eMode))
+ {
+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Unknown update mode (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, (int)eMode));
+ return OMAPLFB_FALSE;
+ }
+ eDSSMode = OMAPLFBToDSSUpdateMode(eMode);
+
+ for (psConnector = NULL;
+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;)
+ {
+ int iRes = omap_connector_set_update_mode(psConnector, eDSSMode);
+ OMAPLFB_BOOL bRes = (iRes == 0);
+
+
+ bSuccess |= bRes;
+ bFailure |= !bRes;
+ }
+
+ if (!bFailure)
+ {
+ if (!bSuccess)
+ {
+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: No screens\n", __FUNCTION__, psDevInfo->uiFBDevID));
+ }
+
+ return OMAPLFB_TRUE;
+ }
+
+ if (!bSuccess)
+ {
+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't set %s for any screen\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode)));
+ return OMAPLFB_FALSE;
+ }
+
+ if (eMode == OMAPLFB_UPDATE_MODE_AUTO)
+ {
+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't set %s for all screens\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode)));
+ return OMAPLFB_FALSE;
+ }
+
+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: %s set for some screens\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode)));
+
+ return OMAPLFB_TRUE;
+#else /* defined(PVR_OMAPLFB_DRM_FB) */
+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo);
+ OMAP_DSS_DRIVER(psDSSDrv, psDSSDev);
+ enum omap_dss_update_mode eDSSMode;
+ int res;
+
+ if (psDSSDrv == NULL || psDSSDrv->set_update_mode == NULL)
+ {
+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Can't set update mode\n", __FUNCTION__, psDevInfo->uiFBDevID));
+ return OMAPLFB_FALSE;
+ }
+
+ if (!OMAPLFBValidateUpdateMode(eMode))
+ {
+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Unknown update mode (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, (int)eMode));
+ return OMAPLFB_FALSE;
+ }
+ eDSSMode = OMAPLFBToDSSUpdateMode(eMode);
+
+ res = psDSSDrv->set_update_mode(psDSSDev, eDSSMode);
+ if (res != 0)
+ {
+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: set_update_mode (%s) failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBDSSUpdateModeToString(eDSSMode), res));
+ }
+
+ return (res == 0);
+#endif /* defined(PVR_OMAPLFB_DRM_FB) */
+}
+
+/* Wait for VSync */
+OMAPLFB_BOOL OMAPLFBWaitForVSync(OMAPLFB_DEVINFO *psDevInfo)
+{
+#if defined(PVR_OMAPLFB_DRM_FB)
+ struct drm_connector *psConnector;
+
+ for (psConnector = NULL;
+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;)
+ {
+ (void) omap_encoder_wait_for_vsync(psConnector->encoder);
+ }
+
+ return OMAPLFB_TRUE;
+#else /* defined(PVR_OMAPLFB_DRM_FB) */
+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo);
+ OMAP_DSS_MANAGER(psDSSMan, psDSSDev);
+
+ if (psDSSMan != NULL && WAIT_FOR_VSYNC(psDSSMan) != NULL)
+ {
+ int res = WAIT_FOR_VSYNC(psDSSMan)(psDSSMan);
+ if (res != 0)
+ {
+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Wait for vsync failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res));
+ return OMAPLFB_FALSE;
+ }
+ }
+
+ return OMAPLFB_TRUE;
+#endif /* defined(PVR_OMAPLFB_DRM_FB) */
+}
+
+/*
+ * Wait for screen to update. If the screen is in manual or auto update
+ * mode, we can call this function to wait for the screen to update.
+ */
+OMAPLFB_BOOL OMAPLFBManualSync(OMAPLFB_DEVINFO *psDevInfo)
+{
+#if defined(PVR_OMAPLFB_DRM_FB)
+ struct drm_connector *psConnector;
+
+ for (psConnector = NULL;
+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL; )
+ {
+ /* Try manual sync first, then try wait for vsync */
+ if (omap_connector_sync(psConnector) != 0)
+ {
+ (void) omap_encoder_wait_for_vsync(psConnector->encoder);
+ }
+ }
+
+ return OMAPLFB_TRUE;
+#else /* defined(PVR_OMAPLFB_DRM_FB) */
+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo);
+ OMAP_DSS_DRIVER(psDSSDrv, psDSSDev);
+
+ if (psDSSDrv != NULL && psDSSDrv->sync != NULL)
+ {
+ int res = psDSSDrv->sync(psDSSDev);
+ if (res != 0)
+ {
+ printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: Sync failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res);
+ return OMAPLFB_FALSE;
+ }
+ }
+
+ return OMAPLFB_TRUE;
+#endif /* defined(PVR_OMAPLFB_DRM_FB) */
+}
+
+/*
+ * If the screen is manual or auto update mode, wait for the screen to
+ * update.
+ */
+OMAPLFB_BOOL OMAPLFBCheckModeAndSync(OMAPLFB_DEVINFO *psDevInfo)
+{
+ OMAPLFB_UPDATE_MODE eMode = OMAPLFBGetUpdateMode(psDevInfo);
+
+ switch(eMode)
+ {
+ case OMAPLFB_UPDATE_MODE_AUTO:
+ case OMAPLFB_UPDATE_MODE_MANUAL:
+ return OMAPLFBManualSync(psDevInfo);
+ default:
+ break;
+ }
+
+ return OMAPLFB_TRUE;
+}
+
+/* Linux Framebuffer event notification handler */
+static int OMAPLFBFrameBufferEvents(struct notifier_block *psNotif,
+ unsigned long event, void *data)
+{
+ OMAPLFB_DEVINFO *psDevInfo;
+ struct fb_event *psFBEvent = (struct fb_event *)data;
+ struct fb_info *psFBInfo = psFBEvent->info;
+ OMAPLFB_BOOL bBlanked;
+
+ /* Only interested in blanking events */
+ if (event != FB_EVENT_BLANK)
+ {
+ return 0;
+ }
+
+ bBlanked = (*(IMG_INT *)psFBEvent->data != 0) ? OMAPLFB_TRUE: OMAPLFB_FALSE;
+
+ psDevInfo = OMAPLFBGetDevInfoPtr(psFBInfo->node);
+
+#if 0
+ if (psDevInfo != NULL)
+ {
+ if (bBlanked)
+ {
+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: Blank event received\n", __FUNCTION__, psDevInfo->uiFBDevID));
+ }
+ else
+ {
+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unblank event received\n", __FUNCTION__, psDevInfo->uiFBDevID));
+ }
+ }
+ else
+ {
+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: Blank/Unblank event for unknown framebuffer\n", __FUNCTION__, psFBInfo->node));
+ }
+#endif
+
+ if (psDevInfo != NULL)
+ {
+ OMAPLFBAtomicBoolSet(&psDevInfo->sBlanked, bBlanked);
+ OMAPLFBAtomicIntInc(&psDevInfo->sBlankEvents);
+ }
+
+ return 0;
+}
+
+/* Unblank the screen */
+OMAPLFB_ERROR OMAPLFBUnblankDisplay(OMAPLFB_DEVINFO *psDevInfo)
+{
+ int res;
+
+ OMAPLFB_CONSOLE_LOCK();
+ res = fb_blank(psDevInfo->psLINFBInfo, 0);
+ OMAPLFB_CONSOLE_UNLOCK();
+ if (res != 0 && res != -EINVAL)
+ {
+ printk(KERN_ERR DRIVER_PREFIX
+ ": %s: Device %u: fb_blank failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res);
+ return (OMAPLFB_ERROR_GENERIC);
+ }
+
+ return (OMAPLFB_OK);
+}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+
+/* Blank the screen */
+static void OMAPLFBBlankDisplay(OMAPLFB_DEVINFO *psDevInfo)
+{
+ OMAPLFB_CONSOLE_LOCK();
+ fb_blank(psDevInfo->psLINFBInfo, 1);
+ OMAPLFB_CONSOLE_UNLOCK();
+}
+
+static void OMAPLFBEarlySuspendHandler(struct early_suspend *h)
+{
+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne();
+ unsigned i;
+
+ for (i=0; i < uiMaxFBDevIDPlusOne; i++)
+ {
+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i);
+
+ if (psDevInfo != NULL)
+ {
+ OMAPLFBAtomicBoolSet(&psDevInfo->sEarlySuspendFlag, OMAPLFB_TRUE);
+ OMAPLFBBlankDisplay(psDevInfo);
+ }
+ }
+}
+
+static void OMAPLFBEarlyResumeHandler(struct early_suspend *h)
+{
+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne();
+ unsigned i;
+
+ for (i=0; i < uiMaxFBDevIDPlusOne; i++)
+ {
+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i);
+
+ if (psDevInfo != NULL)
+ {
+ OMAPLFBUnblankDisplay(psDevInfo);
+ OMAPLFBAtomicBoolSet(&psDevInfo->sEarlySuspendFlag, OMAPLFB_FALSE);
+ }
+ }
+}
+
+#endif /* CONFIG_HAS_EARLYSUSPEND */
+
+/* Set up Linux Framebuffer event notification */
+OMAPLFB_ERROR OMAPLFBEnableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo)
+{
+ int res;
+ OMAPLFB_ERROR eError;
+
+ /* Set up Linux Framebuffer event notification */
+ memset(&psDevInfo->sLINNotifBlock, 0, sizeof(psDevInfo->sLINNotifBlock));
+
+ psDevInfo->sLINNotifBlock.notifier_call = OMAPLFBFrameBufferEvents;
+
+ OMAPLFBAtomicBoolSet(&psDevInfo->sBlanked, OMAPLFB_FALSE);
+ OMAPLFBAtomicIntSet(&psDevInfo->sBlankEvents, 0);
+
+ res = fb_register_client(&psDevInfo->sLINNotifBlock);
+ if (res != 0)
+ {
+ printk(KERN_ERR DRIVER_PREFIX
+ ": %s: Device %u: fb_register_client failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res);
+
+ return (OMAPLFB_ERROR_GENERIC);
+ }
+
+ eError = OMAPLFBUnblankDisplay(psDevInfo);
+ if (eError != OMAPLFB_OK)
+ {
+ printk(KERN_ERR DRIVER_PREFIX
+ ": %s: Device %u: UnblankDisplay failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, eError);
+ return eError;
+ }
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ psDevInfo->sEarlySuspend.suspend = OMAPLFBEarlySuspendHandler;
+ psDevInfo->sEarlySuspend.resume = OMAPLFBEarlyResumeHandler;
+ psDevInfo->sEarlySuspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 1;
+ register_early_suspend(&psDevInfo->sEarlySuspend);
+#endif
+
+ return (OMAPLFB_OK);
+}
+
+/* Disable Linux Framebuffer event notification */
+OMAPLFB_ERROR OMAPLFBDisableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo)
+{
+ int res;
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&psDevInfo->sEarlySuspend);
+#endif
+
+ /* Unregister for Framebuffer events */
+ res = fb_unregister_client(&psDevInfo->sLINNotifBlock);
+ if (res != 0)
+ {
+ printk(KERN_ERR DRIVER_PREFIX
+ ": %s: Device %u: fb_unregister_client failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res);
+ return (OMAPLFB_ERROR_GENERIC);
+ }
+
+ OMAPLFBAtomicBoolSet(&psDevInfo->sBlanked, OMAPLFB_FALSE);
+
+ return (OMAPLFB_OK);
+}
+
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_DISPLAY_CONTROLLER_DRM_IOCTL)
+static OMAPLFB_DEVINFO *OMAPLFBPVRDevIDToDevInfo(unsigned uiPVRDevID)
+{
+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne();
+ unsigned i;
+
+ for (i=0; i < uiMaxFBDevIDPlusOne; i++)
+ {
+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i);
+
+ if (psDevInfo->uiPVRDevID == uiPVRDevID)
+ {
+ return psDevInfo;
+ }
+ }
+
+ printk(KERN_ERR DRIVER_PREFIX
+ ": %s: PVR Device %u: Couldn't find device\n", __FUNCTION__, uiPVRDevID);
+
+ return NULL;
+}
+
+int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Ioctl)(struct drm_device unref__ *dev, void *arg, struct drm_file unref__ *pFile)
+{
+ uint32_t *puiArgs;
+ uint32_t uiCmd;
+ unsigned uiPVRDevID;
+ int ret = 0;
+ OMAPLFB_DEVINFO *psDevInfo;
+
+ if (arg == NULL)
+ {
+ return -EFAULT;
+ }
+
+ puiArgs = (uint32_t *)arg;
+ uiCmd = puiArgs[PVR_DRM_DISP_ARG_CMD];
+ uiPVRDevID = puiArgs[PVR_DRM_DISP_ARG_DEV];
+
+ psDevInfo = OMAPLFBPVRDevIDToDevInfo(uiPVRDevID);
+ if (psDevInfo == NULL)
+ {
+ return -EINVAL;
+ }
+
+
+ switch (uiCmd)
+ {
+ case PVR_DRM_DISP_CMD_LEAVE_VT:
+ case PVR_DRM_DISP_CMD_ENTER_VT:
+ {
+ OMAPLFB_BOOL bLeaveVT = (uiCmd == PVR_DRM_DISP_CMD_LEAVE_VT);
+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: PVR Device %u: %s\n",
+ __FUNCTION__, uiPVRDevID,
+ bLeaveVT ? "Leave VT" : "Enter VT"));
+
+ OMAPLFBCreateSwapChainLock(psDevInfo);
+
+ OMAPLFBAtomicBoolSet(&psDevInfo->sLeaveVT, bLeaveVT);
+ if (psDevInfo->psSwapChain != NULL)
+ {
+ flush_workqueue(psDevInfo->psSwapChain->psWorkQueue);
+
+ if (bLeaveVT)
+ {
+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer);
+ (void) OMAPLFBCheckModeAndSync(psDevInfo);
+ }
+ }
+
+ OMAPLFBCreateSwapChainUnLock(psDevInfo);
+ (void) OMAPLFBUnblankDisplay(psDevInfo);
+ break;
+ }
+ case PVR_DRM_DISP_CMD_ON:
+ case PVR_DRM_DISP_CMD_STANDBY:
+ case PVR_DRM_DISP_CMD_SUSPEND:
+ case PVR_DRM_DISP_CMD_OFF:
+ {
+ int iFBMode;
+#if defined(DEBUG)
+ {
+ const char *pszMode;
+ switch(uiCmd)
+ {
+ case PVR_DRM_DISP_CMD_ON:
+ pszMode = "On";
+ break;
+ case PVR_DRM_DISP_CMD_STANDBY:
+ pszMode = "Standby";
+ break;
+ case PVR_DRM_DISP_CMD_SUSPEND:
+ pszMode = "Suspend";
+ break;
+ case PVR_DRM_DISP_CMD_OFF:
+ pszMode = "Off";
+ break;
+ default:
+ pszMode = "(Unknown Mode)";
+ break;
+ }
+ printk(KERN_WARNING DRIVER_PREFIX ": %s: PVR Device %u: Display %s\n",
+ __FUNCTION__, uiPVRDevID, pszMode);
+ }
+#endif
+ switch(uiCmd)
+ {
+ case PVR_DRM_DISP_CMD_ON:
+ iFBMode = FB_BLANK_UNBLANK;
+ break;
+ case PVR_DRM_DISP_CMD_STANDBY:
+ iFBMode = FB_BLANK_HSYNC_SUSPEND;
+ break;
+ case PVR_DRM_DISP_CMD_SUSPEND:
+ iFBMode = FB_BLANK_VSYNC_SUSPEND;
+ break;
+ case PVR_DRM_DISP_CMD_OFF:
+ iFBMode = FB_BLANK_POWERDOWN;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ OMAPLFBCreateSwapChainLock(psDevInfo);
+
+ if (psDevInfo->psSwapChain != NULL)
+ {
+ flush_workqueue(psDevInfo->psSwapChain->psWorkQueue);
+ }
+
+ OMAPLFB_CONSOLE_LOCK();
+ ret = fb_blank(psDevInfo->psLINFBInfo, iFBMode);
+ OMAPLFB_CONSOLE_UNLOCK();
+
+ OMAPLFBCreateSwapChainUnLock(psDevInfo);
+
+ break;
+ }
+ default:
+ {
+ ret = -EINVAL;
+ break;
+ }
+ }
+
+ return ret;
+}
+#endif
+
+/* Insert the driver into the kernel */
+#if defined(SUPPORT_DRI_DRM)
+int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Init)(struct drm_device unref__ *dev)
+#else
+static int __init OMAPLFB_Init(void)
+#endif
+{
+
+ if(OMAPLFBInit() != OMAPLFB_OK)
+ {
+ printk(KERN_ERR DRIVER_PREFIX ": %s: OMAPLFBInit failed\n", __FUNCTION__);
+ return -ENODEV;
+ }
+
+ return 0;
+
+}
+
+/* Remove the driver from the kernel */
+#if defined(SUPPORT_DRI_DRM)
+void PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Cleanup)(struct drm_device unref__ *dev)
+#else
+static void __exit OMAPLFB_Cleanup(void)
+#endif
+{
+ if(OMAPLFBDeInit() != OMAPLFB_OK)
+ {
+ printk(KERN_ERR DRIVER_PREFIX ": %s: OMAPLFBDeInit failed\n", __FUNCTION__);
+ }
+}
+
+#if !defined(SUPPORT_DRI_DRM)
+/*
+ These macro calls define the initialisation and removal functions of the
+ driver. Although they are prefixed `module_', they apply when compiling
+ statically as well; in both cases they define the function the kernel will
+ run to start/stop the driver.
+*/
+late_initcall(OMAPLFB_Init);
+module_exit(OMAPLFB_Cleanup);
+#endif
diff --git a/pvr-source/services4/include/kernelbuffer.h b/pvr-source/services4/include/kernelbuffer.h
new file mode 100644
index 0000000..6d8aed5
--- /dev/null
+++ b/pvr-source/services4/include/kernelbuffer.h
@@ -0,0 +1,97 @@
+/*************************************************************************/ /*!
+@Title buffer device class API structures and prototypes
+ for kernel services to kernel 3rd party buffer device driver
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description provides display device class API structures and prototypes
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined (__KERNELBUFFER_H__)
+#define __KERNELBUFFER_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/*
+ Function table and pointers for SRVKM->BUFFER
+*/
+typedef PVRSRV_ERROR (*PFN_OPEN_BC_DEVICE)(IMG_UINT32, IMG_HANDLE*);
+typedef PVRSRV_ERROR (*PFN_CLOSE_BC_DEVICE)(IMG_UINT32, 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;
+
+
+/*
+ Function table and pointers for BUFFER->SRVKM
+*/
+typedef PVRSRV_ERROR (*PFN_BC_REGISTER_BUFFER_DEV)(PVRSRV_BC_SRV2BUFFER_KMJTABLE*, IMG_UINT32*);
+typedef IMG_VOID (*PFN_BC_SCHEDULE_DEVICES)(IMG_VOID);
+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_SCHEDULE_DEVICES pfnPVRSRVScheduleDevices;
+ PFN_BC_REMOVE_BUFFER_DEV pfnPVRSRVRemoveBCDevice;
+
+} PVRSRV_BC_BUFFER2SRV_KMJTABLE, *PPVRSRV_BC_BUFFER2SRV_KMJTABLE;
+
+/* function to retrieve kernel services function table from kernel services */
+typedef IMG_BOOL (*PFN_BC_GET_PVRJTABLE) (PPVRSRV_BC_BUFFER2SRV_KMJTABLE);
+
+/* Prototype for platforms that access the JTable via linkage */
+IMG_IMPORT IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable);
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif/* #if !defined (__KERNELBUFFER_H__) */
diff --git a/pvr-source/services4/include/kerneldisplay.h b/pvr-source/services4/include/kerneldisplay.h
new file mode 100644
index 0000000..2efd7b3
--- /dev/null
+++ b/pvr-source/services4/include/kerneldisplay.h
@@ -0,0 +1,243 @@
+/*************************************************************************/ /*!
+@Title Display device class API structures and prototypes
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Provides display device class API structures and prototypes
+ for kernel services to kernel 3rd party display.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined (__KERNELDISPLAY_H__)
+#define __KERNELDISPLAY_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+typedef PVRSRV_ERROR (*PFN_OPEN_DC_DEVICE)(IMG_UINT32, IMG_HANDLE*, PVRSRV_SYNC_DATA*);
+typedef PVRSRV_ERROR (*PFN_CLOSE_DC_DEVICE)(IMG_HANDLE);
+typedef PVRSRV_ERROR (*PFN_ENUM_DC_FORMATS)(IMG_HANDLE, IMG_UINT32*, DISPLAY_FORMAT*);
+typedef PVRSRV_ERROR (*PFN_ENUM_DC_DIMS)(IMG_HANDLE,
+ DISPLAY_FORMAT*,
+ IMG_UINT32*,
+ DISPLAY_DIMS*);
+typedef PVRSRV_ERROR (*PFN_GET_DC_SYSTEMBUFFER)(IMG_HANDLE, IMG_HANDLE*);
+typedef PVRSRV_ERROR (*PFN_GET_DC_INFO)(IMG_HANDLE, DISPLAY_INFO*);
+typedef PVRSRV_ERROR (*PFN_CREATE_DC_SWAPCHAIN)(IMG_HANDLE,
+ IMG_UINT32,
+ DISPLAY_SURF_ATTRIBUTES*,
+ DISPLAY_SURF_ATTRIBUTES*,
+ IMG_UINT32,
+ PVRSRV_SYNC_DATA**,
+ IMG_UINT32,
+ IMG_HANDLE*,
+ IMG_UINT32*);
+typedef PVRSRV_ERROR (*PFN_DESTROY_DC_SWAPCHAIN)(IMG_HANDLE,
+ IMG_HANDLE);
+typedef PVRSRV_ERROR (*PFN_SET_DC_DSTRECT)(IMG_HANDLE, IMG_HANDLE, IMG_RECT*);
+typedef PVRSRV_ERROR (*PFN_SET_DC_SRCRECT)(IMG_HANDLE, IMG_HANDLE, IMG_RECT*);
+typedef PVRSRV_ERROR (*PFN_SET_DC_DSTCK)(IMG_HANDLE, IMG_HANDLE, IMG_UINT32);
+typedef PVRSRV_ERROR (*PFN_SET_DC_SRCCK)(IMG_HANDLE, IMG_HANDLE, IMG_UINT32);
+typedef PVRSRV_ERROR (*PFN_GET_DC_BUFFERS)(IMG_HANDLE,
+ IMG_HANDLE,
+ IMG_UINT32*,
+ IMG_HANDLE*);
+typedef PVRSRV_ERROR (*PFN_SWAP_TO_DC_BUFFER)(IMG_HANDLE,
+ IMG_HANDLE,
+ IMG_UINT32,
+ IMG_HANDLE,
+ IMG_UINT32,
+ IMG_RECT*);
+typedef IMG_VOID (*PFN_QUERY_SWAP_COMMAND_ID)(IMG_HANDLE, IMG_HANDLE, IMG_HANDLE, IMG_HANDLE, IMG_UINT16*, IMG_BOOL*);
+typedef IMG_VOID (*PFN_SET_DC_STATE)(IMG_HANDLE, IMG_UINT32);
+
+/*
+ Function table for SRVKM->DISPLAY
+*/
+typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG
+{
+ IMG_UINT32 ui32TableSize;
+ PFN_OPEN_DC_DEVICE pfnOpenDCDevice;
+ PFN_CLOSE_DC_DEVICE pfnCloseDCDevice;
+ PFN_ENUM_DC_FORMATS pfnEnumDCFormats;
+ PFN_ENUM_DC_DIMS pfnEnumDCDims;
+ PFN_GET_DC_SYSTEMBUFFER pfnGetDCSystemBuffer;
+ PFN_GET_DC_INFO pfnGetDCInfo;
+ PFN_GET_BUFFER_ADDR pfnGetBufferAddr;
+ PFN_CREATE_DC_SWAPCHAIN pfnCreateDCSwapChain;
+ PFN_DESTROY_DC_SWAPCHAIN pfnDestroyDCSwapChain;
+ PFN_SET_DC_DSTRECT pfnSetDCDstRect;
+ PFN_SET_DC_SRCRECT pfnSetDCSrcRect;
+ PFN_SET_DC_DSTCK pfnSetDCDstColourKey;
+ PFN_SET_DC_SRCCK pfnSetDCSrcColourKey;
+ PFN_GET_DC_BUFFERS pfnGetDCBuffers;
+ PFN_SWAP_TO_DC_BUFFER pfnSwapToDCBuffer;
+ PFN_SET_DC_STATE pfnSetDCState;
+ PFN_QUERY_SWAP_COMMAND_ID pfnQuerySwapCommandID;
+
+} PVRSRV_DC_SRV2DISP_KMJTABLE;
+
+/* ISR callback pfn prototype */
+typedef IMG_BOOL (*PFN_ISR_HANDLER)(IMG_VOID*);
+
+/*
+ functions exported by kernel services for use by 3rd party kernel display class device driver
+*/
+typedef PVRSRV_ERROR (*PFN_DC_REGISTER_DISPLAY_DEV)(PVRSRV_DC_SRV2DISP_KMJTABLE*, IMG_UINT32*);
+typedef PVRSRV_ERROR (*PFN_DC_REMOVE_DISPLAY_DEV)(IMG_UINT32);
+typedef PVRSRV_ERROR (*PFN_DC_OEM_FUNCTION)(IMG_UINT32, IMG_VOID*, IMG_UINT32, IMG_VOID*, IMG_UINT32);
+typedef PVRSRV_ERROR (*PFN_DC_REGISTER_COMMANDPROCLIST)(IMG_UINT32, PPFN_CMD_PROC,IMG_UINT32[][2], IMG_UINT32);
+typedef PVRSRV_ERROR (*PFN_DC_REMOVE_COMMANDPROCLIST)(IMG_UINT32, IMG_UINT32);
+typedef IMG_VOID (*PFN_DC_CMD_COMPLETE)(IMG_HANDLE, IMG_BOOL);
+typedef PVRSRV_ERROR (*PFN_DC_REGISTER_SYS_ISR)(PFN_ISR_HANDLER, IMG_VOID*, IMG_UINT32, IMG_UINT32);
+typedef PVRSRV_ERROR (*PFN_DC_REGISTER_POWER)(IMG_UINT32, PFN_PRE_POWER, PFN_POST_POWER,
+ PFN_PRE_CLOCKSPEED_CHANGE, PFN_POST_CLOCKSPEED_CHANGE,
+ IMG_HANDLE, PVRSRV_DEV_POWER_STATE, PVRSRV_DEV_POWER_STATE);
+
+typedef struct _PVRSRV_KERNEL_MEM_INFO_* PDC_MEM_INFO;
+
+typedef PVRSRV_ERROR (*PFN_DC_MEMINFO_GET_CPU_VADDR)(PDC_MEM_INFO, IMG_CPU_VIRTADDR *pVAddr);
+typedef PVRSRV_ERROR (*PFN_DC_MEMINFO_GET_CPU_PADDR)(PDC_MEM_INFO, IMG_SIZE_T uByteOffset, IMG_CPU_PHYADDR *pPAddr);
+typedef PVRSRV_ERROR (*PFN_DC_MEMINFO_GET_BYTE_SIZE)(PDC_MEM_INFO, IMG_SIZE_T *uByteSize);
+typedef IMG_BOOL (*PFN_DC_MEMINFO_IS_PHYS_CONTIG)(PDC_MEM_INFO);
+typedef PVRSRV_ERROR (*PFN_DC_GETBVHANDLE)(PDC_MEM_INFO, IMG_VOID **handle);
+typedef IMG_INT32 (*PFN_DC_MEMINFO_GET_MULTI_PLANE_CPU_PADDRS)(PDC_MEM_INFO, IMG_SIZE_T* puByteOffsets,
+ IMG_CPU_PHYADDR *pPAddrs, IMG_UINT32* pui32NumAddrOffsets);
+
+/*
+ Function table for DISPLAY->SRVKM
+*/
+typedef struct PVRSRV_DC_DISP2SRV_KMJTABLE_TAG
+{
+ IMG_UINT32 ui32TableSize;
+ PFN_DC_REGISTER_DISPLAY_DEV pfnPVRSRVRegisterDCDevice;
+ PFN_DC_REMOVE_DISPLAY_DEV pfnPVRSRVRemoveDCDevice;
+ PFN_DC_OEM_FUNCTION pfnPVRSRVOEMFunction;
+ PFN_DC_REGISTER_COMMANDPROCLIST pfnPVRSRVRegisterCmdProcList;
+ PFN_DC_REMOVE_COMMANDPROCLIST pfnPVRSRVRemoveCmdProcList;
+ PFN_DC_CMD_COMPLETE pfnPVRSRVCmdComplete;
+ PFN_DC_REGISTER_SYS_ISR pfnPVRSRVRegisterSystemISRHandler;
+ PFN_DC_REGISTER_POWER pfnPVRSRVRegisterPowerDevice;
+ PFN_DC_CMD_COMPLETE pfnPVRSRVFreeCmdCompletePacket;
+ PFN_DC_MEMINFO_GET_CPU_VADDR pfnPVRSRVDCMemInfoGetCpuVAddr;
+ PFN_DC_MEMINFO_GET_CPU_PADDR pfnPVRSRVDCMemInfoGetCpuPAddr;
+ PFN_DC_MEMINFO_GET_BYTE_SIZE pfnPVRSRVDCMemInfoGetByteSize;
+ PFN_DC_MEMINFO_IS_PHYS_CONTIG pfnPVRSRVDCMemInfoIsPhysContig;
+ PFN_DC_GETBVHANDLE pfnPVRSRVDCMemInfoGetBvHandle;
+ PFN_DC_MEMINFO_GET_MULTI_PLANE_CPU_PADDRS pfnPVRSRVDCMemInfoGetCpuMultiPlanePAddr;
+
+} PVRSRV_DC_DISP2SRV_KMJTABLE, *PPVRSRV_DC_DISP2SRV_KMJTABLE;
+
+
+typedef struct DISPLAYCLASS_FLIP_COMMAND_TAG
+{
+ /* Ext Device Handle */
+ IMG_HANDLE hExtDevice;
+
+ /* Ext SwapChain Handle */
+ IMG_HANDLE hExtSwapChain;
+
+ /* Ext Buffer Handle (Buffer to Flip to) */
+ IMG_HANDLE hExtBuffer;
+
+ /* private tag */
+ IMG_HANDLE hPrivateTag;
+
+ /* number of clip rects */
+ IMG_UINT32 ui32ClipRectCount;
+
+ /* clip rects */
+ IMG_RECT *psClipRect;
+
+ /* number of vsync intervals between successive flips */
+ IMG_UINT32 ui32SwapInterval;
+
+} DISPLAYCLASS_FLIP_COMMAND;
+
+
+typedef struct DISPLAYCLASS_FLIP_COMMAND2_TAG
+{
+ /* Ext Device Handle */
+ IMG_HANDLE hExtDevice;
+
+ /* Ext SwapChain Handle */
+ IMG_HANDLE hExtSwapChain;
+
+ /* Unused field, padding for compatibility with above structure */
+ IMG_HANDLE hUnused;
+
+ /* number of vsync intervals between successive flips */
+ IMG_UINT32 ui32SwapInterval;
+
+ /* private data from userspace */
+ IMG_PVOID pvPrivData;
+
+ /* length of private data in bytes */
+ IMG_UINT32 ui32PrivDataLength;
+
+ /* meminfos */
+ PDC_MEM_INFO *ppsMemInfos;
+
+ /* number of meminfos */
+ IMG_UINT32 ui32NumMemInfos;
+
+} DISPLAYCLASS_FLIP_COMMAND2;
+
+/* start command IDs from 0 */
+#define DC_FLIP_COMMAND 0
+
+/* States used in PFN_SET_DC_STATE */
+#define DC_STATE_NO_FLUSH_COMMANDS 0
+#define DC_STATE_FLUSH_COMMANDS 1
+#define DC_STATE_FORCE_SWAP_TO_SYSTEM 2
+
+/* function to retrieve kernel services function table from kernel services */
+typedef IMG_BOOL (*PFN_DC_GET_PVRJTABLE)(PPVRSRV_DC_DISP2SRV_KMJTABLE);
+
+/* Prototype for platforms that access the JTable via linkage */
+IMG_IMPORT IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable);
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif/* #if !defined (__KERNELDISPLAY_H__) */
+
+/******************************************************************************
+ End of file (kerneldisplay.h)
+******************************************************************************/
diff --git a/pvr-source/services4/include/pdump.h b/pvr-source/services4/include/pdump.h
new file mode 100644
index 0000000..566a118
--- /dev/null
+++ b/pvr-source/services4/include/pdump.h
@@ -0,0 +1,51 @@
+/*************************************************************************/ /*!
+@Title PDUMP flags definitions.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef _SERVICES_PDUMP_H_
+#define _SERVICES_PDUMP_H_
+
+#define PDUMP_FLAGS_NEVER 0x08000000U
+#define PDUMP_FLAGS_LASTFRAME 0x10000000U
+#define PDUMP_FLAGS_RESETLFBUFFER 0x20000000U
+#define PDUMP_FLAGS_CONTINUOUS 0x40000000U
+#define PDUMP_FLAGS_PERSISTENT 0x80000000U
+
+#endif /* _SERVICES_PDUMP_H_ */
+
diff --git a/pvr-source/services4/include/pvr_bridge.h b/pvr-source/services4/include/pvr_bridge.h
new file mode 100644
index 0000000..71813c4
--- /dev/null
+++ b/pvr-source/services4/include/pvr_bridge.h
@@ -0,0 +1,2255 @@
+/*************************************************************************/ /*!
+@Title PVR Bridge Functionality
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Header for the PVR Bridge code
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __PVR_BRIDGE_H__
+#define __PVR_BRIDGE_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "servicesint.h"
+
+/*
+ * Bridge Cmd Ids
+ */
+
+
+#ifdef __linux__
+
+ #include <linux/ioctl.h>
+ /*!< Nov 2006: according to ioctl-number.txt 'g' wasn't in use. */
+ #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 /* __linux__ */
+
+ #if defined(__QNXNTO__)
+ #define PVRSRV_IOC_GID (0x0UL)
+ #else
+ #error Unknown platform: Cannot define ioctls
+ #endif
+
+ #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 /* __linux__ */
+
+
+/*
+ * Note *REMEMBER* to update PVRSRV_BRIDGE_LAST_CMD (below) if you add any new
+ * bridge commands!
+ */
+
+#define PVRSRV_BRIDGE_CORE_CMD_FIRST 0UL
+#define PVRSRV_BRIDGE_ENUM_DEVICES PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+0) /*!< enumerate device bridge index */
+#define PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+1) /*!< acquire device data bridge index */
+#define PVRSRV_BRIDGE_RELEASE_DEVICEINFO PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+2) /*!< release device data bridge index */
+#define PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+3) /*!< create device addressable memory context */
+#define PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+4) /*!< destroy device addressable memory context */
+#define PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+5) /*!< get device memory heap info */
+#define PVRSRV_BRIDGE_ALLOC_DEVICEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+6) /*!< alloc device memory bridge index */
+#define PVRSRV_BRIDGE_FREE_DEVICEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+7) /*!< free device memory bridge index */
+#define PVRSRV_BRIDGE_GETFREE_DEVICEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+8) /*!< get free device memory bridge index */
+#define PVRSRV_BRIDGE_CREATE_COMMANDQUEUE PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+9) /*!< create Cmd Q bridge index */
+#define PVRSRV_BRIDGE_DESTROY_COMMANDQUEUE PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+10) /*!< destroy Cmd Q bridge index */
+#define PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+11) /*!< generate mmap data from a memory handle */
+#define PVRSRV_BRIDGE_CONNECT_SERVICES PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+12) /*!< services connect bridge index */
+#define PVRSRV_BRIDGE_DISCONNECT_SERVICES PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+13) /*!< services disconnect bridge index */
+#define PVRSRV_BRIDGE_WRAP_DEVICE_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+14) /*!< wrap device memory bridge index */
+#define PVRSRV_BRIDGE_GET_DEVICEMEMINFO PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+15) /*!< read the kernel meminfo record */
+#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_CHG_DEV_MEM_ATTRIBS PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+28)
+#define PVRSRV_BRIDGE_MAP_DEV_MEMORY_2 PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+29)
+#define PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2 PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+30)
+
+#define PVRSRV_BRIDGE_MULTI_MANAGE_DEV_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+31)
+#define PVRSRV_BRIDGE_CORE_CMD_RESERVED_1 PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+32)
+#define PVRSRV_BRIDGE_CORE_CMD_RESERVED_2 PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+33)
+#define PVRSRV_BRIDGE_CORE_CMD_RESERVED_3 PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+34)
+
+#if defined (SUPPORT_ION)
+#define PVRSRV_BRIDGE_MAP_ION_HANDLE PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+35)
+#define PVRSRV_BRIDGE_UNMAP_ION_HANDLE PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+36)
+#define PVRSRV_BRIDGE_CORE_CMD_LAST (PVRSRV_BRIDGE_CORE_CMD_FIRST+37)
+#else
+#define PVRSRV_BRIDGE_CORE_CMD_LAST (PVRSRV_BRIDGE_CORE_CMD_FIRST+34)
+#endif
+/* SIM */
+#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) /*!< RTSIM pseudo ISR */
+#define PVRSRV_BRIDGE_REGISTER_SIM_PROCESS PVRSRV_IOWR(PVRSRV_BRIDGE_SIM_CMD_FIRST+1) /*!< Register RTSIM process thread */
+#define PVRSRV_BRIDGE_UNREGISTER_SIM_PROCESS PVRSRV_IOWR(PVRSRV_BRIDGE_SIM_CMD_FIRST+2) /*!< Unregister RTSIM process thread */
+#define PVRSRV_BRIDGE_SIM_CMD_LAST (PVRSRV_BRIDGE_SIM_CMD_FIRST+2)
+
+/* User Mapping */
+#define PVRSRV_BRIDGE_MAPPING_CMD_FIRST (PVRSRV_BRIDGE_SIM_CMD_LAST+1)
+#define PVRSRV_BRIDGE_MAPPHYSTOUSERSPACE PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+0) /*!< map CPU phys to user space */
+#define PVRSRV_BRIDGE_UNMAPPHYSTOUSERSPACE PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+1) /*!< unmap CPU phys to user space */
+#define PVRSRV_BRIDGE_GETPHYSTOUSERSPACEMAP PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+2) /*!< get user copy of Phys to Lin loopup table */
+#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) /*!< Get FB memory stats */
+#define PVRSRV_BRIDGE_STATS_CMD_LAST (PVRSRV_BRIDGE_STATS_CMD_FIRST+0)
+
+/* API to retrieve misc. info. from services */
+#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) /*!< misc. info. */
+#define PVRSRV_BRIDGE_RELEASE_MISC_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_MISC_CMD_FIRST+1) /*!< misc. info. */
+#define PVRSRV_BRIDGE_MISC_CMD_LAST (PVRSRV_BRIDGE_MISC_CMD_FIRST+1)
+
+/* Overlay ioctls */
+
+#if defined (SUPPORT_OVERLAY_ROTATE_BLIT)
+#define PVRSRV_BRIDGE_OVERLAY_CMD_FIRST (PVRSRV_BRIDGE_MISC_CMD_LAST+1)
+#define PVRSRV_BRIDGE_INIT_3D_OVL_BLT_RES PVRSRV_IOWR(PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+0) /*!< 3D Overlay rotate blit init */
+#define PVRSRV_BRIDGE_DEINIT_3D_OVL_BLT_RES PVRSRV_IOWR(PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+1) /*!< 3D Overlay rotate blit deinit */
+#define PVRSRV_BRIDGE_OVERLAY_CMD_LAST (PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+1)
+#else
+#define PVRSRV_BRIDGE_OVERLAY_CMD_LAST PVRSRV_BRIDGE_MISC_CMD_LAST
+#endif
+
+/* PDUMP */
+#if defined(PDUMP)
+#define PVRSRV_BRIDGE_PDUMP_CMD_FIRST (PVRSRV_BRIDGE_OVERLAY_CMD_LAST+1)
+#define PVRSRV_BRIDGE_PDUMP_INIT PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+0) /*!< pdump command structure */
+#define PVRSRV_BRIDGE_PDUMP_MEMPOL PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+1) /*!< pdump command structure */
+#define PVRSRV_BRIDGE_PDUMP_DUMPMEM PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+2) /*!< pdump command structure */
+#define PVRSRV_BRIDGE_PDUMP_REG PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+3) /*!< pdump command structure */
+#define PVRSRV_BRIDGE_PDUMP_REGPOL PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+4) /*!< pdump command structure */
+#define PVRSRV_BRIDGE_PDUMP_COMMENT PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+5) /*!< pdump command structure */
+#define PVRSRV_BRIDGE_PDUMP_SETFRAME PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+6) /*!< pdump command structure */
+#define PVRSRV_BRIDGE_PDUMP_ISCAPTURING PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+7) /*!< pdump command structure */
+#define PVRSRV_BRIDGE_PDUMP_DUMPBITMAP PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+8) /*!< pdump command structure */
+#define PVRSRV_BRIDGE_PDUMP_DUMPREADREG PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+9) /*!< pdump command structure */
+#define PVRSRV_BRIDGE_PDUMP_SYNCPOL PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+10) /*!< pdump command structure */
+#define PVRSRV_BRIDGE_PDUMP_DUMPSYNC PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+11) /*!< pdump command structure */
+#define PVRSRV_BRIDGE_PDUMP_MEMPAGES PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+12) /*!< pdump command structure */
+#define PVRSRV_BRIDGE_PDUMP_DRIVERINFO PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+13) /*!< pdump command structure */
+#define PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+15) /*!< pdump command structure */
+#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
+/* Note we are carefull here not to leave a large gap in the ioctl numbers.
+ * (Some ports may use these values to index into an array where large gaps can
+ * waste memory) */
+#define PVRSRV_BRIDGE_PDUMP_CMD_LAST PVRSRV_BRIDGE_OVERLAY_CMD_LAST
+#endif
+
+/* DisplayClass APIs */
+#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) /*!< Get OEM Jtable */
+#define PVRSRV_BRIDGE_OEM_CMD_LAST (PVRSRV_BRIDGE_OEM_CMD_FIRST+0)
+
+/* device class enum */
+#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)
+
+/* display class API */
+#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_BUFFER2 PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+14)
+#define PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+15)
+#define PVRSRV_BRIDGE_DISPCLASS_CMD_LAST (PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+15)
+
+/* buffer class API */
+#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)
+
+/* Wrap/Unwrap external memory */
+#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)
+
+/* Shared memory */
+#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)
+
+/* Intialisation Service support */
+#define PVRSRV_BRIDGE_INITSRV_CMD_FIRST (PVRSRV_BRIDGE_SHAREDMEM_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)
+
+/* Event Objects */
+#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)
+
+/* Sync ops */
+#define PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST (PVRSRV_BRIDGE_EVENT_OBJECT_CMD_LAST+1)
+#define PVRSRV_BRIDGE_CREATE_SYNC_INFO_MOD_OBJ PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_DESTROY_SYNC_INFO_MOD_OBJ PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+2)
+#define PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+3)
+#define PVRSRV_BRIDGE_SYNC_OPS_TAKE_TOKEN PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+4)
+#define PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_TOKEN PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+5)
+#define PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_MOD_OBJ PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+6)
+#define PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_DELTA PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+7)
+#define PVRSRV_BRIDGE_ALLOC_SYNC_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+8)
+#define PVRSRV_BRIDGE_FREE_SYNC_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+9)
+#define PVRSRV_BRIDGE_SYNC_OPS_CMD_LAST (PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+9)
+
+/* For sgx_bridge.h (msvdx_bridge.h should probably use these defines too) */
+#define PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD (PVRSRV_BRIDGE_SYNC_OPS_CMD_LAST+1)
+
+
+/******************************************************************************
+ * Bridge flags
+ *****************************************************************************/
+#define PVRSRV_KERNEL_MODE_CLIENT 1
+
+/******************************************************************************
+ * Generic bridge structures
+ *****************************************************************************/
+
+/******************************************************************************
+ * bridge return structure
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_RETURN_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_VOID *pvData;
+
+}PVRSRV_BRIDGE_RETURN;
+
+
+/******************************************************************************
+ * bridge packaging structure
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_PACKAGE_TAG
+{
+ IMG_UINT32 ui32BridgeID; /*!< ioctl/drvesc index */
+ IMG_UINT32 ui32Size; /*!< size of structure */
+ IMG_VOID *pvParamIn; /*!< input data buffer */
+ IMG_UINT32 ui32InBufferSize; /*!< size of input data buffer */
+ IMG_VOID *pvParamOut; /*!< output data buffer */
+ IMG_UINT32 ui32OutBufferSize; /*!< size of output data buffer */
+
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelServices; /*!< kernel servcies handle */
+#else
+ IMG_HANDLE hKernelServices; /*!< kernel servcies handle */
+#endif
+}PVRSRV_BRIDGE_PACKAGE;
+
+
+/******************************************************************************
+ * Input structures for IOCTL/DRVESC
+ *****************************************************************************/
+
+
+/******************************************************************************
+ * 'bridge in' connect to services
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_CONNECT_SERVICES_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ IMG_UINT32 ui32Flags;
+} PVRSRV_BRIDGE_IN_CONNECT_SERVICES;
+
+/******************************************************************************
+ * 'bridge in' acquire device info
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ IMG_UINT32 uiDevIndex;
+ PVRSRV_DEVICE_TYPE eDeviceType;
+
+} PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO;
+
+
+/******************************************************************************
+ * 'bridge in' enum class
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_ENUMCLASS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ PVRSRV_DEVICE_CLASS sDeviceClass;
+} PVRSRV_BRIDGE_IN_ENUMCLASS;
+
+
+/******************************************************************************
+ * 'bridge in' close display class device
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+} PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE;
+
+
+/******************************************************************************
+ * 'bridge in' enum display class formats
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+} PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS;
+
+
+/******************************************************************************
+ * 'bridge in' get display class sysbuffer
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+} PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER;
+
+
+/******************************************************************************
+ * 'bridge in' display class info
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+} PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO;
+
+
+/******************************************************************************
+ * 'bridge in' close buffer class device
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+} PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE;
+
+
+/******************************************************************************
+ * 'bridge in' close buffer class device
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+} PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO;
+
+
+/******************************************************************************
+ * 'bridge out' acquire device info
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_RELEASE_DEVICEINFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+
+} PVRSRV_BRIDGE_IN_RELEASE_DEVICEINFO;
+
+
+/******************************************************************************
+ * 'bridge in' free class devices info.
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_FREE_CLASSDEVICEINFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ PVRSRV_DEVICE_CLASS DeviceClass;
+ IMG_VOID* pvDevInfo;
+
+}PVRSRV_BRIDGE_IN_FREE_CLASSDEVICEINFO;
+
+
+/******************************************************************************
+ * 'bridge in' get device memory heap info
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hDevMemContext;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hDevMemContext;
+#endif
+
+}PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO;
+
+
+/******************************************************************************
+ * 'bridge in' create device memory context
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+
+}PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT;
+
+
+/******************************************************************************
+ * 'bridge in' destroy device memory context
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hDevMemContext;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hDevMemContext;
+#endif
+
+}PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT;
+
+
+/******************************************************************************
+ * 'bridge in' alloc device memory
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hDevMemHeap;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hDevMemHeap;
+#endif
+ IMG_UINT32 ui32Attribs;
+ IMG_SIZE_T ui32Size;
+ IMG_SIZE_T ui32Alignment;
+ IMG_PVOID pvPrivData;
+ IMG_UINT32 ui32PrivDataLength;
+
+ IMG_UINT32 ui32ChunkSize;
+ IMG_UINT32 ui32NumVirtChunks;
+ IMG_UINT32 ui32NumPhysChunks;
+ IMG_BOOL *pabMapChunk;
+}PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM;
+
+/******************************************************************************
+ * 'bridge in' map meminfo to user mode
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_MAPMEMINFOTOUSER_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+
+}PVRSRV_BRIDGE_IN_MAPMEMINFOTOUSER;
+
+/******************************************************************************
+ * 'bridge in' unmap meminfo from user mode
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_UNMAPMEMINFOFROMUSER_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ IMG_PVOID pvLinAddr;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMappingInfo;
+#else
+ IMG_HANDLE hMappingInfo;
+#endif
+
+}PVRSRV_BRIDGE_IN_UNMAPMEMINFOFROMUSER;
+
+/******************************************************************************
+ * 'bridge in' free device memory
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_FREEDEVICEMEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hKernelMemInfo;
+#else
+ IMG_HANDLE hDevCookie;
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+
+}PVRSRV_BRIDGE_IN_FREEDEVICEMEM;
+
+/******************************************************************************
+ * 'bridge in' export device memory
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hKernelMemInfo;
+#else
+ IMG_HANDLE hDevCookie;
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+
+}PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM;
+
+/******************************************************************************
+ * 'bridge in' map ion handle
+ *****************************************************************************/
+typedef struct _PVRSRV_BRIDGE_IN_MAP_ION_HANDLE_
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ IMG_HANDLE handle;
+ IMG_UINT32 ui32Attribs;
+ IMG_SIZE_T ui32Size;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hDevMemContext;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hDevMemContext;
+#endif
+} PVRSRV_BRIDGE_IN_MAP_ION_HANDLE;
+
+/******************************************************************************
+ * 'bridge in' unmap ion handle
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_UNMAP_ION_HANDLE_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+}PVRSRV_BRIDGE_IN_UNMAP_ION_HANDLE;
+
+/******************************************************************************
+ * 'bridge in' get free device memory
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ IMG_UINT32 ui32Flags;
+
+} PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM;
+
+/******************************************************************************
+ * 'bridge in' create Cmd Q
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_CREATECOMMANDQUEUE_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_SIZE_T ui32QueueSize;
+
+}PVRSRV_BRIDGE_IN_CREATECOMMANDQUEUE;
+
+
+/******************************************************************************
+ * 'bridge in' destroy Cmd Q
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_DESTROYCOMMANDQUEUE_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ PVRSRV_QUEUE_INFO *psQueueInfo;
+
+}PVRSRV_BRIDGE_IN_DESTROYCOMMANDQUEUE;
+
+
+/******************************************************************************
+ * 'bridge in' get full map data
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMHandle; /* Handle associated with the memory that needs to be mapped */
+#else
+ IMG_HANDLE hMHandle; /* Handle associated with the memory that needs to be mapped */
+#endif
+} PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA;
+
+
+/******************************************************************************
+ * 'bridge in' get full map data
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMHandle; /* Handle associated with the memory that needs to be mapped */
+#else
+ IMG_HANDLE hMHandle; /* Handle associated with the memory that needs to be mapped */
+#endif
+} PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA;
+
+
+/******************************************************************************
+ * 'bridge in' reserve vm
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_RESERVE_DEV_VIRTMEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemHeap;
+#else
+ IMG_HANDLE hDevMemHeap;
+#endif
+ IMG_DEV_VIRTADDR *psDevVAddr;
+ IMG_SIZE_T ui32Size;
+ IMG_SIZE_T ui32Alignment;
+
+}PVRSRV_BRIDGE_IN_RESERVE_DEV_VIRTMEM;
+
+/******************************************************************************
+ * 'bridge out' connect to services
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_CONNECT_SERVICES_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelServices;
+#else
+ IMG_HANDLE hKernelServices;
+#endif
+}PVRSRV_BRIDGE_OUT_CONNECT_SERVICES;
+
+/******************************************************************************
+ * 'bridge out' reserve vm
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_RESERVE_DEV_VIRTMEM_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+ IMG_SID hKernelSyncInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+
+}PVRSRV_BRIDGE_OUT_RESERVE_DEV_VIRTMEM;
+
+
+/******************************************************************************
+ * 'bridge in' free vm
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_FREE_DEV_VIRTMEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+
+}PVRSRV_BRIDGE_IN_FREE_DEV_VIRTMEM;
+
+
+/******************************************************************************
+ * 'bridge in' map dev memory allocation to another heap
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+ IMG_SID hDstDevMemHeap;
+#else
+ IMG_HANDLE hKernelMemInfo;
+ IMG_HANDLE hDstDevMemHeap;
+#endif
+
+}PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY;
+
+
+/******************************************************************************
+ * 'bridge out' map dev memory allocation to another heap
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDstKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psDstKernelMemInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO sDstClientMemInfo;
+ PVRSRV_CLIENT_SYNC_INFO sDstClientSyncInfo;
+
+}PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY;
+
+
+/******************************************************************************
+ * 'bridge in' unmap dev memory allocation
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+
+}PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY;
+
+
+/******************************************************************************
+ * 'bridge in' map pages
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_MAP_EXT_MEMORY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ IMG_SYS_PHYADDR *psSysPAddr;
+ IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_MAP_EXT_MEMORY;
+
+/******************************************************************************
+ * 'bridge in' unmap pages
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_UNMAP_EXT_MEMORY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+ IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_UNMAP_EXT_MEMORY;
+
+/******************************************************************************
+ * 'bridge in' map device class buffer pages
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceClassBuffer;
+ IMG_SID hDevMemContext;
+#else
+ IMG_HANDLE hDeviceClassBuffer;
+ IMG_HANDLE hDevMemContext;
+#endif
+
+}PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY;
+
+
+/******************************************************************************
+ * 'bridge out' map device class buffer pages
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY_TAG
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+ IMG_SID hMappingInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+ IMG_HANDLE hMappingInfo;
+#endif
+
+}PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY;
+
+
+/******************************************************************************
+ * 'bridge in' unmap device class buffer pages
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+
+}PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY;
+
+
+/******************************************************************************
+ * 'bridge in' pdump memory poll
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_MEMPOL_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ IMG_UINT32 ui32Offset;
+ IMG_UINT32 ui32Value;
+ IMG_UINT32 ui32Mask;
+ PDUMP_POLL_OPERATOR eOperator;
+ IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_MEMPOL;
+
+/******************************************************************************
+ * 'bridge in' pdump sync poll
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfo;
+#else
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+#endif
+ IMG_BOOL bIsRead;
+ IMG_BOOL bUseLastOpDumpVal;
+ IMG_UINT32 ui32Value;
+ IMG_UINT32 ui32Mask;
+
+}PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL;
+
+
+/******************************************************************************
+ * 'bridge in' pdump dump memory
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ IMG_PVOID pvLinAddr;
+ IMG_PVOID pvAltLinAddr;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ IMG_UINT32 ui32Offset;
+ IMG_UINT32 ui32Bytes;
+ IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM;
+
+
+/******************************************************************************
+ * 'bridge in' pdump dump sync
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ IMG_PVOID pvAltLinAddr;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfo;
+#else
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+#endif
+ IMG_UINT32 ui32Offset;
+ IMG_UINT32 ui32Bytes;
+
+}PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC;
+
+
+/******************************************************************************
+ * 'bridge in' pdump dump reg
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPREG_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ PVRSRV_HWREG sHWReg;
+ IMG_UINT32 ui32Flags;
+ IMG_CHAR szRegRegion[32];
+
+}PVRSRV_BRIDGE_IN_PDUMP_DUMPREG;
+
+/******************************************************************************
+ * 'bridge in' pdump dump reg
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_REGPOL_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ PVRSRV_HWREG sHWReg;
+ IMG_UINT32 ui32Mask;
+ IMG_UINT32 ui32Flags;
+ IMG_CHAR szRegRegion[32];
+}PVRSRV_BRIDGE_IN_PDUMP_REGPOL;
+
+/******************************************************************************
+ * 'bridge in' pdump dump PD reg
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPPDREG_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ PVRSRV_HWREG sHWReg;
+ IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_DUMPPDREG;
+
+/******************************************************************************
+ * 'bridge in' pdump dump mem pages
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_MEMPAGES_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hKernelMemInfo;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hKernelMemInfo;
+#endif
+ IMG_DEV_PHYADDR *pPages;
+ IMG_UINT32 ui32NumPages;
+ IMG_DEV_VIRTADDR sDevVAddr;
+ IMG_UINT32 ui32Start;
+ IMG_UINT32 ui32Length;
+ IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_MEMPAGES;
+
+/******************************************************************************
+ * 'bridge in' pdump dump comment
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_COMMENT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ IMG_CHAR szComment[PVRSRV_PDUMP_MAX_COMMENT_SIZE];
+ IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_COMMENT;
+
+
+/******************************************************************************
+ * 'bridge in' pdump set frame
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_SETFRAME_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ IMG_UINT32 ui32Frame;
+
+}PVRSRV_BRIDGE_IN_PDUMP_SETFRAME;
+
+
+/******************************************************************************
+ * 'bridge in' pdump dump bitmap
+ *****************************************************************************/
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_BITMAP_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE];
+ IMG_UINT32 ui32FileOffset;
+ IMG_UINT32 ui32Width;
+ IMG_UINT32 ui32Height;
+ IMG_UINT32 ui32StrideInBytes;
+ IMG_DEV_VIRTADDR sDevBaseAddr;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemContext;
+#else
+ IMG_HANDLE hDevMemContext;
+#endif
+ IMG_UINT32 ui32Size;
+ PDUMP_PIXEL_FORMAT ePixelFormat;
+ PDUMP_MEM_FORMAT eMemFormat;
+ IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_BITMAP;
+
+
+/******************************************************************************
+ * 'bridge in' pdump dump read reg
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_READREG_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE];
+ IMG_UINT32 ui32FileOffset;
+ IMG_UINT32 ui32Address;
+ IMG_UINT32 ui32Size;
+ IMG_UINT32 ui32Flags;
+ IMG_CHAR szRegRegion[32];
+
+}PVRSRV_BRIDGE_IN_PDUMP_READREG;
+
+/******************************************************************************
+ * 'bridge in' pdump dump driver-info
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ 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; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ IMG_HANDLE hKernelMemInfo;
+#endif
+ IMG_UINT32 ui32Offset;
+ IMG_DEV_PHYADDR sPDDevPAddr;
+}PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR;
+
+/******************************************************************************
+ * 'bridge in' pdump cycle count register read
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_PDUM_IN_CYCLE_COUNT_REG_READ_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_UINT32 ui32RegOffset;
+ IMG_BOOL bLastFrame;
+}PVRSRV_BRIDGE_IN_PDUMP_CYCLE_COUNT_REG_READ;
+
+/*****************************************************************************
+ * Output structures for BRIDGEs
+ ****************************************************************************/
+
+/******************************************************************************
+ * 'bridge out' enum. devices
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_ENUMDEVICE_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32NumDevices;
+ PVRSRV_DEVICE_IDENTIFIER asDeviceIdentifier[PVRSRV_MAX_DEVICES];
+
+}PVRSRV_BRIDGE_OUT_ENUMDEVICE;
+
+
+/******************************************************************************
+ * 'bridge out' acquire device info
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO_TAG
+{
+
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+
+} PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO;
+
+
+/******************************************************************************
+ * 'bridge out' enum. class devices
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_ENUMCLASS_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32NumDevices;
+ IMG_UINT32 ui32DevID[PVRSRV_MAX_DEVICES];
+
+}PVRSRV_BRIDGE_OUT_ENUMCLASS;
+
+
+/******************************************************************************
+ * 'bridge in' open display class devices
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ IMG_UINT32 ui32DeviceID;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+
+}PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE;
+
+/******************************************************************************
+ * 'bridge out' open display class devices
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+
+}PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE;
+
+
+/******************************************************************************
+ * 'bridge in' wrap pages
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hDevMemContext;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hDevMemContext;
+#endif
+ IMG_VOID *pvLinAddr;
+ IMG_SIZE_T ui32ByteSize;
+ IMG_SIZE_T ui32PageOffset;
+ IMG_BOOL bPhysContig;
+ IMG_UINT32 ui32NumPageTableEntries;
+ IMG_SYS_PHYADDR *psSysPAddr;
+ IMG_UINT32 ui32Flags;
+
+}PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY;
+
+/******************************************************************************
+ * 'bridge out' wrap pages
+ *****************************************************************************/
+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;
+
+/******************************************************************************
+ * 'bridge in' unwrap pages
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ IMG_HANDLE hKernelMemInfo;
+#endif
+ 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
+
+/******************************************************************************
+ * 'bridge out' enum display class formats
+ *****************************************************************************/
+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;
+
+
+/******************************************************************************
+ * 'bridge in' enum display class dims
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+ DISPLAY_FORMAT sFormat;
+
+}PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS;
+
+
+/******************************************************************************
+ * 'bridge out' enum display class 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;
+
+
+/******************************************************************************
+ * 'bridge out' enum display class dims
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO_TAG
+{
+ PVRSRV_ERROR eError;
+ DISPLAY_INFO sDisplayInfo;
+
+}PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO;
+
+
+/******************************************************************************
+ * 'bridge out' get display class system buffer
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hBuffer;
+#else
+ IMG_HANDLE hBuffer;
+#endif
+
+}PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER;
+
+
+/******************************************************************************
+ * 'bridge in' create swap chain
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+ 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;
+
+
+/******************************************************************************
+ * 'bridge out' create swap chain
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSwapChain;
+#else
+ IMG_HANDLE hSwapChain;
+#endif
+ IMG_UINT32 ui32SwapChainID;
+
+} PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN;
+
+
+/******************************************************************************
+ * 'bridge in' destroy swap chain
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+ IMG_SID hSwapChain;
+#else
+ IMG_HANDLE hDeviceKM;
+ IMG_HANDLE hSwapChain;
+#endif
+
+} PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN;
+
+
+/******************************************************************************
+ * 'bridge in' set DST/SRC rect
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+ IMG_SID hSwapChain;
+#else
+ IMG_HANDLE hDeviceKM;
+ IMG_HANDLE hSwapChain;
+#endif
+ IMG_RECT sRect;
+
+} PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT;
+
+
+/******************************************************************************
+ * 'bridge in' set DST/SRC colourkey
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+ IMG_SID hSwapChain;
+#else
+ IMG_HANDLE hDeviceKM;
+ IMG_HANDLE hSwapChain;
+#endif
+ IMG_UINT32 ui32CKColour;
+
+} PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY;
+
+
+/******************************************************************************
+ * 'bridge in' get buffers (from swapchain)
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+ IMG_SID hSwapChain;
+#else
+ IMG_HANDLE hDeviceKM;
+ IMG_HANDLE hSwapChain;
+#endif
+
+} PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS;
+
+
+/******************************************************************************
+ * 'bridge out' get buffers (from swapchain)
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32BufferCount;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID ahBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
+#else
+ IMG_HANDLE ahBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
+#endif
+ IMG_SYS_PHYADDR asPhyAddr[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
+} PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS;
+
+
+/******************************************************************************
+ * 'bridge in' swap to buffer
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+ IMG_SID hBuffer;
+#else
+ IMG_HANDLE hDeviceKM;
+ IMG_HANDLE hBuffer;
+#endif
+ IMG_UINT32 ui32SwapInterval;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hPrivateTag;
+#else
+ IMG_HANDLE hPrivateTag;
+#endif
+ IMG_UINT32 ui32ClipRectCount;
+ IMG_RECT sClipRect[PVRSRV_MAX_DC_CLIP_RECTS];
+
+} PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER;
+
+/******************************************************************************
+ * 'bridge in' swap to buffer
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER2_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+ IMG_SID hSwapChain;
+#else
+ IMG_HANDLE hDeviceKM;
+ IMG_HANDLE hSwapChain;
+#endif
+ IMG_UINT32 ui32SwapInterval;
+
+ IMG_UINT32 ui32NumMemInfos;
+ PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfos;
+ PVRSRV_KERNEL_SYNC_INFO **ppsKernelSyncInfos;
+
+ IMG_UINT32 ui32PrivDataLength;
+ IMG_PVOID pvPrivData;
+
+} PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER2;
+
+/******************************************************************************
+ * 'bridge in' swap to system buffer (primary)
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+ IMG_SID hSwapChain;
+#else
+ IMG_HANDLE hDeviceKM;
+ IMG_HANDLE hSwapChain;
+#endif
+
+} PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM;
+
+
+/******************************************************************************
+ * 'bridge in' open buffer class device
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ IMG_UINT32 ui32DeviceID;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+
+} PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE;
+
+
+/******************************************************************************
+ * 'bridge out' open buffer class device
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+
+} PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE;
+
+
+/******************************************************************************
+ * 'bridge out' get buffer class info
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO_TAG
+{
+ PVRSRV_ERROR eError;
+ BUFFER_INFO sBufferInfo;
+
+} PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO;
+
+
+/******************************************************************************
+ * 'bridge in' get buffer class buffer
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+ IMG_UINT32 ui32BufferIndex;
+
+} PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER;
+
+
+/******************************************************************************
+ * 'bridge out' get buffer class buffer
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hBuffer;
+#else
+ IMG_HANDLE hBuffer;
+#endif
+
+} PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER;
+
+
+/******************************************************************************
+ * 'bridge out' get heap info
+ *****************************************************************************/
+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;
+
+
+/******************************************************************************
+ * 'bridge out' create device memory context
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemContext;
+#else
+ IMG_HANDLE hDevMemContext;
+#endif
+ IMG_UINT32 ui32ClientHeapCount;
+ PVRSRV_HEAP_INFO sHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
+
+} PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT;
+
+
+/******************************************************************************
+ * 'bridge out' create device memory context
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_CREATE_DEVMEMHEAP_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemHeap;
+#else
+ IMG_HANDLE hDevMemHeap;
+#endif
+
+} PVRSRV_BRIDGE_OUT_CREATE_DEVMEMHEAP;
+
+
+/******************************************************************************
+ * 'bridge out' alloc device memory
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+
+} PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM;
+
+
+/******************************************************************************
+ * 'bridge out' export device memory
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMemInfo;
+#else
+ IMG_HANDLE hMemInfo;
+#endif
+#if defined(SUPPORT_MEMINFO_IDS)
+ IMG_UINT64 ui64Stamp;
+#endif
+
+} PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM;
+
+
+/******************************************************************************
+ * 'bridge out' map ion handle
+ *****************************************************************************/
+typedef struct _PVRSRV_BRIDGE_OUT_MAP_ION_HANDLE_
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo;
+
+} PVRSRV_BRIDGE_OUT_MAP_ION_HANDLE;
+
+
+/******************************************************************************
+ * 'bridge out' map meminfo to user mode
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_MAPMEMINFOTOUSER_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_PVOID pvLinAddr;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMappingInfo;
+#else
+ IMG_HANDLE hMappingInfo;
+#endif
+
+}PVRSRV_BRIDGE_OUT_MAPMEMINFOTOUSER;
+
+
+/******************************************************************************
+ * 'bridge out' get free device memory
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_SIZE_T ui32Total;
+ IMG_SIZE_T ui32Free;
+ IMG_SIZE_T ui32LargestBlock;
+
+} PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM;
+
+
+//#ifdef LINUX
+/******************************************************************************
+ * 'bridge out' get full map data
+ *****************************************************************************/
+#include "pvrmmap.h"
+typedef struct PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA_TAG
+{
+ PVRSRV_ERROR eError;
+
+ /* This is a the offset you should pass to mmap(2) so that
+ * the driver can look up the full details for the mapping
+ * request. */
+ IMG_UINT32 ui32MMapOffset;
+
+ /* This is the byte offset you should add to the mapping you
+ * get from mmap */
+ IMG_UINT32 ui32ByteOffset;
+
+ /* This is the real size of the mapping that will be created
+ * which should be passed to mmap _and_ munmap. */
+ IMG_UINT32 ui32RealByteSize;
+
+ /* User mode address associated with mapping */
+ IMG_UINT32 ui32UserVAddr;
+
+} PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA;
+
+typedef struct PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA_TAG
+{
+ PVRSRV_ERROR eError;
+
+ /* Flag that indicates whether the mapping should be destroyed */
+ IMG_BOOL bMUnmap;
+
+ /* User mode address associated with mapping */
+ IMG_UINT32 ui32UserVAddr;
+
+ /* Size of mapping */
+ IMG_UINT32 ui32RealByteSize;
+} PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA;
+//#endif
+
+
+/******************************************************************************
+ * 'bridge in' get misc info
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_GET_MISC_INFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ PVRSRV_MISC_INFO sMiscInfo;
+
+}PVRSRV_BRIDGE_IN_GET_MISC_INFO;
+
+
+/******************************************************************************
+ * 'bridge out' 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;
+
+
+/******************************************************************************
+ * 'bridge in' get misc info
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_RELEASE_MISC_INFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ PVRSRV_MISC_INFO sMiscInfo;
+
+}PVRSRV_BRIDGE_IN_RELEASE_MISC_INFO;
+
+
+/******************************************************************************
+ * 'bridge out' get misc info
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_RELEASE_MISC_INFO_TAG
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_MISC_INFO sMiscInfo;
+
+}PVRSRV_BRIDGE_OUT_RELEASE_MISC_INFO;
+
+
+/******************************************************************************
+ * 'bridge out' PDUMP is capturing
+ *****************************************************************************/
+
+typedef struct PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_BOOL bIsCapturing;
+
+} PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING;
+
+/******************************************************************************
+ * 'bridge in' get FB mem stats
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_GET_FB_STATS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ IMG_SIZE_T ui32Total;
+ IMG_SIZE_T ui32Available;
+
+} PVRSRV_BRIDGE_IN_GET_FB_STATS;
+
+
+/******************************************************************************
+ * 'bridge in' Map CPU Physical to User Space
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_MAPPHYSTOUSERSPACE_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_SYS_PHYADDR sSysPhysAddr;
+ IMG_UINT32 uiSizeInBytes;
+
+} PVRSRV_BRIDGE_IN_MAPPHYSTOUSERSPACE;
+
+
+/******************************************************************************
+ * 'bridge out' Map CPU Physical to User Space
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_MAPPHYSTOUSERSPACE_TAG
+{
+ IMG_PVOID pvUserAddr;
+ IMG_UINT32 uiActualSize;
+ IMG_PVOID pvProcess;
+
+} PVRSRV_BRIDGE_OUT_MAPPHYSTOUSERSPACE;
+
+
+/******************************************************************************
+ * 'bridge in' Unmap CPU Physical to User Space
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_UNMAPPHYSTOUSERSPACE_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_PVOID pvUserAddr;
+ IMG_PVOID pvProcess;
+
+} PVRSRV_BRIDGE_IN_UNMAPPHYSTOUSERSPACE;
+
+
+/******************************************************************************
+ * 'bridge out' Get user space pointer to Phys to Lin lookup table
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_GETPHYSTOUSERSPACEMAP_TAG
+{
+ IMG_PVOID *ppvTbl;
+ IMG_UINT32 uiTblSize;
+
+} PVRSRV_BRIDGE_OUT_GETPHYSTOUSERSPACEMAP;
+
+
+#if !defined (SUPPORT_SID_INTERFACE)
+/******************************************************************************
+ * 'bridge in' Register RTSIM process thread
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_REGISTER_SIM_PROCESS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ IMG_HANDLE hDevCookie;
+ IMG_PVOID pvProcess;
+
+} PVRSRV_BRIDGE_IN_REGISTER_SIM_PROCESS;
+
+
+/******************************************************************************
+ * 'bridge out' Register RTSIM process thread
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_REGISTER_SIM_PROCESS_TAG
+{
+ IMG_SYS_PHYADDR sRegsPhysBase; /*!< Physical address of current device register */
+ IMG_VOID *pvRegsBase; /*!< User mode linear address of SGX device registers */
+ IMG_PVOID pvProcess;
+ IMG_UINT32 ulNoOfEntries;
+ IMG_PVOID pvTblLinAddr;
+
+} PVRSRV_BRIDGE_OUT_REGISTER_SIM_PROCESS;
+
+
+/******************************************************************************
+ * 'bridge in' Unregister RTSIM process thread
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_UNREGISTER_SIM_PROCESS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ IMG_HANDLE hDevCookie;
+ IMG_PVOID pvProcess;
+ IMG_VOID *pvRegsBase; /*!< User mode linear address of SGX device registers */
+
+} PVRSRV_BRIDGE_IN_UNREGISTER_SIM_PROCESS;
+
+/******************************************************************************
+ * 'bridge in' process simulator ISR event
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_PROCESS_SIMISR_EVENT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ IMG_HANDLE hDevCookie;
+ IMG_UINT32 ui32StatusAndMask;
+ PVRSRV_ERROR eError;
+
+} PVRSRV_BRIDGE_IN_PROCESS_SIMISR_EVENT;
+#endif /* #if !defined (SUPPORT_SID_INTERFACE) */
+
+/******************************************************************************
+ * 'bridge in' initialisation server disconnect
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ IMG_BOOL bInitSuccesful;
+} PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT;
+
+
+typedef struct PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ IMG_UINT32 ui32Flags;
+ IMG_SIZE_T ui32Size;
+}PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM;
+
+typedef struct PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo;
+}PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM;
+
+typedef struct PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM_TAG
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+ IMG_SID hMappingInfo;
+#else
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ 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; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ IMG_HANDLE hKernelMemInfo;
+#endif
+}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;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+ PVRSRV_ERROR eError;
+}PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM;
+
+typedef struct PVRSRV_BRIDGE_IN_UNMAP_MEMINFO_MEM_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ 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_EVENT_OBJECT_WAI_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hOSEventKM;
+#else
+ IMG_HANDLE hOSEventKM;
+#endif
+} 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
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_UINT32 hOSEvent;
+#else
+ IMG_HANDLE hOSEvent;
+#endif
+ PVRSRV_ERROR eError;
+} PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN;
+
+typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE_TAG
+{
+ PVRSRV_EVENTOBJECT sEventObject;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hOSEventKM;
+#else
+ IMG_HANDLE hOSEventKM;
+#endif
+} PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE;
+
+typedef struct PVRSRV_BRIDGE_OUT_CREATE_SYNC_INFO_MOD_OBJ_TAG
+{
+ PVRSRV_ERROR eError;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfoModObj;
+#else
+ IMG_HANDLE hKernelSyncInfoModObj;
+#endif
+
+} PVRSRV_BRIDGE_OUT_CREATE_SYNC_INFO_MOD_OBJ;
+
+typedef struct PVRSRV_BRIDGE_IN_DESTROY_SYNC_INFO_MOD_OBJ
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfoModObj;
+#else
+ IMG_HANDLE hKernelSyncInfoModObj;
+#endif
+} PVRSRV_BRIDGE_IN_DESTROY_SYNC_INFO_MOD_OBJ;
+
+typedef struct PVRSRV_BRIDGE_IN_MODIFY_PENDING_SYNC_OPS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfoModObj;
+ IMG_SID hKernelSyncInfo;
+#else
+ IMG_HANDLE hKernelSyncInfoModObj;
+ IMG_HANDLE hKernelSyncInfo;
+#endif
+ IMG_UINT32 ui32ModifyFlags;
+
+} PVRSRV_BRIDGE_IN_MODIFY_PENDING_SYNC_OPS;
+
+typedef struct PVRSRV_BRIDGE_IN_MODIFY_COMPLETE_SYNC_OPS_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfoModObj;
+#else
+ IMG_HANDLE hKernelSyncInfoModObj;
+#endif
+} PVRSRV_BRIDGE_IN_MODIFY_COMPLETE_SYNC_OPS;
+
+typedef struct PVRSRV_BRIDGE_OUT_MODIFY_PENDING_SYNC_OPS_TAG
+{
+ PVRSRV_ERROR eError;
+
+ /* The following variable are used to return the PRE-INCREMENTED op vals */
+ IMG_UINT32 ui32ReadOpsPending;
+ IMG_UINT32 ui32WriteOpsPending;
+ IMG_UINT32 ui32ReadOps2Pending;
+
+} PVRSRV_BRIDGE_OUT_MODIFY_PENDING_SYNC_OPS;
+
+typedef struct PVRSRV_BRIDGE_IN_SYNC_OPS_TAKE_TOKEN_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfo;
+#else
+ IMG_HANDLE hKernelSyncInfo;
+#endif
+
+} PVRSRV_BRIDGE_IN_SYNC_OPS_TAKE_TOKEN;
+
+typedef struct PVRSRV_BRIDGE_OUT_SYNC_OPS_TAKE_TOKEN_TAG
+{
+ PVRSRV_ERROR eError;
+
+ IMG_UINT32 ui32ReadOpsPending;
+ IMG_UINT32 ui32WriteOpsPending;
+ IMG_UINT32 ui32ReadOps2Pending;
+
+} PVRSRV_BRIDGE_OUT_SYNC_OPS_TAKE_TOKEN;
+
+typedef struct PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_TOKEN_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfo;
+#else
+ IMG_HANDLE hKernelSyncInfo;
+#endif
+ IMG_UINT32 ui32ReadOpsPendingSnapshot;
+ IMG_UINT32 ui32WriteOpsPendingSnapshot;
+ IMG_UINT32 ui32ReadOps2PendingSnapshot;
+} PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_TOKEN;
+
+typedef struct PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_MOD_OBJ_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfoModObj;
+#else
+ IMG_HANDLE hKernelSyncInfoModObj;
+#endif
+} PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_MOD_OBJ;
+
+typedef struct PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_DELTA_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfo;
+#else
+ IMG_HANDLE hKernelSyncInfo;
+#endif
+ IMG_UINT32 ui32Delta;
+} PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_DELTA;
+
+typedef struct PVRSRV_BRIDGE_IN_ALLOC_SYNC_INFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+} PVRSRV_BRIDGE_IN_ALLOC_SYNC_INFO;
+
+typedef struct PVRSRV_BRIDGE_OUT_ALLOC_SYNC_INFO_TAG
+{
+ PVRSRV_ERROR eError;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfo;
+#else
+ IMG_HANDLE hKernelSyncInfo;
+#endif
+} PVRSRV_BRIDGE_OUT_ALLOC_SYNC_INFO;
+
+typedef struct PVRSRV_BRIDGE_IN_FREE_SYNC_INFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelSyncInfo;
+#else
+ IMG_HANDLE hKernelSyncInfo;
+#endif
+} PVRSRV_BRIDGE_IN_FREE_SYNC_INFO;
+
+typedef struct PVRSRV_BRIDGE_IN_CHG_DEV_MEM_ATTRIBS_TAG
+{
+ IMG_SID hKernelMemInfo;
+ IMG_UINT32 ui32Attribs;
+} PVRSRV_BRIDGE_IN_CHG_DEV_MEM_ATTRIBS;
+
+/******************************************************************************
+ * 'bridge in' multi manage device memory
+ *****************************************************************************/
+typedef PVRSRV_MULTI_MANAGE_DEV_MEM_REQUESTS PVRSRV_BRIDGE_IN_MULTI_MANAGE_DEV_MEM;
+
+/******************************************************************************
+ * 'bridge out' multi manage device memory
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_MULTI_MANAGE_DEV_MEM_TAG
+{
+ IMG_UINT32 ui32NumberOfRequestsProcessed;
+ IMG_UINT32 ui32CtrlFlags;
+ IMG_UINT32 ui32StatusFlags;
+ IMG_UINT32 ui32IndexError;
+ PVRSRV_ERROR eError;
+ /* Memory Requests Array - used only with direct (not memory shared( mode */
+ PVRSRV_MANAGE_DEV_MEM_RESPONSE sMemResponse[PVRSRV_MULTI_MANAGE_DEV_MEM_MAX_DIRECT_SIZE];
+}PVRSRV_BRIDGE_OUT_MULTI_MANAGE_DEV_MEM;
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* __PVR_BRIDGE_H__ */
+
+/******************************************************************************
+ End of file (pvr_bridge.h)
+******************************************************************************/
+
diff --git a/pvr-source/services4/include/pvr_bridge_km.h b/pvr-source/services4/include/pvr_bridge_km.h
new file mode 100644
index 0000000..1bf5b9c
--- /dev/null
+++ b/pvr-source/services4/include/pvr_bridge_km.h
@@ -0,0 +1,409 @@
+/*************************************************************************/ /*!
+@Title PVR Bridge Functionality
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Header for the PVR Bridge code
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __PVR_BRIDGE_KM_H_
+#define __PVR_BRIDGE_KM_H_
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "pvr_bridge.h"
+#include "perproc.h"
+
+/******************************************************************************
+ * Function prototypes
+ *****************************************************************************/
+#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_SIZE_T 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_HEAP_INFO_KM *psHeapInfo);
+#else
+ PVRSRV_HEAP_INFO *psHeapInfo);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContextKM(IMG_HANDLE hDevCookie,
+ PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE *phDevMemContext,
+ IMG_UINT32 *pui32ClientHeapCount,
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_HEAP_INFO_KM *psHeapInfo,
+#else
+ PVRSRV_HEAP_INFO *psHeapInfo,
+#endif
+ IMG_BOOL *pbCreated,
+ IMG_BOOL *pbShared);
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContextKM(IMG_HANDLE hDevCookie,
+ IMG_HANDLE hDevMemContext,
+ IMG_BOOL *pbDestroyed);
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfoKM(IMG_HANDLE hDevCookie,
+ IMG_HANDLE hDevMemContext,
+ IMG_UINT32 *pui32ClientHeapCount,
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_HEAP_INFO_KM *psHeapInfo,
+#else
+ PVRSRV_HEAP_INFO *psHeapInfo,
+#endif
+ 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_SIZE_T ui32Size,
+ IMG_SIZE_T ui32Alignment,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_UINT32 ui32ChunkSize,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_BOOL *pabMapChunk,
+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo);
+
+
+#if defined(PVRSRV_LOG_MEMORY_ALLOCS)
+ #define PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, privdata, privdatalength, \
+ chunksize, numvirtchunks, numphyschunks, mapchunk, memInfo, logStr) \
+ (PVR_TRACE(("PVRSRVAllocDeviceMemKM(" #devCookie ", " #perProc ", " #devMemHeap ", " #flags ", " #size \
+ ", " #alignment "," #memInfo "): " logStr " (size = 0x%x)", size)),\
+ _PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, privdata, privdatalength, \
+ chunksize, numvirtchunks, numphyschunks, mapchunk, memInfo))
+#else
+ #define PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, privdata, privdatalength, \
+ chunksize, numvirtchunks, numphyschunks, mapchunk, memInfo, logStr) \
+ _PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, privdata, privdatalength, \
+ chunksize, numvirtchunks, numphyschunks, mapchunk, memInfo)
+#endif
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMemKM(IMG_HANDLE hDevCookie,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo);
+
+IMG_EXPORT
+IMG_INT32 IMG_CALLCONV PVRSRVRemapToDevKM(IMG_HANDLE hDevCookie,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo, IMG_DEV_VIRTADDR *psDevVAddr);
+
+IMG_EXPORT
+IMG_INT32 IMG_CALLCONV PVRSRVUnmapFromDevKM(IMG_HANDLE hDevCookie,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo);
+
+
+#if defined(SUPPORT_ION)
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVMapIonHandleKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE hDevCookie,
+ IMG_HANDLE hDevMemContext,
+ IMG_HANDLE hIon,
+ IMG_UINT32 ui32Flags,
+ IMG_UINT32 ui32Size,
+ PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapIonHandleKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
+#endif /* SUPPORT_ION */
+
+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_SIZE_T ui32Size,
+ IMG_SIZE_T 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_SIZE_T ui32ByteSize,
+ IMG_SIZE_T ui32PageOffset,
+ IMG_BOOL bPhysContig,
+ IMG_SYS_PHYADDR *psSysAddr,
+ IMG_VOID *pvLinAddr,
+ IMG_UINT32 ui32Flags,
+ 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_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_SYS_PHYADDR *psPhyAddr);
+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 PVRSRVSwapToDCBuffer2KM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hBuffer,
+ IMG_UINT32 ui32SwapInterval,
+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfos,
+ PVRSRV_KERNEL_SYNC_INFO **ppsSyncInfos,
+ IMG_UINT32 ui32NumMemSyncInfos,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength);
+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_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_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVChangeDeviceMemoryAttributesKM(IMG_HANDLE hKernelMemInfo,
+ IMG_UINT32 ui32Attribs);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetFreeDeviceMemKM(IMG_UINT32 ui32Flags,
+ IMG_SIZE_T *pui32Total,
+ IMG_SIZE_T *pui32Free,
+ IMG_SIZE_T *pui32LargestBlock);
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE hDevCookie,
+ IMG_HANDLE hDevMemContext,
+ PVRSRV_KERNEL_SYNC_INFO **ppsKernelSyncInfo);
+IMG_IMPORT
+IMG_VOID IMG_CALLCONV PVRSRVAcquireSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo);
+IMG_IMPORT
+IMG_VOID IMG_CALLCONV PVRSRVReleaseSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo);
+
+IMG_IMPORT
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO_KM *psMiscInfo);
+#else
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo);
+#endif
+
+/*!
+ * *****************************************************************************
+ * @brief Allocates memory on behalf of a userspace process that is addressable
+ * by ther kernel. The memory is suitable for mapping into
+ * user space and it is possible to entirely dissociate the memory
+ * from the userspace process via PVRSRVDissociateSharedSysMemoryKM.
+ *
+ * @param psPerProc
+ * @param ui32Flags
+ * @param ui32Size
+ * @param ppsKernelMemInfo
+ *
+ * @return PVRSRV_ERROR
+ ********************************************************************************/
+IMG_IMPORT PVRSRV_ERROR
+PVRSRVAllocSharedSysMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_UINT32 ui32Flags,
+ IMG_SIZE_T ui32Size,
+ PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo);
+
+/*!
+ * *****************************************************************************
+ * @brief Frees memory allocated via PVRSRVAllocSharedSysMemoryKM (Note you must
+ * be sure any additional kernel references you created have been
+ * removed before freeing the memory)
+ *
+ * @param psKernelMemInfo
+ *
+ * @return PVRSRV_ERROR
+ ********************************************************************************/
+IMG_IMPORT PVRSRV_ERROR
+PVRSRVFreeSharedSysMemoryKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
+
+/*!
+******************************************************************************
+
+ @brief Dissociates memory from the process that allocates it. Intended for
+ transfering the ownership of system memory from a particular process
+ to the kernel. Unlike PVRSRVDissociateDeviceMemKM, ownership is not
+ transfered to the kernel context, so the Resource Manager will not
+ automatically clean up such memory.
+
+ @param psKernelMemInfo:
+
+ @return PVRSRV_ERROR:
+******************************************************************************/
+IMG_IMPORT PVRSRV_ERROR
+PVRSRVDissociateMemFromResmanKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* __PVR_BRIDGE_KM_H_ */
+
+/******************************************************************************
+ End of file (pvr_bridge_km.h)
+******************************************************************************/
diff --git a/pvr-source/services4/include/pvrmmap.h b/pvr-source/services4/include/pvrmmap.h
new file mode 100644
index 0000000..1a3930c
--- /dev/null
+++ b/pvr-source/services4/include/pvrmmap.h
@@ -0,0 +1,81 @@
+/*************************************************************************/ /*!
+@Title Main include file for PVRMMAP library.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef __PVRMMAP_H__
+#define __PVRMMAP_H__
+
+/*!
+ **************************************************************************
+ @brief map kernel memory into user memory.
+
+ @param hModule - a handle to the device supplying the kernel memory
+ @param ppvLinAddr - pointer to where the user mode address should be placed
+ @param pvLinAddrKM - the base of kernel address range to map
+ @param phMappingInfo - pointer to mapping information handle
+ @param hMHandle - handle associated with memory to be mapped
+
+ @return PVRSRV_OK, or error code.
+ ***************************************************************************/
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRPMapKMem(IMG_HANDLE hModule, IMG_VOID **ppvLinAddr, IMG_VOID *pvLinAddrKM, IMG_SID *phMappingInfo, IMG_SID hMHandle);
+#else
+PVRSRV_ERROR PVRPMapKMem(IMG_HANDLE hModule, IMG_VOID **ppvLinAddr, IMG_VOID *pvLinAddrKM, IMG_HANDLE *phMappingInfo, IMG_HANDLE hMHandle);
+#endif
+
+
+/*!
+ **************************************************************************
+ @brief Removes a kernel to userspace memory mapping.
+
+ @param hModule - a handle to the device supplying the kernel memory
+ @param hMappingInfo - mapping information handle
+ @param hMHandle - handle associated with memory to be mapped
+
+ @return IMG_BOOL indicating success or otherwise.
+ ***************************************************************************/
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_BOOL PVRUnMapKMem(IMG_HANDLE hModule, IMG_SID hMappingInfo, IMG_SID hMHandle);
+#else
+IMG_BOOL PVRUnMapKMem(IMG_HANDLE hModule, IMG_HANDLE hMappingInfo, IMG_HANDLE hMHandle);
+#endif
+
+#endif /* _PVRMMAP_H_ */
+
diff --git a/pvr-source/services4/include/pvrsrv_errors.h b/pvr-source/services4/include/pvrsrv_errors.h
new file mode 100644
index 0000000..2e95810
--- /dev/null
+++ b/pvr-source/services4/include/pvrsrv_errors.h
@@ -0,0 +1,311 @@
+/*************************************************************************/ /*!
+@Title error code to string translation utility
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description error code to string translation utility
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined (__PVRSRV_ERRORS_H__)
+#define __PVRSRV_ERRORS_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/*
+ NOTE: TO BE INCLUDED ONLY ONCE IN THE UM AND KM SERVICES MODULES
+ PROVIDES IMPLEMENTATIONS OF
+
+ MUST BE KEPT IN SYNC WITH SERVICESEXT.H
+
+ PVRSRVGetErrorString
+ PVRSRVGetErrorStringKM
+ Specifically, we have
+
+ resources.c:
+ IMG_EXPORT
+ const IMG_CHAR *PVRSRVGetErrorString(PVRSRV_ERROR eError)
+ {
+ #include "pvrsrv_errors.h"
+ }
+
+ pvrsrv.c:
+ IMG_EXPORT
+ const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError)
+ {
+ #include "pvrsrv_errors.h"
+ }
+*/
+ switch (eError)
+ {
+ case PVRSRV_OK: return "No Errors";
+ case PVRSRV_ERROR_OUT_OF_MEMORY: return "PVRSRV_ERROR_OUT_OF_MEMORY - Unable to allocate required memory";
+ case PVRSRV_ERROR_TOO_FEW_BUFFERS: return "PVRSRV_ERROR_TOO_FEW_BUFFERS";
+ case PVRSRV_ERROR_INVALID_PARAMS: return "PVRSRV_ERROR_INVALID_PARAMS";
+ case PVRSRV_ERROR_INIT_FAILURE: return "PVRSRV_ERROR_INIT_FAILURE";
+ case PVRSRV_ERROR_CANT_REGISTER_CALLBACK: return "PVRSRV_ERROR_CANT_REGISTER_CALLBACK";
+ case PVRSRV_ERROR_INVALID_DEVICE: return "PVRSRV_ERROR_INVALID_DEVICE";
+ case PVRSRV_ERROR_NOT_OWNER: return "PVRSRV_ERROR_NOT_OWNER";
+ case PVRSRV_ERROR_BAD_MAPPING: return "PVRSRV_ERROR_BAD_MAPPING";
+ case PVRSRV_ERROR_TIMEOUT: return "PVRSRV_ERROR_TIMEOUT";
+ case PVRSRV_ERROR_FLIP_CHAIN_EXISTS: return "PVRSRV_ERROR_FLIP_CHAIN_EXISTS";
+ case PVRSRV_ERROR_INVALID_SWAPINTERVAL: return "PVRSRV_ERROR_INVALID_SWAPINTERVAL";
+ case PVRSRV_ERROR_SCENE_INVALID: return "PVRSRV_ERROR_SCENE_INVALID";
+ case PVRSRV_ERROR_STREAM_ERROR: return "PVRSRV_ERROR_STREAM_ERROR";
+ case PVRSRV_ERROR_FAILED_DEPENDENCIES: return "PVRSRV_ERROR_FAILED_DEPENDENCIES";
+ case PVRSRV_ERROR_CMD_NOT_PROCESSED: return "PVRSRV_ERROR_CMD_NOT_PROCESSED";
+ case PVRSRV_ERROR_CMD_TOO_BIG: return "PVRSRV_ERROR_CMD_TOO_BIG";
+ case PVRSRV_ERROR_DEVICE_REGISTER_FAILED: return "PVRSRV_ERROR_DEVICE_REGISTER_FAILED";
+ case PVRSRV_ERROR_TOOMANYBUFFERS: return "PVRSRV_ERROR_TOOMANYBUFFERS";
+ case PVRSRV_ERROR_NOT_SUPPORTED: return "PVRSRV_ERROR_NOT_SUPPORTED - fix";
+ case PVRSRV_ERROR_PROCESSING_BLOCKED: return "PVRSRV_ERROR_PROCESSING_BLOCKED";
+
+ case PVRSRV_ERROR_CANNOT_FLUSH_QUEUE: return "PVRSRV_ERROR_CANNOT_FLUSH_QUEUE";
+ case PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE: return "PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE";
+ case PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS: return "PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS";
+ case PVRSRV_ERROR_RETRY: return "PVRSRV_ERROR_RETRY";
+
+ case PVRSRV_ERROR_DDK_VERSION_MISMATCH: return "PVRSRV_ERROR_DDK_VERSION_MISMATCH";
+ case PVRSRV_ERROR_BUILD_MISMATCH: return "PVRSRV_ERROR_BUILD_MISMATCH";
+ case PVRSRV_ERROR_CORE_REVISION_MISMATCH: return "PVRSRV_ERROR_CORE_REVISION_MISMATCH";
+
+ case PVRSRV_ERROR_UPLOAD_TOO_BIG: return "PVRSRV_ERROR_UPLOAD_TOO_BIG";
+
+ case PVRSRV_ERROR_INVALID_FLAGS: return "PVRSRV_ERROR_INVALID_FLAGS";
+ case PVRSRV_ERROR_FAILED_TO_REGISTER_PROCESS: return "PVRSRV_ERROR_FAILED_TO_REGISTER_PROCESS";
+
+ case PVRSRV_ERROR_UNABLE_TO_LOAD_LIBRARY: return "PVRSRV_ERROR_UNABLE_TO_LOAD_LIBRARY";
+ case PVRSRV_ERROR_UNABLE_GET_FUNC_ADDR: return "PVRSRV_ERROR_UNABLE_GET_FUNC_ADDR";
+ case PVRSRV_ERROR_UNLOAD_LIBRARY_FAILED: return "PVRSRV_ERROR_UNLOAD_LIBRARY_FAILED";
+
+ case PVRSRV_ERROR_BRIDGE_CALL_FAILED: return "PVRSRV_ERROR_BRIDGE_CALL_FAILED";
+ case PVRSRV_ERROR_IOCTL_CALL_FAILED: return "PVRSRV_ERROR_IOCTL_CALL_FAILED";
+
+ case PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND: return "PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND";
+ case PVRSRV_ERROR_BUFFER_DEVICE_NOT_FOUND: return "PVRSRV_ERROR_BUFFER_DEVICE_NOT_FOUND";
+ case PVRSRV_ERROR_BUFFER_DEVICE_ALREADY_PRESENT:return "PVRSRV_ERROR_BUFFER_DEVICE_ALREADY_PRESENT";
+
+ case PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND: return "PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND";
+ case PVRSRV_ERROR_PCI_CALL_FAILED: return "PVRSRV_ERROR_PCI_CALL_FAILED";
+ case PVRSRV_ERROR_PCI_REGION_TOO_SMALL: return "PVRSRV_ERROR_PCI_REGION_TOO_SMALL";
+ case PVRSRV_ERROR_PCI_REGION_UNAVAILABLE: return "PVRSRV_ERROR_PCI_REGION_UNAVAILABLE";
+ case PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH: return "PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH";
+
+ case PVRSRV_ERROR_REGISTER_BASE_NOT_SET: return "PVRSRV_ERROR_REGISTER_BASE_NOT_SET";
+
+ case PVRSRV_ERROR_BM_BAD_SHAREMEM_HANDLE: return "PVRSRV_ERROR_BM_BAD_SHAREMEM_HANDLE";
+
+ case PVRSRV_ERROR_FAILED_TO_ALLOC_USER_MEM: return "PVRSRV_ERROR_FAILED_TO_ALLOC_USER_MEM";
+ case PVRSRV_ERROR_FAILED_TO_ALLOC_VP_MEMORY: return "PVRSRV_ERROR_FAILED_TO_ALLOC_VP_MEMORY";
+ case PVRSRV_ERROR_FAILED_TO_MAP_SHARED_PBDESC: return "PVRSRV_ERROR_FAILED_TO_MAP_SHARED_PBDESC";
+ case PVRSRV_ERROR_FAILED_TO_GET_PHYS_ADDR: return "PVRSRV_ERROR_FAILED_TO_GET_PHYS_ADDR";
+
+ case PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY: return "PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY";
+ case PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY: return "PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY";
+
+ case PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES: return "PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES";
+ case PVRSRV_ERROR_FAILED_TO_FREE_PAGES: return "PVRSRV_ERROR_FAILED_TO_FREE_PAGES";
+ case PVRSRV_ERROR_FAILED_TO_COPY_PAGES: return "PVRSRV_ERROR_FAILED_TO_COPY_PAGES";
+ case PVRSRV_ERROR_UNABLE_TO_LOCK_PAGES: return "PVRSRV_ERROR_UNABLE_TO_LOCK_PAGES";
+ case PVRSRV_ERROR_UNABLE_TO_UNLOCK_PAGES: return "PVRSRV_ERROR_UNABLE_TO_UNLOCK_PAGES";
+ case PVRSRV_ERROR_STILL_MAPPED: return "PVRSRV_ERROR_STILL_MAPPED";
+ case PVRSRV_ERROR_MAPPING_NOT_FOUND: return "PVRSRV_ERROR_MAPPING_NOT_FOUND";
+ case PVRSRV_ERROR_PHYS_ADDRESS_EXCEEDS_32BIT: return "PVRSRV_ERROR_PHYS_ADDRESS_EXCEEDS_32BIT";
+ case PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE: return "PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE";
+
+ case PVRSRV_ERROR_INVALID_SEGMENT_BLOCK: return "PVRSRV_ERROR_INVALID_SEGMENT_BLOCK";
+ case PVRSRV_ERROR_INVALID_SGXDEVDATA: return "PVRSRV_ERROR_INVALID_SGXDEVDATA";
+ case PVRSRV_ERROR_INVALID_DEVINFO: return "PVRSRV_ERROR_INVALID_DEVINFO";
+ case PVRSRV_ERROR_INVALID_MEMINFO: return "PVRSRV_ERROR_INVALID_MEMINFO";
+ case PVRSRV_ERROR_INVALID_MISCINFO: return "PVRSRV_ERROR_INVALID_MISCINFO";
+ case PVRSRV_ERROR_UNKNOWN_IOCTL: return "PVRSRV_ERROR_UNKNOWN_IOCTL";
+ case PVRSRV_ERROR_INVALID_CONTEXT: return "PVRSRV_ERROR_INVALID_CONTEXT";
+ case PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT: return "PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT";
+ case PVRSRV_ERROR_INVALID_HEAP: return "PVRSRV_ERROR_INVALID_HEAP";
+ case PVRSRV_ERROR_INVALID_KERNELINFO: return "PVRSRV_ERROR_INVALID_KERNELINFO";
+ case PVRSRV_ERROR_UNKNOWN_POWER_STATE: return "PVRSRV_ERROR_UNKNOWN_POWER_STATE";
+ case PVRSRV_ERROR_INVALID_HANDLE_TYPE: return "PVRSRV_ERROR_INVALID_HANDLE_TYPE";
+ case PVRSRV_ERROR_INVALID_WRAP_TYPE: return "PVRSRV_ERROR_INVALID_WRAP_TYPE";
+ case PVRSRV_ERROR_INVALID_PHYS_ADDR: return "PVRSRV_ERROR_INVALID_PHYS_ADDR";
+ case PVRSRV_ERROR_INVALID_CPU_ADDR: return "PVRSRV_ERROR_INVALID_CPU_ADDR";
+ case PVRSRV_ERROR_INVALID_HEAPINFO: return "PVRSRV_ERROR_INVALID_HEAPINFO";
+ case PVRSRV_ERROR_INVALID_PERPROC: return "PVRSRV_ERROR_INVALID_PERPROC";
+ case PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO: return "PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO";
+ case PVRSRV_ERROR_INVALID_MAP_REQUEST: return "PVRSRV_ERROR_INVALID_MAP_REQUEST";
+ case PVRSRV_ERROR_INVALID_UNMAP_REQUEST: return "PVRSRV_ERROR_INVALID_UNMAP_REQUEST";
+ case PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP: return "PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP";
+ case PVRSRV_ERROR_MAPPING_STILL_IN_USE: return "PVRSRV_ERROR_MAPPING_STILL_IN_USE";
+
+ case PVRSRV_ERROR_EXCEEDED_HW_LIMITS: return "PVRSRV_ERROR_EXCEEDED_HW_LIMITS";
+ case PVRSRV_ERROR_NO_STAGING_BUFFER_ALLOCATED: return "PVRSRV_ERROR_NO_STAGING_BUFFER_ALLOCATED";
+
+ case PVRSRV_ERROR_UNABLE_TO_CREATE_PERPROC_AREA:return "PVRSRV_ERROR_UNABLE_TO_CREATE_PERPROC_AREA";
+ case PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT: return "PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT";
+ case PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT: return "PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT";
+ case PVRSRV_ERROR_UNABLE_TO_REGISTER_EVENT: return "PVRSRV_ERROR_UNABLE_TO_REGISTER_EVENT";
+ case PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT: return "PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT";
+ case PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD: return "PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD";
+ case PVRSRV_ERROR_UNABLE_TO_CLOSE_THREAD: return "PVRSRV_ERROR_UNABLE_TO_CLOSE_THREAD";
+ case PVRSRV_ERROR_THREAD_READ_ERROR: return "PVRSRV_ERROR_THREAD_READ_ERROR";
+ case PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER:return "PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER";
+ case PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR: return "PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR";
+ case PVRSRV_ERROR_UNABLE_TO_UNINSTALL_ISR: return "PVRSRV_ERROR_UNABLE_TO_UNINSTALL_ISR";
+ case PVRSRV_ERROR_ISR_ALREADY_INSTALLED: return "PVRSRV_ERROR_ISR_ALREADY_INSTALLED";
+ case PVRSRV_ERROR_ISR_NOT_INSTALLED: return "PVRSRV_ERROR_ISR_NOT_INSTALLED";
+ case PVRSRV_ERROR_UNABLE_TO_INITIALISE_INTERRUPT:return "PVRSRV_ERROR_UNABLE_TO_INITIALISE_INTERRUPT";
+ case PVRSRV_ERROR_UNABLE_TO_RETRIEVE_INFO: return "PVRSRV_ERROR_UNABLE_TO_RETRIEVE_INFO";
+ case PVRSRV_ERROR_UNABLE_TO_DO_BACKWARDS_BLIT: return "PVRSRV_ERROR_UNABLE_TO_DO_BACKWARDS_BLIT";
+ case PVRSRV_ERROR_UNABLE_TO_CLOSE_SERVICES: return "PVRSRV_ERROR_UNABLE_TO_CLOSE_SERVICES";
+ case PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT: return "PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT";
+ case PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE: return "PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE";
+
+ case PVRSRV_ERROR_INVALID_CCB_COMMAND: return "PVRSRV_ERROR_INVALID_CCB_COMMAND";
+
+ case PVRSRV_ERROR_UNABLE_TO_LOCK_RESOURCE: return "PVRSRV_ERROR_UNABLE_TO_LOCK_RESOURCE";
+ case PVRSRV_ERROR_INVALID_LOCK_ID: return "PVRSRV_ERROR_INVALID_LOCK_ID";
+ case PVRSRV_ERROR_RESOURCE_NOT_LOCKED: return "PVRSRV_ERROR_RESOURCE_NOT_LOCKED";
+
+ case PVRSRV_ERROR_FLIP_FAILED: return "PVRSRV_ERROR_FLIP_FAILED";
+ case PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED: return "PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED";
+
+ case PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE: return "PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE";
+
+ case PVRSRV_ERROR_CREATE_RENDER_CONTEXT_FAILED: return "PVRSRV_ERROR_CREATE_RENDER_CONTEXT_FAILED";
+ case PVRSRV_ERROR_UNKNOWN_PRIMARY_FRAG: return "PVRSRV_ERROR_UNKNOWN_PRIMARY_FRAG";
+ case PVRSRV_ERROR_UNEXPECTED_SECONDARY_FRAG: return "PVRSRV_ERROR_UNEXPECTED_SECONDARY_FRAG";
+ case PVRSRV_ERROR_UNEXPECTED_PRIMARY_FRAG: return "PVRSRV_ERROR_UNEXPECTED_PRIMARY_FRAG";
+
+ case PVRSRV_ERROR_UNABLE_TO_INSERT_FENCE_ID: return "PVRSRV_ERROR_UNABLE_TO_INSERT_FENCE_ID";
+
+ case PVRSRV_ERROR_BLIT_SETUP_FAILED: return "PVRSRV_ERROR_BLIT_SETUP_FAILED";
+
+ case PVRSRV_ERROR_PDUMP_NOT_AVAILABLE: return "PVRSRV_ERROR_PDUMP_NOT_AVAILABLE";
+ case PVRSRV_ERROR_PDUMP_BUFFER_FULL: return "PVRSRV_ERROR_PDUMP_BUFFER_FULL";
+ case PVRSRV_ERROR_PDUMP_BUF_OVERFLOW: return "PVRSRV_ERROR_PDUMP_BUF_OVERFLOW";
+ case PVRSRV_ERROR_PDUMP_NOT_ACTIVE: return "PVRSRV_ERROR_PDUMP_NOT_ACTIVE";
+ case PVRSRV_ERROR_INCOMPLETE_LINE_OVERLAPS_PAGES:return "PVRSRV_ERROR_INCOMPLETE_LINE_OVERLAPS_PAGES";
+
+ case PVRSRV_ERROR_MUTEX_DESTROY_FAILED: return "PVRSRV_ERROR_MUTEX_DESTROY_FAILED";
+ case PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR: return "PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR";
+
+ case PVRSRV_ERROR_INSUFFICIENT_SCRIPT_SPACE: return "PVRSRV_ERROR_INSUFFICIENT_SCRIPT_SPACE";
+ case PVRSRV_ERROR_INSUFFICIENT_SPACE_FOR_COMMAND:return "PVRSRV_ERROR_INSUFFICIENT_SPACE_FOR_COMMAND";
+
+ case PVRSRV_ERROR_PROCESS_NOT_INITIALISED: return "PVRSRV_ERROR_PROCESS_NOT_INITIALISED";
+ case PVRSRV_ERROR_PROCESS_NOT_FOUND: return "PVRSRV_ERROR_PROCESS_NOT_FOUND";
+ case PVRSRV_ERROR_SRV_CONNECT_FAILED: return "PVRSRV_ERROR_SRV_CONNECT_FAILED";
+ case PVRSRV_ERROR_SRV_DISCONNECT_FAILED: return "PVRSRV_ERROR_SRV_DISCONNECT_FAILED";
+ case PVRSRV_ERROR_DEINT_PHASE_FAILED: return "PVRSRV_ERROR_DEINT_PHASE_FAILED";
+ case PVRSRV_ERROR_INIT2_PHASE_FAILED: return "PVRSRV_ERROR_INIT2_PHASE_FAILED";
+
+ case PVRSRV_ERROR_NO_DC_DEVICES_FOUND: return "PVRSRV_ERROR_NO_DC_DEVICES_FOUND";
+ case PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE: return "PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE";
+ case PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE: return "PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE";
+ case PVRSRV_ERROR_NO_DEVICEDATA_FOUND: return "PVRSRV_ERROR_NO_DEVICEDATA_FOUND";
+ case PVRSRV_ERROR_NO_DEVICENODE_FOUND: return "PVRSRV_ERROR_NO_DEVICENODE_FOUND";
+ case PVRSRV_ERROR_NO_CLIENTNODE_FOUND: return "PVRSRV_ERROR_NO_CLIENTNODE_FOUND";
+ case PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE: return "PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE";
+
+ case PVRSRV_ERROR_UNABLE_TO_INIT_TASK: return "PVRSRV_ERROR_UNABLE_TO_INIT_TASK";
+ case PVRSRV_ERROR_UNABLE_TO_SCHEDULE_TASK: return "PVRSRV_ERROR_UNABLE_TO_SCHEDULE_TASK";
+ case PVRSRV_ERROR_UNABLE_TO_KILL_TASK: return "PVRSRV_ERROR_UNABLE_TO_KILL_TASK";
+
+ case PVRSRV_ERROR_UNABLE_TO_ENABLE_TIMER: return "PVRSRV_ERROR_UNABLE_TO_ENABLE_TIMER";
+ case PVRSRV_ERROR_UNABLE_TO_DISABLE_TIMER: return "PVRSRV_ERROR_UNABLE_TO_DISABLE_TIMER";
+ case PVRSRV_ERROR_UNABLE_TO_REMOVE_TIMER: return "PVRSRV_ERROR_UNABLE_TO_REMOVE_TIMER";
+
+ case PVRSRV_ERROR_UNKNOWN_PIXEL_FORMAT: return "PVRSRV_ERROR_UNKNOWN_PIXEL_FORMAT";
+ case PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION: return "PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION";
+
+ case PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE: return "PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE";
+ case PVRSRV_ERROR_HANDLE_NOT_ALLOCATED: return "PVRSRV_ERROR_HANDLE_NOT_ALLOCATED";
+ case PVRSRV_ERROR_HANDLE_TYPE_MISMATCH: return "PVRSRV_ERROR_HANDLE_TYPE_MISMATCH";
+ case PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE: return "PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE";
+ case PVRSRV_ERROR_HANDLE_NOT_SHAREABLE: return "PVRSRV_ERROR_HANDLE_NOT_SHAREABLE";
+ case PVRSRV_ERROR_HANDLE_NOT_FOUND: return "PVRSRV_ERROR_HANDLE_NOT_FOUND";
+ case PVRSRV_ERROR_INVALID_SUBHANDLE: return "PVRSRV_ERROR_INVALID_SUBHANDLE";
+ case PVRSRV_ERROR_HANDLE_BATCH_IN_USE: return "PVRSRV_ERROR_HANDLE_BATCH_IN_USE";
+ case PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE: return "PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE";
+
+ case PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE: return "PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE";
+ case PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED:return "PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED";
+
+ case PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE: return "PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE";
+ case PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP: return "PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP";
+
+ case PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE: return "PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE";
+
+ case PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE: return "PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE";
+ case PVRSRV_ERROR_INVALID_DEVICEID: return "PVRSRV_ERROR_INVALID_DEVICEID";
+ case PVRSRV_ERROR_DEVICEID_NOT_FOUND: return "PVRSRV_ERROR_DEVICEID_NOT_FOUND";
+
+ case PVRSRV_ERROR_MEMORY_TEST_FAILED: return "PVRSRV_ERROR_MEMORY_TEST_FAILED";
+ case PVRSRV_ERROR_CPUPADDR_TEST_FAILED: return "PVRSRV_ERROR_CPUPADDR_TEST_FAILED";
+ case PVRSRV_ERROR_COPY_TEST_FAILED: return "PVRSRV_ERROR_COPY_TEST_FAILED";
+
+ case PVRSRV_ERROR_SEMAPHORE_NOT_INITIALISED: return "PVRSRV_ERROR_SEMAPHORE_NOT_INITIALISED";
+
+ case PVRSRV_ERROR_UNABLE_TO_RELEASE_CLOCK: return "PVRSRV_ERROR_UNABLE_TO_RELEASE_CLOCK";
+ case PVRSRV_ERROR_CLOCK_REQUEST_FAILED: return "PVRSRV_ERROR_CLOCK_REQUEST_FAILED";
+ case PVRSRV_ERROR_DISABLE_CLOCK_FAILURE: return "PVRSRV_ERROR_DISABLE_CLOCK_FAILURE";
+ case PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE: return "PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE";
+ case PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE: return "PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE";
+ case PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK: return "PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK";
+ case PVRSRV_ERROR_UNABLE_TO_GET_CLOCK: return "PVRSRV_ERROR_UNABLE_TO_GET_CLOCK";
+ case PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK: return "PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK";
+ case PVRSRV_ERROR_UNABLE_TO_GET_SYSTEM_CLOCK: return "PVRSRV_ERROR_UNABLE_TO_GET_SYSTEM_CLOCK";
+
+ case PVRSRV_ERROR_UNKNOWN_SGL_ERROR: return "PVRSRV_ERROR_UNKNOWN_SGL_ERROR";
+ case PVRSRV_ERROR_BAD_SYNC_STATE: return "PVRSRV_ERROR_BAD_SYNC_STATE";
+
+ case PVRSRV_ERROR_CACHE_INVALIDATE_FAILED: return "PVRSRV_ERROR_CACHE_INVALIDATE_FAILED";
+
+ case PVRSRV_ERROR_FORCE_I32: return "PVRSRV_ERROR_FORCE_I32";
+
+ default:
+ return "Unknown PVRSRV error number";
+ }
+
+#if defined (__cplusplus)
+}
+#endif
+#endif /* __PVRSRV_ERRORS_H__ */
+
+/*****************************************************************************
+ End of file (pvrsrv_errors.h)
+*****************************************************************************/
diff --git a/pvr-source/services4/include/servicesint.h b/pvr-source/services4/include/servicesint.h
new file mode 100644
index 0000000..5b39093
--- /dev/null
+++ b/pvr-source/services4/include/servicesint.h
@@ -0,0 +1,556 @@
+/*************************************************************************/ /*!
+@Title Services Internal Header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description services internal details
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined (__SERVICESINT_H__)
+#define __SERVICESINT_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include "services.h"
+#include "sysinfo.h"
+#include "sysconfig.h"
+
+#define HWREC_DEFAULT_TIMEOUT (500)
+
+#define DRIVERNAME_MAXLENGTH (100)
+
+/*
+ helper macros:
+*/
+#define ALIGNSIZE(size, alignshift) (((size) + ((1UL << (alignshift))-1)) & ~((1UL << (alignshift))-1))
+
+#ifndef MAX
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+#ifndef MIN
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+/*
+ Note:
+ MAX_CLEANUP_TRYS is set to try and be around the frame rate
+ as for every try we will kick the uKernel which we want to avoid
+ doing too often (as we risk flooding the uKernel trace buffer
+ with requests and losing important information from before the
+ cleanup requests started).
+*/
+#define MAX_CLEANUP_TIME_US (MAX_HW_TIME_US * 4)
+#define MAX_CLEANUP_TRYS 100
+#define MAX_CLEANUP_TIME_WAIT_US (MAX_CLEANUP_TIME_US/MAX_CLEANUP_TRYS)
+
+typedef enum _PVRSRV_MEMTYPE_
+{
+ PVRSRV_MEMTYPE_UNKNOWN = 0,
+ PVRSRV_MEMTYPE_DEVICE = 1,
+ PVRSRV_MEMTYPE_DEVICECLASS = 2,
+ PVRSRV_MEMTYPE_WRAPPED = 3,
+ PVRSRV_MEMTYPE_MAPPED = 4,
+ PVRSRV_MEMTYPE_ION = 5,
+} PVRSRV_MEMTYPE;
+
+/*
+ Kernel Memory Information structure
+*/
+typedef struct _PVRSRV_KERNEL_MEM_INFO_
+{
+ /* Kernel Mode CPU Virtual address */
+ IMG_PVOID pvLinAddrKM;
+
+ /* Device Virtual Address */
+ IMG_DEV_VIRTADDR sDevVAddr;
+
+ /* allocation flags */
+ IMG_UINT32 ui32Flags;
+
+ /* Size of the allocated buffer in bytes */
+ IMG_SIZE_T uAllocSize;
+
+ /* Internal implementation details. Do not use outside services code. */
+ PVRSRV_MEMBLK sMemBlk;
+
+ /* Address of the backup buffer used in a save/restore of the surface */
+ IMG_PVOID pvSysBackupBuffer;
+
+ /* refcount for allocation, wrapping and mapping */
+ IMG_UINT32 ui32RefCount;
+
+ /* Set when free call ocured and a mapping was still open */
+ IMG_BOOL bPendingFree;
+
+
+#if defined(SUPPORT_MEMINFO_IDS)
+ #if !defined(USE_CODE)
+ /* Globally unique "stamp" for allocation (not re-used until wrap) */
+ IMG_UINT64 ui64Stamp;
+ #else /* !defined(USE_CODE) */
+ IMG_UINT32 dummy1;
+ IMG_UINT32 dummy2;
+ #endif /* !defined(USE_CODE) */
+#endif /* defined(SUPPORT_MEMINFO_IDS) */
+
+ /* ptr to associated kernel sync info - NULL if no sync */
+ struct _PVRSRV_KERNEL_SYNC_INFO_ *psKernelSyncInfo;
+
+ PVRSRV_MEMTYPE memType;
+
+ IMG_VOID *bvmap_handle;
+
+ /* Device Virtual Address Offsets for the YUV MM planes */
+ IMG_UINT32 planeOffsets[PVRSRV_MAX_NUMBER_OF_MM_BUFFER_PLANES];
+
+ /*
+ To activate the "share mem workaround", add PVRSRV_MEM_XPROC to
+ the flags for the allocation. This will cause the "map" API to
+ call use Alloc Device Mem but will share the underlying memory
+ block and sync data.
+ */
+ struct {
+ /* Record whether the workaround is active for this
+ allocation. The rest of the fields in this struct are
+ undefined unless this is true */
+ IMG_BOOL bInUse;
+
+ /* Store the device cookie handle from the original
+ allocation, as it is not present on the "Map" API. */
+ IMG_HANDLE hDevCookieInt;
+
+ /* This is an index into a static array which store
+ information about the underlying allocation */
+ IMG_UINT32 ui32ShareIndex;
+
+ /* Original arguments as supplied to original
+ "PVRSRVAllocDeviceMem" call, such that a new call to this
+ function can be later constructed */
+ IMG_UINT32 ui32OrigReqAttribs;
+ IMG_UINT32 ui32OrigReqSize;
+ IMG_UINT32 ui32OrigReqAlignment;
+ } sShareMemWorkaround;
+} PVRSRV_KERNEL_MEM_INFO;
+
+
+/*
+ Kernel Sync Info structure
+*/
+typedef struct _PVRSRV_KERNEL_SYNC_INFO_
+{
+ /* kernel sync data */
+ PVRSRV_SYNC_DATA *psSyncData;
+
+ /* Device accessible WriteOp Info */
+ IMG_DEV_VIRTADDR sWriteOpsCompleteDevVAddr;
+
+ /* Device accessible ReadOp Info */
+ IMG_DEV_VIRTADDR sReadOpsCompleteDevVAddr;
+
+ /* Device accessible ReadOp Info */
+ IMG_DEV_VIRTADDR sReadOps2CompleteDevVAddr;
+
+ /* meminfo for sync data */
+ PVRSRV_KERNEL_MEM_INFO *psSyncDataMemInfoKM;
+
+ /* Reference count for deferring destruction of syncinfo when it is shared */
+ /* NB: This is only done for devicemem.c (alloc/map/wrap etc), and
+ not (presently) for deviceclass memory */
+ IMG_PVOID pvRefCount;
+
+ /* Resman cleanup, for those created with explicit API */
+ IMG_HANDLE hResItem;
+
+ /* Unique ID of the sync object */
+ IMG_UINT32 ui32UID;
+} PVRSRV_KERNEL_SYNC_INFO;
+
+/*!
+ *****************************************************************************
+ * This is a device addressable version of a pvrsrv_sync_oject
+ * - any hw cmd may have an unlimited number of these
+ ****************************************************************************/
+typedef struct _PVRSRV_DEVICE_SYNC_OBJECT_
+{
+ /* KEEP THESE 6 VARIABLES TOGETHER FOR UKERNEL BLOCK LOAD */
+ IMG_UINT32 ui32ReadOpsPendingVal;
+ IMG_DEV_VIRTADDR sReadOpsCompleteDevVAddr;
+ IMG_UINT32 ui32WriteOpsPendingVal;
+ IMG_DEV_VIRTADDR sWriteOpsCompleteDevVAddr;
+ IMG_UINT32 ui32ReadOps2PendingVal;
+ IMG_DEV_VIRTADDR sReadOps2CompleteDevVAddr;
+} PVRSRV_DEVICE_SYNC_OBJECT;
+
+/*!
+ *****************************************************************************
+ * encapsulates a single sync object
+ * - any cmd may have an unlimited number of these
+ ****************************************************************************/
+typedef struct _PVRSRV_SYNC_OBJECT
+{
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfoKM;
+ IMG_UINT32 ui32WriteOpsPending;
+ IMG_UINT32 ui32ReadOpsPending;
+ IMG_UINT32 ui32ReadOps2Pending;
+
+}PVRSRV_SYNC_OBJECT, *PPVRSRV_SYNC_OBJECT;
+
+/*!
+ *****************************************************************************
+ * The `one size fits all' generic command.
+ ****************************************************************************/
+typedef struct _PVRSRV_COMMAND
+{
+ IMG_SIZE_T uCmdSize; /*!< total size of command */
+ IMG_UINT32 ui32DevIndex; /*!< device type - 16bit enum (exported by system) */
+ IMG_UINT32 CommandType; /*!< command type */
+ IMG_UINT32 ui32DstSyncCount; /*!< number of dst sync objects */
+ IMG_UINT32 ui32SrcSyncCount; /*!< number of src sync objects */
+ PVRSRV_SYNC_OBJECT *psDstSync; /*!< dst sync ptr list, allocated on
+ back of this structure, i.e. is resident in Q */
+ PVRSRV_SYNC_OBJECT *psSrcSync; /*!< src sync ptr list, allocated on
+ back of this structure, i.e. is resident in Q */
+ IMG_SIZE_T uDataSize; /*!< Size of Cmd Data Packet
+ - only required in terms of allocating Q space */
+ IMG_UINT32 ui32ProcessID; /*!< Process ID for debugging */
+ IMG_VOID *pvData; /*!< data to be passed to Cmd Handler function,
+ allocated on back of this structure, i.e. is resident in Q */
+ PFN_QUEUE_COMMAND_COMPLETE pfnCommandComplete; /*!< Command complete callback */
+ IMG_HANDLE hCallbackData; /*!< Command complete callback data */
+}PVRSRV_COMMAND, *PPVRSRV_COMMAND;
+
+
+/*!
+ *****************************************************************************
+ * Circular command buffer structure forming the queue of pending commands.
+ *
+ * Queues are implemented as circular comamnd buffers (CCBs).
+ * The buffer is allocated as a specified size, plus the size of the largest supported command.
+ * The extra size allows commands to be added without worrying about wrapping around at the end.
+ *
+ * Commands are added to the CCB by client processes and consumed within
+ * kernel mode code running from within an L/MISR typically.
+ *
+ * The process of adding a command to a queue is as follows:-
+ * - A `lock' is acquired to prevent other processes from adding commands to a queue
+ * - Data representing the command to be executed, along with it's PVRSRV_SYNC_INFO
+ * dependencies is written to the buffer representing the queue at the queues
+ * current WriteOffset.
+ * - The PVRSRV_SYNC_INFO that the command depends on are updated to reflect
+ * the addition of the new command.
+ * - The WriteOffset is incremented by the size of the command added.
+ * - If the WriteOffset now lies beyound the declared buffer size, it is
+ * reset to zero.
+ * - The semaphore is released.
+ *
+ *****************************************************************************/
+typedef struct _PVRSRV_QUEUE_INFO_
+{
+ IMG_VOID *pvLinQueueKM; /*!< Pointer to the command buffer in the kernel's
+ address space */
+
+ IMG_VOID *pvLinQueueUM; /*!< Pointer to the command buffer in the user's
+ address space */
+
+ volatile IMG_SIZE_T ui32ReadOffset; /*!< Index into the buffer at which commands are being
+ consumed */
+
+ volatile IMG_SIZE_T ui32WriteOffset; /*!< Index into the buffer at which commands are being
+ added */
+
+ IMG_UINT32 *pui32KickerAddrKM; /*!< kicker address in the kernel's
+ address space*/
+
+ IMG_UINT32 *pui32KickerAddrUM; /*!< kicker address in the user's
+ address space */
+
+ IMG_SIZE_T ui32QueueSize; /*!< Size in bytes of the buffer - excluding the safety allocation */
+
+ IMG_UINT32 ui32ProcessID; /*!< Process ID required by resource locking */
+
+ IMG_HANDLE hMemBlock[2];
+
+ struct _PVRSRV_QUEUE_INFO_ *psNextKM; /*!< The next queue in the system */
+}PVRSRV_QUEUE_INFO;
+
+
+typedef struct _PVRSRV_HEAP_INFO_KM_
+{
+ IMG_UINT32 ui32HeapID;
+ IMG_DEV_VIRTADDR sDevVAddrBase;
+
+ IMG_HANDLE hDevMemHeap;
+ IMG_UINT32 ui32HeapByteSize;
+ IMG_UINT32 ui32Attribs;
+ IMG_UINT32 ui32XTileStride;
+}PVRSRV_HEAP_INFO_KM;
+
+
+/*
+ Event Object information structure
+*/
+typedef struct _PVRSRV_EVENTOBJECT_KM_
+{
+ /* globally unique name of the event object */
+ IMG_CHAR szName[EVENTOBJNAME_MAXLENGTH];
+ /* kernel specific handle for the event object */
+ IMG_HANDLE hOSEventKM;
+
+} PVRSRV_EVENTOBJECT_KM;
+
+
+/*!
+ ******************************************************************************
+ * Structure to retrieve misc. information from services
+ *****************************************************************************/
+typedef struct _PVRSRV_MISC_INFO_KM_
+{
+ IMG_UINT32 ui32StateRequest; /*!< requested State Flags */
+ IMG_UINT32 ui32StatePresent; /*!< Present/Valid State Flags */
+
+ /*!< SOC Timer register */
+ IMG_VOID *pvSOCTimerRegisterKM;
+ IMG_VOID *pvSOCTimerRegisterUM;
+ IMG_HANDLE hSOCTimerRegisterOSMemHandle;
+ IMG_HANDLE hSOCTimerRegisterMappingInfo;
+
+ /*!< SOC Clock Gating registers */
+ IMG_VOID *pvSOCClockGateRegs;
+ IMG_UINT32 ui32SOCClockGateRegsSize;
+
+ /* Memory Stats/DDK version string depending on ui32StateRequest flags */
+ IMG_CHAR *pszMemoryStr;
+ IMG_UINT32 ui32MemoryStrLen;
+
+ /* global event object */
+ PVRSRV_EVENTOBJECT_KM sGlobalEventObject;//FIXME: should be private to services
+ IMG_HANDLE hOSGlobalEvent;
+
+ /* Note: add misc. items as required */
+ IMG_UINT32 aui32DDKVersion[4];
+
+ /*!< CPU cache flush controls: */
+ struct
+ {
+ /*!< Defer the CPU cache op to the next HW op to be submitted (else flush now) */
+ IMG_BOOL bDeferOp;
+
+ /*!< Type of cache operation to perform */
+ PVRSRV_MISC_INFO_CPUCACHEOP_TYPE eCacheOpType;
+
+ /*!< Meminfo (or meminfo handle) to flush */
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+
+ /*!< Offset in MemInfo to start cache op */
+ IMG_VOID *pvBaseVAddr;
+
+ /*!< Length of range to perform cache op */
+ IMG_UINT32 ui32Length;
+ } sCacheOpCtl;
+
+ /*!< Meminfo refcount controls: */
+ struct
+ {
+ /*!< Meminfo (or meminfo handle) to get refcount for */
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+
+ /*!< Resulting refcount */
+ IMG_UINT32 ui32RefCount;
+ } sGetRefCountCtl;
+} PVRSRV_MISC_INFO_KM;
+
+
+/* insert command function pointer */
+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);
+/* submit command function pointer */
+typedef PVRSRV_ERROR (*PFN_SUBMIT_CMD) (PVRSRV_QUEUE_INFO*, PVRSRV_COMMAND*, IMG_BOOL);
+
+
+/***********************************************************************
+ Device Class Structures
+***********************************************************************/
+
+/*
+ Generic Device Class Buffer
+ - details common between DC and BC
+*/
+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;
+ IMG_UINT32 ui32MemMapRefCount;
+} PVRSRV_DEVICECLASS_BUFFER;
+
+
+/*
+ Common Device Class client services information structure
+*/
+typedef struct PVRSRV_CLIENT_DEVICECLASS_INFO_TAG
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDeviceKM;
+#else
+ IMG_HANDLE hDeviceKM;
+#endif
+ IMG_HANDLE hServices;
+} PVRSRV_CLIENT_DEVICECLASS_INFO;
+
+
+typedef enum
+{
+ PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR,
+ PVRSRV_FREE_CALLBACK_ORIGIN_IMPORTER,
+ PVRSRV_FREE_CALLBACK_ORIGIN_EXTERNAL,
+}
+PVRSRV_FREE_CALLBACK_ORIGIN;
+
+
+IMG_IMPORT
+PVRSRV_ERROR FreeMemCallBackCommon(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32Param,
+ PVRSRV_FREE_CALLBACK_ORIGIN eCallbackOrigin);
+
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVQueueCommand(IMG_HANDLE hQueueInfo,
+ PVRSRV_COMMAND *psCommand);
+
+
+/*!
+ * *****************************************************************************
+ * @Description Allocates system memory on behalf of a userspace process that is
+ * addressable by the kernel; suitable for mapping into the current
+ * user space process; suitable for mapping into other userspace
+ * processes and it is possible to entirely disassociate the system
+ * memory from the current userspace process via a call to
+ * PVRSRVDissociateSharedSysMemoryKM.
+ *
+ * @Input psConnection
+ * @Input ui32Flags
+ * @Input ui32Size
+ * @Output ppsClientMemInfo
+ *
+ * @Return PVRSRV_ERROR
+ ********************************************************************************/
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV
+PVRSRVAllocSharedSysMem(const PVRSRV_CONNECTION *psConnection,
+ IMG_UINT32 ui32Flags,
+ IMG_SIZE_T ui32Size,
+ PVRSRV_CLIENT_MEM_INFO **ppsClientMemInfo);
+
+/*!
+ * *****************************************************************************
+ * @Description Frees memory allocated via PVRSRVAllocSharedMemory (Note you must
+ * be sure any additional kernel references you created have been
+ * removed before freeing the memory)
+ *
+ * @Input psConnection
+ * @Input psClientMemInfo
+ *
+ * @Return PVRSRV_ERROR
+ ********************************************************************************/
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV
+PVRSRVFreeSharedSysMem(const PVRSRV_CONNECTION *psConnection,
+ PVRSRV_CLIENT_MEM_INFO *psClientMemInfo);
+
+/*!
+ * *****************************************************************************
+ * @Description Removes any userspace reference to the shared system memory, except
+ * that the memory will remain registered with the services resource
+ * manager so if the process dies/exits the actuall shared memory will
+ * still be freed.
+ * If you need to move ownership of shared memory from userspace
+ * to kernel space then before unrefing a shared piece of memory you can
+ * take a copy of psClientMemInfo->hKernelMemInfo; call
+ * PVRSRVUnrefSharedSysMem; then use some mechanism (specialised bridge
+ * function) to request that the kernel remove any resource manager
+ * reference to the shared memory and assume responsaility for the meminfo
+ * in one atomic operation. (Note to aid with such a kernel space bridge
+ * function see PVRSRVDissociateSharedSysMemoryKM)
+ *
+ * @Input psConnection
+ * @Input psClientMemInfo
+ *
+ * @Return PVRSRV_ERROR
+ ********************************************************************************/
+IMG_IMPORT PVRSRV_ERROR
+PVRSRVUnrefSharedSysMem(const PVRSRV_CONNECTION *psConnection,
+ PVRSRV_CLIENT_MEM_INFO *psClientMemInfo);
+
+/*!
+ * *****************************************************************************
+ * @Description For shared system or device memory that is owned by the kernel, you can
+ * use this function to map the underlying memory into a client using a
+ * handle for the KernelMemInfo.
+ *
+ * @Input psConnection
+ * @Input hKernelMemInfo
+ * @Output ppsClientMemInfo
+ *
+ * @Return PVRSRV_ERROR
+ ********************************************************************************/
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV
+PVRSRVMapMemInfoMem(const PVRSRV_CONNECTION *psConnection,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo,
+#else
+ IMG_HANDLE hKernelMemInfo,
+#endif
+ PVRSRV_CLIENT_MEM_INFO **ppsClientMemInfo);
+
+
+#if defined (__cplusplus)
+}
+#endif
+#endif /* __SERVICESINT_H__ */
+
+/*****************************************************************************
+ End of file (servicesint.h)
+*****************************************************************************/
diff --git a/pvr-source/services4/include/sgx_bridge.h b/pvr-source/services4/include/sgx_bridge.h
new file mode 100644
index 0000000..33b27e3
--- /dev/null
+++ b/pvr-source/services4/include/sgx_bridge.h
@@ -0,0 +1,779 @@
+/*************************************************************************/ /*!
+@Title SGX Bridge Functionality
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Header for the sgx Brdige code
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__SGX_BRIDGE_H__)
+#define __SGX_BRIDGE_H__
+
+#if defined (SUPPORT_SID_INTERFACE)
+#include "sgxapi.h"
+#else
+#include "sgxapi_km.h"
+#endif
+#include "sgxinfo.h"
+#include "pvr_bridge.h"
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+/*
+ * Bridge Cmd Ids
+ */
+
+/* *REMEMBER* to update PVRSRV_BRIDGE_LAST_SGX_CMD if you add/remove a command!
+ * Also you need to ensure all PVRSRV_BRIDGE_SGX_CMD_BASE+ offsets are sequential!
+ */
+
+#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_2DQUERYBLTSCOMPLETE PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+9)
+
+#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)
+
+#define PVRSRV_BRIDGE_SGX_READ_HWPERF_CB PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+29)
+#define PVRSRV_BRIDGE_SGX_SET_RENDER_CONTEXT_PRIORITY PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+30)
+#define PVRSRV_BRIDGE_SGX_SET_TRANSFER_CONTEXT_PRIORITY PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+31)
+
+#if defined(PDUMP)
+#define PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+32)
+#define PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+33)
+#define PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+34)
+#define PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+35)
+#define PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+36)
+#define PVRSRV_BRIDGE_SGX_PDUMP_SAVEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+37)
+#endif
+
+
+
+/* *REMEMBER* to update PVRSRV_BRIDGE_LAST_SGX_CMD if you add/remove a command!
+ * You need to ensure all PVRSRV_BRIDGE_SGX_CMD_BASE+ offsets are sequential!
+ */
+#define PVRSRV_BRIDGE_LAST_SGX_CMD (PVRSRV_BRIDGE_SGX_CMD_BASE+37)
+
+/*****************************************************************************
+ * Input structures for IOCTL/DRVESC
+ *****************************************************************************/
+
+/*!
+ *****************************************************************************
+ * `bridge in' SGX Get Phys Page Addr
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_GETPHYSPAGEADDR
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ IMG_HANDLE hDevMemHeap;
+ IMG_DEV_VIRTADDR sDevVAddr;
+}PVRSRV_BRIDGE_IN_GETPHYSPAGEADDR;
+
+/*!
+ *****************************************************************************
+ * `bridge out' SGX Get Phys Page Addr
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_GETPHYSPAGEADDR
+{
+ PVRSRV_ERROR eError;
+ IMG_DEV_PHYADDR DevPAddr;
+ IMG_CPU_PHYADDR CpuPAddr;
+}PVRSRV_BRIDGE_OUT_GETPHYSPAGEADDR;
+
+/*!
+ *****************************************************************************
+ * `bridge in' set transfer context priority
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_SGX_SET_TRANSFER_CONTEXT_PRIORITY_TAG
+ {
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ #if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hHWTransferContext;
+ #else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hHWTransferContext;
+ #endif
+ IMG_UINT32 ui32Priority;
+ IMG_UINT32 ui32OffsetOfPriorityField;
+}PVRSRV_BRIDGE_IN_SGX_SET_TRANSFER_CONTEXT_PRIORITY;
+
+/*!
+ *****************************************************************************
+ * `bridge in' set render context priority
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_SGX_SET_RENDER_CONTEXT_PRIORITY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hHWRenderContext;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hHWRenderContext;
+#endif
+ IMG_UINT32 ui32Priority;
+ IMG_UINT32 ui32OffsetOfPriorityField;
+}PVRSRV_BRIDGE_IN_SGX_SET_RENDER_CONTEXT_PRIORITY;
+
+/*!
+ *****************************************************************************
+ * `bridge in' Get Client Info
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_GETCLIENTINFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+}PVRSRV_BRIDGE_IN_GETCLIENTINFO;
+
+/*!
+ *****************************************************************************
+ * `bridge out' Get internal device info
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO_TAG
+{
+ SGX_INTERNAL_DEVINFO sSGXInternalDevInfo;
+ PVRSRV_ERROR eError;
+}PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO;
+
+/*!
+ *****************************************************************************
+ * `bridge in' Get internal device info
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+}PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO;
+
+/*!
+ *****************************************************************************
+ * `bridge out' Get Client Info
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_GETCLIENTINFO_TAG
+{
+ SGX_CLIENT_INFO sClientInfo;
+ PVRSRV_ERROR eError;
+}PVRSRV_BRIDGE_OUT_GETCLIENTINFO;
+
+/*!
+ *****************************************************************************
+ * `bridge in' Release Client Info
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_RELEASECLIENTINFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ SGX_CLIENT_INFO sClientInfo;
+}PVRSRV_BRIDGE_IN_RELEASECLIENTINFO;
+
+/*!
+ *****************************************************************************
+ * `bridge in' Pdump ISP mem Pol
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_ISPBREAKPOLL_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+}PVRSRV_BRIDGE_IN_ISPBREAKPOLL;
+
+/*!
+ *****************************************************************************
+ * `bridge in' KickTA
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_DOKICK_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ SGX_CCB_KICK sCCBKick;
+}PVRSRV_BRIDGE_IN_DOKICK;
+
+/*!
+ *****************************************************************************
+ * `bridge in' SGXScheduleProcessQueues
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+}PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES;
+
+
+#if defined(TRANSFER_QUEUE)
+/*!
+ *****************************************************************************
+ * `bridge in' SubmitTransfer
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_SUBMITTRANSFER_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ PVRSRV_TRANSFER_SGX_KICK sKick;
+}PVRSRV_BRIDGE_IN_SUBMITTRANSFER;
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+/*!
+ *****************************************************************************
+ * `bridge in' Submit2D
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_SUBMIT2D_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ PVRSRV_2D_SGX_KICK sKick;
+} PVRSRV_BRIDGE_IN_SUBMIT2D;
+#endif
+#endif
+
+/*!
+ *****************************************************************************
+ * `bridge in' ReadRegistryString
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_READREGDWORD_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_PCHAR pszKey;
+ IMG_PCHAR pszValue;
+}PVRSRV_BRIDGE_IN_READREGDWORD;
+
+/*!
+ *****************************************************************************
+ * `bridge out' ReadRegistryString
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_READREGDWORD_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32Data;
+}PVRSRV_BRIDGE_OUT_READREGDWORD;
+
+
+/*!
+ *****************************************************************************
+ * `bridge in' SGXGetMiscInfo
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_SGXGETMISCINFO_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ SGX_MISC_INFO *psMiscInfo;
+}PVRSRV_BRIDGE_IN_SGXGETMISCINFO;
+
+/*!
+ *****************************************************************************
+ * `bridge in' SGXGetInfoForSrvInit
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+}PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT;
+
+/*!
+ *****************************************************************************
+ * `bridge out' SGXGetInfoForSrvInit
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT_TAG
+{
+ PVRSRV_ERROR eError;
+ SGX_BRIDGE_INFO_FOR_SRVINIT sInitInfo;
+}PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT;
+
+/*!
+ *****************************************************************************
+ * `bridge in' SGXDevInitPart2
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_SGXDEVINITPART2_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ SGX_BRIDGE_INIT_INFO sInitInfo;
+}PVRSRV_BRIDGE_IN_SGXDEVINITPART2;
+
+/*!
+ *****************************************************************************
+ * `bridge out' SGXDevInitPart2
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_OUT_SGXDEVINITPART2_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32KMBuildOptions;
+
+}PVRSRV_BRIDGE_OUT_SGXDEVINITPART2;
+
+/*!
+ *****************************************************************************
+ * `bridge in' 2D query blits complete
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hKernSyncInfo;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hKernSyncInfo;
+#endif
+ 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; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_BOOL bLockOnFailure;
+ IMG_UINT32 ui32TotalPBSize;
+}PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC_TAG
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+ IMG_SID hSharedPBDesc;
+ IMG_SID hSharedPBDescKernelMemInfoHandle;
+ IMG_SID hHWPBDescKernelMemInfoHandle;
+ IMG_SID hBlockKernelMemInfoHandle;
+ IMG_SID hHWBlockKernelMemInfoHandle;
+ IMG_SID ahSharedPBDescSubKernelMemInfoHandles[PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS];
+#else
+ IMG_HANDLE hKernelMemInfo;
+ IMG_HANDLE hSharedPBDesc;
+ IMG_HANDLE hSharedPBDescKernelMemInfoHandle;
+ IMG_HANDLE hHWPBDescKernelMemInfoHandle;
+ IMG_HANDLE hBlockKernelMemInfoHandle;
+ IMG_HANDLE hHWBlockKernelMemInfoHandle;
+ IMG_HANDLE ahSharedPBDescSubKernelMemInfoHandles[PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS];
+#endif
+ IMG_UINT32 ui32SharedPBDescSubKernelMemInfoHandlesCount;
+ PVRSRV_ERROR eError;
+}PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC;
+
+typedef struct PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSharedPBDesc;
+#else
+ IMG_HANDLE hSharedPBDesc;
+#endif
+}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; /* Must be first member of structure */
+ IMG_UINT32 ui32TotalPBSize;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hSharedPBDescKernelMemInfo;
+ IMG_SID hHWPBDescKernelMemInfo;
+ IMG_SID hBlockKernelMemInfo;
+ IMG_SID hHWBlockKernelMemInfo;
+ IMG_SID *phKernelMemInfoHandles;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hSharedPBDescKernelMemInfo;
+ IMG_HANDLE hHWPBDescKernelMemInfo;
+ IMG_HANDLE hBlockKernelMemInfo;
+ IMG_HANDLE hHWBlockKernelMemInfo;
+ IMG_HANDLE *phKernelMemInfoHandles;
+#endif
+ IMG_UINT32 ui32KernelMemInfoHandlesCount;
+ IMG_DEV_VIRTADDR sHWPBDescDevVAddr;
+}PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hSharedPBDesc;
+#else
+ IMG_HANDLE hSharedPBDesc;
+#endif
+}PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC;
+
+
+#ifdef PDUMP
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ 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; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hDevMemContext;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hDevMemContext;
+#endif
+ 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; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ 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; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ 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; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hDevMemContext;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hDevMemContext;
+#endif
+ IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE];
+ IMG_UINT32 ui32FileOffset;
+ IMG_UINT32 ui32PDumpFlags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB;
+
+typedef struct PVRSRV_BRIDGE_IN_PDUMP_SAVEMEM
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hDevMemContext;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE];
+ IMG_UINT32 ui32FileOffset;
+ IMG_DEV_VIRTADDR sDevVAddr;
+ IMG_UINT32 ui32Size;
+#if !defined (SUPPORT_SID_INTERFACE)
+ IMG_HANDLE hDevMemContext;
+#endif
+ IMG_UINT32 ui32PDumpFlags;
+
+}PVRSRV_BRIDGE_IN_PDUMP_SAVEMEM;
+
+#endif
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_CPU_VIRTADDR pHWRenderContextCpuVAddr;
+ IMG_UINT32 ui32HWRenderContextSize;
+ IMG_UINT32 ui32OffsetToPDDevPAddr;
+ IMG_HANDLE hDevMemContext;
+}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hHWRenderContext;
+#else
+ IMG_HANDLE hHWRenderContext;
+#endif
+ IMG_DEV_VIRTADDR sHWRenderContextDevVAddr;
+}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ IMG_BOOL bForceCleanup;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hHWRenderContext;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hHWRenderContext;
+#endif
+}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_CPU_VIRTADDR pHWTransferContextCpuVAddr;
+ IMG_UINT32 ui32HWTransferContextSize;
+ IMG_UINT32 ui32OffsetToPDDevPAddr;
+ IMG_HANDLE hDevMemContext;
+}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hHWTransferContext;
+#else
+ IMG_HANDLE hHWTransferContext;
+#endif
+ IMG_DEV_VIRTADDR sHWTransferContextDevVAddr;
+}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ IMG_BOOL bForceCleanup;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hHWTransferContext;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hHWTransferContext;
+#endif
+}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_DEV_VIRTADDR sHWRTDataSetDevVAddr;
+}PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET;
+
+/*!
+ *****************************************************************************
+ * SGX 2D specific defines
+ *****************************************************************************/
+#if defined(SGX_FEATURE_2D_HARDWARE)
+typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_CPU_VIRTADDR pHW2DContextCpuVAddr;
+ IMG_UINT32 ui32HW2DContextSize;
+ IMG_UINT32 ui32OffsetToPDDevPAddr;
+ IMG_HANDLE hDevMemContext;
+}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT_TAG
+{
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hHW2DContext;
+#else
+ IMG_HANDLE hHW2DContext;
+#endif
+ IMG_DEV_VIRTADDR sHW2DContextDevVAddr;
+}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT;
+
+typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+ IMG_BOOL bForceCleanup;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+ IMG_SID hHW2DContext;
+#else
+ IMG_HANDLE hDevCookie;
+ IMG_HANDLE hHW2DContext;
+#endif
+}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT;
+
+#define SGX2D_MAX_BLT_CMD_SIZ 256 /* Maximum size of a blit command, in bytes */
+#endif /* SGX_FEATURE_2D_HARDWARE */
+
+
+/*!
+ *****************************************************************************
+ * `bridge in' SGXReadHWPerfCB
+ *****************************************************************************/
+typedef struct PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB_TAG
+{
+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevCookie;
+#else
+ IMG_HANDLE hDevCookie;
+#endif
+ IMG_UINT32 ui32ArraySize;
+ PVRSRV_SGX_HWPERF_CB_ENTRY *psHWPerfCBData;
+} PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB;
+
+/*!
+ *****************************************************************************
+ * `bridge out' SGXReadHWPerfCB
+ *****************************************************************************/
+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;
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* __SGX_BRIDGE_H__ */
+
diff --git a/pvr-source/services4/include/sgx_mkif_km.h b/pvr-source/services4/include/sgx_mkif_km.h
new file mode 100644
index 0000000..3a9866f
--- /dev/null
+++ b/pvr-source/services4/include/sgx_mkif_km.h
@@ -0,0 +1,475 @@
+/*************************************************************************/ /*!
+@Title SGX microkernel interface structures used by srvkm
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description SGX microkernel interface structures used by srvkm
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined (__SGX_MKIF_KM_H__)
+#define __SGX_MKIF_KM_H__
+
+#include "img_types.h"
+#include "servicesint.h"
+#include "sgxapi_km.h"
+
+
+#if !defined (SGX_MP_CORE_SELECT)
+/* MP register control macros */
+#if defined(SGX_FEATURE_MP)
+ #define SGX_REG_BANK_SHIFT (14)
+ #define SGX_REG_BANK_SIZE (1 << SGX_REG_BANK_SHIFT)
+ #define SGX_REG_BANK_BASE_INDEX (2)
+ #define SGX_REG_BANK_MASTER_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_MASTER_INDEX * SGX_REG_BANK_SIZE))
+#else
+ #define SGX_MP_CORE_SELECT(x,i) (x)
+#endif /* SGX_FEATURE_MP */
+#endif
+
+
+/*!
+ ******************************************************************************
+ * CCB command structure for SGX
+ *****************************************************************************/
+typedef struct _SGXMKIF_COMMAND_
+{
+ IMG_UINT32 ui32ServiceAddress; /*!< address of the USE command handler */
+ IMG_UINT32 ui32CacheControl; /*!< See SGXMKIF_CC_INVAL_* */
+ IMG_UINT32 ui32Data[6]; /*!< array of other command control words */
+} SGXMKIF_COMMAND;
+
+
+/*!
+ ******************************************************************************
+ * CCB array of commands for SGX
+ *****************************************************************************/
+typedef struct _PVRSRV_SGX_KERNEL_CCB_
+{
+ SGXMKIF_COMMAND asCommands[256]; /*!< array of commands */
+} PVRSRV_SGX_KERNEL_CCB;
+
+
+/*!
+ ******************************************************************************
+ * CCB control for SGX
+ *****************************************************************************/
+typedef struct _PVRSRV_SGX_CCB_CTL_
+{
+ IMG_UINT32 ui32WriteOffset; /*!< write offset into array of commands (MUST be alligned to 16 bytes!) */
+ IMG_UINT32 ui32ReadOffset; /*!< read offset into array of commands */
+} PVRSRV_SGX_CCB_CTL;
+
+
+/*!
+ *****************************************************************************
+ * Control data for SGX
+ *****************************************************************************/
+typedef struct _SGXMKIF_HOST_CTL_
+{
+#if defined(PVRSRV_USSE_EDM_BREAKPOINTS)
+ IMG_UINT32 ui32BreakpointDisable;
+ IMG_UINT32 ui32Continue;
+#endif
+
+ volatile IMG_UINT32 ui32InitStatus; /*!< Microkernel Initialisation status */
+ volatile IMG_UINT32 ui32PowerStatus; /*!< Microkernel Power Management status */
+ volatile IMG_UINT32 ui32CleanupStatus; /*!< Microkernel Resource Management status */
+#if defined(FIX_HW_BRN_28889)
+ volatile IMG_UINT32 ui32InvalStatus; /*!< Microkernel BIF Cache Invalidate status */
+#endif
+#if defined(SUPPORT_HW_RECOVERY)
+ IMG_UINT32 ui32uKernelDetectedLockups; /*!< counter relating to the number of lockups the uKernel has detected */
+ IMG_UINT32 ui32HostDetectedLockups; /*!< counter relating to the number of lockups the host has detected */
+ IMG_UINT32 ui32HWRecoverySampleRate; /*!< SGX lockup detection rate (in multiples of the timer period) */
+#endif /* SUPPORT_HW_RECOVERY*/
+ IMG_UINT32 ui32uKernelTimerClock; /*!< SGX ukernel timer period (in clocks) */
+ IMG_UINT32 ui32ActivePowManSampleRate; /*!< SGX Active Power latency period (in multiples of the timer period) */
+ IMG_UINT32 ui32InterruptFlags; /*!< Interrupt flags - PVRSRV_USSE_EDM_INTERRUPT_xxx */
+ IMG_UINT32 ui32InterruptClearFlags; /*!< Interrupt clear flags - PVRSRV_USSE_EDM_INTERRUPT_xxx */
+ IMG_UINT32 ui32BPSetClearSignal; /*!< Breakpoint set/cear signal */
+
+ IMG_UINT32 ui32NumActivePowerEvents; /*!< counter for the number of active power events */
+
+ IMG_UINT32 ui32TimeWraps; /*!< to count time wraps in the Timer task*/
+ IMG_UINT32 ui32HostClock; /*!< Host clock value at microkernel power-up time */
+ IMG_UINT32 ui32AssertFail; /*!< Microkernel assert failure code */
+
+#if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS)
+ IMG_UINT32 aui32PerfGroup[PVRSRV_SGX_HWPERF_NUM_COUNTERS]; /*!< Specifies the HW's active group selectors */
+ IMG_UINT32 aui32PerfBit[PVRSRV_SGX_HWPERF_NUM_COUNTERS]; /*!< Specifies the HW's active bit selectors */
+ IMG_UINT32 ui32PerfCounterBitSelect; /*!< Specifies the HW's counter bit selectors */
+ IMG_UINT32 ui32PerfSumMux; /*!< Specifies the HW's sum_mux selectors */
+#else
+ IMG_UINT32 ui32PerfGroup; /*!< Specifies the HW's active group */
+#endif /* SGX_FEATURE_EXTENDED_PERF_COUNTERS */
+
+#if defined(FIX_HW_BRN_31939)
+ IMG_UINT32 ui32BRN31939Mem;
+#endif
+
+ IMG_UINT32 ui32OpenCLDelayCount; /* Counter to keep track OpenCL task completion time in units of regular task time out events */
+} SGXMKIF_HOST_CTL;
+
+/*
+ * TA queue Kick flags
+ */
+/* Set in DoKickKM to indicate the command is ready to be processed */
+#define SGXMKIF_CMDTA_CTRLFLAGS_READY 0x00000001
+/*!
+ ******************************************************************************
+ * Shared TA command structure.
+ * This structure is part of the TA command structure proper (SGXMKIF_CMDTA),
+ * and is accessed from the kernel part of the driver and the microkernel.
+ * There shouldn't be a need to access it from user space.
+ *****************************************************************************/
+typedef struct _SGXMKIF_CMDTA_SHARED_
+{
+ IMG_UINT32 ui32CtrlFlags;
+
+ IMG_UINT32 ui32NumTAStatusVals;
+ IMG_UINT32 ui32Num3DStatusVals;
+
+ /* KEEP THESE 4 VARIABLES TOGETHER FOR UKERNEL BLOCK LOAD */
+ IMG_UINT32 ui32TATQSyncWriteOpsPendingVal;
+ IMG_DEV_VIRTADDR sTATQSyncWriteOpsCompleteDevVAddr;
+ IMG_UINT32 ui32TATQSyncReadOpsPendingVal;
+ IMG_DEV_VIRTADDR sTATQSyncReadOpsCompleteDevVAddr;
+
+ /* KEEP THESE 4 VARIABLES TOGETHER FOR UKERNEL BLOCK LOAD */
+ IMG_UINT32 ui323DTQSyncWriteOpsPendingVal;
+ IMG_DEV_VIRTADDR s3DTQSyncWriteOpsCompleteDevVAddr;
+ IMG_UINT32 ui323DTQSyncReadOpsPendingVal;
+ IMG_DEV_VIRTADDR s3DTQSyncReadOpsCompleteDevVAddr;
+
+ /* sync criteria used for TA/3D dependency synchronisation */
+ PVRSRV_DEVICE_SYNC_OBJECT sTA3DDependency;
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+ /* SRC and DST syncs */
+ IMG_UINT32 ui32NumTASrcSyncs;
+ PVRSRV_DEVICE_SYNC_OBJECT asTASrcSyncs[SGX_MAX_TA_SRC_SYNCS];
+ IMG_UINT32 ui32NumTADstSyncs;
+ PVRSRV_DEVICE_SYNC_OBJECT asTADstSyncs[SGX_MAX_TA_DST_SYNCS];
+ IMG_UINT32 ui32Num3DSrcSyncs;
+ PVRSRV_DEVICE_SYNC_OBJECT as3DSrcSyncs[SGX_MAX_3D_SRC_SYNCS];
+#else
+ /* source dependency details */
+ IMG_UINT32 ui32NumSrcSyncs;
+ PVRSRV_DEVICE_SYNC_OBJECT asSrcSyncs[SGX_MAX_SRC_SYNCS_TA];
+#endif
+
+ CTL_STATUS sCtlTAStatusInfo[SGX_MAX_TA_STATUS_VALS];
+ CTL_STATUS sCtl3DStatusInfo[SGX_MAX_3D_STATUS_VALS];
+
+} SGXMKIF_CMDTA_SHARED;
+
+/*
+ * Services internal TQ limits
+ */
+#define SGXTQ_MAX_STATUS SGX_MAX_TRANSFER_STATUS_VALS + 2
+
+/*
+ * Transfer queue Kick flags
+ */
+/* if set the uKernel won't update the sync objects on completion*/
+#define SGXMKIF_TQFLAGS_NOSYNCUPDATE 0x00000001
+/* if set the kernel won't advance the pending values*/
+#define SGXMKIF_TQFLAGS_KEEPPENDING 0x00000002
+/* in services equivalent for the same client flags*/
+#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
+/* if set uKernel only updates syncobjects / status values*/
+#define SGXMKIF_TQFLAGS_DUMMYTRANSFER 0x00000020
+
+/*!
+ ******************************************************************************
+ * Shared Transfer Queue command structure.
+ * This structure is placed at the start of the TQ command structure proper
+ * (SGXMKIF_TRANSFERCMD), and is accessed from the kernel part of the driver
+ * and the microkernel.
+ *****************************************************************************/
+typedef struct _SGXMKIF_TRANSFERCMD_SHARED_
+{
+ /* need to be able to check read and write ops on src, and update reads */
+
+ IMG_UINT32 ui32NumSrcSyncs;
+ PVRSRV_DEVICE_SYNC_OBJECT asSrcSyncs[SGX_MAX_SRC_SYNCS_TQ];
+ /* need to be able to check reads and writes on dest, and update writes */
+
+ IMG_UINT32 ui32NumDstSyncs;
+ PVRSRV_DEVICE_SYNC_OBJECT asDstSyncs[SGX_MAX_DST_SYNCS_TQ];
+ /* KEEP THESE 4 VARIABLES TOGETHER FOR UKERNEL BLOCK LOAD */
+ IMG_UINT32 ui32TASyncWriteOpsPendingVal;
+ IMG_DEV_VIRTADDR sTASyncWriteOpsCompleteDevVAddr;
+ IMG_UINT32 ui32TASyncReadOpsPendingVal;
+ IMG_DEV_VIRTADDR sTASyncReadOpsCompleteDevVAddr;
+
+ /* KEEP THESE 4 VARIABLES TOGETHER FOR UKERNEL BLOCK LOAD */
+ 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;
+
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+typedef struct _SGXMKIF_2DCMD_SHARED_ {
+ /* need to be able to check read and write ops on src, and update reads */
+ IMG_UINT32 ui32NumSrcSync;
+ PVRSRV_DEVICE_SYNC_OBJECT sSrcSyncData[SGX_MAX_2D_SRC_SYNC_OPS];
+
+ /* need to be able to check reads and writes on dest, and update writes */
+ PVRSRV_DEVICE_SYNC_OBJECT sDstSyncData;
+
+ /* need to be able to check reads and writes on TA ops, and update writes */
+ PVRSRV_DEVICE_SYNC_OBJECT sTASyncData;
+
+ /* need to be able to check reads and writes on 2D ops, and update writes */
+ PVRSRV_DEVICE_SYNC_OBJECT s3DSyncData;
+} SGXMKIF_2DCMD_SHARED, *PSGXMKIF_2DCMD_SHARED;
+#endif /* SGX_FEATURE_2D_HARDWARE */
+
+
+typedef struct _SGXMKIF_HWDEVICE_SYNC_LIST_
+{
+ IMG_DEV_VIRTADDR sAccessDevAddr;
+ IMG_UINT32 ui32NumSyncObjects;
+ /* Must be the last variable in the structure */
+ PVRSRV_DEVICE_SYNC_OBJECT asSyncData[1];
+} SGXMKIF_HWDEVICE_SYNC_LIST, *PSGXMKIF_HWDEVICE_SYNC_LIST;
+
+
+/*!
+ *****************************************************************************
+ * Microkernel initialisation status
+ *****************************************************************************/
+#define PVRSRV_USSE_EDM_INIT_COMPLETE (1UL << 0) /*!< ukernel initialisation complete */
+
+/*!
+ *****************************************************************************
+ * Microkernel power status definitions
+ *****************************************************************************/
+#define PVRSRV_USSE_EDM_POWMAN_IDLE_COMPLETE (1UL << 2) /*!< Signal from ukernel->Host indicating SGX is idle */
+#define PVRSRV_USSE_EDM_POWMAN_POWEROFF_COMPLETE (1UL << 3) /*!< Signal from ukernel->Host indicating SGX can be powered down */
+#define PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE (1UL << 4) /*!< Signal from ukernel->Host indicating there is work to do immediately */
+#define PVRSRV_USSE_EDM_POWMAN_NO_WORK (1UL << 5) /*!< Signal from ukernel->Host indicating no work to do */
+
+/*!
+ *****************************************************************************
+ * EDM interrupt defines
+ *****************************************************************************/
+#define PVRSRV_USSE_EDM_INTERRUPT_HWR (1UL << 0) /*!< EDM requesting hardware recovery */
+#define PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER (1UL << 1) /*!< EDM requesting to be powered down */
+#define PVRSRV_USSE_EDM_INTERRUPT_IDLE (1UL << 2) /*!< EDM indicating SGX idle */
+
+/*!
+ *****************************************************************************
+ * EDM Resource management defines
+ *****************************************************************************/
+#define PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE (1UL << 0) /*!< Signal from EDM->Host indicating clean-up request completion */
+#define PVRSRV_USSE_EDM_CLEANUPCMD_BUSY (1UL << 1) /*!< Signal from EDM->Host indicating clean-up is blocked as the resource is busy */
+#define PVRSRV_USSE_EDM_CLEANUPCMD_DONE (1UL << 2) /*!< Signal from EDM->Host indicating clean-up has been done */
+
+#if defined(FIX_HW_BRN_28889)
+/*!
+ *****************************************************************************
+ * EDM BIF Cache Invalidate defines
+ *****************************************************************************/
+#define PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE (1UL << 0) /*!< Signal from EDM->Host indicating the BIF invalidate has started */
+#endif
+
+/*!
+ ****************************************************************************
+ * EDM / uKernel Get misc info defines
+ ****************************************************************************
+ */
+#define PVRSRV_USSE_MISCINFO_READY 0x1UL
+#define PVRSRV_USSE_MISCINFO_GET_STRUCT_SIZES 0x2UL /*!< If set, getmiscinfo ukernel func returns structure sizes */
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+#define PVRSRV_USSE_MISCINFO_MEMREAD 0x4UL /*!< If set, getmiscinfo ukernel func reads arbitrary device mem */
+#define PVRSRV_USSE_MISCINFO_MEMWRITE 0x8UL /*!< If set, getmiscinfo ukernel func writes arbitrary device mem */
+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+#define PVRSRV_USSE_MISCINFO_MEMREAD_FAIL 0x1UL << 31 /* If set, ukernel was unable to read from the mem context */
+#endif
+#endif
+
+
+/* Cleanup command control word */
+#define PVRSRV_CLEANUPCMD_RT 0x1U
+#define PVRSRV_CLEANUPCMD_RC 0x2U
+#define PVRSRV_CLEANUPCMD_TC 0x3U
+#define PVRSRV_CLEANUPCMD_2DC 0x4U
+#define PVRSRV_CLEANUPCMD_PB 0x5U
+
+/* Power command control word */
+#define PVRSRV_POWERCMD_POWEROFF 0x1U
+#define PVRSRV_POWERCMD_IDLE 0x2U
+#define PVRSRV_POWERCMD_RESUME 0x3U
+
+/* Context suspend command control word */
+#define PVRSRV_CTXSUSPCMD_SUSPEND 0x1U
+#define PVRSRV_CTXSUSPCMD_RESUME 0x2U
+
+
+#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+#define SGX_BIF_DIR_LIST_INDEX_EDM (SGX_FEATURE_BIF_NUM_DIRLISTS - 1)
+#else
+#define SGX_BIF_DIR_LIST_INDEX_EDM (0)
+#endif
+
+/*!
+ ******************************************************************************
+ * microkernel cache control requests
+ ******************************************************************************/
+#define SGXMKIF_CC_INVAL_BIF_PT 0x1
+#define SGXMKIF_CC_INVAL_BIF_PD 0x2
+#define SGXMKIF_CC_INVAL_BIF_SL 0x4
+#define SGXMKIF_CC_INVAL_DATA 0x8
+
+
+/*!
+ ******************************************************************************
+ * SGX microkernel interface structure sizes
+ ******************************************************************************/
+typedef struct _SGX_MISCINFO_STRUCT_SIZES_
+{
+#if defined (SGX_FEATURE_2D_HARDWARE)
+ IMG_UINT32 ui32Sizeof_2DCMD;
+ IMG_UINT32 ui32Sizeof_2DCMD_SHARED;
+#endif
+ IMG_UINT32 ui32Sizeof_CMDTA;
+ IMG_UINT32 ui32Sizeof_CMDTA_SHARED;
+ IMG_UINT32 ui32Sizeof_TRANSFERCMD;
+ IMG_UINT32 ui32Sizeof_TRANSFERCMD_SHARED;
+ IMG_UINT32 ui32Sizeof_3DREGISTERS;
+ IMG_UINT32 ui32Sizeof_HWPBDESC;
+ IMG_UINT32 ui32Sizeof_HWRENDERCONTEXT;
+ IMG_UINT32 ui32Sizeof_HWRENDERDETAILS;
+ IMG_UINT32 ui32Sizeof_HWRTDATA;
+ IMG_UINT32 ui32Sizeof_HWRTDATASET;
+ IMG_UINT32 ui32Sizeof_HWTRANSFERCONTEXT;
+ IMG_UINT32 ui32Sizeof_HOST_CTL;
+ IMG_UINT32 ui32Sizeof_COMMAND;
+} SGX_MISCINFO_STRUCT_SIZES;
+
+
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+/*!
+ *****************************************************************************
+ * SGX misc info for accessing device memory from ukernel
+ *****************************************************************************
+ */
+typedef struct _PVRSRV_SGX_MISCINFO_MEMACCESS
+{
+ IMG_DEV_VIRTADDR sDevVAddr; /*!< dev virtual addr for mem access */
+ IMG_DEV_PHYADDR sPDDevPAddr; /*!< device physical addr of PD for the mem heap */
+} PVRSRV_SGX_MISCINFO_MEMACCESS;
+#endif
+
+/*!
+ *****************************************************************************
+ * SGX Misc Info structure used in the microkernel
+ * PVRSRV_SGX_MISCINFO_FEATURES is defined in sgxapi_km.h
+ ****************************************************************************/
+typedef struct _PVRSRV_SGX_MISCINFO_INFO
+{
+ IMG_UINT32 ui32MiscInfoFlags;
+ PVRSRV_SGX_MISCINFO_FEATURES sSGXFeatures; /*!< external info for client */
+ SGX_MISCINFO_STRUCT_SIZES sSGXStructSizes; /*!< internal info: microkernel structure sizes */
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+ PVRSRV_SGX_MISCINFO_MEMACCESS sSGXMemAccessSrc; /*!< internal info: for reading dev memory */
+ PVRSRV_SGX_MISCINFO_MEMACCESS sSGXMemAccessDest; /*!< internal info: for writing dev memory */
+#endif
+} PVRSRV_SGX_MISCINFO_INFO;
+
+#ifdef PVRSRV_USSE_EDM_STATUS_DEBUG
+/*!
+ *****************************************************************************
+ * Number of entries in the microkernel status buffer
+ *****************************************************************************/
+#define SGXMK_TRACE_BUFFER_SIZE 512
+#endif /* PVRSRV_USSE_EDM_STATUS_DEBUG */
+
+#define SGXMKIF_HWPERF_CB_SIZE 0x100 /* must be 2^n*/
+
+/*!
+ *****************************************************************************
+ * One entry in the HWPerf Circular Buffer.
+ *****************************************************************************/
+typedef struct _SGXMKIF_HWPERF_CB_ENTRY_
+{
+ IMG_UINT32 ui32FrameNo;
+ IMG_UINT32 ui32PID;
+ IMG_UINT32 ui32RTData;
+ IMG_UINT32 ui32Type;
+ IMG_UINT32 ui32Ordinal;
+ IMG_UINT32 ui32Info;
+ IMG_UINT32 ui32TimeWraps;
+ IMG_UINT32 ui32Time;
+ /* NOTE: There should always be at least as many 3D cores as TA cores. */
+ IMG_UINT32 ui32Counters[SGX_FEATURE_MP_CORE_COUNT_3D][PVRSRV_SGX_HWPERF_NUM_COUNTERS];
+ IMG_UINT32 ui32MiscCounters[SGX_FEATURE_MP_CORE_COUNT_3D][PVRSRV_SGX_HWPERF_NUM_MISC_COUNTERS];
+} SGXMKIF_HWPERF_CB_ENTRY;
+
+/*!
+ *****************************************************************************
+ * The HWPerf Circular Buffer.
+ *****************************************************************************/
+typedef struct _SGXMKIF_HWPERF_CB_
+{
+ IMG_UINT32 ui32Woff;
+ IMG_UINT32 ui32Roff;
+ IMG_UINT32 ui32Ordinal;
+ SGXMKIF_HWPERF_CB_ENTRY psHWPerfCBData[SGXMKIF_HWPERF_CB_SIZE];
+} SGXMKIF_HWPERF_CB;
+
+
+#endif /* __SGX_MKIF_KM_H__ */
+
+/******************************************************************************
+ End of file (sgx_mkif_km.h)
+******************************************************************************/
+
+
diff --git a/pvr-source/services4/include/sgx_ukernel_status_codes.h b/pvr-source/services4/include/sgx_ukernel_status_codes.h
new file mode 100644
index 0000000..dc8f2f3
--- /dev/null
+++ b/pvr-source/services4/include/sgx_ukernel_status_codes.h
@@ -0,0 +1,966 @@
+/*************************************************************************/ /*!
+@File sgx_ukernel_status_codes.h
+@Title SGX microkernel debug status codes
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description SGX microkernel debug status codes
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __SGX_UKERNEL_STATUS_CODES_H__
+#define __SGX_UKERNEL_STATUS_CODES_H__
+
+/*
+ NOTE: Do not add any conditional macros to this file! There must be
+ no use of #if defined(). This file is included in srvkm to print
+ stringified ukernel status codes, it must build identically to
+ srvinit.
+*/
+
+/*
+ Users of this header might define this macro to do something
+ clever; the primary use right now is to generate a switch/case
+ LUT for debugging in srvkm. If you add a new code, make sure it
+ has a corresponding MKTC_ST.
+*/
+#ifndef MKTC_ST
+#define MKTC_ST(x)
+#endif
+
+/*
+ It would be nice to put these definitions into an enumeration, but USEASM
+ only has access to the C preprocessor so macros are required.
+*/
+
+/*
+ Bits 24-31 of these codes (0xAD) are a magic number used to help
+ distinguish between them and other debug information which can be
+ optionally dumped into the status buffer, e.g. sync object values.
+*/
+
+/*
+ Microkernel trace codes
+*/
+#define MKTC_EHEVENT_3DMEMFREE 0xAD000001
+MKTC_ST(MKTC_EHEVENT_3DMEMFREE)
+#define MKTC_EHEVENT_PIXELENDRENDER 0xAD000002
+MKTC_ST(MKTC_EHEVENT_PIXELENDRENDER)
+#define MKTC_EHEVENT_ISPBREAKPOINT 0xAD000004
+MKTC_ST(MKTC_EHEVENT_ISPBREAKPOINT)
+#define MKTC_EHEVENT_TAFINISHED 0xAD000005
+MKTC_ST(MKTC_EHEVENT_TAFINISHED)
+#define MKTC_EHEVENT_OUTOFMEM 0xAD000007
+MKTC_ST(MKTC_EHEVENT_OUTOFMEM)
+#define MKTC_EHEVENT_TATERMINATE 0xAD000008
+MKTC_ST(MKTC_EHEVENT_TATERMINATE)
+#define MKTC_EHEVENT_TIMER 0xAD000009
+MKTC_ST(MKTC_EHEVENT_TIMER)
+#define MKTC_EHEVENT_SWEVENT 0xAD00000A
+MKTC_ST(MKTC_EHEVENT_SWEVENT)
+#define MKTC_EHEVENT_2DCOMPLETE 0xAD00000B
+MKTC_ST(MKTC_EHEVENT_2DCOMPLETE)
+
+#define MKTC_3DEVENT_3DMEMFREE 0xAD000100
+MKTC_ST(MKTC_3DEVENT_3DMEMFREE)
+#define MKTC_3DEVENT_PIXELENDRENDER 0xAD000101
+MKTC_ST(MKTC_3DEVENT_PIXELENDRENDER)
+#define MKTC_3DEVENT_ISPBREAKPOINT 0xAD000102
+MKTC_ST(MKTC_3DEVENT_ISPBREAKPOINT)
+#define MKTC_3DEVENT_END 0xAD000104
+MKTC_ST(MKTC_3DEVENT_END)
+#define MKTC_3DLB_3DMEMFREE 0xAD000180
+MKTC_ST(MKTC_3DLB_3DMEMFREE)
+#define MKTC_3DLB_PIXELENDRENDER 0xAD000181
+MKTC_ST(MKTC_3DLB_PIXELENDRENDER)
+#define MKTC_3DLB_ISPBREAKPOINT 0xAD000182
+MKTC_ST(MKTC_3DLB_ISPBREAKPOINT)
+#define MKTC_3DLB_FIND3D 0xAD000183
+MKTC_ST(MKTC_3DLB_FIND3D)
+#define MKTC_3DLB_END 0xAD000184
+MKTC_ST(MKTC_3DLB_END)
+
+#define MKTC_TAEVENT_TAFINISHED 0xAD000200
+MKTC_ST(MKTC_TAEVENT_TAFINISHED)
+#define MKTC_TAEVENT_END 0xAD000202
+MKTC_ST(MKTC_TAEVENT_END)
+#define MKTC_TALB_TAFINISHED 0xAD000280
+MKTC_ST(MKTC_TALB_TAFINISHED)
+#define MKTC_TALB_FINDTA 0xAD000281
+MKTC_ST(MKTC_TALB_FINDTA)
+#define MKTC_TALB_END 0xAD000282
+MKTC_ST(MKTC_TALB_END)
+
+#define MKTC_CRRL_WRITEOPSBLOCKED 0xAD000300
+MKTC_ST(MKTC_CRRL_WRITEOPSBLOCKED)
+#define MKTC_CRRL_READOPSBLOCKED 0xAD000301
+MKTC_ST(MKTC_CRRL_READOPSBLOCKED)
+#define MKTC_CRRL_FOUNDRENDER 0xAD000302
+MKTC_ST(MKTC_CRRL_FOUNDRENDER)
+#define MKTC_CRRL_NORENDER 0xAD000303
+MKTC_ST(MKTC_CRRL_NORENDER)
+#define MKTC_CRRL_TARC_DIFFERENT 0xAD000304
+MKTC_ST(MKTC_CRRL_TARC_DIFFERENT)
+#define MKTC_CRRL_BLOCKEDRC 0xAD000309
+MKTC_ST(MKTC_CRRL_BLOCKEDRC)
+#define MKTC_CRRL_BLOCKEDRTDATA 0xAD00030A
+MKTC_ST(MKTC_CRRL_BLOCKEDRTDATA)
+#define MKTC_CRRL_CONTEXT_SUSPENDED 0xAD00030B
+MKTC_ST(MKTC_CRRL_CONTEXT_SUSPENDED)
+#define MKTC_CRRL_TAWAITINGFORMEM 0xAD00030C
+MKTC_ST(MKTC_CRRL_TAWAITINGFORMEM)
+#define MKTC_CRRL_TAOOMBUTPRIOINV 0xAD00030D
+MKTC_ST(MKTC_CRRL_TAOOMBUTPRIOINV)
+#define MKTC_CRRL_READOPS2BLOCKED 0xAD00030E
+MKTC_ST(MKTC_CRRL_READOPS2BLOCKED)
+#define MKTC_CRRL_SRC_WRITEOPSBLOCKED 0xAD00030F
+MKTC_ST(MKTC_CRRL_SRC_WRITEOPSBLOCKED)
+#define MKTC_CRRL_SRC_READOPSBLOCKED 0xAD000310
+MKTC_ST(MKTC_CRRL_SRC_READOPSBLOCKED)
+#define MKTC_CRRL_TQ_WRITEOPSBLOCKED 0xAD000311
+MKTC_ST(MKTC_CRRL_TQ_WRITEOPSBLOCKED)
+#define MKTC_CRRL_TQ_READOPSBLOCKED 0xAD000312
+MKTC_ST(MKTC_CRRL_TQ_READOPSBLOCKED)
+
+#define MKTC_KICKRENDER_START 0xAD000400
+MKTC_ST(MKTC_KICKRENDER_START)
+#define MKTC_KICKRENDER_OVERLAP 0xAD000401
+MKTC_ST(MKTC_KICKRENDER_OVERLAP)
+#define MKTC_KICKRENDER_ISP_START 0xAD000402
+MKTC_ST(MKTC_KICKRENDER_ISP_START)
+#define MKTC_KICKRENDER_RESUME 0xAD000403
+MKTC_ST(MKTC_KICKRENDER_RESUME)
+#define MKTC_KICKRENDER_CONFIG_REGION_HDRS 0xAD000404
+MKTC_ST(MKTC_KICKRENDER_CONFIG_REGION_HDRS)
+#define MKTC_KICKRENDER_END 0xAD000408
+MKTC_ST(MKTC_KICKRENDER_END)
+#define MKTC_KICKRENDER_RENDERCONTEXT 0xAD000409
+MKTC_ST(MKTC_KICKRENDER_RENDERCONTEXT)
+#define MKTC_KICKRENDER_RTDATA 0xAD00040A
+MKTC_ST(MKTC_KICKRENDER_RTDATA)
+#define MKTC_KICKRENDER_PID 0xAD00040B
+MKTC_ST(MKTC_KICKRENDER_PID)
+
+#define MKTC_RENDERFINISHED_START 0xAD000500
+MKTC_ST(MKTC_RENDERFINISHED_START)
+#define MKTC_RF_START_NEXT_MT 0xAD000501
+MKTC_ST(MKTC_RF_START_NEXT_MT)
+#define MKTC_RF_ALL_MTS_DONE 0xAD000502
+MKTC_ST(MKTC_RF_ALL_MTS_DONE)
+#define MKTC_RENDERFINISHED_END 0xAD000503
+MKTC_ST(MKTC_RENDERFINISHED_END)
+#define MKTC_VISQUERY_START 0xAD000504
+MKTC_ST(MKTC_VISQUERY_START)
+#define MKTC_VISQUERY_END 0xAD000505
+MKTC_ST(MKTC_VISQUERY_END)
+#define MKTC_TRANSFERRENDERFINISHED_START 0xAD000508
+MKTC_ST(MKTC_TRANSFERRENDERFINISHED_START)
+#define MKTC_TRANSFERRENDERFINISHED_END 0xAD000509
+MKTC_ST(MKTC_TRANSFERRENDERFINISHED_END)
+#define MKTC_TRF_UPDATESTATUSVALS 0xAD00050A
+MKTC_ST(MKTC_TRF_UPDATESTATUSVALS)
+#define MKTC_TRF_UPDATESTATUSVALS_DONE 0xAD00050B
+MKTC_ST(MKTC_TRF_UPDATESTATUSVALS_DONE)
+
+#define MKTC_PIXELENDRENDER_START 0xAD000600
+MKTC_ST(MKTC_PIXELENDRENDER_START)
+#define MKTC_PIXELENDRENDER_AFTERLOCK 0xAD000601
+MKTC_ST(MKTC_PIXELENDRENDER_AFTERLOCK)
+#define MKTC_PIXELENDRENDER_END 0xAD000602
+MKTC_ST(MKTC_PIXELENDRENDER_END)
+#define MKTC_PIXELENDRENDER_TLQEND 0xAD000603
+MKTC_ST(MKTC_PIXELENDRENDER_TLQEND)
+
+#define MKTC_3DMEMFREE_START 0xAD000700
+MKTC_ST(MKTC_3DMEMFREE_START)
+#define MKTC_3DMEMFREE_AFTERLOCK 0xAD000701
+MKTC_ST(MKTC_3DMEMFREE_AFTERLOCK)
+#define MKTC_3DMEMFREE_TESTEOR 0xAD000702
+MKTC_ST(MKTC_3DMEMFREE_TESTEOR)
+#define MKTC_3DMEMFREE_END 0xAD000703
+MKTC_ST(MKTC_3DMEMFREE_END)
+
+#define MKTC_KICKTA_START 0xAD000800
+MKTC_ST(MKTC_KICKTA_START)
+#define MKTC_KICKTA_OVERLAP 0xAD000801
+MKTC_ST(MKTC_KICKTA_OVERLAP)
+#define MKTC_KICKTA_RESETCONTEXT 0xAD000802
+MKTC_ST(MKTC_KICKTA_RESETCONTEXT)
+#define MKTC_KICKTA_VDM_START 0xAD000803
+MKTC_ST(MKTC_KICKTA_VDM_START)
+#define MKTC_KICKTA_END 0xAD000804
+MKTC_ST(MKTC_KICKTA_END)
+#define MKTC_KICKTA_RENDERCONTEXT 0xAD000805
+MKTC_ST(MKTC_KICKTA_RENDERCONTEXT)
+#define MKTC_KICKTA_RTDATA 0xAD000806
+MKTC_ST(MKTC_KICKTA_RTDATA)
+#define MKTC_KICKTA_RESET_VDMCSSTATUS 0xAD000807
+MKTC_ST(MKTC_KICKTA_RESET_VDMCSSTATUS)
+#define MKTC_KICKTA_RESET_BUFFERS 0xAD000808
+MKTC_ST(MKTC_KICKTA_RESET_BUFFERS)
+#define MKTC_KICKTA_PID 0xAD000809
+MKTC_ST(MKTC_KICKTA_PID)
+#define MKTC_KICKTA_TACMD_DEBUG 0xAD00080A
+MKTC_ST(MKTC_KICKTA_TACMD_DEBUG)
+#define MKTC_KICKTA_FREECONTEXT 0xAD00080B
+MKTC_ST(MKTC_KICKTA_FREECONTEXT)
+#define MKTC_KICKTA_PIM_PATCHING 0xAD00080C
+MKTC_ST(MKTC_KICKTA_PIM_PATCHING)
+
+#define MKTC_KICKTA_CHKPT_START_DUMMY_CS 0xAD0008A1
+MKTC_ST(MKTC_KICKTA_CHKPT_START_DUMMY_CS)
+#define MKTC_KICKTA_CHKPT_START_DUMMY_TAK 0xAD0008A2
+MKTC_ST(MKTC_KICKTA_CHKPT_START_DUMMY_TAK)
+#define MKTC_KICKTA_CHKPT_WAIT_FOR_DUMMY_KICK 0xAD0008A3
+MKTC_ST(MKTC_KICKTA_CHKPT_WAIT_FOR_DUMMY_KICK)
+#define MKTC_KICKTA_CHKPT_WAIT_NEXT_CORE 0xAD0008A4
+MKTC_ST(MKTC_KICKTA_CHKPT_WAIT_NEXT_CORE)
+#define MKTC_KICKTA_CHKPT_RESET_COMPLETE 0xAD0008A5
+MKTC_ST(MKTC_KICKTA_CHKPT_RESET_COMPLETE)
+#define MKTC_KICKTA_CHKPT_CHECK_SWITCH 0xAD0008A6
+MKTC_ST(MKTC_KICKTA_CHKPT_CHECK_SWITCH)
+
+#define MKTC_HOSTKICK_START 0xAD000900
+MKTC_ST(MKTC_HOSTKICK_START)
+#define MKTC_HOSTKICK_END 0xAD000901
+MKTC_ST(MKTC_HOSTKICK_END)
+#define MKTC_HOSTKICK_PROCESS_QUEUES_END 0xAD000902
+MKTC_ST(MKTC_HOSTKICK_PROCESS_QUEUES_END)
+#define MKTC_HOSTKICK_2D 0xAD000903
+MKTC_ST(MKTC_HOSTKICK_2D)
+#define MKTC_HOSTKICK_TRANSFER 0xAD000904
+MKTC_ST(MKTC_HOSTKICK_TRANSFER)
+#define MKTC_HOSTKICK_TA 0xAD000905
+MKTC_ST(MKTC_HOSTKICK_TA)
+#define MKTC_HOSTKICK_PROCESS_QUEUES 0xAD000906
+MKTC_ST(MKTC_HOSTKICK_PROCESS_QUEUES)
+#define MKTC_HOSTKICK_RESUME 0xAD000908
+MKTC_ST(MKTC_HOSTKICK_RESUME)
+#define MKTC_HOSTKICK_POWEROFF 0xAD000909
+MKTC_ST(MKTC_HOSTKICK_POWEROFF)
+#define MKTC_HOSTKICK_IDLE 0xAD00090A
+MKTC_ST(MKTC_HOSTKICK_IDLE)
+#define MKTC_HOSTKICK_CTXSUSPEND 0xAD00090B
+MKTC_ST(MKTC_HOSTKICK_CTXSUSPEND)
+#define MKTC_HOSTKICK_CTXRESUME 0xAD00090C
+MKTC_ST(MKTC_HOSTKICK_CTXRESUME)
+
+#define MKTC_TIMER_POTENTIAL_TA_LOCKUP 0xAD000A00
+MKTC_ST(MKTC_TIMER_POTENTIAL_TA_LOCKUP)
+#define MKTC_TIMER_POTENTIAL_3D_LOCKUP 0xAD000A01
+MKTC_ST(MKTC_TIMER_POTENTIAL_3D_LOCKUP)
+#define MKTC_TIMER_CTAL_START 0xAD000A02
+MKTC_ST(MKTC_TIMER_CTAL_START)
+#define MKTC_TIMER_CTAL_END 0xAD000A03
+MKTC_ST(MKTC_TIMER_CTAL_END)
+#define MKTC_TIMER_C3DL_START 0xAD000A04
+MKTC_ST(MKTC_TIMER_C3DL_START)
+#define MKTC_TIMER_C3DL_END 0xAD000A05
+MKTC_ST(MKTC_TIMER_C3DL_END)
+#define MKTC_TIMER_LOCKUP 0xAD000A0A
+MKTC_ST(MKTC_TIMER_LOCKUP)
+#define MKTC_TIMER_NOT_TA_LOCKUP 0xAD000A0B
+MKTC_ST(MKTC_TIMER_NOT_TA_LOCKUP)
+#define MKTC_TIMER_NOT_3D_LOCKUP 0xAD000A0C
+MKTC_ST(MKTC_TIMER_NOT_3D_LOCKUP)
+#define MKTC_TIMER_2D_LOCKUP 0xAD000A0D
+MKTC_ST(MKTC_TIMER_2D_LOCKUP)
+#define MKTC_TIMER_POTENTIAL_2D_LOCKUP 0xAD000A10
+MKTC_ST(MKTC_TIMER_POTENTIAL_2D_LOCKUP)
+#define MKTC_TIMER_C2DL_START 0xAD000A11
+MKTC_ST(MKTC_TIMER_C2DL_START)
+#define MKTC_TIMER_C2DL_END 0xAD000A12
+MKTC_ST(MKTC_TIMER_C2DL_END)
+#define MKTC_TIMER_NOT_2D_LOCKUP 0xAD000A13
+MKTC_ST(MKTC_TIMER_NOT_2D_LOCKUP)
+#define MKTC_TIMER_ABORTALL 0xAD000A0E
+MKTC_ST(MKTC_TIMER_ABORTALL)
+#define MKTC_TIMER_END 0xAD000A0F
+MKTC_ST(MKTC_TIMER_END)
+
+#define MKTC_HWR_START 0xAD000B00
+MKTC_ST(MKTC_HWR_START)
+#define MKTC_HWR_END 0xAD000B01
+MKTC_ST(MKTC_HWR_END)
+#define MKTC_HWR_HKS 0xAD000B02
+MKTC_ST(MKTC_HWR_HKS)
+#define MKTC_HWR_PRL 0xAD000B03
+MKTC_ST(MKTC_HWR_PRL)
+#define MKTC_HWR_PRL_DP 0xAD000B04
+MKTC_ST(MKTC_HWR_PRL_DP)
+#define MKTC_HWR_CRL 0xAD000B05
+MKTC_ST(MKTC_HWR_CRL)
+#define MKTC_HWR_CRL_DP 0xAD000B06
+MKTC_ST(MKTC_HWR_CRL_DP)
+#define MKTC_HWR_TRL 0xAD000B07
+MKTC_ST(MKTC_HWR_TRL)
+#define MKTC_HWR_TRL_DP 0xAD000B08
+MKTC_ST(MKTC_HWR_TRL_DP)
+#define MKTC_HWR_ISC 0xAD000B09
+MKTC_ST(MKTC_HWR_ISC)
+#define MKTC_HWR_2DL 0xAD000B0A
+MKTC_ST(MKTC_HWR_2DL)
+#define MKTC_HWR_CLEANUP 0xAD000B0B
+MKTC_ST(MKTC_HWR_CLEANUP)
+
+#define MKTC_URSV_START 0xAD000C00
+MKTC_ST(MKTC_URSV_START)
+#define MKTC_URSV_UPDATEWRITEOPS 0xAD000C01
+MKTC_ST(MKTC_URSV_UPDATEWRITEOPS)
+#define MKTC_URSV_UPDATESTATUSVALS 0xAD000C03
+MKTC_ST(MKTC_URSV_UPDATESTATUSVALS)
+#define MKTC_URSV_UPDATESTATUSVALS_DONE 0xAD000C04
+MKTC_ST(MKTC_URSV_UPDATESTATUSVALS_DONE)
+#define MKTC_URSV_END 0xAD000C05
+MKTC_ST(MKTC_URSV_END)
+
+#define MKTC_STORETACONTEXT_START 0xAD000D00
+MKTC_ST(MKTC_STORETACONTEXT_START)
+#define MKTC_STORETACONTEXT_END 0xAD000D01
+MKTC_ST(MKTC_STORETACONTEXT_END)
+#define MKTC_LOADTACONTEXT_START 0xAD000D02
+MKTC_ST(MKTC_LOADTACONTEXT_START)
+#define MKTC_LOADTACONTEXT_END 0xAD000D03
+MKTC_ST(MKTC_LOADTACONTEXT_END)
+#define MKTC_STORE3DCONTEXT_START 0xAD000D04
+MKTC_ST(MKTC_STORE3DCONTEXT_START)
+#define MKTC_STORE3DCONTEXT_END 0xAD000D05
+MKTC_ST(MKTC_STORE3DCONTEXT_END)
+#define MKTC_LOAD3DCONTEXT_START 0xAD000D06
+MKTC_ST(MKTC_LOAD3DCONTEXT_START)
+#define MKTC_LOAD3DCONTEXT_END 0xAD000D07
+MKTC_ST(MKTC_LOAD3DCONTEXT_END)
+
+#define MKTC_FINDTA_POWERREQUEST 0xAD000E00
+MKTC_ST(MKTC_FINDTA_POWERREQUEST)
+#define MKTC_FINDTA_TA3D_OVERLAP_BLOCKED 0xAD000E01
+MKTC_ST(MKTC_FINDTA_TA3D_OVERLAP_BLOCKED)
+#define MKTC_FINDTA_RTDATA_RENDERING 0xAD000E02
+MKTC_ST(MKTC_FINDTA_RTDATA_RENDERING)
+#define MKTC_FINDTA_3DRC_DIFFERENT 0xAD000E03
+MKTC_ST(MKTC_FINDTA_3DRC_DIFFERENT)
+#define MKTC_FINDTA_WRITEOPSBLOCKED 0xAD000E04
+MKTC_ST(MKTC_FINDTA_WRITEOPSBLOCKED)
+#define MKTC_FINDTA_READOPSBLOCKED 0xAD000E05
+MKTC_ST(MKTC_FINDTA_READOPSBLOCKED)
+#define MKTC_FINDTA_RESIZE_PB 0xAD000E06
+MKTC_ST(MKTC_FINDTA_RESIZE_PB)
+#define MKTC_FINDTA_RESIZE_PB_BLOCKED 0xAD000E07
+MKTC_ST(MKTC_FINDTA_RESIZE_PB_BLOCKED)
+#define MKTC_FINDTA_SHRINK_PB 0xAD000E08
+MKTC_ST(MKTC_FINDTA_SHRINK_PB)
+#define MKTC_FINDTA_TAPB_DIFFERENT 0xAD000E09
+MKTC_ST(MKTC_FINDTA_TAPB_DIFFERENT)
+#define MKTC_FINDTA_TACONTEXT_DIFFERENT 0xAD000E0A
+MKTC_ST(MKTC_FINDTA_TACONTEXT_DIFFERENT)
+#define MKTC_FINDTA_TA2D_OVERLAP_BLOCKED 0xAD000E0B
+MKTC_ST(MKTC_FINDTA_TA2D_OVERLAP_BLOCKED)
+#define MKTC_FINDTA_CONTEXT_SUSPENDED 0xAD000E0C
+MKTC_ST(MKTC_FINDTA_CONTEXT_SUSPENDED)
+#define MKTC_FINDTA_SRC_READOPSBLOCKED 0xAD000E0D
+MKTC_ST(MKTC_FINDTA_SRC_READOPSBLOCKED)
+#define MKTC_FINDTA_SRC_WRITEOPSBLOCKED 0xAD000E0E
+MKTC_ST(MKTC_FINDTA_SRC_WRITEOPSBLOCKED)
+#define MKTC_FINDTA_READOPS2BLOCKED 0xAD000E0F
+MKTC_ST(MKTC_FINDTA_READOPS2BLOCKED)
+
+#define MKTC_CTRL_SRCREADOPSBLOCKED 0xAD000F00
+MKTC_ST(MKTC_CTRL_SRCREADOPSBLOCKED)
+#define MKTC_CTRL_SRCWRITEOPSBLOCKED 0xAD000F01
+MKTC_ST(MKTC_CTRL_SRCWRITEOPSBLOCKED)
+#define MKTC_CTRL_DSTREADOPSBLOCKED 0xAD000F02
+MKTC_ST(MKTC_CTRL_DSTREADOPSBLOCKED)
+#define MKTC_CTRL_DSTWRITEOPSBLOCKED 0xAD000F03
+MKTC_ST(MKTC_CTRL_DSTWRITEOPSBLOCKED)
+#define MKTC_CTRL_TARC_DIFFERENT 0xAD000F04
+MKTC_ST(MKTC_CTRL_TARC_DIFFERENT)
+#define MKTC_CTRL_CONTEXT_SUSPENDED 0xAD000F05
+MKTC_ST(MKTC_CTRL_CONTEXT_SUSPENDED)
+#define MKTC_CTRL_SRCREADOPS2BLOCKED 0xAD000F06
+MKTC_ST(MKTC_CTRL_SRCREADOPS2BLOCKED)
+#define MKTC_CTRL_3D_WRITEOPSBLOCKED 0xAD000F07
+MKTC_ST(MKTC_CTRL_3D_WRITEOPSBLOCKED)
+#define MKTC_CTRL_3D_READOPSBLOCKED 0xAD000F08
+MKTC_ST(MKTC_CTRL_3D_READOPSBLOCKED)
+
+#define MKTC_DPTA_START 0xAD001000
+MKTC_ST(MKTC_DPTA_START)
+#define MKTC_DPTA_UPDATESTATUSVALS 0xAD001001
+MKTC_ST(MKTC_DPTA_UPDATESTATUSVALS)
+#define MKTC_DPTA_UPDATESTATUSVALS_DONE 0xAD001002
+MKTC_ST(MKTC_DPTA_UPDATESTATUSVALS_DONE)
+#define MKTC_DPTA_NORENDER 0xAD001003
+MKTC_ST(MKTC_DPTA_NORENDER)
+#define MKTC_DPTA_MEMFREE 0xAD001004
+MKTC_ST(MKTC_DPTA_MEMFREE)
+#define MKTC_DPTA_INC_COMPLETECOUNT 0xAD001005
+MKTC_ST(MKTC_DPTA_INC_COMPLETECOUNT)
+
+#define MKTC_INVALDC 0xAD001100
+MKTC_ST(MKTC_INVALDC)
+#define MKTC_INVALPT 0xAD001101
+MKTC_ST(MKTC_INVALPT)
+#define MKTC_INVALSLC 0xAD001102
+MKTC_ST(MKTC_INVALSLC)
+#define MKTC_INVALDATA 0xAD001103
+MKTC_ST(MKTC_INVALDATA)
+
+#define MKTC_RESTARTTA 0xAD001200
+MKTC_ST(MKTC_RESTARTTA)
+#define MKTC_CSABORTNONGBL 0xAD001201
+MKTC_ST(MKTC_CSABORTNONGBL)
+#define MKTC_CSABORTALL 0xAD001202
+MKTC_ST(MKTC_CSABORTALL)
+#define MKTC_CSRENDERINPROGRESS 0xAD001203
+MKTC_ST(MKTC_CSRENDERINPROGRESS)
+#define MKTC_TATERMRENDERINPROGRESS 0xAD001204
+MKTC_ST(MKTC_TATERMRENDERINPROGRESS)
+#define MKTC_RESTARTTANORENDER 0xAD001205
+MKTC_ST(MKTC_RESTARTTANORENDER)
+#define MKTC_SPM_KICKRENDER 0xAD001206
+MKTC_ST(MKTC_SPM_KICKRENDER)
+#define MKTC_SPM_RESUME_ABORTCOMPLETE 0xAD001208
+MKTC_ST(MKTC_SPM_RESUME_ABORTCOMPLETE)
+#define MKTC_RESUMEVDM 0xAD001209
+MKTC_ST(MKTC_RESUMEVDM)
+#define MKTC_REMOVE_RESERVE_MEM 0xAD00120A
+MKTC_ST(MKTC_REMOVE_RESERVE_MEM)
+#define MKTC_INCREASEZLSTHRESHOLD 0xAD00120B
+MKTC_ST(MKTC_INCREASEZLSTHRESHOLD)
+#define MKTC_CSFORCEABORTALL 0xAD00120C
+MKTC_ST(MKTC_CSFORCEABORTALL)
+
+#define MKTC_DUMMY_DEPTH 0xAD00120D
+MKTC_ST(MKTC_DUMMY_DEPTH)
+#define MKTC_DUMMY_DEPTH_CS 0xAD00120E
+MKTC_ST(MKTC_DUMMY_DEPTH_CS)
+
+#define MKTC_MTETE_OOM 0xAD00120F
+MKTC_ST(MKTC_MTETE_OOM)
+#define MKTC_MTETE_OOM_FIRST_STORE_REF 0xAD001210
+MKTC_ST(MKTC_MTETE_OOM_FIRST_STORE_REF)
+#define MKTC_MERGE_STATE_TABLES 0xAD001211
+MKTC_ST(MKTC_MERGE_STATE_TABLES)
+#define MKTC_NO_PAGES_LEFT_FOR_23055 0xAD001212
+MKTC_ST(MKTC_NO_PAGES_LEFT_FOR_23055)
+#define MKTC_NO_STATE_MODS 0xAD001213
+MKTC_ST(MKTC_NO_STATE_MODS)
+#define MKTC_FIND_MTE_PAGE_IN_STATE 0xAD001214
+MKTC_ST(MKTC_FIND_MTE_PAGE_IN_STATE)
+#define MKTC_MTE_PAGE_FOUND 0xAD001215
+MKTC_ST(MKTC_MTE_PAGE_FOUND)
+#define MKTC_MOVE_MTE_PAGE_TO_TA_STATE 0xAD001216
+MKTC_ST(MKTC_MOVE_MTE_PAGE_TO_TA_STATE)
+#define MKTC_MOVE_MTE_PAGE_TO_TA_STATE_END 0xAD001217
+MKTC_ST(MKTC_MOVE_MTE_PAGE_TO_TA_STATE_END)
+#define MKTC_ZERO_ZLS_THRESHOLD 0xAD001218
+MKTC_ST(MKTC_ZERO_ZLS_THRESHOLD)
+#define MKTC_RESTORE_ZLS_THRESHOLD 0xAD001219
+MKTC_ST(MKTC_RESTORE_ZLS_THRESHOLD)
+#define MKTC_FIND_MTE_PAGE_IN_CSM 0xAD00121A
+MKTC_ST(MKTC_FIND_MTE_PAGE_IN_CSM)
+#define MKTC_REISSUE_MTE_PAGE 0xAD00121B
+MKTC_ST(MKTC_REISSUE_MTE_PAGE)
+#define MKTC_REISSUE_MTE_PAGE_REQUIRED 0xAD00121C
+MKTC_ST(MKTC_REISSUE_MTE_PAGE_REQUIRED)
+#define MKTC_REISSUE_MTE_PAGE_END 0xAD00121D
+MKTC_ST(MKTC_REISSUE_MTE_PAGE_END)
+#define MKTC_RESET_TE_PSG 0xAD00121E
+MKTC_ST(MKTC_RESET_TE_PSG)
+
+#define MKTC_OOM_WRITEOPSBLOCKED 0xAD00121F
+MKTC_ST(MKTC_OOM_WRITEOPSBLOCKED)
+#define MKTC_OOM_READOPSBLOCKED 0xAD001220
+MKTC_ST(MKTC_OOM_READOPSBLOCKED)
+#define MKTC_OOM_SRC_WRITEOPSBLOCKED 0xAD001221
+MKTC_ST(MKTC_OOM_SRC_WRITEOPSBLOCKED)
+#define MKTC_OOM_SRC_READOPSBLOCKED 0xAD001222
+MKTC_ST(MKTC_OOM_SRC_READOPSBLOCKED)
+#define MKTC_OOM_SPM_DEADLOCK 0xAD001223
+MKTC_ST(MKTC_OOM_SPM_DEADLOCK)
+#define MKTC_OOM_SPM_DEADLOCK_MEM_ADDED 0xAD001224
+MKTC_ST(MKTC_OOM_SPM_DEADLOCK_MEM_ADDED)
+#define MKTC_RESET 0xAD001225
+MKTC_ST(MKTC_RESET)
+#define MKTC_SPM_INVALID_ZLSCONFIG 0xAD001226
+MKTC_ST(MKTC_SPM_INVALID_ZLSCONFIG)
+
+#define MKTC_OOM_TYPE_MT 0xAD00122A
+MKTC_ST(MKTC_OOM_TYPE_MT)
+#define MKTC_OOM_TYPE_GLOBAL 0xAD001230
+MKTC_ST(MKTC_OOM_TYPE_GLOBAL)
+#define MKTC_OOM_CAUSE_GBL_OOM 0xAD001231
+MKTC_ST(MKTC_OOM_CAUSE_GBL_OOM)
+#define MKTC_OOM_RESTORE_LIST_SIZE 0xAD001232
+MKTC_ST(MKTC_OOM_RESTORE_LIST_SIZE)
+
+#define MKTC_CHECK_MTE_PAGE_REISSUE 0xAD001240
+MKTC_ST(MKTC_CHECK_MTE_PAGE_REISSUE)
+#define MKTC_CPRI_VALID_ENTRIES 0xAD001241
+MKTC_ST(MKTC_CPRI_VALID_ENTRIES)
+#define MKTC_CPRI_STORE_DPLIST 0xAD001242
+MKTC_ST(MKTC_CPRI_STORE_DPLIST)
+#define MKTC_CPRI_STORE_OTPM_CSM 0xAD001243
+MKTC_ST(MKTC_CPRI_STORE_OTPM_CSM)
+#define MKTC_CPRI_ABORT_MT_IDX 0xAD001244
+MKTC_ST(MKTC_CPRI_ABORT_MT_IDX)
+#define MKTC_CPRI_ABORT_CORE_IDX 0xAD001245
+MKTC_ST(MKTC_CPRI_ABORT_CORE_IDX)
+#define MKTC_CPRI_CSM_TABLE_DATA 0xAD001246
+MKTC_ST(MKTC_CPRI_CSM_TABLE_DATA)
+#define MKTC_CPRI_PIM_DATA 0xAD001247
+MKTC_ST(MKTC_CPRI_PIM_DATA)
+#define MKTC_CPRI_DO_CIRCULAR_TEST 0xAD001248
+MKTC_ST(MKTC_CPRI_DO_CIRCULAR_TEST)
+#define MKTC_CPRI_WRITE_ENTRIES 0xAD001249
+MKTC_ST(MKTC_CPRI_WRITE_ENTRIES)
+
+#define MKTC_MTE_ENTRY_NOT_IN_ANY_LIST 0xAD001250
+MKTC_ST(MKTC_MTE_ENTRY_NOT_IN_ANY_LIST)
+
+#define MKTC_SPMAC_IGNORE_TERMINATE 0xAD001251
+MKTC_ST(MKTC_SPMAC_IGNORE_TERMINATE)
+
+#define MKTC_SPMAC_REQUEST_3D_TIMEOUT 0xAD001252
+MKTC_ST(MKTC_SPMAC_REQUEST_3D_TIMEOUT)
+#define MKTC_SPMAC_3D_TIMEOUT_COMPLETE 0xAD001253
+MKTC_ST(MKTC_SPMAC_3D_TIMEOUT_COMPLETE)
+#define MKTC_OOM_READOPS2BLOCKED 0xAD001254
+MKTC_ST(MKTC_OOM_READOPS2BLOCKED)
+
+/* PB Load/store status */
+#define MKTC_LOADTAPB_START 0xAD001300
+MKTC_ST(MKTC_LOADTAPB_START)
+#define MKTC_LOADTAPB_END 0xAD001301
+MKTC_ST(MKTC_LOADTAPB_END)
+#define MKTC_STORETAPB_START 0xAD001302
+MKTC_ST(MKTC_STORETAPB_START)
+#define MKTC_STORETAPB_END 0xAD001303
+MKTC_ST(MKTC_STORETAPB_END)
+#define MKTC_LOAD3DPB_START 0xAD001304
+MKTC_ST(MKTC_LOAD3DPB_START)
+#define MKTC_LOAD3DPB_END 0xAD001305
+MKTC_ST(MKTC_LOAD3DPB_END)
+#define MKTC_STORE3DPB_START 0xAD001306
+MKTC_ST(MKTC_STORE3DPB_START)
+#define MKTC_STORE3DPB_END 0xAD001307
+MKTC_ST(MKTC_STORE3DPB_END)
+#define MKTC_LOADTAPB_PAGETABLE_DONE 0xAD001308
+MKTC_ST(MKTC_LOADTAPB_PAGETABLE_DONE)
+#define MKTC_LOAD3DPB_PAGETABLE_DONE 0xAD001309
+MKTC_ST(MKTC_LOAD3DPB_PAGETABLE_DONE)
+
+#define MKTC_TIMER_RC_CLEANUP 0xAD001400
+MKTC_ST(MKTC_TIMER_RC_CLEANUP)
+#define MKTC_TIMER_RC_CLEANUP_DONE 0xAD001401
+MKTC_ST(MKTC_TIMER_RC_CLEANUP_DONE)
+#define MKTC_TIMER_RC_CLEANUP_BUSY 0xAD001402
+MKTC_ST(MKTC_TIMER_RC_CLEANUP_BUSY)
+#define MKTC_TIMER_RT_CLEANUP 0xAD001410
+MKTC_ST(MKTC_TIMER_RT_CLEANUP)
+#define MKTC_TIMER_RT_CLEANUP_DONE 0xAD001411
+MKTC_ST(MKTC_TIMER_RT_CLEANUP_DONE)
+#define MKTC_TIMER_RT_CLEANUP_PENDING 0xAD001412
+MKTC_ST(MKTC_TIMER_RT_CLEANUP_PENDING)
+#define MKTC_TIMER_RT_CLEANUP_TIDYPARTIALLIST 0xAD001413
+MKTC_ST(MKTC_TIMER_RT_CLEANUP_TIDYPARTIALLIST)
+#define MKTC_TIMER_RT_CLEANUP_BUSY 0xAD001414
+MKTC_ST(MKTC_TIMER_RT_CLEANUP_BUSY)
+#define MKTC_TIMER_TC_CLEANUP 0xAD001420
+MKTC_ST(MKTC_TIMER_TC_CLEANUP)
+#define MKTC_TIMER_TC_CLEANUP_DONE 0xAD001421
+MKTC_ST(MKTC_TIMER_TC_CLEANUP_DONE)
+#define MKTC_TIMER_TC_CLEANUP_BUSY 0xAD001422
+MKTC_ST(MKTC_TIMER_TC_CLEANUP_BUSY)
+#define MKTC_TIMER_2DC_CLEANUP 0xAD001430
+MKTC_ST(MKTC_TIMER_2DC_CLEANUP)
+#define MKTC_TIMER_2DC_CLEANUP_DONE 0xAD001431
+MKTC_ST(MKTC_TIMER_2DC_CLEANUP_DONE)
+#define MKTC_TIMER_2DC_CLEANUP_BUSY 0xAD001432
+MKTC_ST(MKTC_TIMER_2DC_CLEANUP_BUSY)
+#define MKTC_TIMER_SHAREDPBDESC_CLEANUP 0xAD001440
+MKTC_ST(MKTC_TIMER_SHAREDPBDESC_CLEANUP)
+
+
+#define MKTC_TIMER_ISP_SWITCH_POTENTIAL_LOCKUP 0xAD001450
+MKTC_ST(MKTC_TIMER_ISP_SWITCH_POTENTIAL_LOCKUP)
+#define MKTC_TIMER_ISP_SWITCH_FORCE_SWITCH 0xAD001451
+MKTC_ST(MKTC_TIMER_ISP_SWITCH_FORCE_SWITCH)
+
+#define MKTC_UTSO_UPDATEREADOPS 0xAD001600
+MKTC_ST(MKTC_UTSO_UPDATEREADOPS)
+#define MKTC_UTSO_UPDATEWRITEOPS 0xAD001601
+MKTC_ST(MKTC_UTSO_UPDATEWRITEOPS)
+
+#define MKTC_TAFINISHED_UPDATESTATUSVALS 0xAD001700
+MKTC_ST(MKTC_TAFINISHED_UPDATESTATUSVALS)
+#define MKTC_TAFINISHED_UPDATESTATUSVALS_DONE 0xAD001701
+MKTC_ST(MKTC_TAFINISHED_UPDATESTATUSVALS_DONE)
+#define MKTC_TAFINISHED_NORENDER 0xAD001702
+MKTC_ST(MKTC_TAFINISHED_NORENDER)
+#define MKTC_TAFINISHED_LASTKICK 0xAD001703
+MKTC_ST(MKTC_TAFINISHED_LASTKICK)
+#define MKTC_TAFINISHED_FINDRENDER 0xAD001704
+MKTC_ST(MKTC_TAFINISHED_FINDRENDER)
+#define MKTC_TAFINISHED_FINDTA 0xAD001705
+MKTC_ST(MKTC_TAFINISHED_FINDTA)
+#define MKTC_TAFINISHED_END 0xAD001706
+MKTC_ST(MKTC_TAFINISHED_END)
+#define MKTC_TAF_SPM_DEADLOCK_MEM_REMOVED 0xAD001707
+MKTC_ST(MKTC_TAF_SPM_DEADLOCK_MEM_REMOVED)
+#define MKTC_TAF_RESERVE_MEM 0xAD001708
+MKTC_ST(MKTC_TAF_RESERVE_MEM)
+#define MKTC_TAF_RESERVE_MEM_REQUEST_RENDER 0xAD001709
+MKTC_ST(MKTC_TAF_RESERVE_MEM_REQUEST_RENDER)
+#define MKTC_TAF_RESERVE_FREE_RENDER_FINISHED 0xAD00170A
+MKTC_ST(MKTC_TAF_RESERVE_FREE_RENDER_FINISHED)
+#define MKTC_TAF_RESERVE_FREE_DUMMY_RENDER 0xAD00170B
+MKTC_ST(MKTC_TAF_RESERVE_FREE_DUMMY_RENDER)
+#define MKTC_TAF_DEBUG_SAS 0xAD00170C
+MKTC_ST(MKTC_TAF_DEBUG_SAS)
+#define MKTC_TAFINISHED_NOCONTEXTSWITCH 0xAD00170D
+MKTC_ST(MKTC_TAFINISHED_NOCONTEXTSWITCH)
+
+#define MKTC_TAFINISHED_TERM_COMPLETE_START 0xAD001710
+MKTC_ST(MKTC_TAFINISHED_TERM_COMPLETE_START)
+#define MKTC_TAFINISHED_TERM_COMPLETE_END 0xAD001711
+MKTC_ST(MKTC_TAFINISHED_TERM_COMPLETE_END)
+
+#define MKTC_TAFINISHED_DPMPAGERECYCLING 0xAD001720
+MKTC_ST(MKTC_TAFINISHED_DPMPAGERECYCLING)
+
+#define MKTC_2DEVENT_2DCOMPLETE 0xAD001800
+MKTC_ST(MKTC_2DEVENT_2DCOMPLETE)
+#define MKTC_2DEVENT_END 0xAD001801
+MKTC_ST(MKTC_2DEVENT_END)
+#define MKTC_2DLB_2DCOMPLETE 0xAD001802
+MKTC_ST(MKTC_2DLB_2DCOMPLETE)
+#define MKTC_2DLB_FIND2D 0xAD001803
+MKTC_ST(MKTC_2DLB_FIND2D)
+#define MKTC_2DLB_END 0xAD001804
+MKTC_ST(MKTC_2DLB_END)
+#define MKTC_2DCOMPLETE_START 0xAD001805
+MKTC_ST(MKTC_2DCOMPLETE_START)
+#define MKTC_2DCOMPLETE_END 0xAD001806
+MKTC_ST(MKTC_2DCOMPLETE_END)
+#define MKTC_KICK2D_START 0xAD001807
+MKTC_ST(MKTC_KICK2D_START)
+#define MKTC_KICK2D_END 0xAD001808
+MKTC_ST(MKTC_KICK2D_END)
+#define MKTC_DUMMYPROC2D 0xAD001809
+MKTC_ST(MKTC_DUMMYPROC2D)
+#define MKTC_FTD_SRCREADOPSBLOCKED 0xAD00180A
+MKTC_ST(MKTC_FTD_SRCREADOPSBLOCKED)
+#define MKTC_FTD_SRCWRITEOPSBLOCKED 0xAD00180B
+MKTC_ST(MKTC_FTD_SRCWRITEOPSBLOCKED)
+#define MKTC_FTD_DSTREADOPSBLOCKED 0xAD00180C
+MKTC_ST(MKTC_FTD_DSTREADOPSBLOCKED)
+#define MKTC_FTD_DSTWRITEOPSBLOCKED 0xAD00180D
+MKTC_ST(MKTC_FTD_DSTWRITEOPSBLOCKED)
+#define MKTC_FTD_TA2D_OVERLAP_BLOCKED 0xAD00180E
+MKTC_ST(MKTC_FTD_TA2D_OVERLAP_BLOCKED)
+#define MKTC_U2DSO_UPDATEREADOPS 0xAD00180F
+MKTC_ST(MKTC_U2DSO_UPDATEREADOPS)
+#define MKTC_U2DSO_UPDATEWRITEOPS 0xAD001810
+MKTC_ST(MKTC_U2DSO_UPDATEWRITEOPS)
+#define MKTC_FTD_TAOPSBLOCKED 0xAD001811
+MKTC_ST(MKTC_FTD_TAOPSBLOCKED)
+#define MKTC_KICK2D_2DSLAVEPORT 0xAD001812
+MKTC_ST(MKTC_KICK2D_2DSLAVEPORT)
+#define MKTC_KICK2D_2DSLAVEPORT_DONE 0xAD001813
+MKTC_ST(MKTC_KICK2D_2DSLAVEPORT_DONE)
+#define MKTC_FTD_CONTEXT_SUSPENDED 0xAD001814
+MKTC_ST(MKTC_FTD_CONTEXT_SUSPENDED)
+#define MKTC_KICK2D_PID 0xAD001815
+MKTC_ST(MKTC_KICK2D_PID)
+#define MKTC_FIND2D_ADDR_SPACE_DIFFERENT 0xAD001816
+MKTC_ST(MKTC_FIND2D_ADDR_SPACE_DIFFERENT)
+#define MKTC_FTD_3DOPSBLOCKED 0xAD001817
+MKTC_ST(MKTC_FTD_3DOPSBLOCKED)
+#define MKTC_FTD_DSTREADOPS2BLOCKED 0xAD001818
+MKTC_ST(MKTC_FTD_DSTREADOPS2BLOCKED)
+
+#define MKTC_FCM_START 0xAD001900
+MKTC_ST(MKTC_FCM_START)
+#define MKTC_FCM_END 0xAD001901
+MKTC_ST(MKTC_FCM_END)
+
+#define MKTC_TIMER_ACTIVE_POWER 0xAD001A00
+MKTC_ST(MKTC_TIMER_ACTIVE_POWER)
+#define MKTC_TIMER_POWER_3D_ACTIVE 0xAD001A01
+MKTC_ST(MKTC_TIMER_POWER_3D_ACTIVE)
+#define MKTC_TIMER_POWER_TA_ACTIVE 0xAD001A02
+MKTC_ST(MKTC_TIMER_POWER_TA_ACTIVE)
+#define MKTC_TIMER_POWER_2D_ACTIVE 0xAD001A03
+MKTC_ST(MKTC_TIMER_POWER_2D_ACTIVE)
+#define MKTC_TIMER_POWER_PENDING_EVENTS 0xAD001A04
+MKTC_ST(MKTC_TIMER_POWER_PENDING_EVENTS)
+#define MKTC_TIMER_POWER_IDLE 0xAD001A05
+MKTC_ST(MKTC_TIMER_POWER_IDLE)
+#define MKTC_TIMER_POWER_OFF 0xAD001A06
+MKTC_ST(MKTC_TIMER_POWER_OFF)
+#define MKTC_TIMER_POWER_CCB_ERROR 0xAD001A07
+MKTC_ST(MKTC_TIMER_POWER_CCB_ERROR)
+#define MKTC_TIMER_POWER_RESTART_IMMEDIATE 0xAD001A08
+MKTC_ST(MKTC_TIMER_POWER_RESTART_IMMEDIATE)
+
+#define MKTC_3DCONTEXT_SWITCH 0xAD001B00
+MKTC_ST(MKTC_3DCONTEXT_SWITCH)
+#define MKTC_3DCONTEXT_SWITCH_END 0xAD001B01
+MKTC_ST(MKTC_3DCONTEXT_SWITCH_END)
+
+#define MKTC_TACONTEXT_SWITCH 0xAD001C00
+MKTC_ST(MKTC_TACONTEXT_SWITCH)
+#define MKTC_TACONTEXT_SWITCH_END 0xAD001C02
+MKTC_ST(MKTC_TACONTEXT_SWITCH_END)
+
+#define MKTC_GETMISCINFO_MEMREAD_START 0xAD001D00
+MKTC_ST(MKTC_GETMISCINFO_MEMREAD_START)
+#define MKTC_GETMISCINFO_MEMREAD_END 0xAD001D01
+MKTC_ST(MKTC_GETMISCINFO_MEMREAD_END)
+#define MKTC_GETMISCINFO_MEMWRITE_START 0xAD001D02
+MKTC_ST(MKTC_GETMISCINFO_MEMWRITE_START)
+#define MKTC_GETMISCINFO_MEMWRITE_END 0xAD001D03
+MKTC_ST(MKTC_GETMISCINFO_MEMWRITE_END)
+
+#define MKTC_HALTTA 0xAD001E00
+MKTC_ST(MKTC_HALTTA)
+#define MKTC_HTA_SET_FLAG 0xAD001E01
+MKTC_ST(MKTC_HTA_SET_FLAG)
+#define MKTC_HTA_SAVE_COMPLEX_PTR 0xAD001E02
+MKTC_ST(MKTC_HTA_SAVE_COMPLEX_PTR)
+#define MKTC_HALTTA_END 0xAD001E03
+MKTC_ST(MKTC_HALTTA_END)
+
+#define MKTC_RESUMETA 0xAD001F00
+MKTC_ST(MKTC_RESUMETA)
+#define MKTC_RTA_CONTEXT_LOADED 0xAD001F01
+MKTC_ST(MKTC_RTA_CONTEXT_LOADED)
+#define MKTC_RTA_MTE_STATE_KICKED 0xAD001F02
+MKTC_ST(MKTC_RTA_MTE_STATE_KICKED)
+#define MKTC_RTA_CMPLX_GEOM_PRESENT 0xAD001F03
+MKTC_ST(MKTC_RTA_CMPLX_GEOM_PRESENT)
+#define MKTC_RTA_CMPLX_STATE_KICKED 0xAD001F04
+MKTC_ST(MKTC_RTA_CMPLX_STATE_KICKED)
+#define MKTC_RTA_CHECK_NEXT_SA_PROG 0xAD001F05
+MKTC_ST(MKTC_RTA_CHECK_NEXT_SA_PROG)
+#define MKTC_RTA_CORE_COMPLETED 0xAD001F06
+MKTC_ST(MKTC_RTA_CORE_COMPLETED)
+#define MKTC_RTA_DEBUG_SAS 0xAD001F07
+MKTC_ST(MKTC_RTA_DEBUG_SAS)
+#define MKTC_RESUMETA_END 0xAD001F0F
+MKTC_ST(MKTC_RESUMETA_END)
+
+#define MKTC_RENDERHALT 0xAD002000
+MKTC_ST(MKTC_RENDERHALT)
+#define MKTC_RH_CLEARFLAGS 0xAD002001
+MKTC_ST(MKTC_RH_CLEARFLAGS)
+#define MKTC_RH_CTRL_ADDR 0xAD002002
+MKTC_ST(MKTC_RH_CTRL_ADDR)
+#define MKTC_RH_RGN_ADDR 0xAD002003
+MKTC_ST(MKTC_RH_RGN_ADDR)
+#define MKTC_RH_EMPTY_TILE 0xAD002004
+MKTC_ST(MKTC_RH_EMPTY_TILE)
+#define MKTC_RH_EMPTY_LAST_TILE 0xAD002005
+MKTC_ST(MKTC_RH_EMPTY_LAST_TILE)
+#define MKTC_RH_3D_TIMEOUT 0xAD002006
+MKTC_ST(MKTC_RH_3D_TIMEOUT)
+#define MKTC_RH_NOT_EMPTY 0xAD002007
+MKTC_ST(MKTC_RH_NOT_EMPTY)
+#define MKTC_RH_OBJECT_COMPLETE 0xAD002008
+MKTC_ST(MKTC_RH_OBJECT_COMPLETE)
+#define MKTC_RH_STREAM_LINK 0xAD002009
+MKTC_ST(MKTC_RH_STREAM_LINK)
+#define MKTC_RH_OBJECT_INCOMPLETE 0xAD00200A
+MKTC_ST(MKTC_RH_OBJECT_INCOMPLETE)
+#define MKTC_RH_PRIM_MASK_PRESENT 0xAD00200B
+MKTC_ST(MKTC_RH_PRIM_MASK_PRESENT)
+#define MKTC_RH_BYTE_MASK_PRESENT 0xAD00200C
+MKTC_ST(MKTC_RH_BYTE_MASK_PRESENT)
+#define MKTC_RH_BYTE_MASK_ZERO 0xAD00200D
+MKTC_ST(MKTC_RH_BYTE_MASK_ZERO)
+#define MKTC_RH_PRIM_MASK_ZERO 0xAD00200E
+MKTC_ST(MKTC_RH_PRIM_MASK_ZERO)
+#define MKTC_RH_INVALIDATE_OBJECTS 0xAD00200F
+MKTC_ST(MKTC_RH_INVALIDATE_OBJECTS)
+#define MKTC_RH_OBJECTS_INVALIDATED 0xAD002010
+MKTC_ST(MKTC_RH_OBJECTS_INVALIDATED)
+#define MKTC_RH_DPM_RGN_PARSER_IDLE 0xAD002011
+MKTC_ST(MKTC_RH_DPM_RGN_PARSER_IDLE)
+#define MKTC_RH_NEXT_RGN_BASE 0xAD002012
+MKTC_ST(MKTC_RH_NEXT_RGN_BASE)
+#define MKTC_RH_OCC_EXIT 0xAD002013
+MKTC_ST(MKTC_RH_OCC_EXIT)
+#define MKTC_RH_STILL_RUNNING 0xAD002020
+MKTC_ST(MKTC_RH_STILL_RUNNING)
+#define MKTC_RH_CLEARMCI 0xAD002021
+MKTC_ST(MKTC_RH_CLEARMCI)
+#define MKTC_RH_EOR 0xAD002022
+MKTC_ST(MKTC_RH_EOR)
+#define MKTC_RENDERHALT_END 0xAD002030
+MKTC_ST(MKTC_RENDERHALT_END)
+
+#define MKTC_FIND3D_POWERREQUEST 0xAD002100
+MKTC_ST(MKTC_FIND3D_POWERREQUEST)
+
+#define MKTC_FIND2D_POWERREQUEST 0xAD002200
+MKTC_ST(MKTC_FIND2D_POWERREQUEST)
+
+#define MKTC_UKERNEL_INIT 0xAD002300
+MKTC_ST(MKTC_UKERNEL_INIT)
+#define MKTC_UKERNEL_INIT_DCS_COMPLETE 0xAD002301
+MKTC_ST(MKTC_UKERNEL_INIT_DCS_COMPLETE)
+#define MKTC_UKERNEL_INIT_VDMKICK_COMPLETE 0xAD002303
+MKTC_ST(MKTC_UKERNEL_INIT_VDMKICK_COMPLETE)
+
+#define MKTC_KICKTRANSFERRENDER_START 0xAD002400
+MKTC_ST(MKTC_KICKTRANSFERRENDER_START)
+#define MKTC_KICKTRANSFERRENDER_ISP_START 0xAD002401
+MKTC_ST(MKTC_KICKTRANSFERRENDER_ISP_START)
+#define MKTC_KICKTRANSFERRENDER_END 0xAD002402
+MKTC_ST(MKTC_KICKTRANSFERRENDER_END)
+#define MKTC_DUMMYPROCTRANSFER 0xAD002403
+MKTC_ST(MKTC_DUMMYPROCTRANSFER)
+#define MKTC_KTR_TQFENCE 0xAD002404
+MKTC_ST(MKTC_KTR_TQFENCE)
+#define MKTC_KICKTRANSFERRENDER_PID 0xAD002405
+MKTC_ST(MKTC_KICKTRANSFERRENDER_PID)
+
+#define MKTC_HOSTKICK_CLEANUP_RT 0xAD002500
+MKTC_ST(MKTC_HOSTKICK_CLEANUP_RT)
+#define MKTC_HOSTKICK_CLEANUP_RC 0xAD002501
+MKTC_ST(MKTC_HOSTKICK_CLEANUP_RC)
+#define MKTC_HOSTKICK_CLEANUP_TC 0xAD002502
+MKTC_ST(MKTC_HOSTKICK_CLEANUP_TC)
+#define MKTC_HOSTKICK_CLEANUP_2DC 0xAD002503
+MKTC_ST(MKTC_HOSTKICK_CLEANUP_2DC)
+#define MKTC_HOSTKICK_CLEANUP_PB 0xAD002504
+MKTC_ST(MKTC_HOSTKICK_CLEANUP_PB)
+#define MKTC_HOSTKICK_GETMISCINFO 0xAD002505
+MKTC_ST(MKTC_HOSTKICK_GETMISCINFO)
+#define MKTC_HOSTKICK_DATABREAKPOINT 0xAD002506
+MKTC_ST(MKTC_HOSTKICK_DATABREAKPOINT)
+#define MKTC_HOSTKICK_SETHWPERFSTATUS 0xAD002507
+MKTC_ST(MKTC_HOSTKICK_SETHWPERFSTATUS)
+
+#define MKTC_ZEROPC 0xAD002600
+MKTC_ST(MKTC_ZEROPC)
+
+#define MKTC_ASSERT_FAIL 0xAD002700
+MKTC_ST(MKTC_ASSERT_FAIL)
+
+#define MKTC_SDLB_ILLEGAL 0xAD002800
+MKTC_ST(MKTC_SDLB_ILLEGAL)
+
+#define MKTC_SPMEVENT_OUTOFMEM 0xAD002901
+MKTC_ST(MKTC_SPMEVENT_OUTOFMEM)
+#define MKTC_SPMEVENT_TATERMINATE 0xAD002902
+MKTC_ST(MKTC_SPMEVENT_TATERMINATE)
+#define MKTC_SPMEVENT_END 0xAD002904
+MKTC_ST(MKTC_SPMEVENT_END)
+
+#define MKTC_SPMLB_OUTOFMEM 0xAD002981
+MKTC_ST(MKTC_SPMLB_OUTOFMEM)
+#define MKTC_SPMLB_TATERMINATE 0xAD002982
+MKTC_ST(MKTC_SPMLB_TATERMINATE)
+#define MKTC_SPMLB_SPMRENDERFINSHED 0xAD002983
+MKTC_ST(MKTC_SPMLB_SPMRENDERFINSHED)
+#define MKTC_SPMLB_END 0xAD002985
+MKTC_ST(MKTC_SPMLB_END)
+
+#define MKTC_SPM_CHECK_MT_DEADLOCK 0xAD002991
+MKTC_ST(MKTC_SPM_CHECK_MT_DEADLOCK)
+#define MKTC_SPM_CHECK_GLOBAL_DEADLOCK 0xAD002992
+MKTC_ST(MKTC_SPM_CHECK_GLOBAL_DEADLOCK)
+#define MKTC_SPM_RESERVE_ADDED 0xAD002993
+MKTC_ST(MKTC_SPM_RESERVE_ADDED)
+#define MKTC_SPM_FORCE_GLOBAL_OOM_FAILED 0xAD00299E
+MKTC_ST(MKTC_SPM_FORCE_GLOBAL_OOM_FAILED)
+#define MKTC_SPM_DEADLOCK_MEM_FAILED 0xAD00299F
+MKTC_ST(MKTC_SPM_DEADLOCK_MEM_FAILED)
+
+#define MKTC_IBC_ILLEGAL 0xAD002A00
+MKTC_ST(MKTC_IBC_ILLEGAL)
+
+#define MKTC_HWP_CLEARCOUNTERS 0xAD002B00
+MKTC_ST(MKTC_HWP_CLEARCOUNTERS)
+
+#define MKTC_TA_FRAMENUM 0xAD002C00
+MKTC_ST(MKTC_TA_FRAMENUM)
+#define MKTC_3D_FRAMENUM 0xAD002C01
+MKTC_ST(MKTC_3D_FRAMENUM)
+#define MKTC_SPM3D_FRAMENUM 0xAD002C02
+MKTC_ST(MKTC_SPM3D_FRAMENUM)
+
+#define MKTC_HKTA_RENDERCONTEXT 0xAD002D00
+MKTC_ST(MKTC_HKTA_RENDERCONTEXT)
+#define MKTC_IDLECORE_REFCOUNT_FAIL 0xAD002E00
+MKTC_ST(MKTC_IDLECORE_REFCOUNT_FAIL)
+
+#define MKTC_MCISTATE_NOT_CLEARED 0xAD002F00
+MKTC_ST(MKTC_MCISTATE_NOT_CLEARED)
+
+#define MKTC_LOWERED_TO_PDS_THRESHOLD 0xAD003000
+MKTC_ST(MKTC_LOWERED_TO_PDS_THRESHOLD)
+#define MKTC_REDUCE_MAX_VTX_PARTITIONS 0xAD003001
+MKTC_ST(MKTC_REDUCE_MAX_VTX_PARTITIONS)
+#define MKTC_KTAOVERRIDE_MAX_VTX_PARTITIONS 0xAD003002
+MKTC_ST(MKTC_KTAOVERRIDE_MAX_VTX_PARTITIONS)
+#define MKTC_KTANOOVERRIDE_MAX_VTX_PARTITIONS 0xAD003003
+MKTC_ST(MKTC_KTANOOVERRIDE_MAX_VTX_PARTITIONS)
+
+#define MKTC_IPRB_NORENDERDETAILS 0xAD003010
+MKTC_ST(MKTC_IPRB_NORENDERDETAILS)
+#define MKTC_IPRB_HAVERENDERDETAILS 0xAD003011
+MKTC_ST(MKTC_IPRB_HAVERENDERDETAILS)
+
+#define MKTC_RENDER_OUT_OF_ORDER 0xAD003020
+MKTC_ST(MKTC_RENDER_OUT_OF_ORDER)
+#define MKTC_RENDER_NOT_OUT_OF_ORDER 0xAD003021
+MKTC_ST(MKTC_RENDER_NOT_OUT_OF_ORDER)
+
+#define MKTC_ZLS_IDLE_BEGIN 0xAD003030
+MKTC_ST(MKTC_ZLS_IDLE_BEGIN)
+#define MKTC_ZLS_ISP_CLK_GATING_EN 0xAD003031
+MKTC_ST(MKTC_ZLS_ISP_CLK_GATING_EN)
+#define MKTC_ZLS_IDLE_END 0xAD003032
+MKTC_ST(MKTC_ZLS_IDLE_END)
+
+#endif /* __SGX_UKERNEL_STATUS_CODES_H__ */
+
+/******************************************************************************
+ End of file (sgx_ukernel_status_codes.h)
+******************************************************************************/
diff --git a/pvr-source/services4/include/sgxinfo.h b/pvr-source/services4/include/sgxinfo.h
new file mode 100644
index 0000000..17f6d95
--- /dev/null
+++ b/pvr-source/services4/include/sgxinfo.h
@@ -0,0 +1,493 @@
+/*************************************************************************/ /*!
+@Title sgx services structures/functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description inline functions/structures shared across UM and KM services components
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#if !defined (__SGXINFO_H__)
+#define __SGXINFO_H__
+
+#include "sgxscript.h"
+#include "servicesint.h"
+#include "services.h"
+#if !defined (SUPPORT_SID_INTERFACE)
+#include "sgxapi_km.h"
+#endif
+#include "sgx_mkif_km.h"
+
+
+#define SGX_MAX_DEV_DATA 24
+#define SGX_MAX_INIT_MEM_HANDLES 18
+
+
+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 enum _SGXMKIF_CMD_TYPE_
+{
+ SGXMKIF_CMD_TA = 0,
+ SGXMKIF_CMD_TRANSFER = 1,
+ SGXMKIF_CMD_2D = 2,
+ SGXMKIF_CMD_POWER = 3,
+ SGXMKIF_CMD_CONTEXTSUSPEND = 4,
+ SGXMKIF_CMD_CLEANUP = 5,
+ SGXMKIF_CMD_GETMISCINFO = 6,
+ SGXMKIF_CMD_PROCESS_QUEUES = 7,
+ SGXMKIF_CMD_DATABREAKPOINT = 8,
+ SGXMKIF_CMD_SETHWPERFSTATUS = 9,
+ SGXMKIF_CMD_FLUSHPDCACHE = 10,
+ SGXMKIF_CMD_MAX = 11,
+
+ SGXMKIF_CMD_FORCE_I32 = -1,
+
+} SGXMKIF_CMD_TYPE;
+
+
+typedef struct _SGX_BRIDGE_INIT_INFO_
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelCCBMemInfo;
+ IMG_SID hKernelCCBCtlMemInfo;
+ IMG_SID hKernelCCBEventKickerMemInfo;
+ IMG_SID hKernelSGXHostCtlMemInfo;
+ IMG_SID hKernelSGXTA3DCtlMemInfo;
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+ IMG_SID hKernelSGXPTLAWriteBackMemInfo;
+#endif
+ IMG_SID hKernelSGXMiscMemInfo;
+#else
+ IMG_HANDLE hKernelCCBMemInfo;
+ IMG_HANDLE hKernelCCBCtlMemInfo;
+ IMG_HANDLE hKernelCCBEventKickerMemInfo;
+ IMG_HANDLE hKernelSGXHostCtlMemInfo;
+ IMG_HANDLE hKernelSGXTA3DCtlMemInfo;
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+ IMG_HANDLE hKernelSGXPTLAWriteBackMemInfo;
+#endif
+ IMG_HANDLE hKernelSGXMiscMemInfo;
+#endif
+
+ IMG_UINT32 aui32HostKickAddr[SGXMKIF_CMD_MAX];
+
+ SGX_INIT_SCRIPTS sScripts;
+
+ IMG_UINT32 ui32ClientBuildOptions;
+ SGX_MISCINFO_STRUCT_SIZES sSGXStructSizes;
+
+#if defined(SGX_SUPPORT_HWPROFILING)
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelHWProfilingMemInfo;
+#else
+ IMG_HANDLE hKernelHWProfilingMemInfo;
+#endif
+#endif
+#if defined(SUPPORT_SGX_HWPERF)
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelHWPerfCBMemInfo;
+#else
+ IMG_HANDLE hKernelHWPerfCBMemInfo;
+#endif
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelTASigBufferMemInfo;
+ IMG_SID hKernel3DSigBufferMemInfo;
+#else
+ IMG_HANDLE hKernelTASigBufferMemInfo;
+ IMG_HANDLE hKernel3DSigBufferMemInfo;
+#endif
+
+#if defined(FIX_HW_BRN_29702)
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelCFIMemInfo;
+#else
+ IMG_HANDLE hKernelCFIMemInfo;
+#endif
+#endif
+#if defined(FIX_HW_BRN_29823)
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelDummyTermStreamMemInfo;
+#else
+ IMG_HANDLE hKernelDummyTermStreamMemInfo;
+#endif
+#endif
+
+#if defined(FIX_HW_BRN_31542) || defined(FIX_HW_BRN_36513)
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelClearClipWAVDMStreamMemInfo;
+ IMG_SID hKernelClearClipWAIndexStreamMemInfo;
+ IMG_SID hKernelClearClipWAPDSMemInfo;
+ IMG_SID hKernelClearClipWAUSEMemInfo;
+ IMG_SID hKernelClearClipWAParamMemInfo;
+ IMG_SID hKernelClearClipWAPMPTMemInfo;
+ IMG_SID hKernelClearClipWATPCMemInfo;
+ IMG_SID hKernelClearClipWAPSGRgnHdrMemInfo;
+#else
+ IMG_HANDLE hKernelClearClipWAVDMStreamMemInfo;
+ IMG_HANDLE hKernelClearClipWAIndexStreamMemInfo;
+ IMG_HANDLE hKernelClearClipWAPDSMemInfo;
+ IMG_HANDLE hKernelClearClipWAUSEMemInfo;
+ IMG_HANDLE hKernelClearClipWAParamMemInfo;
+ IMG_HANDLE hKernelClearClipWAPMPTMemInfo;
+ IMG_HANDLE hKernelClearClipWATPCMemInfo;
+ IMG_HANDLE hKernelClearClipWAPSGRgnHdrMemInfo;
+#endif
+#endif
+
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31559)
+ IMG_HANDLE hKernelVDMSnapShotBufferMemInfo;
+ IMG_HANDLE hKernelVDMCtrlStreamBufferMemInfo;
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \
+ defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX)
+ IMG_HANDLE hKernelVDMStateUpdateBufferMemInfo;
+#endif
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelEDMStatusBufferMemInfo;
+#else
+ IMG_HANDLE hKernelEDMStatusBufferMemInfo;
+#endif
+#endif
+
+ IMG_UINT32 ui32EDMTaskReg0;
+ IMG_UINT32 ui32EDMTaskReg1;
+
+ IMG_UINT32 ui32ClkGateCtl;
+ IMG_UINT32 ui32ClkGateCtl2;
+ IMG_UINT32 ui32ClkGateStatusReg;
+ IMG_UINT32 ui32ClkGateStatusMask;
+#if defined(SGX_FEATURE_MP)
+ IMG_UINT32 ui32MasterClkGateStatusReg;
+ IMG_UINT32 ui32MasterClkGateStatusMask;
+ IMG_UINT32 ui32MasterClkGateStatus2Reg;
+ IMG_UINT32 ui32MasterClkGateStatus2Mask;
+#endif /* SGX_FEATURE_MP */
+
+ IMG_UINT32 ui32CacheControl;
+
+ IMG_UINT32 asInitDevData[SGX_MAX_DEV_DATA];
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID asInitMemHandles[SGX_MAX_INIT_MEM_HANDLES];
+#else
+ IMG_HANDLE asInitMemHandles[SGX_MAX_INIT_MEM_HANDLES];
+#endif
+
+} SGX_BRIDGE_INIT_INFO;
+
+
+typedef struct _SGX_DEVICE_SYNC_LIST_
+{
+ PSGXMKIF_HWDEVICE_SYNC_LIST psHWDeviceSyncList;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelHWSyncListMemInfo;
+#else
+ IMG_HANDLE hKernelHWSyncListMemInfo;
+#endif
+ PVRSRV_CLIENT_MEM_INFO *psHWDeviceSyncListClientMemInfo;
+ PVRSRV_CLIENT_MEM_INFO *psAccessResourceClientMemInfo;
+
+ volatile IMG_UINT32 *pui32Lock;
+
+ struct _SGX_DEVICE_SYNC_LIST_ *psNext;
+
+ /* Must be the last variable in the structure */
+ IMG_UINT32 ui32NumSyncObjects;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID ahSyncHandles[1];
+#else
+ IMG_HANDLE ahSyncHandles[1];
+#endif
+} SGX_DEVICE_SYNC_LIST, *PSGX_DEVICE_SYNC_LIST;
+
+
+typedef struct _SGX_INTERNEL_STATUS_UPDATE_
+{
+ CTL_STATUS sCtlStatus;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ IMG_HANDLE hKernelMemInfo;
+#endif
+} SGX_INTERNEL_STATUS_UPDATE;
+
+
+typedef struct _SGX_CCB_KICK_
+{
+ SGXMKIF_COMMAND sCommand;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hCCBKernelMemInfo;
+#else
+ IMG_HANDLE hCCBKernelMemInfo;
+#endif
+
+ IMG_UINT32 ui32NumDstSyncObjects;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelHWSyncListMemInfo;
+#else
+ IMG_HANDLE hKernelHWSyncListMemInfo;
+#endif
+
+ /* DST syncs */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID *pahDstSyncHandles;
+#else
+ IMG_HANDLE *pahDstSyncHandles;
+#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
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID ahTAStatusSyncInfo[SGX_MAX_TA_STATUS_VALS];
+ IMG_SID ah3DStatusSyncInfo[SGX_MAX_3D_STATUS_VALS];
+#else
+ IMG_HANDLE ahTAStatusSyncInfo[SGX_MAX_TA_STATUS_VALS];
+ IMG_HANDLE ah3DStatusSyncInfo[SGX_MAX_3D_STATUS_VALS];
+#endif
+#endif
+
+ IMG_BOOL bFirstKickOrResume;
+#if defined(NO_HARDWARE) || defined(PDUMP)
+ IMG_BOOL bTerminateOrAbort;
+#endif
+ IMG_BOOL bLastInScene;
+
+ /* CCB offset of data structure associated with this kick */
+ IMG_UINT32 ui32CCBOffset;
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+ /* SRC and DST syncs */
+ IMG_UINT32 ui32NumTASrcSyncs;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID ahTASrcKernelSyncInfo[SGX_MAX_TA_SRC_SYNCS];
+#else
+ IMG_HANDLE ahTASrcKernelSyncInfo[SGX_MAX_TA_SRC_SYNCS];
+#endif
+ IMG_UINT32 ui32NumTADstSyncs;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID ahTADstKernelSyncInfo[SGX_MAX_TA_DST_SYNCS];
+#else
+ IMG_HANDLE ahTADstKernelSyncInfo[SGX_MAX_TA_DST_SYNCS];
+#endif
+ IMG_UINT32 ui32Num3DSrcSyncs;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID ah3DSrcKernelSyncInfo[SGX_MAX_3D_SRC_SYNCS];
+#else
+ IMG_HANDLE ah3DSrcKernelSyncInfo[SGX_MAX_3D_SRC_SYNCS];
+#endif
+#else
+ /* SRC syncs */
+ IMG_UINT32 ui32NumSrcSyncs;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS_TA];
+#else
+ IMG_HANDLE ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS_TA];
+#endif
+#endif
+
+ /* TA/3D dependency data */
+ IMG_BOOL bTADependency;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hTA3DSyncInfo;
+
+ IMG_SID hTASyncInfo;
+ IMG_SID h3DSyncInfo;
+#else
+ IMG_HANDLE hTA3DSyncInfo;
+
+ IMG_HANDLE hTASyncInfo;
+ IMG_HANDLE h3DSyncInfo;
+#endif
+#if defined(PDUMP)
+ IMG_UINT32 ui32CCBDumpWOff;
+#endif
+#if defined(NO_HARDWARE)
+ IMG_UINT32 ui32WriteOpsPendingVal;
+#endif
+ IMG_HANDLE hDevMemContext;
+} SGX_CCB_KICK;
+
+
+/*!
+ ******************************************************************************
+ * shared client/kernel device information structure for SGX
+ *****************************************************************************/
+#define SGX_KERNEL_USE_CODE_BASE_INDEX 15
+
+
+/*!
+ ******************************************************************************
+ * Client device information structure for SGX
+ *****************************************************************************/
+typedef struct _SGX_CLIENT_INFO_
+{
+ IMG_UINT32 ui32ProcessID; /*!< ID of process controlling SGX device */
+ IMG_VOID *pvProcess; /*!< pointer to OS specific 'process' structure */
+ PVRSRV_MISC_INFO sMiscInfo; /*!< Misc. Information, inc. SOC specifics */
+
+ IMG_UINT32 asDevData[SGX_MAX_DEV_DATA];
+
+} SGX_CLIENT_INFO;
+
+/*!
+ ******************************************************************************
+ * Internal device information structure for SGX
+ *****************************************************************************/
+typedef struct _SGX_INTERNAL_DEVINFO_
+{
+ IMG_UINT32 ui32Flags;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hHostCtlKernelMemInfoHandle;
+#else
+ IMG_HANDLE hHostCtlKernelMemInfoHandle;
+#endif
+ IMG_BOOL bForcePTOff;
+} SGX_INTERNAL_DEVINFO;
+
+
+typedef struct _SGX_INTERNAL_DEVINFO_KM_
+{
+ IMG_UINT32 ui32Flags;
+ IMG_HANDLE hHostCtlKernelMemInfoHandle;
+ IMG_BOOL bForcePTOff;
+} SGX_INTERNAL_DEVINFO_KM;
+
+
+#if defined(TRANSFER_QUEUE)
+typedef struct _PVRSRV_TRANSFER_SGX_KICK_
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hCCBMemInfo;
+#else
+ IMG_HANDLE hCCBMemInfo;
+#endif
+ IMG_UINT32 ui32SharedCmdCCBOffset;
+
+ IMG_DEV_VIRTADDR sHWTransferContextDevVAddr;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hTASyncInfo;
+ IMG_SID h3DSyncInfo;
+#else
+ IMG_HANDLE hTASyncInfo;
+ IMG_HANDLE h3DSyncInfo;
+#endif
+
+ IMG_UINT32 ui32NumSrcSync;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID ahSrcSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS];
+#else
+ IMG_HANDLE ahSrcSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS];
+#endif
+
+ IMG_UINT32 ui32NumDstSync;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID ahDstSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS];
+#else
+ IMG_HANDLE ahDstSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS];
+#endif
+
+ IMG_UINT32 ui32Flags;
+
+ IMG_UINT32 ui32PDumpFlags;
+#if defined(PDUMP)
+ IMG_UINT32 ui32CCBDumpWOff;
+#endif
+ IMG_HANDLE hDevMemContext;
+} PVRSRV_TRANSFER_SGX_KICK, *PPVRSRV_TRANSFER_SGX_KICK;
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+typedef struct _PVRSRV_2D_SGX_KICK_
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hCCBMemInfo;
+#else
+ IMG_HANDLE hCCBMemInfo;
+#endif
+ IMG_UINT32 ui32SharedCmdCCBOffset;
+
+ IMG_DEV_VIRTADDR sHW2DContextDevVAddr;
+
+ IMG_UINT32 ui32NumSrcSync;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID ahSrcSyncInfo[SGX_MAX_2D_SRC_SYNC_OPS];
+
+ /* need to be able to check reads and writes on dest, and update writes */
+ IMG_SID hDstSyncInfo;
+
+ /* need to be able to check reads and writes on TA ops, and update writes */
+ IMG_SID hTASyncInfo;
+
+ /* need to be able to check reads and writes on 2D ops, and update writes */
+ IMG_SID h3DSyncInfo;
+#else
+ IMG_HANDLE ahSrcSyncInfo[SGX_MAX_2D_SRC_SYNC_OPS];
+
+ /* need to be able to check reads and writes on dest, and update writes */
+ IMG_HANDLE hDstSyncInfo;
+
+ /* need to be able to check reads and writes on TA ops, and update writes */
+ IMG_HANDLE hTASyncInfo;
+
+ /* need to be able to check reads and writes on 2D ops, and update writes */
+ IMG_HANDLE h3DSyncInfo;
+#endif
+
+ IMG_UINT32 ui32PDumpFlags;
+#if defined(PDUMP)
+ IMG_UINT32 ui32CCBDumpWOff;
+#endif
+ IMG_HANDLE hDevMemContext;
+} PVRSRV_2D_SGX_KICK, *PPVRSRV_2D_SGX_KICK;
+#endif /* defined(SGX_FEATURE_2D_HARDWARE) */
+#endif /* defined(TRANSFER_QUEUE) */
+
+
+#endif /* __SGXINFO_H__ */
+/******************************************************************************
+ End of file (sgxinfo.h)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/bridged/bridged_pvr_bridge.c b/pvr-source/services4/srvkm/bridged/bridged_pvr_bridge.c
new file mode 100644
index 0000000..d98a71c
--- /dev/null
+++ b/pvr-source/services4/srvkm/bridged/bridged_pvr_bridge.c
@@ -0,0 +1,5512 @@
+/*************************************************************************/ /*!
+@Title PVR Common Bridge Module (kernel side)
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Receives calls from the user portion of services and
+ despatches them to functions in the kernel portion.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+
+
+#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
+#if defined(SUPPORT_MSVDX)
+#include "msvdx_bridge.h"
+#endif
+#include "perproc.h"
+#include "device.h"
+#include "buffer_manager.h"
+#include "refcount.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
+#if defined(SUPPORT_MSVDX)
+#include "bridged_msvdx_bridge.h"
+#endif
+
+#include "env_data.h"
+
+#if defined (__linux__) || defined(__QNXNTO__)
+#include "mmap.h"
+#endif
+
+
+#include "srvkm.h"
+
+/* FIXME: we should include an OS specific header here to allow configuration of
+ * which functions should be excluded (like the shared srvclient bridge code)
+ * so that ports may choose to override certain things. */
+
+/* For the purpose of maintainability, it is intended that this file should not
+ * contain large amounts of OS specific #ifdefs. Headers are fine, and perhaps
+ * a few one liners, but for anything more, please find a way to add e.g.
+ * an osfunc.c abstraction or override the entire function in question within
+ * env,*,pvr_bridge_k.c
+ */
+
+
+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) || defined (SUPPORT_SID_INTERFACE)
+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;
+ }
+
+ /*
+ * Handle is not allocated in batch mode, as there is no resource
+ * allocation to undo if the handle allocation fails.
+ */
+ 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;
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_HEAP_INFO_KM asHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
+#endif
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT);
+
+ /*
+ * We potentially need one handle for the device memory context,
+ * and one handle for each client heap.
+ */
+ 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asHeapInfo[0],
+#else
+ &psCreateDevMemContextOUT->sHeapInfo[0],
+#endif
+ &bCreated,
+ pbSharedDeviceMemHeap);
+
+ if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ /*
+ * Only allocate a handle if the device memory context was created.
+ * If an existing context was returned, lookup the existing
+ * handle.
+ */
+ 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++)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemHeapExt;
+#else
+ IMG_HANDLE hDevMemHeapExt;
+#endif
+
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ if(abSharedDeviceMemHeap[i])
+#endif
+ {
+ /*
+ * Heaps shared by everybody. These heaps are not
+ * created as part of the device memory context
+ * creation, and exist for the lifetime of the
+ * driver, hence, we use shared handles for these
+ * heaps.
+ */
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &hDevMemHeapExt,
+ asHeapInfo[i].hDevMemHeap,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+#else
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt,
+ psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+#endif
+ }
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ else
+ {
+ /*
+ * Heaps belonging to this context. The handles for
+ * these are made subhandles of the memory context
+ * handle, so that they are automatically deallocated
+ * when the memory context handle is deallocated.
+ */
+ if(bCreated)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &hDevMemHeapExt,
+ asHeapInfo[i].hDevMemHeap,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psCreateDevMemContextOUT->hDevMemContext);
+#else
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt,
+ psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psCreateDevMemContextOUT->hDevMemContext);
+#endif
+ }
+ else
+ {
+ psCreateDevMemContextOUT->eError =
+ PVRSRVFindHandle(psPerProc->psHandleBase,
+ &hDevMemHeapExt,
+#if defined (SUPPORT_SID_INTERFACE)
+ asHeapInfo[i].hDevMemHeap,
+#else
+ psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap,
+#endif
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
+ if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+ }
+#endif
+ psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap = hDevMemHeapExt;
+#if defined (SUPPORT_SID_INTERFACE)
+ psCreateDevMemContextOUT->sHeapInfo[i].ui32HeapID = asHeapInfo[i].ui32HeapID;
+ psCreateDevMemContextOUT->sHeapInfo[i].sDevVAddrBase = asHeapInfo[i].sDevVAddrBase;
+ psCreateDevMemContextOUT->sHeapInfo[i].ui32HeapByteSize = asHeapInfo[i].ui32HeapByteSize;
+ psCreateDevMemContextOUT->sHeapInfo[i].ui32Attribs = asHeapInfo[i].ui32Attribs;
+ psCreateDevMemContextOUT->sHeapInfo[i].ui32XTileStride = asHeapInfo[i].ui32XTileStride;
+#endif
+ }
+
+ 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;
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_HEAP_INFO_KM asHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
+#endif
+
+ 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asHeapInfo[0],
+#else
+ &psGetDevMemHeapInfoOUT->sHeapInfo[0],
+#endif
+ pbSharedDeviceMemHeap);
+
+ if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ for(i = 0; i < psGetDevMemHeapInfoOUT->ui32ClientHeapCount; i++)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hDevMemHeapExt;
+#else
+ IMG_HANDLE hDevMemHeapExt;
+#endif
+
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ if(abSharedDeviceMemHeap[i])
+#endif
+ {
+ /*
+ * Heaps shared by everybody. These heaps are not
+ * created as part of the device memory context
+ * creation, and exist for the lifetime of the
+ * driver, hence, we use shared handles for these
+ * heaps.
+ */
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &hDevMemHeapExt,
+ asHeapInfo[i].hDevMemHeap,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+#else
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt,
+ psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+#endif
+ }
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ else
+ {
+ /*
+ * Heaps belonging to this context. The handles for
+ * these are made subhandles of the memory context
+ * handle, so that they are automatically deallocated
+ * when the memory context handle is deallocated.
+ */
+ psGetDevMemHeapInfoOUT->eError =
+ PVRSRVFindHandle(psPerProc->psHandleBase,
+ &hDevMemHeapExt,
+#if defined (SUPPORT_SID_INTERFACE)
+ asHeapInfo[i].hDevMemHeap,
+#else
+ psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap,
+#endif
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
+ if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+#endif
+ psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap = hDevMemHeapExt;
+#if defined (SUPPORT_SID_INTERFACE)
+ psGetDevMemHeapInfoOUT->sHeapInfo[i].ui32HeapID = asHeapInfo[i].ui32HeapID;
+ psGetDevMemHeapInfoOUT->sHeapInfo[i].sDevVAddrBase = asHeapInfo[i].sDevVAddrBase;
+ psGetDevMemHeapInfoOUT->sHeapInfo[i].ui32HeapByteSize = asHeapInfo[i].ui32HeapByteSize;
+ psGetDevMemHeapInfoOUT->sHeapInfo[i].ui32Attribs = asHeapInfo[i].ui32Attribs;
+ psGetDevMemHeapInfoOUT->sHeapInfo[i].ui32XTileStride = asHeapInfo[i].ui32XTileStride;
+#endif
+ }
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psGetDevMemHeapInfoOUT->eError, psPerProc)
+
+ return 0;
+}
+
+
+#if defined(OS_PVRSRV_ALLOC_DEVICE_MEM_BW)
+/* customised version */
+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;
+ IMG_UINT32 ui32ShareIndex;
+ IMG_BOOL bUseShareMemWorkaround;
+ IMG_BOOL *pabMapChunk = IMG_NULL;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_DEVICEMEM);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psAllocDeviceMemOUT->eError, psPerProc, 2)
+
+ /* Do same sanity checking */
+ if (psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_SPARSE)
+ {
+ if (psAllocDeviceMemIN->ui32NumPhysChunks > psAllocDeviceMemIN->ui32NumVirtChunks)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocDeviceMemBW: more physical chunks then virtual space"));
+ psAllocDeviceMemOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+
+ if (psAllocDeviceMemIN->pabMapChunk == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocDeviceMemBW: Called in sparse mapping mode but without MapChunk array"));
+ psAllocDeviceMemOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+ }
+
+ 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;
+ }
+
+ /* Memory sharing workaround, version 2 */
+
+ bUseShareMemWorkaround = ((psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_XPROC) != 0) ? IMG_TRUE : IMG_FALSE;
+ ui32ShareIndex = 7654321; /* stops MSVC compiler warning */
+
+ if (bUseShareMemWorkaround)
+ {
+ /* allocate a shared-surface ID, prior to the call to AllocDeviceMem */
+ /* We could plumb in an extra argument, but for now, we'll keep the
+ shared-surface ID as a piece of global state, and rely upon the
+ bridge mutex to make it safe for us */
+
+ psAllocDeviceMemOUT->eError =
+ BM_XProcWorkaroundFindNewBufferAndSetShareIndex(&ui32ShareIndex);
+ if(psAllocDeviceMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+ /* Check access to private data, if provided */
+ if(psAllocDeviceMemIN->pvPrivData)
+ {
+ if(!OSAccessOK(PVR_VERIFY_READ,
+ psAllocDeviceMemIN->pvPrivData,
+ psAllocDeviceMemIN->ui32PrivDataLength))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocDeviceMemBW: Access check failed for pvPrivData"));
+ return -EFAULT;
+ }
+ }
+
+ if (psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_SPARSE)
+ {
+ /* Check access to the sparse mapping table, if provided */
+ if(!OSAccessOK(PVR_VERIFY_READ,
+ psAllocDeviceMemIN->pabMapChunk,
+ psAllocDeviceMemIN->ui32NumVirtChunks))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocDeviceMemBW: Access check failed for pabMapChunk"));
+ return -EFAULT;
+ }
+
+ psAllocDeviceMemOUT->eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(IMG_BOOL) * psAllocDeviceMemIN->ui32NumVirtChunks,
+ (IMG_VOID **) &pabMapChunk,
+ 0,
+ "MapChunk kernel copy");
+ if (psAllocDeviceMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psAllocDeviceMemOUT->eError = OSCopyFromUser(psPerProc,
+ pabMapChunk,
+ psAllocDeviceMemIN->pabMapChunk,
+ sizeof(IMG_BOOL) * psAllocDeviceMemIN->ui32NumVirtChunks);
+ if (psAllocDeviceMemOUT->eError != PVRSRV_OK)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(IMG_BOOL) * psAllocDeviceMemIN->ui32NumVirtChunks,
+ pabMapChunk,
+ 0);
+ return 0;
+ }
+ }
+
+
+ psAllocDeviceMemOUT->eError =
+ PVRSRVAllocDeviceMemKM(hDevCookieInt,
+ psPerProc,
+ hDevMemHeapInt,
+ psAllocDeviceMemIN->ui32Attribs,
+ psAllocDeviceMemIN->ui32Size,
+ psAllocDeviceMemIN->ui32Alignment,
+ psAllocDeviceMemIN->pvPrivData,
+ psAllocDeviceMemIN->ui32PrivDataLength,
+ psAllocDeviceMemIN->ui32ChunkSize,
+ psAllocDeviceMemIN->ui32NumVirtChunks,
+ psAllocDeviceMemIN->ui32NumPhysChunks,
+ pabMapChunk,
+ &psMemInfo,
+ "" /*FIXME: add something meaningful*/);
+
+ /* Allow mapping this buffer to the GC MMU only on allocation time, if
+ * this buffer is mapped into another process context we don't want the
+ * GC MMU mapping to happen.
+ */
+ psAllocDeviceMemIN->ui32Attribs &= ~PVRSRV_MAP_GC_MMU;
+
+ if (bUseShareMemWorkaround)
+ {
+ PVR_ASSERT(ui32ShareIndex != 7654321);
+ BM_XProcWorkaroundUnsetShareIndex(ui32ShareIndex);
+ }
+
+ if(psAllocDeviceMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psMemInfo->sShareMemWorkaround.bInUse = bUseShareMemWorkaround;
+ if (bUseShareMemWorkaround)
+ {
+ PVR_ASSERT(ui32ShareIndex != 7654321);
+ psMemInfo->sShareMemWorkaround.ui32ShareIndex = ui32ShareIndex;
+ psMemInfo->sShareMemWorkaround.hDevCookieInt = hDevCookieInt;
+ psMemInfo->sShareMemWorkaround.ui32OrigReqAttribs = psAllocDeviceMemIN->ui32Attribs;
+ psMemInfo->sShareMemWorkaround.ui32OrigReqSize = (IMG_UINT32)psAllocDeviceMemIN->ui32Size;
+ psMemInfo->sShareMemWorkaround.ui32OrigReqAlignment = (IMG_UINT32)psAllocDeviceMemIN->ui32Alignment;
+ }
+
+ 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.uAllocSize = psMemInfo->uAllocSize;
+ OSMemCopy(psAllocDeviceMemOUT->sClientMemInfo.planeOffsets, psMemInfo->planeOffsets,
+ sizeof(psMemInfo->planeOffsets));
+#if defined (SUPPORT_SID_INTERFACE)
+ /* see below */
+#else
+ psAllocDeviceMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle;
+#endif
+
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo,
+ psMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_ASSERT(psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo != 0);
+
+ if (psMemInfo->sMemBlk.hOSMemHandle != IMG_NULL)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psAllocDeviceMemOUT->sClientMemInfo.hMappingInfo,
+ psMemInfo->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo);
+ }
+ else
+ {
+ psAllocDeviceMemOUT->sClientMemInfo.hMappingInfo = 0;
+ }
+#endif
+
+ if(psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_NO_SYNCOBJ)
+ {
+ /* signal no syncinfo */
+ OSMemSet(&psAllocDeviceMemOUT->sClientSyncInfo,
+ 0,
+ sizeof (PVRSRV_CLIENT_SYNC_INFO));
+ psAllocDeviceMemOUT->sClientMemInfo.psClientSyncInfo = IMG_NULL;
+ }
+ else
+ {
+ /* and setup the sync info */
+
+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
+ psAllocDeviceMemOUT->sClientSyncInfo.psSyncData =
+ psMemInfo->psKernelSyncInfo->psSyncData;
+ psAllocDeviceMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
+ psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
+ psAllocDeviceMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
+ psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
+ psAllocDeviceMemOUT->sClientSyncInfo.sReadOps2CompleteDevVAddr =
+ psMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != IMG_NULL)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psAllocDeviceMemOUT->sClientSyncInfo.hMappingInfo,
+ psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo);
+ }
+ else
+ {
+ psAllocDeviceMemOUT->sClientSyncInfo.hMappingInfo = 0;
+ }
+#else
+ psAllocDeviceMemOUT->sClientSyncInfo.hMappingInfo =
+ psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
+#endif
+#endif
+
+ 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 /* OS_PVRSRV_ALLOC_DEVICE_MEM_BW */
+
+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_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,
+#if defined (SUPPORT_SID_INTERFACE)
+ psFreeDeviceMemIN->hKernelMemInfo,
+#else
+ psFreeDeviceMemIN->psKernelMemInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError = PVRSRVFreeDeviceMemKM(hDevCookieInt, pvKernelMemInfo);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ psFreeDeviceMemIN->hKernelMemInfo,
+#else
+ psFreeDeviceMemIN->psKernelMemInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVMultiManageDevMemBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_MULTI_MANAGE_DEV_MEM *psMultiMemDevRequestIN,
+ PVRSRV_BRIDGE_OUT_MULTI_MANAGE_DEV_MEM *psMultiMemDevRequestOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ PVRSRV_KERNEL_MEM_INFO *psSharedBuffKernelMemInfo = NULL;
+ PVRSRV_MANAGE_DEV_MEM_REQUEST* pRequestsArray;
+ PVRSRV_MANAGE_DEV_MEM_RESPONSE* pResponseArray;
+ IMG_UINT32 reqNum;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MULTI_MANAGE_DEV_MEM);
+
+ psMultiMemDevRequestOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
+ psMultiMemDevRequestIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psMultiMemDevRequestOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"%s: invalid hDevCookie", __FUNCTION__));
+ return 0;
+ }
+
+ if(psMultiMemDevRequestIN->hKernelMemInfo)
+ {
+ PVRSRV_MULTI_MANAGE_DEV_MEM_REQUESTS* psMultiMemDevRequest;
+ psMultiMemDevRequestOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID **)&psSharedBuffKernelMemInfo,
+ #if defined (SUPPORT_SID_INTERFACE)
+ psMultiMemDevRequestIN->hKernelMemInfo,
+ #else
+ psMultiMemDevRequestIN->hKernelMemInfo,
+ #endif
+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
+
+ if(psMultiMemDevRequestOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"%s: invalid shared memory hKernelMemInfo", __FUNCTION__));
+ return 0;
+ }
+
+ psMultiMemDevRequest = (PVRSRV_MULTI_MANAGE_DEV_MEM_REQUESTS*)psSharedBuffKernelMemInfo->pvLinAddrKM;
+ if( (psMultiMemDevRequest->psSharedMemClientMemInfo != psMultiMemDevRequestIN->psSharedMemClientMemInfo ) ||
+ (psMultiMemDevRequest->ui32MaxNumberOfRequests != psMultiMemDevRequestIN->ui32MaxNumberOfRequests) ||
+ psMultiMemDevRequest->ui32NumberOfValidRequests != psMultiMemDevRequestIN->ui32NumberOfValidRequests ||
+ psMultiMemDevRequest->ui32CtrlFlags != psMultiMemDevRequestIN->ui32CtrlFlags)
+ {
+ psMultiMemDevRequestOUT->eError = PVRSRV_ERROR_BAD_MAPPING;
+ return 0;
+ }
+ pRequestsArray = psMultiMemDevRequest->sMemRequests;
+ pResponseArray = psMultiMemDevRequest->sMemRequests;
+ }
+ else
+ {
+ pRequestsArray = psMultiMemDevRequestIN->sMemRequests;
+ pResponseArray = psMultiMemDevRequestOUT->sMemResponse;
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE, "\n%s: %s %d Number of request/s, Control flag = 0x%08x\n",
+ __FUNCTION__,
+ (psMultiMemDevRequestIN->hKernelMemInfo ? "Shared" : "Direct"),
+ psMultiMemDevRequestIN->ui32NumberOfValidRequests,
+ psMultiMemDevRequestIN->ui32CtrlFlags));
+
+ for(reqNum = 0; reqNum < psMultiMemDevRequestIN->ui32NumberOfValidRequests; reqNum++)
+ {
+ PVRSRV_MANAGE_DEV_MEM_REQUEST *pRequest = &pRequestsArray[reqNum];
+ PVRSRV_MANAGE_DEV_MEM_REQUEST *pResponse = &pResponseArray[reqNum];
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = NULL;
+
+ /* At the kernel size, psClientMemInfo only works as a verification token */
+ if(psMultiMemDevRequestIN->hKernelMemInfo == NULL)
+ {
+ pResponse->psClientMemInfo = pRequest->psClientMemInfo;
+ pResponse->eReqType = pRequest->eReqType;
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE, "%s: Request %d for ClientMemInfo %p\n"
+ "DevVirtAddr 0x%08x, GpuRefCount %d "
+ "CpuVirtAddr %p, CpuRefCount %d, Kernel Handle %p, sync %p\n"
+ "Size %d, Attrib 0x%08x, Align %d, Subsystem 0x%llx, Hints 0x%08x "
+ "transfer slot %d\n",
+ __FUNCTION__, pResponse->eReqType,
+ pRequest->psClientMemInfo,
+ pRequest->sDevVAddr.uiAddr,
+ pRequest->ui32GpuMapRefCount,
+ pRequest->pvLinAddr,
+ pRequest->ui32CpuMapRefCount,
+ pRequest->hKernelMemInfo,
+ pRequest->hKernelSyncInfo,
+ pRequest->uSize,
+ pRequest->ui32Attribs,
+ pRequest->uAlignment,
+ pRequest->uiSubSystem,
+ pRequest->ui32Hints,
+ pRequest->ui32TransferFromToReqSlotIndx));
+
+ pResponse->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_PVOID *)&psKernelMemInfo,
+ #if defined (SUPPORT_SID_INTERFACE)
+ pRequest->hKernelMemInfo,
+ #else
+ pRequest->hKernelMemInfo,
+ #endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(pResponse->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"%s: invalid hKernelMemInfo for slot %d",
+ __FUNCTION__, reqNum));
+ continue;
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE, "%s: KernelMemInfo %p -%s SHARED\n"
+ "DevVirtAddr 0x%08x, RefCount %d "
+ "Size %d, Flags 0x%08x, OrigAlign %d, Subsystem 0x%llx, Hints 0x%08x\n",
+ __FUNCTION__, psKernelMemInfo,
+ (psKernelMemInfo->sShareMemWorkaround.bInUse ? "" : "NOT"),
+ psKernelMemInfo->sDevVAddr.uiAddr,
+ psKernelMemInfo->ui32RefCount,
+ psKernelMemInfo->uAllocSize,
+ psKernelMemInfo->ui32Flags,
+ psKernelMemInfo->sShareMemWorkaround.ui32OrigReqAlignment,
+ (IMG_UINT64)0, 0));
+
+ if(psKernelMemInfo->sDevVAddr.uiAddr != pRequest->sDevVAddr.uiAddr)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s: Kernel and Client MemInfo's "
+ "virtual addresses are not equal\n"
+ "Kernel DevVirtAddr 0x%08x != Client DevVirtAddr 0x%08x",
+ __FUNCTION__,
+ psKernelMemInfo->sDevVAddr.uiAddr, pRequest->sDevVAddr.uiAddr));
+ }
+
+ switch(pResponse->eReqType)
+ {
+ case PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_MAP:
+ case PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_LOCK_MAP:
+ {
+ IMG_INT32 result = PVRSRVRemapToDevKM(hDevCookieInt,
+ psKernelMemInfo, &pResponse->sDevVAddr);
+
+ if(result < 0)
+ {
+ pResponse->eError = -result;
+ PVR_DPF((PVR_DBG_ERROR, "Request for GPU Virtual "
+ "memory mapping had failed "
+ "with error %d",
+ pResponse->eError));
+ }
+ else
+ {
+ pResponse->ui32GpuMapRefCount = result;
+ pResponse->eError = PVRSRV_OK;
+ }
+ }
+ break;
+ case PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_SWAP_MAP_TO_NEXT:
+ pResponse->eError = PVRSRV_OK;
+ pResponse->ui32GpuMapRefCount = 1;
+ pResponse->sDevVAddr = psKernelMemInfo->sDevVAddr;
+ break;
+ case PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_UNMAP:
+ case PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_UNLOCK_MAP:
+ {
+ IMG_INT32 result = PVRSRVUnmapFromDevKM(hDevCookieInt, psKernelMemInfo);
+ if(result < 0)
+ {
+ pResponse->eError = -result;
+ PVR_DPF((PVR_DBG_ERROR, "Request for GPU Virtual memory "
+ "un-mapping had failed "
+ "with error %d",
+ pResponse->eError));
+ }
+ else
+ {
+ pResponse->ui32GpuMapRefCount = result;
+ pResponse->eError = PVRSRV_OK;
+ }
+ pResponse->sDevVAddr = psKernelMemInfo->sDevVAddr;
+ }
+ break;
+ case PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_SWAP_MAP_FROM_PREV:
+ pResponse->eError = PVRSRV_OK;
+ pResponse->ui32GpuMapRefCount = 1;
+ pResponse->sDevVAddr = psKernelMemInfo->sDevVAddr;
+ break;
+ default:
+ pResponse->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ break;
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE, "%s: RETURN: ClientMemInfo %p "
+ "DevVirtAddr 0x%08x, GpuMapRefCount %d, err %d\n",
+ __FUNCTION__, pRequest->psClientMemInfo,
+ pResponse->sDevVAddr.uiAddr,
+ pResponse->ui32GpuMapRefCount,
+ pResponse->eError));
+ }
+
+ if(psMultiMemDevRequestIN->hKernelMemInfo == NULL)
+ psMultiMemDevRequestOUT->ui32CtrlFlags = psMultiMemDevRequestIN->ui32CtrlFlags;
+ /* No status implemented yet */
+ psMultiMemDevRequestOUT->ui32StatusFlags = 0;
+
+ 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;
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = IMG_NULL;
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+#endif
+
+ PVR_ASSERT(ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_EXPORT_DEVICEMEM) ||
+ ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2));
+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+
+ /* find the device cookie */
+ 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;
+ }
+
+ /* find the kernel meminfo from the process handle list */
+ psExportDeviceMemOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_PVOID *)&psKernelMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+ psExportDeviceMemIN->hKernelMemInfo,
+#else
+ psExportDeviceMemIN->psKernelMemInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+ if(psExportDeviceMemOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: can't find kernel meminfo"));
+ return 0;
+ }
+
+ /* see if it's already exported */
+ psExportDeviceMemOUT->eError =
+ PVRSRVFindHandle(KERNEL_HANDLE_BASE,
+ &psExportDeviceMemOUT->hMemInfo,
+ psKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(psExportDeviceMemOUT->eError == PVRSRV_OK)
+ {
+ /* it's already exported */
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVExportDeviceMemBW: allocation is already exported"));
+ return 0;
+ }
+
+ /* export the allocation */
+ 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;
+ }
+
+ /* mark the meminfo as 'exported' */
+ 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;
+
+ PVR_ASSERT(ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_MAP_DEV_MEMORY) ||
+ ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_MAP_DEV_MEMORY_2));
+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psMapDevMemOUT->eError, psPerProc, 2)
+
+ /* lookup srcmeminfo handle */
+ psMapDevMemOUT->eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+ (IMG_VOID**)&psSrcKernelMemInfo,
+ psMapDevMemIN->hKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(psMapDevMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ /* lookup dev mem heap handle */
+ psMapDevMemOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDstDevMemHeap,
+ psMapDevMemIN->hDstDevMemHeap,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
+ if(psMapDevMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ /* check for workaround */
+ if (psSrcKernelMemInfo->sShareMemWorkaround.bInUse)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "using the mem wrap workaround."));
+
+ /* Check the XPROC mapping count -if it is "0",
+ * then the object is about to go away - do not allow mapping */
+ if(BM_XProcGetShareDataRefCount(psSrcKernelMemInfo->sShareMemWorkaround.ui32ShareIndex) < 1)
+ {
+ psMapDevMemOUT->eError = PVRSRV_ERROR_MAPPING_NOT_FOUND;
+ PVR_DPF((PVR_DBG_WARNING, "%s: Can't map buffer with slot %d, size %d "
+ "and refcount %d\n\t Invalid XPROC refcount of %d",
+ __FUNCTION__, psSrcKernelMemInfo->sShareMemWorkaround.ui32ShareIndex,
+ psSrcKernelMemInfo->uAllocSize, psSrcKernelMemInfo->ui32RefCount,
+ BM_XProcGetShareDataRefCount(psSrcKernelMemInfo->sShareMemWorkaround.ui32ShareIndex)));
+ return 0;
+ }
+
+ /* Ensure we get the same ID for this allocation, such that it
+ inherits the same physical block. Rather than add a lot of
+ plumbing to several APIs, we call into buffer manager directly
+ to set "global" state. This works only if we make
+ this allocation while holding the bridge mutex and don't
+ make any other allocations (because the state persists and
+ would affect other device memory allocations too). It is
+ important that we bracket the PVRSRVAllocDeviceMemKM() call
+ with this Set/Unset pair. */
+ psMapDevMemOUT->eError = BM_XProcWorkaroundSetShareIndex(psSrcKernelMemInfo->sShareMemWorkaround.ui32ShareIndex);
+ if(psMapDevMemOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryBW(): failed to recycle shared buffer"));
+ return 0;
+ }
+
+ psMapDevMemOUT->eError =
+ PVRSRVAllocDeviceMemKM(psSrcKernelMemInfo->sShareMemWorkaround.hDevCookieInt,
+ psPerProc,
+ hDstDevMemHeap,
+ psSrcKernelMemInfo->sShareMemWorkaround.ui32OrigReqAttribs | PVRSRV_MEM_NO_SYNCOBJ,
+ psSrcKernelMemInfo->sShareMemWorkaround.ui32OrigReqSize,
+ psSrcKernelMemInfo->sShareMemWorkaround.ui32OrigReqAlignment,
+ IMG_NULL,
+ 0,
+ /* FIXME: Do we need to be able to export sparse memory? */
+ 0,0,0,IMG_NULL, /* No sparse mapping data */
+ &psDstKernelMemInfo,
+ "" /*FIXME: add something meaningful*/);
+ /* counterpart of the above "SetShareIndex". NB: this must be
+ done in both the success and failure paths of the
+ AllocDeviceMemKM() call */
+ BM_XProcWorkaroundUnsetShareIndex(psSrcKernelMemInfo->sShareMemWorkaround.ui32ShareIndex);
+ if(psMapDevMemOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryBW: Failed to create allocation for cross-process memory map"));
+ return 0;
+ }
+
+ if(psSrcKernelMemInfo->psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoIncRef(psSrcKernelMemInfo->psKernelSyncInfo, psSrcKernelMemInfo);
+ }
+
+ psDstKernelMemInfo->psKernelSyncInfo = psSrcKernelMemInfo->psKernelSyncInfo;
+ }
+ else
+ {
+ /* map the meminfo to the target heap and memory context */
+ psMapDevMemOUT->eError = PVRSRVMapDeviceMemoryKM(psPerProc,
+ psSrcKernelMemInfo,
+ hDstDevMemHeap,
+ &psDstKernelMemInfo);
+ if(psMapDevMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+ /* copy the workaround info */
+ psDstKernelMemInfo->sShareMemWorkaround = psSrcKernelMemInfo->sShareMemWorkaround;
+
+ 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.uAllocSize = psDstKernelMemInfo->uAllocSize;
+ OSMemCopy(psMapDevMemOUT->sDstClientMemInfo.planeOffsets, psDstKernelMemInfo->planeOffsets,
+ sizeof(psDstKernelMemInfo->planeOffsets));
+#if defined (SUPPORT_SID_INTERFACE)
+ /* see below */
+#else
+ psMapDevMemOUT->sDstClientMemInfo.hMappingInfo = psDstKernelMemInfo->sMemBlk.hOSMemHandle;
+#endif
+
+ /* allocate handle to the DST kernel meminfo */
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo,
+ psDstKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+ psMapDevMemOUT->sDstClientSyncInfo.hKernelSyncInfo = IMG_NULL;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ /* alloc subhandle for the mapping info */
+ if (psDstKernelMemInfo->sMemBlk.hOSMemHandle != IMG_NULL)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psMapDevMemOUT->sDstClientMemInfo.hMappingInfo,
+ psDstKernelMemInfo->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo);
+ }
+ else
+ {
+ psMapDevMemOUT->sDstClientMemInfo.hMappingInfo = 0;
+ }
+#endif
+
+ /* and setup the sync info */
+ if(psDstKernelMemInfo->psKernelSyncInfo)
+ {
+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
+ psMapDevMemOUT->sDstClientSyncInfo.psSyncData =
+ psDstKernelMemInfo->psKernelSyncInfo->psSyncData;
+ psMapDevMemOUT->sDstClientSyncInfo.sWriteOpsCompleteDevVAddr =
+ psDstKernelMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
+ psMapDevMemOUT->sDstClientSyncInfo.sReadOpsCompleteDevVAddr =
+ psDstKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
+ psMapDevMemOUT->sDstClientSyncInfo.sReadOps2CompleteDevVAddr =
+ psDstKernelMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ /* alloc subhandle for the mapping info */
+ if (psDstKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != IMG_NULL)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psMapDevMemOUT->sDstClientSyncInfo.hMappingInfo,
+ psDstKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo);
+ }
+ else
+ {
+ psMapDevMemOUT->sDstClientSyncInfo.hMappingInfo = 0;
+ }
+#else
+ psMapDevMemOUT->sDstClientSyncInfo.hMappingInfo =
+ psDstKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
+#endif
+#endif
+
+ psMapDevMemOUT->sDstClientMemInfo.psClientSyncInfo = &psMapDevMemOUT->sDstClientSyncInfo;
+ /*
+ * The sync info is associated with the device buffer,
+ * and not allocated here. It isn't exported when created,
+ * hence the handle allocation rather than a lookup.
+ */
+ 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ psUnmapDevMemIN->hKernelMemInfo,
+#else
+ psUnmapDevMemIN->psKernelMemInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ if (psKernelMemInfo->sShareMemWorkaround.bInUse)
+ {
+ psRetOUT->eError = PVRSRVFreeDeviceMemKM(psKernelMemInfo->sShareMemWorkaround.hDevCookieInt, psKernelMemInfo);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVUnmapDeviceMemoryBW: internal error, should expect FreeDeviceMem to fail"));
+ return 0;
+ }
+ }
+ else
+ {
+ psRetOUT->eError = PVRSRVUnmapDeviceMemoryKM(psKernelMemInfo);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+ psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ psUnmapDevMemIN->hKernelMemInfo,
+#else
+ psUnmapDevMemIN->psKernelMemInfo,
+#endif
+ 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)
+
+ /*
+ * The buffer to be mapped can belong to a 3rd party display or
+ * buffer driver, and we don't know which type we have at this
+ * point.
+ */
+ psMapDevClassMemOUT->eError =
+ PVRSRVLookupHandleAnyType(psPerProc->psHandleBase,
+ &hDeviceClassBufferInt,
+ &eHandleType,
+ psMapDevClassMemIN->hDeviceClassBuffer);
+
+ if(psMapDevClassMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ /* get the device memory context */
+ psMapDevClassMemOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ psMapDevClassMemIN->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if(psMapDevClassMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ /* Having looked up the handle, now check its type */
+ switch(eHandleType)
+ {
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ 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_INVALID_HANDLE_TYPE;
+ 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.uAllocSize = psMemInfo->uAllocSize;
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psMemInfo->sMemBlk.hOSMemHandle != 0)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psMapDevClassMemOUT->sClientMemInfo.hMappingInfo,
+ psMemInfo->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psMapDevClassMemIN->hDeviceClassBuffer);
+ }
+ else
+ {
+ psMapDevClassMemOUT->sClientMemInfo.hMappingInfo = 0;
+ }
+#else
+ psMapDevClassMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle;
+#endif
+
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo,
+ psMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psMapDevClassMemIN->hDeviceClassBuffer);
+
+ psMapDevClassMemOUT->sClientSyncInfo.hKernelSyncInfo = IMG_NULL;
+
+ /* and setup the sync info */
+ if(psMemInfo->psKernelSyncInfo)
+ {
+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
+ psMapDevClassMemOUT->sClientSyncInfo.psSyncData =
+ psMemInfo->psKernelSyncInfo->psSyncData;
+ psMapDevClassMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
+ psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
+ psMapDevClassMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
+ psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
+ psMapDevClassMemOUT->sClientSyncInfo.sReadOps2CompleteDevVAddr =
+ psMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != 0)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psMapDevClassMemOUT->sClientSyncInfo.hMappingInfo,
+ psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+ psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo);
+ }
+ else
+ {
+ psMapDevClassMemOUT->sClientSyncInfo.hMappingInfo = 0;
+ }
+#else
+ psMapDevClassMemOUT->sClientSyncInfo.hMappingInfo =
+ psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
+#endif
+#endif
+
+ psMapDevClassMemOUT->sClientMemInfo.psClientSyncInfo = &psMapDevClassMemOUT->sClientSyncInfo;
+ /*
+ * The sync info is associated with the device buffer,
+ * and not allocated here. It isn't exported when
+ * created, hence the handle allocation rather than a
+ * lookup.
+ */
+ 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ psUnmapDevClassMemIN->hKernelMemInfo,
+#else
+ psUnmapDevClassMemIN->psKernelMemInfo,
+#endif
+ 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ psUnmapDevClassMemIN->hKernelMemInfo,
+#else
+ psUnmapDevClassMemIN->psKernelMemInfo,
+#endif
+ 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 /* OS_PVRSRV_WRAP_EXT_MEM_BW */
+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_SYS_PHYADDR *psSysPAddr = IMG_NULL;
+ IMG_UINT32 ui32PageTableSize = 0;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_WRAP_EXT_MEMORY);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psWrapExtMemOUT->eError, psPerProc, 2)
+
+ /*
+ * FIXME: This needs reworking - don't use the user supplied page
+ * table list, get the list from the OS.
+ */
+ psWrapExtMemOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
+ psWrapExtMemIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psWrapExtMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ /* get the device memory context */
+ 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,
+ "Page Table"));
+
+ if(CopyFromUserWrapper(psPerProc,
+ ui32BridgeID,
+ psSysPAddr,
+ psWrapExtMemIN->psSysPAddr,
+ ui32PageTableSize) != PVRSRV_OK)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32PageTableSize, (IMG_VOID *)psSysPAddr, 0);
+ /*not nulling pointer, out of scope*/
+ return -EFAULT;
+ }
+ }
+
+ psWrapExtMemOUT->eError =
+ PVRSRVWrapExtMemoryKM(hDevCookieInt,
+ psPerProc,
+ hDevMemContextInt,
+ psWrapExtMemIN->ui32ByteSize,
+ psWrapExtMemIN->ui32PageOffset,
+ psWrapExtMemIN->bPhysContig,
+ psSysPAddr,
+ psWrapExtMemIN->pvLinAddr,
+ psWrapExtMemIN->ui32Flags,
+ &psMemInfo);
+
+ if(psWrapExtMemIN->ui32NumPageTableEntries)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32PageTableSize,
+ (IMG_VOID *)psSysPAddr, 0);
+ /*not nulling pointer, out of scope*/
+ }
+
+ if(psWrapExtMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psWrapExtMemOUT->sClientMemInfo.pvLinAddrKM =
+ psMemInfo->pvLinAddrKM;
+
+ /* setup the mem info */
+ psWrapExtMemOUT->sClientMemInfo.pvLinAddr = 0;
+ psWrapExtMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr;
+ psWrapExtMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags;
+ psWrapExtMemOUT->sClientMemInfo.uAllocSize = psMemInfo->uAllocSize;
+#if defined (SUPPORT_SID_INTERFACE)
+/* see below */
+#else
+ psWrapExtMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle;
+#endif
+
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo,
+ psMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+#if defined (SUPPORT_SID_INTERFACE)
+ /* alloc subhandle for the mapping info */
+ if (psMemInfo->sMemBlk.hOSMemHandle != IMG_NULL)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psWrapExtMemOUT->sClientMemInfo.hMappingInfo,
+ psMemInfo->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo);
+ }
+ else
+ {
+ psWrapExtMemOUT->sClientMemInfo.hMappingInfo = 0;
+ }
+#endif
+
+ /* setup the sync info */
+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
+ psWrapExtMemOUT->sClientSyncInfo.psSyncData =
+ psMemInfo->psKernelSyncInfo->psSyncData;
+ psWrapExtMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
+ psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
+ psWrapExtMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
+ psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
+ psWrapExtMemOUT->sClientSyncInfo.sReadOps2CompleteDevVAddr =
+ psMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ /* alloc subhandle for the mapping info */
+ if (psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != IMG_NULL)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psWrapExtMemOUT->sClientSyncInfo.hMappingInfo,
+ psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo);
+ }
+ else
+ {
+ psWrapExtMemOUT->sClientSyncInfo.hMappingInfo = 0;
+ }
+#else
+ psWrapExtMemOUT->sClientSyncInfo.hMappingInfo =
+ psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
+#endif
+#endif
+
+ 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 /* OS_PVRSRV_WRAP_EXT_MEM_BW */
+
+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;
+}
+
+#if defined(SUPPORT_ION)
+static IMG_INT
+PVRSRVMapIonHandleBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_MAP_ION_HANDLE *psMapIonIN,
+ PVRSRV_BRIDGE_OUT_MAP_ION_HANDLE *psMapIonOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+
+ psMapIonOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &psMapIonIN->hDevCookie,
+ psMapIonIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if (psMapIonOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to lookup device node handle", __FUNCTION__));
+ return 0;
+ }
+
+ psMapIonOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &psMapIonIN->hDevMemContext,
+ psMapIonIN->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+ if (psMapIonOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to lookup memory context handle", __FUNCTION__));
+ return 0;
+ }
+
+ psMapIonOUT->eError = PVRSRVMapIonHandleKM(psPerProc,
+ psMapIonIN->hDevCookie,
+ psMapIonIN->hDevMemContext,
+ psMapIonIN->handle,
+ psMapIonIN->ui32Attribs,
+ psMapIonIN->ui32Size,
+ &psKernelMemInfo);
+ if (psMapIonOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to map ion handle", __FUNCTION__));
+ return 0;
+ }
+
+ OSMemSet(&psMapIonOUT->sClientMemInfo,
+ 0,
+ sizeof(psMapIonOUT->sClientMemInfo));
+
+ psMapIonOUT->sClientMemInfo.pvLinAddrKM =
+ psKernelMemInfo->pvLinAddrKM;
+
+ psMapIonOUT->sClientMemInfo.pvLinAddr = 0;
+ psMapIonOUT->sClientMemInfo.sDevVAddr = psKernelMemInfo->sDevVAddr;
+ psMapIonOUT->sClientMemInfo.ui32Flags = psKernelMemInfo->ui32Flags;
+ psMapIonOUT->sClientMemInfo.uAllocSize = psKernelMemInfo->uAllocSize;
+
+ /* No mapping info, we map through ion */
+ psMapIonOUT->sClientMemInfo.hMappingInfo = IMG_NULL;
+
+
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psMapIonOUT->sClientMemInfo.hKernelMemInfo,
+ psKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+ if(psMapIonIN->ui32Attribs & PVRSRV_MEM_NO_SYNCOBJ)
+ {
+ /* signal no syncinfo */
+ OSMemSet(&psMapIonOUT->sClientSyncInfo,
+ 0,
+ sizeof (PVRSRV_CLIENT_SYNC_INFO));
+ psMapIonOUT->sClientMemInfo.psClientSyncInfo = IMG_NULL;
+ }
+ else
+ {
+ /* and setup the sync info */
+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
+ psMapIonOUT->sClientSyncInfo.psSyncData =
+ psKernelMemInfo->psKernelSyncInfo->psSyncData;
+ psMapIonOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
+ psKernelMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
+ psMapIonOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
+ psKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
+ psMapIonOUT->sClientSyncInfo.sReadOps2CompleteDevVAddr =
+ psKernelMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != IMG_NULL)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psMapIonOUT->sClientSyncInfo.hMappingInfo,
+ psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psMapIonOUT->sClientMemInfo.hKernelMemInfo);
+ }
+ else
+ {
+ psMapIonOUT->sClientSyncInfo.hMappingInfo = 0;
+ }
+#else
+ psMapIonOUT->sClientSyncInfo.hMappingInfo =
+ psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
+#endif
+#endif
+
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psMapIonOUT->sClientSyncInfo.hKernelSyncInfo,
+ psKernelMemInfo->psKernelSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE,
+ psMapIonOUT->sClientMemInfo.hKernelMemInfo);
+
+ psMapIonOUT->sClientMemInfo.psClientSyncInfo =
+ &psMapIonOUT->sClientSyncInfo;
+ }
+ return 0;
+}
+
+static IMG_INT
+PVRSRVUnmapIonHandleBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_UNMAP_ION_HANDLE *psUnmapIonIN,
+ PVRSRV_BRIDGE_RETURN *psUnmapIonOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvKernelMemInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNMAP_ION_HANDLE);
+
+ psUnmapIonOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvKernelMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+ psUnmapIonIN->hKernelMemInfo,
+#else
+ psUnmapIonIN->psKernelMemInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+ if(psUnmapIonOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psUnmapIonOUT->eError = PVRSRVUnmapIonHandleKM(pvKernelMemInfo);
+
+ if(psUnmapIonOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psUnmapIonOUT->eError =
+ PVRSRVReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ psUnmapIonIN->hKernelMemInfo,
+#else
+ psUnmapIonIN->psKernelMemInfo,
+#endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+ return 0;
+}
+#endif /* SUPPORT_ION */
+
+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__) || defined (__QNXNTO__)
+ 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__) || defined (__QNXNTO__)
+ 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;
+}
+
+
+#if defined (SUPPORT_SID_INTERFACE)
+static IMG_INT
+PVRSRVChangeDeviceMemoryAttributesBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_CHG_DEV_MEM_ATTRIBS *psChgMemAttribIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hKernelMemInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CHG_DEV_MEM_ATTRIBS);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hKernelMemInfo,
+ psChgMemAttribIN->hKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVChangeDeviceMemoryAttributesKM(hKernelMemInfo, psChgMemAttribIN->ui32Attribs);
+
+ return 0;
+}
+#else
+static IMG_INT
+PVRSRVChangeDeviceMemoryAttributesBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_CHG_DEV_MEM_ATTRIBS *psChgMemAttribIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+ PVR_UNREFERENCED_PARAMETER(psChgMemAttribIN);
+ PVR_UNREFERENCED_PARAMETER(psRetOUT);
+ PVR_UNREFERENCED_PARAMETER(psPerProc);
+
+ return 0;
+}
+#endif
+
+#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_DEVICE_NODE *psDeviceNode;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_REG);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID **)&psDeviceNode,
+ psPDumpRegDumpIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError = PDumpRegWithFlagsKM (psPDumpRegDumpIN->szRegRegion,
+ 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_DEVICE_NODE *psDeviceNode;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_REGPOL);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID **)&psDeviceNode,
+ psPDumpRegPolIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ psRetOUT->eError =
+ PDumpRegPolWithFlagsKM(psPDumpRegPolIN->szRegRegion,
+ psPDumpRegPolIN->sHWReg.ui32RegAddr,
+ psPDumpRegPolIN->sHWReg.ui32RegVal,
+ psPDumpRegPolIN->ui32Mask,
+ psPDumpRegPolIN->ui32Flags,
+ PDUMP_POLL_OPERATOR_EQUAL);
+
+ 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ psPDumpMemPolIN->hKernelMemInfo,
+#else
+ psPDumpMemPolIN->psKernelMemInfo,
+#endif
+ 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,
+ psPDumpMemPolIN->eOperator,
+ psPDumpMemPolIN->ui32Flags,
+ 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ psPDumpMemDumpIN->hKernelMemInfo,
+#else
+ psPDumpMemDumpIN->psKernelMemInfo,
+#endif
+ 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)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_HANDLE hDevMemContextInt;
+
+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID **)&psDeviceNode,
+ psPDumpBitmapIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle( psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ psPDumpBitmapIN->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PDumpBitmapKM(psDeviceNode,
+ &psPDumpBitmapIN->szFileName[0],
+ psPDumpBitmapIN->ui32FileOffset,
+ psPDumpBitmapIN->ui32Width,
+ psPDumpBitmapIN->ui32Height,
+ psPDumpBitmapIN->ui32StrideInBytes,
+ psPDumpBitmapIN->sDevBaseAddr,
+ hDevMemContextInt,
+ 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_DEVICE_NODE *psDeviceNode;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPREADREG);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID **)&psDeviceNode,
+ psPDumpReadRegIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ psRetOUT->eError =
+ PDumpReadRegKM(&psPDumpReadRegIN->szRegRegion[0],
+ &psPDumpReadRegIN->szFileName[0],
+ psPDumpReadRegIN->ui32FileOffset,
+ psPDumpReadRegIN->ui32Address,
+ psPDumpReadRegIN->ui32Size,
+ psPDumpReadRegIN->ui32Flags);
+
+ return 0;
+}
+
+static IMG_INT
+PDumpMemPagesBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_MEMPAGES *psPDumpMemPagesIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_MEMPAGES);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID **)&psDeviceNode,
+ psPDumpMemPagesIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ psPDumpSyncDumpIN->hKernelSyncInfo,
+#else
+ psPDumpSyncDumpIN->psKernelSyncInfo,
+#endif
+ 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;
+ IMG_UINT32 ui32Value;
+ IMG_UINT32 ui32Mask;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_SYNCPOL);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvSyncInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+ psPDumpSyncPolIN->hKernelSyncInfo,
+#else
+ psPDumpSyncPolIN->psKernelSyncInfo,
+#endif
+ 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);
+ }
+
+ /* FIXME: Move this code to somewhere outside of the bridge */
+ if (psPDumpSyncPolIN->bUseLastOpDumpVal)
+ {
+ if(psPDumpSyncPolIN->bIsRead)
+ {
+ ui32Value = ((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncData->ui32LastReadOpDumpVal;
+ }
+ else
+ {
+ ui32Value = ((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncData->ui32LastOpDumpVal;
+ }
+ ui32Mask = 0xffffffff;
+ }
+ else
+ {
+ ui32Value = psPDumpSyncPolIN->ui32Value;
+ ui32Mask = psPDumpSyncPolIN->ui32Mask;
+ }
+
+ psRetOUT->eError =
+ PDumpMemPolKM(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM,
+ ui32Offset,
+ ui32Value,
+ ui32Mask,
+ PDUMP_POLL_OPERATOR_EQUAL,
+ 0,
+ MAKEUNIQUETAG(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM));
+
+ 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_DEVICE_NODE *psDeviceNode;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID **)&psDeviceNode,
+ psPDumpCycleCountRegReadIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ PDumpCycleCountRegRead(&psDeviceNode->sDevId,
+ 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 /* PDUMP */
+
+
+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)
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_MISC_INFO_KM sMiscInfo = {0};
+#endif
+ PVRSRV_ERROR eError;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_MISC_INFO);
+
+#if defined (SUPPORT_SID_INTERFACE)
+ sMiscInfo.ui32StateRequest = psGetMiscInfoIN->sMiscInfo.ui32StateRequest;
+ sMiscInfo.ui32StatePresent = psGetMiscInfoIN->sMiscInfo.ui32StatePresent;
+ sMiscInfo.ui32MemoryStrLen = psGetMiscInfoIN->sMiscInfo.ui32MemoryStrLen;
+ sMiscInfo.pszMemoryStr = psGetMiscInfoIN->sMiscInfo.pszMemoryStr;
+
+ OSMemCopy(&sMiscInfo.sCacheOpCtl,
+ &psGetMiscInfoIN->sMiscInfo.sCacheOpCtl,
+ sizeof(sMiscInfo.sCacheOpCtl));
+ OSMemCopy(&sMiscInfo.sGetRefCountCtl,
+ &psGetMiscInfoIN->sMiscInfo.sGetRefCountCtl,
+ sizeof(sMiscInfo.sGetRefCountCtl));
+#else
+ OSMemCopy(&psGetMiscInfoOUT->sMiscInfo,
+ &psGetMiscInfoIN->sMiscInfo,
+ sizeof(PVRSRV_MISC_INFO));
+#endif
+
+ if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) &&
+ ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0) &&
+ ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0))
+ {
+ /* Client must choose which of memstats and DDK version will be written to
+ * kernel side buffer */
+ 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) ||
+ ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0))
+ {
+ /* Alloc kernel side buffer to write into */
+#if defined (SUPPORT_SID_INTERFACE)
+ ASSIGN_AND_EXIT_ON_ERROR(psGetMiscInfoOUT->eError,
+ OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen,
+ (IMG_VOID **)&sMiscInfo.pszMemoryStr, 0,
+ "Output string buffer"));
+ psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&sMiscInfo);
+
+ /* Copy result to user */
+ eError = CopyToUserWrapper(psPerProc, ui32BridgeID,
+ psGetMiscInfoIN->sMiscInfo.pszMemoryStr,
+ sMiscInfo.pszMemoryStr,
+ sMiscInfo.ui32MemoryStrLen);
+#else
+ ASSIGN_AND_EXIT_ON_ERROR(psGetMiscInfoOUT->eError,
+ OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen,
+ (IMG_VOID **)&psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, 0,
+ "Output string buffer"));
+
+ psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo);
+
+ /* Copy result to user */
+ eError = CopyToUserWrapper(psPerProc, ui32BridgeID,
+ psGetMiscInfoIN->sMiscInfo.pszMemoryStr,
+ psGetMiscInfoOUT->sMiscInfo.pszMemoryStr,
+ psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen);
+#endif
+
+ /* Free kernel side buffer again */
+#if defined (SUPPORT_SID_INTERFACE)
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sMiscInfo.ui32MemoryStrLen,
+ (IMG_VOID *)sMiscInfo.pszMemoryStr, 0);
+#else
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen,
+ (IMG_VOID *)psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, 0);
+#endif
+
+ /* Replace output buffer pointer with input pointer, as both are expected
+ * to point to the same userspace memory.
+ */
+ psGetMiscInfoOUT->sMiscInfo.pszMemoryStr = psGetMiscInfoIN->sMiscInfo.pszMemoryStr;
+
+ if(eError != PVRSRV_OK)
+ {
+ /* Do error check at the end as we always have to free and reset the
+ * pointer.
+ */
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoBW Error copy to user"));
+ return -EFAULT;
+ }
+ }
+ else
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&sMiscInfo);
+#else
+ psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo);
+#endif
+ }
+
+ /* Return on error so exit status of PVRSRVGetMiscInfoKM is propagated to client.
+ * Don't alloc handles for event object or timer; if error exit status is returned
+ * the handles should not be used (even if not null) */
+ if (psGetMiscInfoOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ /*
+ * The handles are not allocated in batch mode as they are shared
+ * (a shared handle is allocated at most once), and there is no
+ * resource allocation to undo if the handle allocation fails.
+ */
+#if defined (SUPPORT_SID_INTERFACE)
+ if (sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT)
+#else
+ if (psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT)
+#endif
+ {
+ psGetMiscInfoOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
+ &psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.hOSEventKM,
+#if defined (SUPPORT_SID_INTERFACE)
+ sMiscInfo.sGlobalEventObject.hOSEventKM,
+#else
+ psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.hOSEventKM,
+#endif
+ PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT,
+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+
+ if (psGetMiscInfoOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ OSMemCopy(&psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.szName,
+ sMiscInfo.sGlobalEventObject.szName,
+ EVENTOBJNAME_MAXLENGTH);
+#endif
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if (sMiscInfo.hSOCTimerRegisterOSMemHandle)
+#else
+ if (psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle)
+#endif
+ {
+ /* Allocate handle for SOC OSMemHandle */
+ psGetMiscInfoOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
+ &psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle,
+#if defined (SUPPORT_SID_INTERFACE)
+ sMiscInfo.hSOCTimerRegisterOSMemHandle,
+#else
+ psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle,
+#endif
+ PVRSRV_HANDLE_TYPE_SOC_TIMER,
+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+
+ if (psGetMiscInfoOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+#if defined (SUPPORT_SID_INTERFACE)
+ else
+ {
+ psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle = 0;
+ }
+
+ /* copy data from local sMiscInfo to OUT */
+ psGetMiscInfoOUT->sMiscInfo.ui32StateRequest = sMiscInfo.ui32StateRequest;
+ psGetMiscInfoOUT->sMiscInfo.ui32StatePresent = sMiscInfo.ui32StatePresent;
+
+ psGetMiscInfoOUT->sMiscInfo.pvSOCTimerRegisterKM = sMiscInfo.pvSOCTimerRegisterKM;
+ psGetMiscInfoOUT->sMiscInfo.pvSOCTimerRegisterUM = sMiscInfo.pvSOCTimerRegisterUM;
+ psGetMiscInfoOUT->sMiscInfo.pvSOCClockGateRegs = sMiscInfo.pvSOCClockGateRegs;
+
+ psGetMiscInfoOUT->sMiscInfo.ui32SOCClockGateRegsSize = sMiscInfo.ui32SOCClockGateRegsSize;
+
+ OSMemCopy(&psGetMiscInfoOUT->sMiscInfo.aui32DDKVersion,
+ &sMiscInfo.aui32DDKVersion,
+ sizeof(psGetMiscInfoOUT->sMiscInfo.aui32DDKVersion));
+ OSMemCopy(&psGetMiscInfoOUT->sMiscInfo.sCacheOpCtl,
+ &sMiscInfo.sCacheOpCtl,
+ sizeof(psGetMiscInfoOUT->sMiscInfo.sCacheOpCtl));
+ OSMemCopy(&psGetMiscInfoOUT->sMiscInfo.sGetRefCountCtl,
+ &sMiscInfo.sGetRefCountCtl,
+ sizeof(psGetMiscInfoOUT->sMiscInfo.sGetRefCountCtl));
+#endif
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVConnectBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_CONNECT_SERVICES *psConnectServicesIN,
+ PVRSRV_BRIDGE_OUT_CONNECT_SERVICES *psConnectServicesOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CONNECT_SERVICES);
+
+#if defined(PDUMP)
+ /* Store the per process connection info.
+ * The Xserver initially connects via PVR2D which sets the persistent flag.
+ * But, later the Xserver may connect via SGL which doesn't carry the flag (in
+ * general SGL clients aren't persistent). So we OR in the flag so if it was set
+ * before it remains set.
+ */
+ if ((psConnectServicesIN->ui32Flags & SRV_FLAGS_PERSIST) != 0)
+ {
+ psPerProc->bPDumpPersistent = IMG_TRUE;
+ }
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ /* Select whether this client is our 'active' target for pdumping in a
+ * multi-process environment.
+ * NOTE: only 1 active target is supported at present.
+ */
+ if ((psConnectServicesIN->ui32Flags & SRV_FLAGS_PDUMP_ACTIVE) != 0)
+ {
+ psPerProc->bPDumpActive = IMG_TRUE;
+ }
+#endif /* SUPPORT_PDUMP_MULTI_PROCESS */
+#else
+ PVR_UNREFERENCED_PARAMETER(psConnectServicesIN);
+#endif
+ psConnectServicesOUT->hKernelServices = psPerProc->hPerProcData;
+ psConnectServicesOUT->eError = PVRSRV_OK;
+
+ 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);
+
+ /* just return OK, per-process data is cleaned up by resmgr */
+ 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);
+ 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;
+}
+
+#if defined(SUPPORT_PVRSRV_GET_DC_SYSTEM_BUFFER)
+static IMG_INT
+PVRSRVGetDCSystemBufferBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER *psGetDispClassSysBufferIN, //IMG_HANDLE *phGetDispClassSysBufferIN,
+ 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;
+ }
+
+ /* PRQA S 1461 6 */ /* ignore warning about enum type being converted */
+ 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;
+}
+#endif
+
+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;
+ IMG_UINT32 ui32SwapChainID;
+
+ 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;
+ }
+
+ /* Get ui32SwapChainID from input */
+ ui32SwapChainID = psCreateDispClassSwapChainIN->ui32SwapChainID;
+
+ psCreateDispClassSwapChainOUT->eError =
+ PVRSRVCreateDCSwapChainKM(psPerProc, pvDispClassInfo,
+ psCreateDispClassSwapChainIN->ui32Flags,
+ &psCreateDispClassSwapChainIN->sDstSurfAttrib,
+ &psCreateDispClassSwapChainIN->sSrcSurfAttrib,
+ psCreateDispClassSwapChainIN->ui32BufferCount,
+ psCreateDispClassSwapChainIN->ui32OEMFlags,
+ &hSwapChainInt,
+ &ui32SwapChainID);
+
+ if(psCreateDispClassSwapChainOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ /* Pass ui32SwapChainID to output */
+ psCreateDispClassSwapChainOUT->ui32SwapChainID = ui32SwapChainID;
+
+ 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;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_HANDLE *pahBuffer;
+#endif
+
+ 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;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ psGetDispClassBuffersOUT->eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(IMG_HANDLE) * PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS,
+ (IMG_PVOID *)&pahBuffer, 0,
+ "Temp Swapchain Buffers");
+
+ if (psGetDispClassBuffersOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+#endif
+
+ psGetDispClassBuffersOUT->eError =
+ PVRSRVGetDCBuffersKM(pvDispClassInfo,
+ pvSwapChain,
+ &psGetDispClassBuffersOUT->ui32BufferCount,
+#if defined (SUPPORT_SID_INTERFACE)
+ pahBuffer,
+#else
+ psGetDispClassBuffersOUT->ahBuffer,
+#endif
+ psGetDispClassBuffersOUT->asPhyAddr);
+ if (psGetDispClassBuffersOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ PVR_ASSERT(psGetDispClassBuffersOUT->ui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);
+
+ for(i = 0; i < psGetDispClassBuffersOUT->ui32BufferCount; i++)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hBufferExt;
+#else
+ IMG_HANDLE hBufferExt;
+#endif
+
+ /* PRQA S 1461 15 */ /* ignore warning about enum type being converted */
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &hBufferExt,
+ pahBuffer[i],
+ PVRSRV_HANDLE_TYPE_DISP_BUFFER,
+ (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
+ psGetDispClassBuffersIN->hSwapChain);
+#else
+ 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);
+#endif
+
+ psGetDispClassBuffersOUT->ahBuffer[i] = hBufferExt;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(IMG_HANDLE) * PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS,
+ (IMG_PVOID)pahBuffer, 0);
+#endif
+
+ 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;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_HANDLE hPrivateTag;
+#endif
+
+ 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;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psSwapDispClassBufferIN->hPrivateTag != 0)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupSubHandle(psPerProc->psHandleBase,
+ &hPrivateTag,
+ psSwapDispClassBufferIN->hPrivateTag,
+ PVRSRV_HANDLE_TYPE_DISP_BUFFER,
+ psSwapDispClassBufferIN->hDeviceKM);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ hPrivateTag = IMG_NULL;
+ }
+#endif
+
+ psRetOUT->eError =
+ PVRSRVSwapToDCBufferKM(pvDispClassInfo,
+ pvSwapChainBuf,
+ psSwapDispClassBufferIN->ui32SwapInterval,
+#if defined (SUPPORT_SID_INTERFACE)
+ hPrivateTag,
+#else
+ psSwapDispClassBufferIN->hPrivateTag,
+#endif
+ psSwapDispClassBufferIN->ui32ClipRectCount,
+ psSwapDispClassBufferIN->sClipRect);
+
+ return 0;
+}
+
+static IMG_INT
+PVRSRVSwapToDCBuffer2BW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER2 *psSwapDispClassBufferIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_VOID *pvPrivData = IMG_NULL;
+ IMG_VOID *pvDispClassInfo;
+ IMG_VOID *pvSwapChain;
+ IMG_UINT32 i;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER2);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvDispClassInfo,
+ psSwapDispClassBufferIN->hDeviceKM,
+ PVRSRV_HANDLE_TYPE_DISP_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Failed to look up DISP_INFO handle"));
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupSubHandle(psPerProc->psHandleBase,
+ &pvSwapChain,
+ psSwapDispClassBufferIN->hSwapChain,
+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
+ psSwapDispClassBufferIN->hDeviceKM);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Failed to look up DISP_BUFFER handle"));
+ return 0;
+ }
+
+ if(!OSAccessOK(PVR_VERIFY_WRITE,
+ psSwapDispClassBufferIN->ppsKernelMemInfos,
+ sizeof(IMG_HANDLE) * psSwapDispClassBufferIN->ui32NumMemInfos))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Access check failed for ppsKernelMemInfos"));
+ return -EFAULT;
+ }
+
+ if(!OSAccessOK(PVR_VERIFY_WRITE,
+ psSwapDispClassBufferIN->ppsKernelSyncInfos,
+ sizeof(IMG_HANDLE) * psSwapDispClassBufferIN->ui32NumMemInfos))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Access check failed for ppsKernelSyncInfos"));
+ return -EFAULT;
+ }
+
+ for (i = 0; i < psSwapDispClassBufferIN->ui32NumMemInfos; i++)
+ {
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_PVOID *)&psKernelMemInfo,
+ psSwapDispClassBufferIN->ppsKernelMemInfos[i],
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Failed to look up MEM_INFO handle"));
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_PVOID *)&psKernelSyncInfo,
+ psSwapDispClassBufferIN->ppsKernelSyncInfos[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Failed to look up SYNC_INFO handle"));
+ return 0;
+ }
+
+ psSwapDispClassBufferIN->ppsKernelMemInfos[i] = psKernelMemInfo;
+ psSwapDispClassBufferIN->ppsKernelSyncInfos[i] = psKernelSyncInfo;
+ }
+
+ if(psSwapDispClassBufferIN->ui32PrivDataLength > 0)
+ {
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ psSwapDispClassBufferIN->ui32PrivDataLength,
+ (IMG_VOID **)&pvPrivData, IMG_NULL,
+ "Swap Command Private Data") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2BW: Failed to allocate private data space"));
+ return -ENOMEM;
+ }
+
+ if(CopyFromUserWrapper(psPerProc,
+ ui32BridgeID,
+ pvPrivData,
+ psSwapDispClassBufferIN->pvPrivData,
+ psSwapDispClassBufferIN->ui32PrivDataLength) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Failed to copy private data"));
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ psSwapDispClassBufferIN->ui32PrivDataLength,
+ pvPrivData, IMG_NULL);
+ return -EFAULT;
+ }
+ }
+
+ psRetOUT->eError =
+ PVRSRVSwapToDCBuffer2KM(pvDispClassInfo,
+ pvSwapChain,
+ psSwapDispClassBufferIN->ui32SwapInterval,
+ psSwapDispClassBufferIN->ppsKernelMemInfos,
+ psSwapDispClassBufferIN->ppsKernelSyncInfos,
+ psSwapDispClassBufferIN->ui32NumMemInfos,
+ pvPrivData,
+ psSwapDispClassBufferIN->ui32PrivDataLength);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ psSwapDispClassBufferIN->ui32PrivDataLength,
+ pvPrivData, IMG_NULL);
+ }
+
+ 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);
+
+ 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;
+ }
+
+ /* PRQA S 1461 6 */ /* ignore warning about enum type being converted */
+ 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.uAllocSize =
+ psKernelMemInfo->uAllocSize;
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psKernelMemInfo->sMemBlk.hOSMemHandle != IMG_NULL)
+ {
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psAllocSharedSysMemOUT->sClientMemInfo.hMappingInfo,
+ psKernelMemInfo->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+ }
+ else
+ {
+ psAllocSharedSysMemOUT->sClientMemInfo.hMappingInfo = 0;
+ }
+#else
+ psAllocSharedSysMemOUT->sClientMemInfo.hMappingInfo = psKernelMemInfo->sMemBlk.hOSMemHandle;
+#endif
+
+ 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ psFreeSharedSysMemIN->hKernelMemInfo,
+#else
+ psFreeSharedSysMemIN->psKernelMemInfo,
+#endif
+ 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;
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psFreeSharedSysMemIN->hMappingInfo != 0)
+ {
+ psFreeSharedSysMemOUT->eError =
+ PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psFreeSharedSysMemIN->hMappingInfo,
+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
+ if(psFreeSharedSysMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+#endif
+
+ psFreeSharedSysMemOUT->eError =
+ PVRSRVReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ psFreeSharedSysMemIN->hKernelMemInfo,
+#else
+ psFreeSharedSysMemIN->psKernelMemInfo,
+#endif
+ 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;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hParent;
+#else
+ IMG_HANDLE hParent;
+#endif
+ 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) || defined (SUPPORT_SID_INTERFACE)
+ 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_INVALID_HANDLE_TYPE;
+ return 0;
+ }
+
+ /*
+ * To prevent the building up of deep chains of subhandles, parent
+ * the new meminfo off the parent of the input meminfo, if it has
+ * a parent.
+ */
+ psMapMemInfoMemOUT->eError =
+ PVRSRVGetParentHandle(psPerProc->psHandleBase,
+ &hParent,
+ psMapMemInfoMemIN->hKernelMemInfo,
+ eHandleType);
+ if (psMapMemInfoMemOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+#if defined (SUPPORT_SID_INTERFACE)
+ if (hParent == 0)
+#else
+ if (hParent == IMG_NULL)
+#endif
+ {
+ 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.uAllocSize =
+ psKernelMemInfo->uAllocSize;
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psKernelMemInfo->sMemBlk.hOSMemHandle != IMG_NULL)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo,
+ psKernelMemInfo->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+ hParent);
+ }
+ else
+ {
+ psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo = 0;
+ }
+#else
+ psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo = psKernelMemInfo->sMemBlk.hOSMemHandle;
+#endif
+
+ 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)
+ {
+ /* signal no syncinfo */
+ OSMemSet(&psMapMemInfoMemOUT->sClientSyncInfo,
+ 0,
+ sizeof (PVRSRV_CLIENT_SYNC_INFO));
+ }
+ else
+ {
+ /* and setup the sync info */
+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
+ psMapMemInfoMemOUT->sClientSyncInfo.psSyncData =
+ psKernelMemInfo->psKernelSyncInfo->psSyncData;
+ psMapMemInfoMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
+ psKernelMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
+ psMapMemInfoMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
+ psKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
+ psMapMemInfoMemOUT->sClientSyncInfo.sReadOps2CompleteDevVAddr =
+ psKernelMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != IMG_NULL)
+ {
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psMapMemInfoMemOUT->sClientSyncInfo.hMappingInfo,
+ psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
+ psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo);
+ }
+ else
+ {
+ psMapMemInfoMemOUT->sClientSyncInfo.hMappingInfo = 0;
+ }
+#else
+ psMapMemInfoMemOUT->sClientSyncInfo.hMappingInfo =
+ psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
+#endif
+#endif
+
+ 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;
+}
+
+
+
+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 %u (%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 %u mapped to "
+ "Dummy Wrapper (probably not what you want!)",
+ __FUNCTION__, ui32BridgeID));
+#endif
+ return -ENOTTY;
+}
+
+
+/*!
+ * *****************************************************************************
+ * @brief A wrapper for filling in the g_BridgeDispatchTable array that does
+ * error checking.
+ *
+ * @param ui32Index
+ * @param pszIOCName
+ * @param pfFunction
+ * @param pszFunctionName
+ *
+ * @return
+ ********************************************************************************/
+IMG_VOID
+_SetDispatchTableEntry(IMG_UINT32 ui32Index,
+ const IMG_CHAR *pszIOCName,
+ BridgeWrapperFunction pfFunction,
+ const IMG_CHAR *pszFunctionName)
+{
+ static IMG_UINT32 ui32PrevIndex = ~0UL; /* -1 */
+#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)
+ /* INTEGRATION_POINT: Enable this to dump out the dispatch table entries */
+ PVR_DPF((PVR_DBG_WARNING, "%s: %d %s %s", __FUNCTION__, ui32Index, pszIOCName, pszFunctionName));
+#endif
+
+ /* We should never be over-writing a previous entry.
+ * If we are, tell the world about it.
+ * NOTE: This shouldn't be debug only since switching from debug->release
+ * etc is likly to modify the available ioctls and thus be a point where
+ * mistakes are exposed. This isn't run at at a performance critical time.
+ */
+ 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=%u)",
+ __FUNCTION__, pszIOCName, ui32Index));
+#endif
+ PVR_DPF((PVR_DBG_ERROR, "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE may help debug this issue."));
+ }
+
+ /* Any gaps are sub-optimal in-terms of memory usage, but we are mainly
+ * interested in spotting any large gap of wasted memory that could be
+ * accidentally introduced.
+ *
+ * This will currently flag up any gaps > 5 entries.
+ *
+ * NOTE: This shouldn't be debug only since switching from debug->release
+ * etc is likly to modify the available ioctls and thus be a point where
+ * mistakes are exposed. This isn't run at at a performance critical time.
+ */
+// if((ui32PrevIndex != (IMG_UINT32)-1) &&
+ 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 %u (%s) and %u (%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."));
+ }
+
+ 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);
+
+ /* PRQA S 3415 1 */ /* side effects needed - if any step fails */
+ if((OSProcHasPrivSrvInit() == IMG_FALSE) || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING) || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN))
+ {
+ psRetOUT->eError = PVRSRV_ERROR_SRV_CONNECT_FAILED;
+ return 0;
+ }
+
+#if defined (__linux__) || defined (__QNXNTO__)
+ 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_SRV_DISCONNECT_FAILED;
+ return 0;
+ }
+
+ psPerProc->bInitProcess = IMG_FALSE;
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ psPerProc->bPDumpActive = IMG_FALSE;
+#endif
+
+ PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_FALSE);
+ PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RAN, IMG_TRUE);
+
+ psRetOUT->eError = PVRSRVFinaliseSystem(psInitSrvDisconnectIN->bInitSuccesful);
+
+ PVRSRVSetInitServerState( PVRSRV_INIT_SERVER_SUCCESSFUL ,
+ ((psRetOUT->eError == PVRSRV_OK) && (psInitSrvDisconnectIN->bInitSuccesful))
+ ? IMG_TRUE : IMG_FALSE);
+
+ 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 = OSEventObjectWaitKM(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)
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_EVENTOBJECT_KM sEventObject;
+ IMG_HANDLE hOSEvent;
+#endif
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_OPEN);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc, 1)
+
+ psEventObjectOpenOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sEventObject.hOSEventKM,
+#else
+ &psEventObjectOpenIN->sEventObject.hOSEventKM,
+#endif
+ psEventObjectOpenIN->sEventObject.hOSEventKM,
+ PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT);
+
+ if(psEventObjectOpenOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ OSMemCopy(&sEventObject.szName,
+ &psEventObjectOpenIN->sEventObject.szName,
+ EVENTOBJNAME_MAXLENGTH);
+
+ psEventObjectOpenOUT->eError = OSEventObjectOpenKM(&sEventObject, &hOSEvent);
+#else
+ psEventObjectOpenOUT->eError = OSEventObjectOpenKM(&psEventObjectOpenIN->sEventObject, &psEventObjectOpenOUT->hOSEvent);
+#endif
+
+ if(psEventObjectOpenOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+/* Windows7, WinXP and Vista already use an Index type handle which the client glue uses directly */
+/* Linux requires a SID handle */
+#if !defined (WINXP) && !defined(SUPPORT_VISTA)
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psEventObjectOpenOUT->hOSEvent,
+ hOSEvent,
+ PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI);
+#endif
+#else
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psEventObjectOpenOUT->hOSEvent,
+ psEventObjectOpenOUT->hOSEvent,
+ PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI);
+#endif
+
+ 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;
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_EVENTOBJECT_KM sEventObject;
+#endif
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sEventObject.hOSEventKM,
+#else
+ &psEventObjectCloseIN->sEventObject.hOSEventKM,
+#endif
+ 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;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if(CopyFromUserWrapper(psPerProc, ui32BridgeID,
+ &sEventObject.szName,
+ &psEventObjectCloseIN->sEventObject.szName,
+ EVENTOBJNAME_MAXLENGTH) != PVRSRV_OK)
+ {
+ /*not nulling pointer, out of scope*/
+ return -EFAULT;
+ }
+
+ psRetOUT->eError = OSEventObjectCloseKM(&sEventObject, hOSEventKM);
+#else
+ psRetOUT->eError = OSEventObjectCloseKM(&psEventObjectCloseIN->sEventObject, hOSEventKM);
+#endif
+
+ return 0;
+}
+
+
+typedef struct _MODIFY_SYNC_OP_INFO
+{
+ IMG_HANDLE hResItem;
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+ IMG_UINT32 ui32ModifyFlags;
+ IMG_UINT32 ui32ReadOpsPendingSnapShot;
+ IMG_UINT32 ui32WriteOpsPendingSnapShot;
+ IMG_UINT32 ui32ReadOps2PendingSnapShot;
+} MODIFY_SYNC_OP_INFO;
+
+
+static PVRSRV_ERROR DoQuerySyncOpsSatisfied(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+ IMG_UINT32 ui32ReadOpsPendingSnapShot,
+ IMG_UINT32 ui32WriteOpsPendingSnapShot,
+ IMG_UINT32 ui32ReadOps2PendingSnapShot)
+{
+ IMG_UINT32 ui32WriteOpsPending;
+ IMG_UINT32 ui32ReadOpsPending;
+ IMG_UINT32 ui32ReadOps2Pending;
+
+ /*
+ *
+ * We wait until the complete count reaches _or_moves_past_ the
+ * snapshot value.
+ *
+ */
+
+ if (!psKernelSyncInfo)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ /*
+ let p be the pending ops count
+ let c be the complete ops count
+ let p' be the previously taken snapshot
+
+ if p exceeds c by an amount greater than that by which
+ p exceeds p', then the condition is not yet satisfied.
+
+ Note that (p - c) can never be negative, and neither can (p - p')
+ so we can do the comparison using unsigned arithmetic
+ */
+ ui32WriteOpsPending = psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
+ ui32ReadOpsPending = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
+ ui32ReadOps2Pending = psKernelSyncInfo->psSyncData->ui32ReadOps2Pending;
+
+ if((ui32WriteOpsPending - ui32WriteOpsPendingSnapShot >=
+ ui32WriteOpsPending - psKernelSyncInfo->psSyncData->ui32WriteOpsComplete) &&
+ (ui32ReadOpsPending - ui32ReadOpsPendingSnapShot >=
+ ui32ReadOpsPending - psKernelSyncInfo->psSyncData->ui32ReadOpsComplete) &&
+ (ui32ReadOps2Pending - ui32ReadOps2PendingSnapShot >=
+ ui32ReadOps2Pending - psKernelSyncInfo->psSyncData->ui32ReadOps2Complete))
+ {
+#if defined(PDUMP) && !defined(SUPPORT_VGX)
+ /* pdump the sync pol: reads */
+ PDumpComment("Poll for read ops complete to reach value (pdump: %u, actual snapshot: %u)",
+ psKernelSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ ui32ReadOpsPendingSnapShot);
+ PDumpMemPolKM(psKernelSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+ psKernelSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ 0xFFFFFFFF,
+ PDUMP_POLL_OPERATOR_EQUAL, /* * see "NB" below */
+ 0,
+ MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM));
+
+ /* pdump the sync pol: writes */
+ PDumpComment("Poll for write ops complete to reach value (pdump: %u, actual snapshot: %u)",
+ psKernelSyncInfo->psSyncData->ui32LastOpDumpVal,
+ ui32WriteOpsPendingSnapShot);
+ PDumpMemPolKM(psKernelSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
+ psKernelSyncInfo->psSyncData->ui32LastOpDumpVal,
+ 0xFFFFFFFF,
+ PDUMP_POLL_OPERATOR_EQUAL, /* * see "NB" below */
+ 0,
+ MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM));
+ /* NB: FIXME -- really need to POL on an expression to
+ accurately reflect the condition we need to check. How to
+ do this in PDUMP? */
+#endif
+ return PVRSRV_OK;
+ }
+ else
+ {
+ return PVRSRV_ERROR_RETRY;
+ }
+}
+
+
+static PVRSRV_ERROR DoModifyCompleteSyncOps(MODIFY_SYNC_OP_INFO *psModSyncOpInfo)
+{
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+
+ psKernelSyncInfo = psModSyncOpInfo->psKernelSyncInfo;
+
+ if (!psKernelSyncInfo)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ /* If user has used the API correctly, we will always have reached the pending snapshot.
+ We should catch this error on the client side of the bridge and report it in an obvious way */
+ if((psModSyncOpInfo->ui32WriteOpsPendingSnapShot != psKernelSyncInfo->psSyncData->ui32WriteOpsComplete)
+ || (psModSyncOpInfo->ui32ReadOpsPendingSnapShot != psKernelSyncInfo->psSyncData->ui32ReadOpsComplete))
+ {
+ return PVRSRV_ERROR_BAD_SYNC_STATE;
+ }
+
+ /* update the WOpComplete */
+ if(psModSyncOpInfo->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC)
+ {
+ psKernelSyncInfo->psSyncData->ui32WriteOpsComplete++;
+ }
+
+ /* update the ROpComplete */
+ if(psModSyncOpInfo->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC)
+ {
+ psKernelSyncInfo->psSyncData->ui32ReadOpsComplete++;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR ModifyCompleteSyncOpsCallBack(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ if (!pvParam)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ModifyCompleteSyncOpsCallBack: invalid parameter"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psModSyncOpInfo = (MODIFY_SYNC_OP_INFO*)pvParam;
+
+ if (psModSyncOpInfo->psKernelSyncInfo)
+ {
+ LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+ {
+ if (DoQuerySyncOpsSatisfied(psModSyncOpInfo->psKernelSyncInfo,
+ psModSyncOpInfo->ui32ReadOpsPendingSnapShot,
+ psModSyncOpInfo->ui32WriteOpsPendingSnapShot,
+ psModSyncOpInfo->ui32ReadOps2PendingSnapShot) == PVRSRV_OK)
+ {
+ goto OpFlushedComplete;
+ }
+ PVR_DPF((PVR_DBG_WARNING, "ModifyCompleteSyncOpsCallBack: waiting for current Ops to flush"));
+ OSSleepms(1);
+ } END_LOOP_UNTIL_TIMEOUT();
+
+ PVR_DPF((PVR_DBG_ERROR, "ModifyCompleteSyncOpsCallBack: timeout whilst waiting for current Ops to flush."));
+ PVR_DPF((PVR_DBG_ERROR, " Write ops pending snapshot = %d, write ops complete = %d",
+ psModSyncOpInfo->ui32WriteOpsPendingSnapShot,
+ psModSyncOpInfo->psKernelSyncInfo->psSyncData->ui32WriteOpsComplete));
+ PVR_DPF((PVR_DBG_ERROR, " Read ops pending snapshot = %d, read ops complete = %d",
+ psModSyncOpInfo->ui32ReadOpsPendingSnapShot,
+ psModSyncOpInfo->psKernelSyncInfo->psSyncData->ui32ReadOpsComplete));
+ PVR_DPF((PVR_DBG_ERROR, " Read ops pending snapshot = %d, read ops2 complete = %d",
+ psModSyncOpInfo->ui32ReadOps2PendingSnapShot,
+ psModSyncOpInfo->psKernelSyncInfo->psSyncData->ui32ReadOps2Complete));
+ return PVRSRV_ERROR_TIMEOUT;
+
+OpFlushedComplete:
+ DoModifyCompleteSyncOps(psModSyncOpInfo);
+ PVRSRVKernelSyncInfoDecRef(psModSyncOpInfo->psKernelSyncInfo, IMG_NULL);
+ }
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(MODIFY_SYNC_OP_INFO), (IMG_VOID *)psModSyncOpInfo, 0);
+
+ /* re-kick all services managed devices */
+ PVRSRVScheduleDeviceCallbacks();
+
+ return PVRSRV_OK;
+}
+
+
+static IMG_INT
+PVRSRVCreateSyncInfoModObjBW(IMG_UINT32 ui32BridgeID,
+ IMG_VOID *psBridgeIn,
+ PVRSRV_BRIDGE_OUT_CREATE_SYNC_INFO_MOD_OBJ *psCreateSyncInfoModObjOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
+
+ PVR_UNREFERENCED_PARAMETER(psBridgeIn);
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_SYNC_INFO_MOD_OBJ);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psCreateSyncInfoModObjOUT->eError, psPerProc, 1)
+
+ ASSIGN_AND_EXIT_ON_ERROR(psCreateSyncInfoModObjOUT->eError,
+ OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(MODIFY_SYNC_OP_INFO),
+ (IMG_VOID **)&psModSyncOpInfo, 0,
+ "ModSyncOpInfo (MODIFY_SYNC_OP_INFO)"));
+
+ psModSyncOpInfo->psKernelSyncInfo = IMG_NULL; /* mark it as empty */
+
+ psCreateSyncInfoModObjOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
+ &psCreateSyncInfoModObjOUT->hKernelSyncInfoModObj,
+ psModSyncOpInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ,
+ PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE);
+
+ if (psCreateSyncInfoModObjOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psModSyncOpInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_MODIFY_SYNC_OPS,
+ psModSyncOpInfo,
+ 0,
+ &ModifyCompleteSyncOpsCallBack);
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psCreateSyncInfoModObjOUT->eError, psPerProc)
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVDestroySyncInfoModObjBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_DESTROY_SYNC_INFO_MOD_OBJ *psDestroySyncInfoModObjIN,
+ PVRSRV_BRIDGE_RETURN *psDestroySyncInfoModObjOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_SYNC_INFO_MOD_OBJ);
+
+ psDestroySyncInfoModObjOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psModSyncOpInfo,
+ psDestroySyncInfoModObjIN->hKernelSyncInfoModObj,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
+ if (psDestroySyncInfoModObjOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVDestroySyncInfoModObjBW: PVRSRVLookupHandle failed"));
+ return 0;
+ }
+
+ if(psModSyncOpInfo->psKernelSyncInfo != IMG_NULL)
+ {
+ /* Not empty */
+ psDestroySyncInfoModObjOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+
+ PVRSRVKernelSyncInfoDecRef(psModSyncOpInfo->psKernelSyncInfo, IMG_NULL);
+
+ psDestroySyncInfoModObjOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psDestroySyncInfoModObjIN->hKernelSyncInfoModObj,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
+
+ if (psDestroySyncInfoModObjOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVDestroySyncInfoModObjBW: PVRSRVReleaseHandle failed"));
+ return 0;
+ }
+
+ psDestroySyncInfoModObjOUT->eError = ResManFreeResByPtr(psModSyncOpInfo->hResItem, CLEANUP_WITH_POLL);
+ if (psDestroySyncInfoModObjOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVDestroySyncInfoModObjBW: ResManFreeResByPtr failed"));
+ return 0;
+ }
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVModifyPendingSyncOpsBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_MODIFY_PENDING_SYNC_OPS *psModifySyncOpsIN,
+ PVRSRV_BRIDGE_OUT_MODIFY_PENDING_SYNC_OPS *psModifySyncOpsOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+ MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS);
+
+ psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psModSyncOpInfo,
+ psModifySyncOpsIN->hKernelSyncInfoModObj,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
+ if (psModifySyncOpsOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyPendingSyncOpsBW: PVRSRVLookupHandle failed"));
+ return 0;
+ }
+
+ psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psKernelSyncInfo,
+ psModifySyncOpsIN->hKernelSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if (psModifySyncOpsOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyPendingSyncOpsBW: PVRSRVLookupHandle failed"));
+ return 0;
+ }
+
+ if(psModSyncOpInfo->psKernelSyncInfo)
+ {
+ /* SyncInfoModification is not empty */
+ psModifySyncOpsOUT->eError = PVRSRV_ERROR_RETRY;
+ PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVModifyPendingSyncOpsBW: SyncInfo Modification object is not empty"));
+ return 0;
+ }
+
+ /* Should never happen, but check to be sure */
+ if (psKernelSyncInfo == IMG_NULL)
+ {
+ psModifySyncOpsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVModifyPendingSyncOpsBW: SyncInfo bad handle"));
+ return 0;
+ }
+
+ PVRSRVKernelSyncInfoIncRef(psKernelSyncInfo, IMG_NULL);
+ /* setup info to store in resman */
+ psModSyncOpInfo->psKernelSyncInfo = psKernelSyncInfo;
+ psModSyncOpInfo->ui32ModifyFlags = psModifySyncOpsIN->ui32ModifyFlags;
+ psModSyncOpInfo->ui32ReadOpsPendingSnapShot = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
+ psModSyncOpInfo->ui32WriteOpsPendingSnapShot = psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
+ psModSyncOpInfo->ui32ReadOps2PendingSnapShot = psKernelSyncInfo->psSyncData->ui32ReadOps2Pending;
+
+ /* We return PRE-INCREMENTED versions of all sync Op Values */
+
+ psModifySyncOpsOUT->ui32ReadOpsPending = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
+ psModifySyncOpsOUT->ui32WriteOpsPending = psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
+ psModifySyncOpsOUT->ui32ReadOps2Pending = psKernelSyncInfo->psSyncData->ui32ReadOps2Pending;
+
+ if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC)
+ {
+ psKernelSyncInfo->psSyncData->ui32WriteOpsPending++;
+ }
+
+ if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC)
+ {
+ psKernelSyncInfo->psSyncData->ui32ReadOpsPending++;
+ }
+
+ /* pull the resman item to the front of the list */
+ psModifySyncOpsOUT->eError = ResManDissociateRes(psModSyncOpInfo->hResItem,
+ psPerProc->hResManContext);
+
+ if (psModifySyncOpsOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyPendingSyncOpsBW: PVRSRVLookupHandle failed"));
+ return 0;
+ }
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVModifyCompleteSyncOpsBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_MODIFY_COMPLETE_SYNC_OPS *psModifySyncOpsIN,
+ PVRSRV_BRIDGE_RETURN *psModifySyncOpsOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS);
+
+ psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psModSyncOpInfo,
+ psModifySyncOpsIN->hKernelSyncInfoModObj,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
+ if (psModifySyncOpsOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyCompleteSyncOpsBW: PVRSRVLookupHandle failed"));
+ return 0;
+ }
+
+ if(psModSyncOpInfo->psKernelSyncInfo == IMG_NULL)
+ {
+ /* Empty */
+ psModifySyncOpsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+
+ psModifySyncOpsOUT->eError = DoModifyCompleteSyncOps(psModSyncOpInfo);
+
+ if (psModifySyncOpsOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyCompleteSyncOpsBW: DoModifyCompleteSyncOps failed"));
+ return 0;
+ }
+
+ PVRSRVKernelSyncInfoDecRef(psModSyncOpInfo->psKernelSyncInfo, IMG_NULL);
+ psModSyncOpInfo->psKernelSyncInfo = IMG_NULL;
+
+ /* re-kick all services managed devices */
+ PVRSRVScheduleDeviceCallbacks();
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVSyncOpsTakeTokenBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SYNC_OPS_TAKE_TOKEN *psSyncOpsTakeTokenIN,
+ PVRSRV_BRIDGE_OUT_SYNC_OPS_TAKE_TOKEN *psSyncOpsTakeTokenOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_TAKE_TOKEN);
+
+ psSyncOpsTakeTokenOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psKernelSyncInfo,
+ psSyncOpsTakeTokenIN->hKernelSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if (psSyncOpsTakeTokenOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsTakeTokenBW: PVRSRVLookupHandle failed"));
+ return 0;
+ }
+
+ /* We return PRE-INCREMENTED versions of all sync Op Values */
+
+ psSyncOpsTakeTokenOUT->ui32ReadOpsPending = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
+ psSyncOpsTakeTokenOUT->ui32WriteOpsPending = psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
+ psSyncOpsTakeTokenOUT->ui32ReadOps2Pending = psKernelSyncInfo->psSyncData->ui32ReadOps2Pending;
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVSyncOpsFlushToTokenBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_TOKEN *psSyncOpsFlushToTokenIN,
+ PVRSRV_BRIDGE_RETURN *psSyncOpsFlushToTokenOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
+ IMG_UINT32 ui32ReadOpsPendingSnapshot;
+ IMG_UINT32 ui32WriteOpsPendingSnapshot;
+ IMG_UINT32 ui32ReadOps2PendingSnapshot;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_TOKEN);
+
+ psSyncOpsFlushToTokenOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psKernelSyncInfo,
+ psSyncOpsFlushToTokenIN->hKernelSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if (psSyncOpsFlushToTokenOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToTokenBW: PVRSRVLookupHandle failed"));
+ return 0;
+ }
+
+ ui32ReadOpsPendingSnapshot = psSyncOpsFlushToTokenIN->ui32ReadOpsPendingSnapshot;
+ ui32WriteOpsPendingSnapshot = psSyncOpsFlushToTokenIN->ui32WriteOpsPendingSnapshot;
+ ui32ReadOps2PendingSnapshot = psSyncOpsFlushToTokenIN->ui32ReadOps2PendingSnapshot;
+
+ psSyncOpsFlushToTokenOUT->eError = DoQuerySyncOpsSatisfied(psKernelSyncInfo,
+ ui32ReadOpsPendingSnapshot,
+ ui32WriteOpsPendingSnapshot,
+ ui32ReadOps2PendingSnapshot);
+
+ if (psSyncOpsFlushToTokenOUT->eError != PVRSRV_OK && psSyncOpsFlushToTokenOUT->eError != PVRSRV_ERROR_RETRY)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToTokenBW: DoQuerySyncOpsSatisfied failed"));
+ return 0;
+ }
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVSyncOpsFlushToModObjBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_MOD_OBJ *psSyncOpsFlushToModObjIN,
+ PVRSRV_BRIDGE_RETURN *psSyncOpsFlushToModObjOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_MOD_OBJ);
+
+ psSyncOpsFlushToModObjOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psModSyncOpInfo,
+ psSyncOpsFlushToModObjIN->hKernelSyncInfoModObj,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
+ if (psSyncOpsFlushToModObjOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToModObjBW: PVRSRVLookupHandle failed"));
+ return 0;
+ }
+
+ if(psModSyncOpInfo->psKernelSyncInfo == IMG_NULL)
+ {
+ /* Empty */
+ psSyncOpsFlushToModObjOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+
+ psSyncOpsFlushToModObjOUT->eError = DoQuerySyncOpsSatisfied(psModSyncOpInfo->psKernelSyncInfo,
+ psModSyncOpInfo->ui32ReadOpsPendingSnapShot,
+ psModSyncOpInfo->ui32WriteOpsPendingSnapShot,
+ psModSyncOpInfo->ui32ReadOps2PendingSnapShot);
+
+ if (psSyncOpsFlushToModObjOUT->eError != PVRSRV_OK && psSyncOpsFlushToModObjOUT->eError != PVRSRV_ERROR_RETRY)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToModObjBW: DoQuerySyncOpsSatisfied failed"));
+ return 0;
+ }
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVSyncOpsFlushToDeltaBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_DELTA *psSyncOpsFlushToDeltaIN,
+ PVRSRV_BRIDGE_RETURN *psSyncOpsFlushToDeltaOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
+ IMG_UINT32 ui32DeltaRead;
+ IMG_UINT32 ui32DeltaWrite;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_DELTA);
+
+ psSyncOpsFlushToDeltaOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psSyncInfo,
+ psSyncOpsFlushToDeltaIN->hKernelSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if (psSyncOpsFlushToDeltaOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToDeltaBW: PVRSRVLookupHandle failed"));
+ return 0;
+ }
+
+ /* FIXME: there's logic here in the bridge-wrapper - this needs to be moved to
+ a better place */
+
+ ui32DeltaRead = psSyncInfo->psSyncData->ui32ReadOpsPending - psSyncInfo->psSyncData->ui32ReadOpsComplete;
+ ui32DeltaWrite = psSyncInfo->psSyncData->ui32WriteOpsPending - psSyncInfo->psSyncData->ui32WriteOpsComplete;
+
+ if (ui32DeltaRead <= psSyncOpsFlushToDeltaIN->ui32Delta && ui32DeltaWrite <= psSyncOpsFlushToDeltaIN->ui32Delta)
+ {
+#if defined(PDUMP) && !defined(SUPPORT_VGX)
+ /* pdump the sync pol: reads */
+ PDumpComment("Poll for read ops complete to delta (%u)",
+ psSyncOpsFlushToDeltaIN->ui32Delta);
+ psSyncOpsFlushToDeltaOUT->eError =
+ PDumpMemPolKM(psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ 0xFFFFFFFF,
+ PDUMP_POLL_OPERATOR_GREATEREQUAL,
+ 0,
+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+
+ /* pdump the sync pol: writes */
+ PDumpComment("Poll for write ops complete to delta (%u)",
+ psSyncOpsFlushToDeltaIN->ui32Delta);
+ psSyncOpsFlushToDeltaOUT->eError =
+ PDumpMemPolKM(psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
+ psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ 0xFFFFFFFF,
+ PDUMP_POLL_OPERATOR_GREATEREQUAL,
+ 0,
+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+#endif
+
+ psSyncOpsFlushToDeltaOUT->eError = PVRSRV_OK;
+ }
+ else
+ {
+ psSyncOpsFlushToDeltaOUT->eError = PVRSRV_ERROR_RETRY;
+ }
+
+ return 0;
+}
+
+
+static PVRSRV_ERROR
+FreeSyncInfoCallback(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)pvParam;
+
+ PVRSRVKernelSyncInfoDecRef(psSyncInfo, IMG_NULL);
+
+ return PVRSRV_OK;
+}
+
+
+static IMG_INT
+PVRSRVAllocSyncInfoBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_ALLOC_SYNC_INFO *psAllocSyncInfoIN,
+ PVRSRV_BRIDGE_OUT_ALLOC_SYNC_INFO *psAllocSyncInfoOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
+ PVRSRV_ERROR eError;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_HANDLE hDevMemContext;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_SYNC_INFO);
+
+ NEW_HANDLE_BATCH_OR_ERROR(psAllocSyncInfoOUT->eError, psPerProc, 1)
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_HANDLE *)&psDeviceNode,
+ psAllocSyncInfoIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(eError != PVRSRV_OK)
+ {
+ goto allocsyncinfo_errorexit;
+ }
+
+ hDevMemContext = psDeviceNode->sDevMemoryInfo.pBMKernelContext;
+
+ eError = PVRSRVAllocSyncInfoKM(psDeviceNode,
+ hDevMemContext,
+ &psSyncInfo);
+
+ if (eError != PVRSRV_OK)
+ {
+ goto allocsyncinfo_errorexit;
+ }
+
+ eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
+ &psAllocSyncInfoOUT->hKernelSyncInfo,
+ psSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO,
+ PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE);
+
+ if(eError != PVRSRV_OK)
+ {
+ goto allocsyncinfo_errorexit_freesyncinfo;
+ }
+
+ psSyncInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_SYNC_INFO,
+ psSyncInfo,
+ 0,
+ &FreeSyncInfoCallback);
+
+ /* Success */
+ goto allocsyncinfo_commit;
+
+ /* Error handling */
+ allocsyncinfo_errorexit_freesyncinfo:
+ PVRSRVKernelSyncInfoDecRef(psSyncInfo, IMG_NULL);
+
+ allocsyncinfo_errorexit:
+
+ /* Common exit */
+ allocsyncinfo_commit:
+ psAllocSyncInfoOUT->eError = eError;
+ COMMIT_HANDLE_BATCH_OR_ERROR(eError, psPerProc);
+
+ return 0;
+}
+
+
+static IMG_INT
+PVRSRVFreeSyncInfoBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_FREE_SYNC_INFO *psFreeSyncInfoIN,
+ PVRSRV_BRIDGE_RETURN *psFreeSyncInfoOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
+ PVRSRV_ERROR eError;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_SYNC_INFO);
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psSyncInfo,
+ psFreeSyncInfoIN->hKernelSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeSyncInfoBW: PVRSRVLookupHandle failed"));
+ psFreeSyncInfoOUT->eError = eError;
+ return 0;
+ }
+
+ eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psFreeSyncInfoIN->hKernelSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeSyncInfoBW: PVRSRVReleaseHandle failed"));
+ psFreeSyncInfoOUT->eError = eError;
+ return 0;
+ }
+
+ eError = ResManFreeResByPtr(psSyncInfo->hResItem, CLEANUP_WITH_POLL);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeSyncInfoBW: ResManFreeResByPtr failed"));
+ psFreeSyncInfoOUT->eError = eError;
+ return 0;
+ }
+
+ 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_CHG_DEV_MEM_ATTRIBS, PVRSRVChangeDeviceMemoryAttributesBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_DEV_MEMORY_2, PVRSRVMapDeviceMemoryBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2, PVRSRVExportDeviceMemBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_MULTI_MANAGE_DEV_MEM, PVRSRVMultiManageDevMemBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_CORE_CMD_RESERVED_1, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_CORE_CMD_RESERVED_2, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_CORE_CMD_RESERVED_3, DummyBW);
+#if defined(SUPPORT_ION)
+ SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_ION_HANDLE, PVRSRVMapIonHandleBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_ION_HANDLE, PVRSRVUnmapIonHandleBW);
+#endif
+
+ /* SIM */
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PROCESS_SIMISR_EVENT, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_REGISTER_SIM_PROCESS, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_UNREGISTER_SIM_PROCESS, DummyBW);
+
+ /* User Mapping */
+ SetDispatchTableEntry(PVRSRV_BRIDGE_MAPPHYSTOUSERSPACE, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAPPHYSTOUSERSPACE, DummyBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_GETPHYSTOUSERSPACEMAP, DummyBW);
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_FB_STATS, DummyBW);
+
+ /* API to retrieve misc. info. from services */
+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_MISC_INFO, PVRSRVGetMiscInfoBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_MISC_INFO, DummyBW);
+
+ /* Overlay ioctls */
+#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
+
+
+ /* PDUMP */
+#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_MEMPAGES, PDumpMemPagesBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DRIVERINFO, PDumpDriverInfoBW);
+ 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 /* defined(PDUMP) */
+
+ /* DisplayClass APIs */
+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_OEMJTABLE, DummyBW);
+
+ /* device class enum */
+ SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_CLASS, PVRSRVEnumerateDCBW);
+
+ /* display class API */
+ 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);
+#if defined(SUPPORT_PVRSRV_GET_DC_SYSTEM_BUFFER)
+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER, PVRSRVGetDCSystemBufferBW);
+#else
+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER, DummyBW);
+#endif
+ 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_BUFFER2, PVRSRVSwapToDCBuffer2BW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM, PVRSRVSwapToDCSystemBW);
+
+ /* buffer class API */
+ 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);
+
+ /* Wrap/Unwrap external memory */
+ SetDispatchTableEntry(PVRSRV_BRIDGE_WRAP_EXT_MEMORY, PVRSRVWrapExtMemoryBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY, PVRSRVUnwrapExtMemoryBW);
+
+ /* Shared memory */
+ SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM, PVRSRVAllocSharedSysMemoryBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM, PVRSRVFreeSharedSysMemoryBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_MEMINFO_MEM, PVRSRVMapMemInfoMemBW);
+
+ /* Intialisation Service support */
+ SetDispatchTableEntry(PVRSRV_BRIDGE_INITSRV_CONNECT, &PVRSRVInitSrvConnectBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_INITSRV_DISCONNECT, &PVRSRVInitSrvDisconnectBW);
+
+ /* Event Object */
+ SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_WAIT, &PVRSRVEventObjectWaitBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_OPEN, &PVRSRVEventObjectOpenBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE, &PVRSRVEventObjectCloseBW);
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_SYNC_INFO_MOD_OBJ, PVRSRVCreateSyncInfoModObjBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_SYNC_INFO_MOD_OBJ, PVRSRVDestroySyncInfoModObjBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS, PVRSRVModifyPendingSyncOpsBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS, PVRSRVModifyCompleteSyncOpsBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC_OPS_TAKE_TOKEN, PVRSRVSyncOpsTakeTokenBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_TOKEN, PVRSRVSyncOpsFlushToTokenBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_MOD_OBJ, PVRSRVSyncOpsFlushToModObjBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_DELTA, PVRSRVSyncOpsFlushToDeltaBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_SYNC_INFO, PVRSRVAllocSyncInfoBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_SYNC_INFO, PVRSRVFreeSyncInfoBW);
+
+#if defined (SUPPORT_SGX)
+ SetSGXDispatchTableEntry();
+#endif
+#if defined (SUPPORT_VGX)
+ SetVGXDispatchTableEntry();
+#endif
+#if defined (SUPPORT_MSVDX)
+ SetMSVDXDispatchTableEntry();
+#endif
+
+ /* A safety net to help ensure there won't be any un-initialised dispatch
+ * table entries... */
+ /* Note: This is specifically done _after_ setting all the dispatch entries
+ * so that SetDispatchTableEntry can detect mistakes where entries
+ * overlap */
+ 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
+ {
+ /* Only certain operations are allowed */
+ 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__)
+ {
+ /* This should be moved into the linux specific code */
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+
+ /* We have already set up some static buffers to store our ioctl data... */
+ psBridgeIn = ((ENV_DATA *)psSysData->pvEnvSpecificData)->pvBridgeData;
+ psBridgeOut = (IMG_PVOID)((IMG_PBYTE)psBridgeIn + PVRSRV_MAX_BRIDGE_IN_SIZE);
+
+ /* check we are not using a bigger bridge than allocated */
+ if((psBridgePackageKM->ui32InBufferSize > PVRSRV_MAX_BRIDGE_IN_SIZE) ||
+ (psBridgePackageKM->ui32OutBufferSize > PVRSRV_MAX_BRIDGE_OUT_SIZE))
+ {
+ goto return_fault;
+ }
+
+
+ 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__)
+ /* This should be moved into the linux specific code */
+ if(CopyToUserWrapper(psPerProc,
+ ui32BridgeID,
+ psBridgePackageKM->pvParamOut,
+ psBridgeOut,
+ psBridgePackageKM->ui32OutBufferSize)
+ != PVRSRV_OK)
+ {
+ goto return_fault;
+ }
+#endif
+
+ err = 0;
+return_fault:
+
+ ReleaseHandleBatch(psPerProc);
+ return err;
+}
+
+/******************************************************************************
+ End of file (bridged_pvr_bridge.c)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/bridged/bridged_pvr_bridge.h b/pvr-source/services4/srvkm/bridged/bridged_pvr_bridge.h
new file mode 100644
index 0000000..b0145f7
--- /dev/null
+++ b/pvr-source/services4/srvkm/bridged/bridged_pvr_bridge.h
@@ -0,0 +1,257 @@
+/*************************************************************************/ /*!
+@Title PVR Bridge Functionality
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Header for the PVR Bridge code
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#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) || defined (SUPPORT_SID_INTERFACE)
+#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 /* defined(PVR_SECURE_HANDLES) */
+#define NEW_HANDLE_BATCH_OR_ERROR(error, psPerProc, ui32BatchSize)
+#define COMMIT_HANDLE_BATCH_OR_ERROR(error, psPerProc)
+#define ReleaseHandleBatch(psPerProc)
+#endif /* defined(PVR_SECURE_HANDLES) */
+
+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; /*!< The wrapper function that validates the ioctl
+ arguments before calling into srvkm proper */
+#if defined(DEBUG_BRIDGE_KM)
+ const IMG_CHAR *pszIOCName; /*!< Name of the ioctl: e.g. "PVRSRV_BRIDGE_CONNECT_SERVICES" */
+ const IMG_CHAR *pszFunctionName; /*!< Name of the wrapper function: e.g. "PVRSRVConnectBW" */
+ IMG_UINT32 ui32CallCount; /*!< The total number of times the ioctl has been called */
+ IMG_UINT32 ui32CopyFromUserTotalBytes; /*!< The total number of bytes copied from
+ userspace within this ioctl */
+ IMG_UINT32 ui32CopyToUserTotalBytes; /*!< The total number of bytes copied from
+ userspace within this ioctl */
+#endif
+}PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY;
+
+#if defined(SUPPORT_VGX) || defined(SUPPORT_MSVDX)
+ #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
+ #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_MSVDX_CMD+1)
+ #define PVRSRV_BRIDGE_LAST_DEVICE_CMD PVRSRV_BRIDGE_LAST_MSVDX_CMD
+ #endif
+#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);
+
+
+/* PRQA S 0884,3410 2*/ /* macro relies on the lack of brackets */
+#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;
+
+/* OS specific code way want to report the stats held here and within the
+ * BRIDGE_DISPATCH_TABLE_ENTRYs (E.g. on Linux we report these via a
+ * proc entry /proc/pvr/bridge_stats. Ref printLinuxBridgeStats()) */
+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 /* __BRIDGED_PVR_BRIDGE_H__ */
+
+/******************************************************************************
+ End of file (bridged_pvr_bridge.h)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/bridged/bridged_support.c b/pvr-source/services4/srvkm/bridged/bridged_support.c
new file mode 100644
index 0000000..25baf29
--- /dev/null
+++ b/pvr-source/services4/srvkm/bridged/bridged_support.c
@@ -0,0 +1,117 @@
+/*************************************************************************/ /*!
+@Title PVR Bridge Support Functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description User/kernel mode bridge support. The functions in here
+ may be used beyond the bridge code proper (e.g. Linux
+ mmap interface).
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "img_defs.h"
+#include "servicesint.h"
+#include "bridged_support.h"
+
+
+/*
+ * Derive the internal OS specific memory handle from a secure
+ * handle.
+ */
+PVRSRV_ERROR
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psHandleBase, IMG_HANDLE *phOSMemHandle, IMG_SID hMHandle)
+#else
+PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psHandleBase, IMG_HANDLE *phOSMemHandle, IMG_HANDLE hMHandle)
+#endif
+{
+ IMG_HANDLE hMHandleInt;
+ PVRSRV_HANDLE_TYPE eHandleType;
+ PVRSRV_ERROR eError;
+
+ /*
+ * We don't know the type of the handle at this point, so we use
+ * PVRSRVLookupHandleAnyType to look it up.
+ */
+ eError = PVRSRVLookupHandleAnyType(psHandleBase, &hMHandleInt,
+ &eHandleType,
+ hMHandle);
+ if(eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ switch(eHandleType)
+ {
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ 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;
+}
+/******************************************************************************
+ End of file (bridged_support.c)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/bridged/bridged_support.h b/pvr-source/services4/srvkm/bridged/bridged_support.h
new file mode 100644
index 0000000..04d5168
--- /dev/null
+++ b/pvr-source/services4/srvkm/bridged/bridged_support.h
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@Title PVR Bridge Support
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description User/kernel mode bridge support. The functions in here
+ may be used beyond the bridge code proper (e.g. Linux
+ mmap interface).
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __BRIDGED_SUPPORT_H__
+#define __BRIDGED_SUPPORT_H__
+
+#include "handle.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * Derive the internal OS specific memory handle from a secure
+ * handle.
+ */
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phOSMemHandle, IMG_SID hMHandle);
+#else
+PVRSRV_ERROR PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phOSMemHandle, IMG_HANDLE hMHandle);
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* __BRIDGED_SUPPORT_H__ */
+
+/******************************************************************************
+ End of file (bridged_support.h)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c b/pvr-source/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c
new file mode 100644
index 0000000..bee5dc6
--- /dev/null
+++ b/pvr-source/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c
@@ -0,0 +1,3864 @@
+/*************************************************************************/ /*!
+@Title SGX Common Bridge Module (kernel side)
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Receives calls from the user portion of services and
+ despatches them to functions in the kernel portion.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+
+
+#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 "sgx_options.h"
+
+#if defined(SUPPORT_MSVDX)
+ #include "msvdx_bridge.h"
+#endif
+
+#include "bridged_pvr_bridge.h"
+#include "bridged_sgx_bridge.h"
+#include "sgxutils.h"
+#include "buffer_manager.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 can be zero if an error occurred before SGXGetClientInfo is called
+ */
+ if (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;
+#if defined (SUPPORT_SID_INTERFACE)
+ SGX_INTERNAL_DEVINFO_KM sSGXInternalDevInfo;
+#endif
+
+ 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sSGXInternalDevInfo);
+#else
+ &psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo);
+#endif
+
+ /*
+ * Handle is not allocated in batch mode, as there is no resource
+ * allocation to undo if the handle allocation fails.
+ */
+ psSGXGetInternalDevInfoOUT->eError =
+ PVRSRVAllocHandle(psPerProc->psHandleBase,
+ &psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo.hHostCtlKernelMemInfoHandle,
+#if defined (SUPPORT_SID_INTERFACE)
+ sSGXInternalDevInfo.hHostCtlKernelMemInfoHandle,
+#else
+ psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo.hHostCtlKernelMemInfoHandle,
+#endif
+ 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;
+ IMG_INT ret = 0;
+ IMG_UINT32 ui32NumDstSyncs;
+#if defined (SUPPORT_SID_INTERFACE)
+ SGX_CCB_KICK_KM sCCBKickKM = {{0}};
+ IMG_HANDLE ahSyncInfoHandles[16];
+#else
+ IMG_HANDLE *phKernelSyncInfoHandles = IMG_NULL;
+#endif
+
+ 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.hCCBKernelMemInfo,
+#else
+ &psDoKickIN->sCCBKick.hCCBKernelMemInfo,
+#endif
+ psDoKickIN->sCCBKick.hCCBKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psDoKickIN->sCCBKick.ui32NumDstSyncObjects > 16)
+ {
+ return 0;
+ }
+
+ if(psDoKickIN->sCCBKick.hTA3DSyncInfo != 0)
+#else
+ if(psDoKickIN->sCCBKick.hTA3DSyncInfo != IMG_NULL)
+#endif
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.hTA3DSyncInfo,
+#else
+ &psDoKickIN->sCCBKick.hTA3DSyncInfo,
+#endif
+ psDoKickIN->sCCBKick.hTA3DSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if(psDoKickIN->sCCBKick.hTASyncInfo != 0)
+#else
+ if(psDoKickIN->sCCBKick.hTASyncInfo != IMG_NULL)
+#endif
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.hTASyncInfo,
+#else
+ &psDoKickIN->sCCBKick.hTASyncInfo,
+#endif
+ psDoKickIN->sCCBKick.hTASyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+#if defined(FIX_HW_BRN_31620)
+ /* We need to lookup the mem context and pass it through */
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &psDoKickIN->sCCBKick.hDevMemContext,
+ psDoKickIN->sCCBKick.hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+#endif
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if(psDoKickIN->sCCBKick.h3DSyncInfo != 0)
+#else
+ if(psDoKickIN->sCCBKick.h3DSyncInfo != IMG_NULL)
+#endif
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.h3DSyncInfo,
+#else
+ &psDoKickIN->sCCBKick.h3DSyncInfo,
+#endif
+ psDoKickIN->sCCBKick.h3DSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+ /* SRC and DST sync details */
+ if (psDoKickIN->sCCBKick.ui32NumTASrcSyncs > SGX_MAX_TA_SRC_SYNCS)
+ {
+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ sCCBKickKM.ui32NumTASrcSyncs = psDoKickIN->sCCBKick.ui32NumTASrcSyncs;
+#endif
+ for(i=0; i<psDoKickIN->sCCBKick.ui32NumTASrcSyncs; i++)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.ahTASrcKernelSyncInfo[i],
+#else
+ &psDoKickIN->sCCBKick.ahTASrcKernelSyncInfo[i],
+#endif
+ psDoKickIN->sCCBKick.ahTASrcKernelSyncInfo[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+ if (psDoKickIN->sCCBKick.ui32NumTADstSyncs > SGX_MAX_TA_DST_SYNCS)
+ {
+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ sCCBKickKM.ui32NumTADstSyncs = psDoKickIN->sCCBKick.ui32NumTADstSyncs;
+#endif
+ for(i=0; i<psDoKickIN->sCCBKick.ui32NumTADstSyncs; i++)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.ahTADstKernelSyncInfo[i],
+#else
+ &psDoKickIN->sCCBKick.ahTADstKernelSyncInfo[i],
+#endif
+ psDoKickIN->sCCBKick.ahTADstKernelSyncInfo[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+ if (psDoKickIN->sCCBKick.ui32Num3DSrcSyncs > SGX_MAX_3D_SRC_SYNCS)
+ {
+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ sCCBKickKM.ui32Num3DSrcSyncs = psDoKickIN->sCCBKick.ui32Num3DSrcSyncs;
+#endif
+ for(i=0; i<psDoKickIN->sCCBKick.ui32Num3DSrcSyncs; i++)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.ah3DSrcKernelSyncInfo[i],
+#else
+ &psDoKickIN->sCCBKick.ah3DSrcKernelSyncInfo[i],
+#endif
+ psDoKickIN->sCCBKick.ah3DSrcKernelSyncInfo[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+#else/* #if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) */
+ /* texture dependency details */
+ if (psDoKickIN->sCCBKick.ui32NumSrcSyncs > SGX_MAX_SRC_SYNCS_TA)
+ {
+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ sCCBKickKM.ui32NumSrcSyncs = psDoKickIN->sCCBKick.ui32NumSrcSyncs;
+#endif
+ for(i=0; i<psDoKickIN->sCCBKick.ui32NumSrcSyncs; i++)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.ahSrcKernelSyncInfo[i],
+#else
+ &psDoKickIN->sCCBKick.ahSrcKernelSyncInfo[i],
+#endif
+ psDoKickIN->sCCBKick.ahSrcKernelSyncInfo[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+#endif/* #if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) */
+
+ 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.asTAStatusUpdate[i].hKernelMemInfo,
+#else
+ &psDoKickIN->sCCBKick.asTAStatusUpdate[i].hKernelMemInfo,
+#endif
+ psDoKickIN->sCCBKick.asTAStatusUpdate[i].hKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+#if defined (SUPPORT_SID_INTERFACE)
+ sCCBKickKM.asTAStatusUpdate[i].sCtlStatus = psDoKickIN->sCCBKick.asTAStatusUpdate[i].sCtlStatus;
+#endif
+
+#else
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.ahTAStatusSyncInfo[i],
+#else
+ &psDoKickIN->sCCBKick.ahTAStatusSyncInfo[i],
+#endif
+ 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.as3DStatusUpdate[i].hKernelMemInfo,
+#else
+ &psDoKickIN->sCCBKick.as3DStatusUpdate[i].hKernelMemInfo,
+#endif
+ psDoKickIN->sCCBKick.as3DStatusUpdate[i].hKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+#if defined (SUPPORT_SID_INTERFACE)
+ sCCBKickKM.as3DStatusUpdate[i].sCtlStatus = psDoKickIN->sCCBKick.as3DStatusUpdate[i].sCtlStatus;
+#endif
+#else
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.ah3DStatusSyncInfo[i],
+#else
+ &psDoKickIN->sCCBKick.ah3DStatusSyncInfo[i],
+#endif
+ psDoKickIN->sCCBKick.ah3DStatusSyncInfo[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+#endif
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+ ui32NumDstSyncs = psDoKickIN->sCCBKick.ui32NumDstSyncObjects;
+
+ if(ui32NumDstSyncs > 0)
+ {
+ if(!OSAccessOK(PVR_VERIFY_READ,
+ psDoKickIN->sCCBKick.pahDstSyncHandles,
+ ui32NumDstSyncs * sizeof(IMG_HANDLE)))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: SGXDoKickBW:"
+ " Invalid pasDstSyncHandles pointer", __FUNCTION__));
+ return -EFAULT;
+ }
+
+ psRetOUT->eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32NumDstSyncs * sizeof(IMG_HANDLE),
+ (IMG_VOID **)&phKernelSyncInfoHandles,
+ 0,
+ "Array of Synchronization Info Handles");
+ if (psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ sCCBKickKM.pahDstSyncHandles = phKernelSyncInfoHandles;
+#else
+ if(CopyFromUserWrapper(psPerProc,
+ ui32BridgeID,
+ phKernelSyncInfoHandles,
+ psDoKickIN->sCCBKick.pahDstSyncHandles,
+ ui32NumDstSyncs * sizeof(IMG_HANDLE)) != PVRSRV_OK)
+ {
+ ret = -EFAULT;
+ goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT;
+ }
+
+ /* Set sCCBKick.pahDstSyncHandles to point to the local memory */
+ psDoKickIN->sCCBKick.pahDstSyncHandles = phKernelSyncInfoHandles;
+#endif
+
+ for( i = 0; i < ui32NumDstSyncs; i++)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.pahDstSyncHandles[i],
+#else
+ &psDoKickIN->sCCBKick.pahDstSyncHandles[i],
+#endif
+ psDoKickIN->sCCBKick.pahDstSyncHandles[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT;
+ }
+
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM.hKernelHWSyncListMemInfo,
+#else
+ &psDoKickIN->sCCBKick.hKernelHWSyncListMemInfo,
+#endif
+ psDoKickIN->sCCBKick.hKernelHWSyncListMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT;
+ }
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ OSMemCopy(&sCCBKickKM.sCommand, &psDoKickIN->sCCBKick.sCommand, sizeof(sCCBKickKM.sCommand));
+
+ sCCBKickKM.ui32NumDstSyncObjects = psDoKickIN->sCCBKick.ui32NumDstSyncObjects;
+ sCCBKickKM.ui32NumTAStatusVals = psDoKickIN->sCCBKick.ui32NumTAStatusVals;
+ sCCBKickKM.ui32Num3DStatusVals = psDoKickIN->sCCBKick.ui32Num3DStatusVals;
+ sCCBKickKM.bFirstKickOrResume = psDoKickIN->sCCBKick.bFirstKickOrResume;
+ sCCBKickKM.ui32CCBOffset = psDoKickIN->sCCBKick.ui32CCBOffset;
+ sCCBKickKM.bTADependency = psDoKickIN->sCCBKick.bTADependency;
+
+#if defined(NO_HARDWARE) || defined(PDUMP)
+ sCCBKickKM.bTerminateOrAbort = psDoKickIN->sCCBKick.bTerminateOrAbort;
+#endif
+#if defined(PDUMP)
+ sCCBKickKM.ui32CCBDumpWOff = psDoKickIN->sCCBKick.ui32CCBDumpWOff;
+#endif
+
+#if defined(NO_HARDWARE)
+ sCCBKickKM.ui32WriteOpsPendingVal = psDoKickIN->sCCBKick.ui32WriteOpsPendingVal;
+#endif
+#endif /* #if defined (SUPPORT_SID_INTERFACE) */
+ psRetOUT->eError =
+ SGXDoKickKM(hDevCookieInt,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sCCBKickKM);
+#else
+ &psDoKickIN->sCCBKick);
+#endif
+
+PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT:
+
+ if(phKernelSyncInfoHandles)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32NumDstSyncs * sizeof(IMG_HANDLE),
+ (IMG_VOID *)phKernelSyncInfoHandles,
+ 0);
+ /*not nulling pointer, out of scope*/
+ }
+ return ret;
+}
+
+
+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;
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_TRANSFER_SGX_KICK_KM sKickKM = {0};
+#endif
+ IMG_UINT32 i;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SUBMITTRANSFER);
+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+
+ psKick = &psSubmitTransferIN->sKick;
+
+#if defined(FIX_HW_BRN_31620)
+ /* We need to lookup the mem context and pass it through */
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &psKick->hDevMemContext,
+ psKick->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+#endif
+
+ 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sKickKM.hCCBMemInfo,
+#else
+ &psKick->hCCBMemInfo,
+#endif
+ psKick->hCCBMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ if (psKick->hTASyncInfo != IMG_NULL)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sKickKM.hTASyncInfo,
+#else
+ &psKick->hTASyncInfo,
+#endif
+ psKick->hTASyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+ if (psKick->h3DSyncInfo != IMG_NULL)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sKickKM.h3DSyncInfo,
+#else
+ &psKick->h3DSyncInfo,
+#endif
+ 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sKickKM.ahSrcSyncInfo[i],
+#else
+ &psKick->ahSrcSyncInfo[i],
+#endif
+ 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sKickKM.ahDstSyncInfo[i],
+#else
+ &psKick->ahDstSyncInfo[i],
+#endif
+ psKick->ahDstSyncInfo[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ sKickKM.sHWTransferContextDevVAddr = psKick->sHWTransferContextDevVAddr;
+ sKickKM.ui32SharedCmdCCBOffset = psKick->ui32SharedCmdCCBOffset;
+ sKickKM.ui32NumSrcSync = psKick->ui32NumSrcSync;
+ sKickKM.ui32NumDstSync = psKick->ui32NumDstSync;
+ sKickKM.ui32Flags = psKick->ui32Flags;
+ sKickKM.ui32PDumpFlags = psKick->ui32PDumpFlags;
+#if defined(PDUMP)
+ sKickKM.ui32CCBDumpWOff = psKick->ui32CCBDumpWOff;
+#endif
+
+ psRetOUT->eError = SGXSubmitTransferKM(hDevCookieInt, &sKickKM);
+#else
+ psRetOUT->eError = SGXSubmitTransferKM(hDevCookieInt, psKick);
+#endif
+
+ return 0;
+}
+
+static IMG_INT
+SGXSetTransferContextPriorityBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGX_SET_TRANSFER_CONTEXT_PRIORITY *psSGXSetTransferContextPriorityIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_HANDLE hTransferContextInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SET_TRANSFER_CONTEXT_PRIORITY);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psSGXSetTransferContextPriorityIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hTransferContextInt,
+ psSGXSetTransferContextPriorityIN->hHWTransferContext,
+ PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError = SGXSetTransferContextPriorityKM(
+ hDevCookieInt,
+ hTransferContextInt,
+ psSGXSetTransferContextPriorityIN->ui32Priority,
+ psSGXSetTransferContextPriorityIN->ui32OffsetOfPriorityField);
+
+ return 0;
+}
+
+static IMG_INT
+SGXSetRenderContextPriorityBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGX_SET_RENDER_CONTEXT_PRIORITY *psSGXSetRenderContextPriorityIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_HANDLE hRenderContextInt;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SET_RENDER_CONTEXT_PRIORITY);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psSGXSetRenderContextPriorityIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hRenderContextInt,
+ psSGXSetRenderContextPriorityIN->hHWRenderContext,
+ PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError = SGXSetRenderContextPriorityKM(
+ hDevCookieInt,
+ hRenderContextInt,
+ psSGXSetRenderContextPriorityIN->ui32Priority,
+ psSGXSetRenderContextPriorityIN->ui32OffsetOfPriorityField);
+
+ 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;
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_2D_SGX_KICK_KM sKickKM;
+#endif
+ IMG_UINT32 i;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SUBMIT2D);
+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
+
+ psKick = &psSubmit2DIN->sKick;
+
+#if defined(FIX_HW_BRN_31620)
+ /* We need to lookup the mem context and pass it through */
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &psKick->hDevMemContext,
+ psKick->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+#endif
+
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psSubmit2DIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sKickKM.hCCBMemInfo,
+#else
+ &psKick->hCCBMemInfo,
+#endif
+ psKick->hCCBMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if (psKick->hTASyncInfo != 0)
+#else
+ if (psKick->hTASyncInfo != IMG_NULL)
+#endif
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sKickKM.hTASyncInfo,
+#else
+ &psKick->hTASyncInfo,
+#endif
+ psKick->hTASyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+#if defined (SUPPORT_SID_INTERFACE)
+ else
+ {
+ sKickKM.hTASyncInfo = IMG_NULL;
+ }
+#endif
+
+ if (psKick->h3DSyncInfo != IMG_NULL)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sKickKM.h3DSyncInfo,
+#else
+ &psKick->h3DSyncInfo,
+#endif
+ psKick->h3DSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+#if defined (SUPPORT_SID_INTERFACE)
+ else
+ {
+ sKickKM.h3DSyncInfo = IMG_NULL;
+ }
+#endif
+
+ if (psKick->ui32NumSrcSync > SGX_MAX_2D_SRC_SYNC_OPS)
+ {
+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+ return 0;
+ }
+#if defined (SUPPORT_SID_INTERFACE)
+ for (i = 0; i < SGX_MAX_2D_SRC_SYNC_OPS; i++)
+ {
+ if (i < psKick->ui32NumSrcSync)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &sKickKM.ahSrcSyncInfo[i],
+ psKick->ahSrcSyncInfo[i],
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ sKickKM.ahSrcSyncInfo[i] = IMG_NULL;
+ }
+ }
+#else
+ 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;
+ }
+ }
+#endif
+
+ if (psKick->hDstSyncInfo != IMG_NULL)
+ {
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &sKickKM.hDstSyncInfo,
+#else
+ &psKick->hDstSyncInfo,
+#endif
+ psKick->hDstSyncInfo,
+ PVRSRV_HANDLE_TYPE_SYNC_INFO);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+#if defined (SUPPORT_SID_INTERFACE)
+ else
+ {
+ sKickKM.hDstSyncInfo = IMG_NULL;
+ }
+
+ /* copy common members across */
+ sKickKM.ui32SharedCmdCCBOffset = psKick->ui32SharedCmdCCBOffset;
+ sKickKM.ui32NumSrcSync = psKick->ui32NumSrcSync;
+ sKickKM.ui32PDumpFlags = psKick->ui32PDumpFlags;
+ sKickKM.sHW2DContextDevVAddr = psKick->sHW2DContextDevVAddr;
+#if defined(PDUMP)
+ sKickKM.ui32CCBDumpWOff = psKick->ui32CCBDumpWOff;
+#endif
+#endif
+
+ psRetOUT->eError =
+#if defined (SUPPORT_SID_INTERFACE)
+ SGXSubmit2DKM(hDevCookieInt, &sKickKM);
+#else
+ SGXSubmit2DKM(hDevCookieInt, psKick);
+#endif
+
+ return 0;
+}
+#endif /* #if defined(SGX_FEATURE_2D_HARDWARE) */
+#endif /* #if defined(TRANSFER_QUEUE) */
+
+
+static IMG_INT
+SGXGetMiscInfoBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGXGETMISCINFO *psSGXGetMiscInfoIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+ IMG_HANDLE hDevMemContextInt = 0;
+ 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;
+ }
+
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+ /* Lookup handle for dev mem context */
+ if (psSGXGetMiscInfoIN->psMiscInfo->eRequest == SGX_MISC_INFO_REQUEST_MEMREAD)
+ {
+ psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ psSGXGetMiscInfoIN->psMiscInfo->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+#endif
+ /* device node is required for scheduling a CCB command */
+ psDeviceNode = hDevCookieInt;
+ PVR_ASSERT(psDeviceNode != IMG_NULL);
+ if (psDeviceNode == IMG_NULL)
+ {
+ return -EFAULT;
+ }
+
+ psDevInfo = psDeviceNode->pvDevice;
+
+ /* Copy psMiscInfo to kernel space */
+ psRetOUT->eError = CopyFromUserWrapper(psPerProc,
+ ui32BridgeID,
+ &sMiscInfo,
+ psSGXGetMiscInfoIN->psMiscInfo,
+ sizeof(SGX_MISC_INFO));
+ if (psRetOUT->eError != PVRSRV_OK)
+ {
+ return -EFAULT;
+ }
+
+ {
+ psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo, &sMiscInfo, psDeviceNode, hDevMemContextInt);
+
+ if (psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+ }
+
+ /* Copy back misc info to user address space */
+ psRetOUT->eError = CopyToUserWrapper(psPerProc,
+ ui32BridgeID,
+ psSGXGetMiscInfoIN->psMiscInfo,
+ &sMiscInfo,
+ sizeof(SGX_MISC_INFO));
+ if (psRetOUT->eError != PVRSRV_OK)
+ {
+ return -EFAULT;
+ }
+ 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,
+ "Array of Hardware Performance Circular Buffer Data"));
+
+ 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);
+ /*not nulling pointer, out of scope*/
+
+ return 0;
+}
+
+
+static IMG_INT
+SGXDevInitPart2BW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_SGXDEVINITPART2 *psSGXDevInitPart2IN,
+ PVRSRV_BRIDGE_OUT_SGXDEVINITPART2 *psSGXDevInitPart2OUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_HANDLE hDevCookieInt;
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_ERROR eError = PVRSRV_OK;
+#else
+ PVRSRV_ERROR eError;
+#endif
+ IMG_BOOL bDissociateFailed = IMG_FALSE;
+ IMG_BOOL bLookupFailed = IMG_FALSE;
+ IMG_BOOL bReleaseFailed = IMG_FALSE;
+ IMG_HANDLE hDummy;
+ IMG_UINT32 i;
+#if defined (SUPPORT_SID_INTERFACE)
+ SGX_BRIDGE_INIT_INFO_KM asInitInfoKM = {0};
+#endif
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_DEVINITPART2);
+
+ /* Report the kernel-side build options to UM */
+ psSGXDevInitPart2OUT->ui32KMBuildOptions = SGX_BUILD_OPTIONS;
+
+ if(!psPerProc->bInitProcess)
+ {
+ psSGXDevInitPart2OUT->eError = PVRSRV_ERROR_PROCESS_NOT_INITIALISED;
+ return 0;
+ }
+
+ psSGXDevInitPart2OUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevCookieInt,
+ psSGXDevInitPart2IN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psSGXDevInitPart2OUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ /* Check all the meminfo handles */
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXPTLAWriteBackMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+#endif
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+
+#if defined(SGX_SUPPORT_HWPROFILING)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+#endif
+
+#if defined(SUPPORT_SGX_HWPERF)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXDevInitPart2BW: Failed to look up HWPerf meminfo (possibly due to SUPPORT_SGX_HWPERF option mismatch)"));
+ bLookupFailed = IMG_TRUE;
+ }
+#endif
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelTASigBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernel3DSigBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+
+#if defined(FIX_HW_BRN_29702)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelCFIMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+#endif
+
+#if defined(FIX_HW_BRN_29823)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelDummyTermStreamMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+#endif
+
+
+#if defined(FIX_HW_BRN_31542) || defined(FIX_HW_BRN_36513)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAVDMStreamMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAIndexStreamMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPDSMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAUSEMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAParamMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPMPTMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWATPCMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPSGRgnHdrMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+#endif
+
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31559)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelVDMSnapShotBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelVDMCtrlStreamBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \
+ defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelVDMStateUpdateBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+#endif
+
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+#endif
+
+ for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
+#else
+ IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
+#endif
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if (hHandle == 0)
+#else
+ if (hHandle == IMG_NULL)
+#endif
+ {
+ continue;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDummy,
+ hHandle,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+ }
+
+ if (bLookupFailed)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXDevInitPart2BW: A handle lookup failed"));
+ psSGXDevInitPart2OUT->eError = PVRSRV_ERROR_INIT2_PHASE_FAILED;
+ return 0;
+ }
+
+ /* Lookup and release the device memory handles */
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelCCBMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelCCBCtlMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelCCBEventKickerMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+
+
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelSGXHostCtlMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelSGXTA3DCtlMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelSGXPTLAWriteBackMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelSGXPTLAWriteBackMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXPTLAWriteBackMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+#endif
+
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelSGXMiscMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+
+
+#if defined(SGX_SUPPORT_HWPROFILING)
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelHWProfilingMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+#endif
+
+#if defined(SUPPORT_SGX_HWPERF)
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelHWPerfCBMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+#endif
+
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelTASigBufferMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelTASigBufferMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelTASigBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernel3DSigBufferMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernel3DSigBufferMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernel3DSigBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+
+#if defined(FIX_HW_BRN_29702)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelCFIMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelCFIMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelCFIMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bLookupFailed = IMG_TRUE;
+ }
+#endif
+
+#if defined(FIX_HW_BRN_29823)
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelDummyTermStreamMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelDummyTermStreamMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelDummyTermStreamMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+#endif
+
+
+#if defined(FIX_HW_BRN_31542) || defined(FIX_HW_BRN_36513)
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelClearClipWAVDMStreamMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAVDMStreamMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAVDMStreamMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelClearClipWAIndexStreamMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAIndexStreamMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAIndexStreamMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelClearClipWAPDSMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPDSMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPDSMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelClearClipWAUSEMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAUSEMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAUSEMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelClearClipWAParamMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAParamMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAParamMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelClearClipWAPMPTMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPMPTMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPMPTMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelClearClipWATPCMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWATPCMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWATPCMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelClearClipWAPSGRgnHdrMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPSGRgnHdrMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPSGRgnHdrMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31559)
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+ &psSGXDevInitPart2IN->sInitInfo.hKernelVDMSnapShotBufferMemInfo,
+ psSGXDevInitPart2IN->sInitInfo.hKernelVDMSnapShotBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+ &psSGXDevInitPart2IN->sInitInfo.hKernelVDMCtrlStreamBufferMemInfo,
+ psSGXDevInitPart2IN->sInitInfo.hKernelVDMCtrlStreamBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \
+ defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX)
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+ &psSGXDevInitPart2IN->sInitInfo.hKernelVDMStateUpdateBufferMemInfo,
+ psSGXDevInitPart2IN->sInitInfo.hKernelVDMStateUpdateBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+#endif
+
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asInitInfoKM.hKernelEDMStatusBufferMemInfo,
+#else
+ &psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo,
+#endif
+ psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+#endif
+
+ for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
+ IMG_HANDLE *phHandleKM = &asInitInfoKM.asInitMemHandles[i];
+
+ if (hHandle == 0)
+#else
+ IMG_HANDLE *phHandle = &psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
+
+ if (*phHandle == IMG_NULL)
+#endif
+ continue;
+
+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
+#if defined (SUPPORT_SID_INTERFACE)
+ phHandleKM,
+ hHandle,
+#else
+ phHandle,
+ *phHandle,
+#endif
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError != PVRSRV_OK)
+ {
+ bReleaseFailed = IMG_TRUE;
+ }
+ }
+
+ if (bReleaseFailed)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXDevInitPart2BW: A handle release failed"));
+ psSGXDevInitPart2OUT->eError = PVRSRV_ERROR_INIT2_PHASE_FAILED;
+ /*
+ * Given that we checked the handles before release, a release
+ * failure is unexpected.
+ */
+ PVR_DBG_BREAK;
+ return 0;
+ }
+
+ /* Dissociate device memory from caller */
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelCCBMemInfo);
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelCCBCtlMemInfo);
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelCCBEventKickerMemInfo);
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXHostCtlMemInfo);
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXTA3DCtlMemInfo);
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXPTLAWriteBackMemInfo);
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXPTLAWriteBackMemInfo);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#endif
+
+ /* Dissociate SGX MiscInfo buffer from user space */
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXMiscMemInfo);
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+
+
+#if defined(SGX_SUPPORT_HWPROFILING)
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelHWProfilingMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#endif
+
+#if defined(SUPPORT_SGX_HWPERF)
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelHWPerfCBMemInfo);
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#endif
+
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelTASigBufferMemInfo);
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelTASigBufferMemInfo);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernel3DSigBufferMemInfo);
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernel3DSigBufferMemInfo);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+
+#if defined(FIX_HW_BRN_29702)
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelCFIMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCFIMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#endif
+
+#if defined(FIX_HW_BRN_29823)
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelDummyTermStreamMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelDummyTermStreamMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#endif
+
+#if defined(FIX_HW_BRN_31542) || defined(FIX_HW_BRN_36513)
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAVDMStreamMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAVDMStreamMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAIndexStreamMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAIndexStreamMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAPDSMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPDSMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAUSEMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAUSEMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAParamMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAParamMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAPMPTMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPMPTMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWATPCMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWATPCMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelClearClipWAPSGRgnHdrMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPSGRgnHdrMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#endif
+
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31559)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelVDMSnapShotBufferMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelVDMCtrlStreamBufferMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \
+ defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelVDMStateUpdateBufferMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+#if defined (SUPPORT_SID_INTERFACE)
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelEDMStatusBufferMemInfo);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+#else
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo);
+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
+#endif
+#endif
+
+ for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_HANDLE hHandle = asInitInfoKM.asInitMemHandles[i];
+#else
+ IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
+#endif
+
+ if (hHandle == IMG_NULL)
+ continue;
+
+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, hHandle);
+ if (eError != PVRSRV_OK)
+ {
+ bDissociateFailed = IMG_TRUE;
+ }
+ }
+
+ /* If any dissociations failed, free all the device memory passed in */
+ if(bDissociateFailed)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelCCBMemInfo);
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelCCBCtlMemInfo);
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXHostCtlMemInfo);
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXTA3DCtlMemInfo);
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXPTLAWriteBackMemInfo);
+#endif
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, asInitInfoKM.hKernelSGXMiscMemInfo);
+#else
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo);
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo);
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo);
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo);
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXPTLAWriteBackMemInfo);
+#endif
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo);
+#endif
+
+ for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_HANDLE hHandle = asInitInfoKM.asInitMemHandles[i];
+
+ if (hHandle == 0)
+#else
+ IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
+
+ if (hHandle == IMG_NULL)
+#endif
+ continue;
+
+ PVRSRVFreeDeviceMemKM(hDevCookieInt, (PVRSRV_KERNEL_MEM_INFO *)hHandle);
+
+ }
+
+ PVR_DPF((PVR_DBG_ERROR, "SGXDevInitPart2BW: A dissociate failed"));
+
+ psSGXDevInitPart2OUT->eError = PVRSRV_ERROR_INIT2_PHASE_FAILED;
+
+ /* A dissociation failure is unexpected */
+ PVR_DBG_BREAK;
+ return 0;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ asInitInfoKM.sScripts = psSGXDevInitPart2IN->sInitInfo.sScripts;
+ asInitInfoKM.ui32ClientBuildOptions = psSGXDevInitPart2IN->sInitInfo.ui32ClientBuildOptions;
+ asInitInfoKM.sSGXStructSizes = psSGXDevInitPart2IN->sInitInfo.sSGXStructSizes;
+ asInitInfoKM.ui32CacheControl = psSGXDevInitPart2IN->sInitInfo.ui32CacheControl;
+ asInitInfoKM.ui32EDMTaskReg0 = psSGXDevInitPart2IN->sInitInfo.ui32EDMTaskReg0;
+ asInitInfoKM.ui32EDMTaskReg1 = psSGXDevInitPart2IN->sInitInfo.ui32EDMTaskReg1;
+ asInitInfoKM.ui32ClkGateStatusReg = psSGXDevInitPart2IN->sInitInfo.ui32ClkGateStatusReg;
+ asInitInfoKM.ui32ClkGateStatusMask = psSGXDevInitPart2IN->sInitInfo.ui32ClkGateStatusMask;
+
+ OSMemCopy(&asInitInfoKM.asInitDevData ,
+ &psSGXDevInitPart2IN->sInitInfo.asInitDevData,
+ sizeof(asInitInfoKM.asInitDevData));
+ OSMemCopy(&asInitInfoKM.aui32HostKickAddr,
+ &psSGXDevInitPart2IN->sInitInfo.aui32HostKickAddr,
+ sizeof(asInitInfoKM.aui32HostKickAddr));
+
+ psSGXDevInitPart2OUT->eError =
+ DevInitSGXPart2KM(psPerProc,
+ hDevCookieInt,
+ &asInitInfoKM);
+#else
+ psSGXDevInitPart2OUT->eError =
+ DevInitSGXPart2KM(psPerProc,
+ hDevCookieInt,
+ &psSGXDevInitPart2IN->sInitInfo);
+#endif
+
+ 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;
+// PVRSRV_SGXDEV_INFO *psDevInfo;
+ 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->pHWRenderContextCpuVAddr,
+ psSGXRegHWRenderContextIN->ui32HWRenderContextSize,
+ psSGXRegHWRenderContextIN->ui32OffsetToPDDevPAddr,
+ psSGXRegHWRenderContextIN->hDevMemContext,
+ &psSGXRegHWRenderContextOUT->sHWRenderContextDevVAddr,
+ psPerProc);
+
+ if (hHWRenderContextInt == IMG_NULL)
+ {
+ psSGXRegHWRenderContextOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT;
+ 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,
+ psSGXUnregHWRenderContextIN->bForceCleanup);
+ 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->pHWTransferContextCpuVAddr,
+ psSGXRegHWTransferContextIN->ui32HWTransferContextSize,
+ psSGXRegHWTransferContextIN->ui32OffsetToPDDevPAddr,
+ psSGXRegHWTransferContextIN->hDevMemContext,
+ &psSGXRegHWTransferContextOUT->sHWTransferContextDevVAddr,
+ psPerProc);
+
+ if (hHWTransferContextInt == IMG_NULL)
+ {
+ psSGXRegHWTransferContextOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT;
+ 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)
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_HANDLE hHWTransferContextInt = 0;
+#else
+ IMG_HANDLE hHWTransferContextInt;
+#endif
+
+ 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,
+ psSGXUnregHWTransferContextIN->bForceCleanup);
+ 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->pHW2DContextCpuVAddr,
+ psSGXRegHW2DContextIN->ui32HW2DContextSize,
+ psSGXRegHW2DContextIN->ui32OffsetToPDDevPAddr,
+ psSGXRegHW2DContextIN->hDevMemContext,
+ &psSGXRegHW2DContextOUT->sHW2DContextDevVAddr,
+ psPerProc);
+
+ if (hHW2DContextInt == IMG_NULL)
+ {
+ psSGXRegHW2DContextOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT;
+ 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,
+ psSGXUnregHW2DContextIN->bForceCleanup);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psSGXUnregHW2DContextIN->hHW2DContext,
+ PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT);
+
+ return 0;
+}
+#endif /* #if defined(SGX_FEATURE_2D_HARDWARE) */
+
+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_SGXDEV_INFO *psDevInfo;
+
+ 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;
+ }
+
+// psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice;
+
+ psRetOUT->eError = SGXFlushHWRenderTargetKM(hDevCookieInt, psSGXFlushHWRenderTargetIN->sHWRTDataSetDevVAddr, IMG_FALSE);
+
+ 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 *psHWBlockKernelMemInfo;
+ 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,
+ &psHWBlockKernelMemInfo,
+ &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;
+ /* It's not an error if we don't find a buffer,
+ * we just return NULL */
+ goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT;
+ }
+
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psSGXFindSharedPBDescOUT->hSharedPBDesc,
+ hSharedPBDesc,
+ PVRSRV_HANDLE_TYPE_SHARED_PB_DESC,
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE);
+
+ /*
+ * We allocate handles of type PVRSRV_HANDLE_TYPE_MEM_INFO_REF here,
+ * as the process doesn't own the underlying memory, and so should
+ * only be allowed a restricted set of operations on it, such as
+ * mapping it into its address space.
+ */
+ 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);
+
+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+ &psSGXFindSharedPBDescOUT->hHWBlockKernelMemInfoHandle,
+ psHWBlockKernelMemInfo,
+ 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;
+ PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo;
+ IMG_UINT32 ui32KernelMemInfoHandlesCount =
+ psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount;
+ IMG_INT ret = 0;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID *phKernelMemInfoHandles = 0;
+#else
+ IMG_HANDLE *phKernelMemInfoHandles = IMG_NULL;
+#endif
+ 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;
+ }
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID **)&psHWBlockKernelMemInfo,
+ psSGXAddSharedPBDescIN->hHWBlockKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_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,
+ "Array of Handles");
+ 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,
+ "Array of pointers to Kernel Memory Info");
+ 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;
+ }
+ }
+
+ /*
+ * Release all the handles we've just looked up, as none
+ * of the associated resources will be valid for access via
+ * those handles once we return from SGXAddSharedPBDesc.
+ */
+ /* PRQA S 3198 2 */ /* override redundant warning as PVR_ASSERT is ignored by QAC */
+ eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psSGXAddSharedPBDescIN->hSharedPBDescKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
+ PVR_ASSERT(eError == PVRSRV_OK);
+
+ /* PRQA S 3198 2 */ /* override redundant warning as PVR_ASSERT is ignored by QAC */
+ eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psSGXAddSharedPBDescIN->hHWPBDescKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ PVR_ASSERT(eError == PVRSRV_OK);
+
+ /* PRQA S 3198 2 */ /* override redundant warning as PVR_ASSERT is ignored by QAC */
+ eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psSGXAddSharedPBDescIN->hBlockKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
+ PVR_ASSERT(eError == PVRSRV_OK);
+
+ /* PRQA S 3198 2 */ /* override redundant warning as PVR_ASSERT is ignored by QAC */
+ eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ psSGXAddSharedPBDescIN->hHWBlockKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ PVR_ASSERT(eError == PVRSRV_OK);
+
+ for(i=0; i<ui32KernelMemInfoHandlesCount; i++)
+ {
+ /* PRQA S 3198 2 */ /* override redundant warning as PVR_ASSERT is ignored by QAC */
+ eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+ phKernelMemInfoHandles[i],
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ PVR_ASSERT(eError == PVRSRV_OK);
+ }
+
+ eError = SGXAddSharedPBDescKM(psPerProc, hDevCookieInt,
+ psSharedPBDescKernelMemInfo,
+ psHWPBDescKernelMemInfo,
+ psBlockKernelMemInfo,
+ psHWBlockKernelMemInfo,
+ psSGXAddSharedPBDescIN->ui32TotalPBSize,
+ &hSharedPBDesc,
+ ppsKernelMemInfos,
+ ui32KernelMemInfoHandlesCount,
+ psSGXAddSharedPBDescIN->sHWPBDescDevVAddr);
+
+
+ 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;
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_HEAP_INFO_KM asHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
+#endif
+ 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_PROCESS_NOT_INITIALISED;
+ 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,
+#if defined (SUPPORT_SID_INTERFACE)
+ &asHeapInfo[0],
+ &psSGXInfoForSrvinitOUT->sInitInfo.sPDDevPAddr);
+#else
+ &psSGXInfoForSrvinitOUT->sInitInfo);
+#endif
+
+ 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 defined (SUPPORT_SID_INTERFACE)
+ if ((asHeapInfo[i].ui32HeapID != (IMG_UINT32)SGX_UNDEFINED_HEAP_ID) &&
+ (asHeapInfo[i].hDevMemHeap != IMG_NULL))
+ {
+ /* Allocate heap handle */
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &psHeapInfo->hDevMemHeap,
+ asHeapInfo[i].hDevMemHeap,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+ }
+ else
+ {
+ psHeapInfo->hDevMemHeap = 0;
+ }
+
+ psHeapInfo->ui32HeapID = asHeapInfo[i].ui32HeapID;
+ psHeapInfo->sDevVAddrBase = asHeapInfo[i].sDevVAddrBase;
+ psHeapInfo->ui32HeapByteSize = asHeapInfo[i].ui32HeapByteSize;
+ psHeapInfo->ui32Attribs = asHeapInfo[i].ui32Attribs;
+ psHeapInfo->ui32XTileStride = asHeapInfo[i].ui32XTileStride;
+#else
+ if (psHeapInfo->ui32HeapID != (IMG_UINT32)SGX_UNDEFINED_HEAP_ID)
+ {
+ IMG_HANDLE hDevMemHeapExt;
+
+ if (psHeapInfo->hDevMemHeap != IMG_NULL)
+ {
+ /* Allocate heap handle */
+ PVRSRVAllocHandleNR(psPerProc->psHandleBase,
+ &hDevMemHeapExt,
+ psHeapInfo->hDevMemHeap,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
+ psHeapInfo->hDevMemHeap = hDevMemHeapExt;
+ }
+ }
+#endif
+ }
+
+ COMMIT_HANDLE_BATCH_OR_ERROR(psSGXInfoForSrvinitOUT->eError, psPerProc);
+
+ return 0;
+}
+
+#if defined(PDUMP)
+// PRQA S 5120++
+/*****************************************************************************
+ FUNCTION : DumpBufferArray
+ PURPOSE : PDUMP information in stored buffer array
+ PARAMETERS :
+ RETURNS :
+*****************************************************************************/
+static IMG_VOID
+DumpBufferArray(PVRSRV_PER_PROCESS_DATA *psPerProc,
+#if defined (SUPPORT_SID_INTERFACE)
+ PSGX_KICKTA_DUMP_BUFFER_KM psBufferArray,
+#else
+ PSGX_KICKTA_DUMP_BUFFER psBufferArray,
+#endif
+ IMG_UINT32 ui32BufferArrayLength,
+ IMG_BOOL bDumpPolls)
+{
+ IMG_UINT32 i;
+
+ for (i=0; i<ui32BufferArrayLength; i++)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ PSGX_KICKTA_DUMP_BUFFER_KM psBuffer;
+#else
+ PSGX_KICKTA_DUMP_BUFFER psBuffer;
+#endif
+ 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
+ {
+ /*
+ Range of data wraps the end of the buffer so it needs to be dumped in two sections
+ */
+
+ 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,
+ 0,
+ 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;
+#if defined (SUPPORT_SID_INTERFACE)
+ SGX_KICKTA_DUMP_BUFFER *psUMPtr;
+ SGX_KICKTA_DUMP_BUFFER_KM *psKickTADumpBufferKM, *psKMPtr;
+#else
+#if defined(__QNXNTO__)
+ const IMG_UINT32 NAME_BUFFER_SIZE = 30;
+ IMG_PCHAR pszNameBuffer, pszName;
+ IMG_UINT32 ui32NameBufferArraySize, ui32NameLength;
+#endif
+ SGX_KICKTA_DUMP_BUFFER *psKickTADumpBuffer;
+#endif
+ IMG_UINT32 ui32BufferArrayLength =
+ psPDumpBufferArrayIN->ui32BufferArrayLength;
+ IMG_UINT32 ui32BufferArraySize =
+ ui32BufferArrayLength * sizeof(SGX_KICKTA_DUMP_BUFFER);
+ PVRSRV_ERROR eError = PVRSRV_ERROR_TOO_FEW_BUFFERS;
+
+ PVR_UNREFERENCED_PARAMETER(psBridgeOut);
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY);
+
+#if defined (SUPPORT_SID_INTERFACE)
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32BufferArraySize,
+ (IMG_PVOID *)&psKickTADumpBufferKM, 0,
+ "Array of Kick Tile Accelerator Dump Buffer") != PVRSRV_OK)
+#else
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32BufferArraySize,
+ (IMG_PVOID *)&psKickTADumpBuffer, 0,
+ "Array of Kick Tile Accelerator Dump Buffer") != PVRSRV_OK)
+#endif
+ {
+ return -ENOMEM;
+ }
+
+#if !defined (SUPPORT_SID_INTERFACE)
+ if(CopyFromUserWrapper(psPerProc,
+ ui32BridgeID,
+ psKickTADumpBuffer,
+ psPDumpBufferArrayIN->psBufferArray,
+ ui32BufferArraySize) != PVRSRV_OK)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBuffer, 0);
+ /*not nulling pointer, out of scope*/
+ return -EFAULT;
+ }
+
+#if defined (__QNXNTO__)
+ ui32NameBufferArraySize = ui32BufferArrayLength * NAME_BUFFER_SIZE;
+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, ui32NameBufferArraySize,
+ (IMG_PVOID *)&pszNameBuffer, 0,
+ "Kick Tile Accelerator Dump Buffer names") != PVRSRV_OK)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBuffer, 0);
+ return -ENOMEM;
+ }
+
+ pszName = pszNameBuffer;
+
+ for (i=0; i<ui32BufferArrayLength; i++)
+ {
+ if (psKickTADumpBuffer[i].pszName)
+ {
+ ui32NameLength = psKickTADumpBuffer[i].ui32NameLength;
+ if (ui32NameLength >= NAME_BUFFER_SIZE)
+ {
+ ui32NameLength = NAME_BUFFER_SIZE - 1;
+ }
+
+ if (ui32NameLength &&
+ (CopyFromUserWrapper(psPerProc, ui32BridgeID, pszName,
+ psKickTADumpBuffer[i].pszName, ui32NameLength + 1) == PVRSRV_OK))
+ {
+ pszName[NAME_BUFFER_SIZE - 1] = 0;
+ psKickTADumpBuffer[i].pszName = pszName;
+ pszName += NAME_BUFFER_SIZE;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_WARNING, "Failed to read PDUMP buffer name"));
+ psKickTADumpBuffer[i].pszName = 0;
+ }
+ }
+ }
+#endif
+#endif
+
+ for(i = 0; i < ui32BufferArrayLength; i++)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_VOID *pvMemInfo = IMG_NULL;
+ psUMPtr = &psPDumpBufferArrayIN->psBufferArray[i];
+ psKMPtr = &psKickTADumpBufferKM[i];
+#else
+ IMG_VOID *pvMemInfo;
+#endif
+
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+ psUMPtr->hKernelMemInfo,
+#else
+ psKickTADumpBuffer[i].hKernelMemInfo,
+#endif
+ 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;
+ }
+#if defined (SUPPORT_SID_INTERFACE)
+ psKMPtr->hKernelMemInfo = pvMemInfo;
+#else
+ psKickTADumpBuffer[i].hKernelMemInfo = pvMemInfo;
+#endif
+
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &pvMemInfo,
+#if defined (SUPPORT_SID_INTERFACE)
+ psUMPtr->hCtrlKernelMemInfo,
+#else
+ psKickTADumpBuffer[i].hCtrlKernelMemInfo,
+#endif
+ 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;
+ }
+#if defined (SUPPORT_SID_INTERFACE)
+ psKMPtr->hCtrlKernelMemInfo = pvMemInfo;
+ psKMPtr->sCtrlDevVAddr = psUMPtr->sCtrlDevVAddr;
+#else
+ psKickTADumpBuffer[i].hCtrlKernelMemInfo = pvMemInfo;
+#endif
+#endif
+
+#if defined (SUPPORT_SID_INTERFACE)
+ psKMPtr->ui32SpaceUsed = psUMPtr->ui32SpaceUsed;
+ psKMPtr->ui32Start = psUMPtr->ui32Start;
+ psKMPtr->ui32End = psUMPtr->ui32End;
+ psKMPtr->ui32BufferSize = psUMPtr->ui32BufferSize;
+ psKMPtr->ui32BackEndLength = psUMPtr->ui32BackEndLength;
+ psKMPtr->uiAllocIndex = psUMPtr->uiAllocIndex;
+ psKMPtr->pvLinAddr = psUMPtr->pvLinAddr;
+ psKMPtr->pszName = psUMPtr->pszName;
+#endif
+ }
+
+ if(eError == PVRSRV_OK)
+ {
+ DumpBufferArray(psPerProc,
+#if defined (SUPPORT_SID_INTERFACE)
+ psKickTADumpBufferKM,
+#else
+ psKickTADumpBuffer,
+#endif
+ ui32BufferArrayLength,
+ psPDumpBufferArrayIN->bDumpPolls);
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBufferKM, 0);
+#else
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBuffer, 0);
+#if defined (__QNXNTO__)
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32NameBufferArraySize, pszNameBuffer, 0);
+#endif
+#endif
+ /*not nulling pointer, out of scope*/
+
+ return 0;
+}
+
+static IMG_INT
+SGXPDump3DSignatureRegistersBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS *psPDump3DSignatureRegistersIN,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_UINT32 ui32RegisterArraySize = psPDump3DSignatureRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32);
+ IMG_UINT32 *pui32Registers = IMG_NULL;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270)
+ IMG_UINT32 ui32RegVal = 0;
+#endif
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_HANDLE hDevMemContextInt = 0;
+ IMG_UINT32 ui32MMUContextID;
+ IMG_INT ret = -EFAULT;
+
+ PVR_UNREFERENCED_PARAMETER(psRetOUT);
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS);
+
+ if (ui32RegisterArraySize == 0)
+ {
+ goto ExitNoError;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psDeviceNode,
+ psPDump3DSignatureRegistersIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: hDevCookie lookup failed"));
+ goto Exit;
+ }
+
+ psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+
+#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270)
+ /* Enable all cores available */
+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT);
+#if defined(PDUMP)
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT,
+ psPDump3DSignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
+#endif
+#endif
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32RegisterArraySize,
+ (IMG_PVOID *)&pui32Registers, 0,
+ "Array of Registers") != 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(&psDeviceNode->sDevId,
+ psPDump3DSignatureRegistersIN->ui32DumpFrameNum,
+ psPDump3DSignatureRegistersIN->bLastFrame,
+ pui32Registers,
+ psPDump3DSignatureRegistersIN->ui32NumRegisters);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle( psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ psPDump3DSignatureRegistersIN->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ /* look up the MMU context ID */
+ PVR_ASSERT(psDeviceNode->pfnMMUGetContextID != IMG_NULL);
+ ui32MMUContextID = psDeviceNode->pfnMMUGetContextID((IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext);
+
+ PDumpSignatureBuffer(&psDeviceNode->sDevId,
+ "out.tasig", "TA", 0,
+ psDevInfo->psKernelTASigBufferMemInfo->sDevVAddr,
+ (IMG_UINT32)psDevInfo->psKernelTASigBufferMemInfo->uAllocSize,
+ ui32MMUContextID,
+ 0 /*ui32PDumpFlags*/);
+ PDumpSignatureBuffer(&psDeviceNode->sDevId,
+ "out.3dsig", "3D", 0,
+ psDevInfo->psKernel3DSigBufferMemInfo->sDevVAddr,
+ (IMG_UINT32)psDevInfo->psKernel3DSigBufferMemInfo->uAllocSize,
+ ui32MMUContextID,
+ 0 /*ui32PDumpFlags*/);
+
+ExitNoError:
+ psRetOUT->eError = PVRSRV_OK;
+ ret = 0;
+Exit:
+ if (pui32Registers != IMG_NULL)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0);
+ }
+
+#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270)
+ if (psDevInfo != IMG_NULL)
+ {
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, ui32RegVal);
+#if defined(PDUMP)
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_CORE, ui32RegVal,
+ psPDump3DSignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
+#endif
+ }
+#endif
+
+ 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;
+ PVRSRV_DEVICE_NODE *psDeviceNode ;
+ 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(PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psDeviceNode,
+ psPDumpCounterRegistersIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXPDumpCounterRegistersBW: hDevCookie lookup failed"));
+ ret = -ENOMEM;
+ goto Exit;
+ }
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32RegisterArraySize,
+ (IMG_PVOID *)&pui32Registers, 0,
+ "Array of Registers") != 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(&psDeviceNode->sDevId,
+ 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,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ IMG_UINT32 ui32RegisterArraySize = psPDumpTASignatureRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32);
+ IMG_UINT32 *pui32Registers = IMG_NULL;
+#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270)
+ PVRSRV_SGXDEV_INFO *psDevInfo = IMG_NULL;
+ IMG_UINT32 ui32RegVal = 0;
+#endif
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_INT ret = -EFAULT;
+
+ PVR_UNREFERENCED_PARAMETER(psRetOUT);
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS);
+
+ if (ui32RegisterArraySize == 0)
+ {
+ goto ExitNoError;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID**)&psDeviceNode,
+ psPDumpTASignatureRegistersIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: hDevCookie lookup failed"));
+ goto Exit;
+ }
+
+#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270)
+
+ psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+
+ /* Enable all cores available */
+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT);
+#if defined(PDUMP)
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT,
+ psPDumpTASignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
+#endif
+#endif
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32RegisterArraySize,
+ (IMG_PVOID *)&pui32Registers, 0,
+ "Array of Registers") != 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(&psDeviceNode->sDevId,
+ psPDumpTASignatureRegistersIN->ui32DumpFrameNum,
+ psPDumpTASignatureRegistersIN->ui32TAKickCount,
+ psPDumpTASignatureRegistersIN->bLastFrame,
+ pui32Registers,
+ psPDumpTASignatureRegistersIN->ui32NumRegisters);
+
+ExitNoError:
+ psRetOUT->eError = PVRSRV_OK;
+ ret = 0;
+Exit:
+ if (pui32Registers != IMG_NULL)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0);
+ }
+
+#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270)
+ if (psDevInfo != IMG_NULL)
+ {
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, ui32RegVal);
+#if defined(PDUMP)
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_CORE, ui32RegVal,
+ psPDumpTASignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
+#endif
+ }
+#endif
+
+ return ret;
+}
+//PRQA S 5120--
+
+
+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;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_HANDLE hDevMemContextInt = 0;
+ IMG_UINT32 ui32MMUContextID = 0;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID**)&psDeviceNode,
+ psPDumpHWPerfCBIN->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psDevInfo = psDeviceNode->pvDevice;
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle( psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ psPDumpHWPerfCBIN->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ /* look up the MMU context ID */
+ PVR_ASSERT(psDeviceNode->pfnMMUGetContextID != IMG_NULL);
+ ui32MMUContextID = psDeviceNode->pfnMMUGetContextID(hDevMemContextInt);
+
+ PDumpHWPerfCBKM(&psDeviceNode->sDevId,
+ &psPDumpHWPerfCBIN->szFileName[0],
+ psPDumpHWPerfCBIN->ui32FileOffset,
+ psDevInfo->psKernelHWPerfCBMemInfo->sDevVAddr,
+ psDevInfo->psKernelHWPerfCBMemInfo->uAllocSize,
+ ui32MMUContextID,
+ 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 /* defined(SUPPORT_SGX_HWPERF) */
+}
+
+
+static IMG_INT
+SGXPDumpSaveMemBW(IMG_UINT32 ui32BridgeID,
+ PVRSRV_BRIDGE_IN_PDUMP_SAVEMEM *psPDumpSaveMem,
+ PVRSRV_BRIDGE_RETURN *psRetOUT,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_HANDLE hDevMemContextInt = 0;
+ IMG_UINT32 ui32MMUContextID;
+
+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_SAVEMEM);
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_VOID**)&psDeviceNode,
+ psPDumpSaveMem->hDevCookie,
+ PVRSRV_HANDLE_TYPE_DEV_NODE);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ psRetOUT->eError =
+ PVRSRVLookupHandle( psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ psPDumpSaveMem->hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+ if(psRetOUT->eError != PVRSRV_OK)
+ {
+ return 0;
+ }
+
+ /* look up the MMU context ID */
+ PVR_ASSERT(psDeviceNode->pfnMMUGetContextID != IMG_NULL);
+ ui32MMUContextID = psDeviceNode->pfnMMUGetContextID(hDevMemContextInt);
+
+ PDumpSaveMemKM(&psDeviceNode->sDevId,
+ &psPDumpSaveMem->szFileName[0],
+ psPDumpSaveMem->ui32FileOffset,
+ psPDumpSaveMem->sDevVAddr,
+ psPDumpSaveMem->ui32Size,
+ ui32MMUContextID,
+ psPDumpSaveMem->ui32PDumpFlags);
+ return 0;
+}
+
+#endif /* PDUMP */
+
+
+/* PRQA S 0313,3635 END_SET_SGX */ /* function macro required this format */
+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_2DQUERYBLTSCOMPLETE, SGX2DQueryBlitsCompleteBW);
+
+#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);
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES, SGXScheduleProcessQueuesBW);
+
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READ_HWPERF_CB, SGXReadHWPerfCBBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SET_RENDER_CONTEXT_PRIORITY, SGXSetRenderContextPriorityBW);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SET_TRANSFER_CONTEXT_PRIORITY, SGXSetTransferContextPriorityBW);
+
+#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);
+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_SAVEMEM, SGXPDumpSaveMemBW);
+#endif
+}
+/* PRQA L:END_SET_SGX */ /* end of setup overrides */
+
+#endif /* SUPPORT_SGX */
diff --git a/pvr-source/services4/srvkm/bridged/sgx/bridged_sgx_bridge.h b/pvr-source/services4/srvkm/bridged/sgx/bridged_sgx_bridge.h
new file mode 100644
index 0000000..3cb6282
--- /dev/null
+++ b/pvr-source/services4/srvkm/bridged/sgx/bridged_sgx_bridge.h
@@ -0,0 +1,61 @@
+/*************************************************************************/ /*!
+@Title SGX Bridge Functionality
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Header for the PVR Bridge code
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#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 /* __BRIDGED_SGX_BRIDGE_H__ */
+
+/******************************************************************************
+ End of file (bridged_sgx_bridge.h)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/common/buffer_manager.c b/pvr-source/services4/srvkm/common/buffer_manager.c
new file mode 100644
index 0000000..9ce7a11
--- /dev/null
+++ b/pvr-source/services4/srvkm/common/buffer_manager.c
@@ -0,0 +1,3573 @@
+/*************************************************************************/ /*!
+@Title Buffer management functions for Linux
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Manages buffers mapped into two memory spaces - cpu and device,
+ either of which can be virtual or physical.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "services_headers.h"
+
+#include "sysconfig.h"
+#include "hash.h"
+#include "ra.h"
+#include "pdump_km.h"
+#include "lists.h"
+
+static IMG_BOOL
+ZeroBuf(BM_BUF *pBuf, BM_MAPPING *pMapping, IMG_SIZE_T 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_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength, IMG_UINTPTR_T *pBase);
+
+static IMG_INT32
+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_INT32
+DevMemoryFree (BM_MAPPING *pMapping);
+
+/*!
+******************************************************************************
+
+ @Function AllocMemory
+
+ @Description Allocate a buffer mapped into both cpu and device virtual
+ address spaces. This is now quite simple:
+
+ 1. Choose whence to get the memory;
+ 2. Obtain memory from that source;
+ 3. Work out the actual buffer addresses in other spaces.
+
+ In choosing whence to get the memory we work like this:
+
+ 1. If an import arena exists, use unless BP_CONTIGUOUS is set;
+ 2. Use a contiguous pool.
+
+ @Input pBMContext - BM context
+ @Input psBMHeap - BM heap
+ @Input psDevVAddr - device virtual address (optional)
+ @Input uSize - requested buffer size in bytes.
+ @Input uFlags - property flags for the buffer.
+ @Input uDevVAddrAlignment - required device virtual address
+ alignment, or 0.
+ @Input pvPrivData - opaque private data passed through to allocator
+ @Input ui32PrivDataLength - length of opaque private data
+
+ @Output pBuf - receives a pointer to a descriptor of the allocated
+ buffer.
+ @Return IMG_TRUE - Success
+ IMG_FALSE - Failed.
+
+ *****************************************************************************/
+static IMG_BOOL
+AllocMemory (BM_CONTEXT *pBMContext,
+ BM_HEAP *psBMHeap,
+ IMG_DEV_VIRTADDR *psDevVAddr,
+ IMG_SIZE_T uSize,
+ IMG_UINT32 uFlags,
+ IMG_UINT32 uDevVAddrAlignment,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_UINT32 ui32ChunkSize,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_BOOL *pabMapChunk,
+ BM_BUF *pBuf)
+{
+ BM_MAPPING *pMapping;
+ IMG_UINTPTR_T uOffset;
+ RA_ARENA *pArena = IMG_NULL;
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "AllocMemory (uSize=0x%x, uFlags=0x%x, align=0x%x)",
+ uSize, uFlags, uDevVAddrAlignment));
+
+ /*
+ what to do depends on combination of DevVaddr generation
+ and backing RAM requirement
+ */
+ if(uFlags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
+ {
+ if(uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR)
+ {
+ /* user supplied DevVAddr, RAM backing */
+ PVR_DPF ((PVR_DBG_ERROR, "AllocMemory: combination of DevVAddr management and RAM backing mode unsupported"));
+ return IMG_FALSE;
+ }
+
+ /* BM supplied DevVAddr, RAM Backing */
+
+ /* check heap attributes */
+ if(psBMHeap->ui32Attribs
+ & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
+ |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
+ {
+ /* specify arena (VM+RAM)*/
+ pArena = psBMHeap->pImportArena;
+ PVR_ASSERT(psBMHeap->sDevArena.psDeviceMemoryHeapInfo->ui32Attribs & PVRSRV_MEM_RAM_BACKED_ALLOCATION);
+ }
+ else
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "AllocMemory: backing store type doesn't match heap"));
+ return IMG_FALSE;
+ }
+
+ /* Now allocate from the arena we chose above. */
+ /* in case of a pageable buffer, we must bypass RA which could
+ * combine/split individual mappings between buffers:
+ */
+ if (uFlags & (PVRSRV_MEM_SPARSE | PVRSRV_HAP_GPU_PAGEABLE))
+ {
+ IMG_BOOL bSuccess;
+ IMG_SIZE_T puiActualSize;
+ IMG_SIZE_T uRequestSize = uSize;
+
+ if(uFlags & PVRSRV_MEM_SPARSE)
+ {
+ uRequestSize = ui32ChunkSize * ui32NumPhysChunks;
+ uSize = ui32ChunkSize * ui32NumVirtChunks;
+ }
+
+ /* Allocate physical memory */
+ if (!BM_ImportMemory(psBMHeap,
+ uRequestSize,
+ &puiActualSize,
+ &pMapping,
+ uFlags,
+ pvPrivData,
+ ui32PrivDataLength,
+ (IMG_UINTPTR_T *)&(pBuf->DevVAddr.uiAddr)))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "BM_ImportMemory: Failed to allocate device memory"));
+ return IMG_FALSE;
+ }
+ pBuf->hOSMemHandle = pMapping->hOSMemHandle;
+
+ /* We allocate VM space for sparse area */
+ if(uFlags & PVRSRV_MEM_SPARSE)
+ {
+ if (puiActualSize != ui32ChunkSize * ui32NumPhysChunks)
+ {
+ /*
+ * Most likely the chunk size was not host page multiple,
+ * so return with an error
+ */
+ PVR_DPF((PVR_DBG_ERROR, "AllocMemory: Failed to allocate"
+ "memory for sparse allocation"));
+ BM_FreeMemory(pArena, IMG_NULL, pMapping);
+ return IMG_FALSE;
+ }
+
+ pMapping->uSizeVM = uSize;
+ pMapping->ui32ChunkSize = ui32ChunkSize;
+ pMapping->ui32NumVirtChunks = ui32NumVirtChunks;
+ pMapping->ui32NumPhysChunks = ui32NumPhysChunks;
+ pMapping->pabMapChunk = pabMapChunk;
+
+ if (!(uFlags & PVRSRV_HAP_NO_GPU_VIRTUAL_ON_ALLOC))
+ {
+ /* Allocate VA space and map in the physical memory */
+ bSuccess = DevMemoryAlloc (pBMContext,
+ pMapping,
+ IMG_NULL,
+ uFlags,
+ (IMG_UINT32)uDevVAddrAlignment,
+ &pMapping->DevVAddr);
+ if (!bSuccess)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "AllocMemory: Failed to allocate device memory"));
+ BM_FreeMemory(pArena, IMG_NULL, pMapping);
+ return IMG_FALSE;
+ }
+
+ /* uDevVAddrAlignment is currently set to zero so QAC
+ * generates warning which we override */
+ /* PRQA S 3356,3358 1 */
+ PVR_ASSERT (uDevVAddrAlignment>1?(pMapping->DevVAddr.uiAddr%uDevVAddrAlignment)==0:1);
+ pBuf->DevVAddr.uiAddr = pMapping->DevVAddr.uiAddr;
+ }
+ }
+ }
+ else
+ {
+ if (!RA_Alloc(pArena,
+ uSize,
+ IMG_NULL,
+ (IMG_VOID*) &pMapping,
+ uFlags,
+ uDevVAddrAlignment,
+ 0,
+ pvPrivData,
+ ui32PrivDataLength,
+ (IMG_UINTPTR_T *)&(pBuf->DevVAddr.uiAddr)))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "AllocMemory: RA_Alloc(0x%x) hOSMemHandle %p, flags 0x%08x FAILED",
+ uSize, pMapping->hOSMemHandle, uFlags));
+ 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->uSizeVM)
+ {
+ 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;
+ }
+ }
+
+ /* for hm_contiguous and hm_wrapped memory, the pMapping
+ * will have a physical address, else 0 */
+ 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)
+ {
+ /* user supplied DevVAddr, no RAM backing */
+ PVR_ASSERT(psDevVAddr != IMG_NULL);
+
+ if (psDevVAddr == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "AllocMemory: invalid parameter - psDevVAddr"));
+ return IMG_FALSE;
+ }
+
+ /* just make space in the pagetables */
+ pBMContext->psDeviceNode->pfnMMUAlloc (psBMHeap->pMMUHeap,
+ uSize,
+ IMG_NULL,
+ PVRSRV_MEM_USER_SUPPLIED_DEVVADDR,
+ uDevVAddrAlignment,
+ psDevVAddr);
+
+ /* setup buf */
+ pBuf->DevVAddr = *psDevVAddr;
+ }
+ else
+ {
+ IMG_BOOL bResult;
+ /* BM supplied DevVAddr, no RAM Backing */
+
+ /* just make space in the pagetables */
+ bResult = pBMContext->psDeviceNode->pfnMMUAlloc (psBMHeap->pMMUHeap,
+ uSize,
+ IMG_NULL,
+ 0,
+ uDevVAddrAlignment,
+ &pBuf->DevVAddr);
+
+ if(!bResult)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "AllocMemory: MMUAlloc failed"));
+ return IMG_FALSE;
+ }
+ }
+
+ /* allocate a mocked-up mapping */
+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof (struct _BM_MAPPING_),
+ (IMG_PVOID *)&pMapping, IMG_NULL,
+ "Buffer Manager Mapping") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "AllocMemory: OSAllocMem(0x%x) FAILED", sizeof(*pMapping)));
+ return IMG_FALSE;
+ }
+
+ /* setup buf */
+ pBuf->CpuVAddr = IMG_NULL;
+ pBuf->hOSMemHandle = 0;
+ pBuf->CpuPAddr.uiAddr = 0;
+
+ /* setup mapping */
+ pMapping->CpuVAddr = IMG_NULL;
+ pMapping->CpuPAddr.uiAddr = 0;
+ pMapping->DevVAddr = pBuf->DevVAddr;
+ pMapping->ui32MappingCount = 1;
+ pMapping->psSysAddr = IMG_NULL;
+ pMapping->uSize = uSize;
+ pMapping->hOSMemHandle = 0;
+ }
+
+ /* Record the arena pointer in the mapping. */
+ pMapping->pArena = pArena;
+ pMapping->ui32DevVAddrAlignment = uDevVAddrAlignment;
+
+ /* record the heap */
+ pMapping->pBMHeap = psBMHeap;
+ pBuf->pMapping = pMapping;
+
+ /* output some stats */
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "AllocMemory: pMapping=%08x: DevV=%08X CpuV=%08x CpuP=%08X uSize=0x%x",
+ (IMG_UINTPTR_T)pMapping,
+ pMapping->DevVAddr.uiAddr,
+ (IMG_UINTPTR_T)pMapping->CpuVAddr,
+ pMapping->CpuPAddr.uiAddr,
+ pMapping->uSize));
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "AllocMemory: pBuf=%08x: DevV=%08X CpuV=%08x CpuP=%08X uSize=0x%x",
+ (IMG_UINTPTR_T)pBuf,
+ pBuf->DevVAddr.uiAddr,
+ (IMG_UINTPTR_T)pBuf->CpuVAddr,
+ pBuf->CpuPAddr.uiAddr,
+ uSize));
+
+ /* Verify virtual device address alignment */
+ PVR_ASSERT(((pBuf->DevVAddr.uiAddr) & (uDevVAddrAlignment - 1)) == 0);
+
+ return IMG_TRUE;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function WrapMemory
+
+ @Description Allocate a buffer mapped into both cpu and device virtual
+ address spaces.
+
+ @Input psBMHeap - BM heap
+ @Input uSize - requested buffer size in bytes.
+ @Input ui32BaseOffset - Offset from page of wrap.
+ @Input bPhysContig - Is the wrap physically contiguous.
+ @Input psAddr - List of pages to wrap.
+ @Input pvCPUVAddr - Optional CPU Kernel virtual address (page aligned) of memory to wrap
+ @Input uFlags - property flags for the buffer.
+ @Output Buf - receives a pointer to a descriptor of the allocated
+ buffer.
+ @Return IMG_TRUE - Success
+ IMG_FALSE - Failed.
+
+ *****************************************************************************/
+static IMG_BOOL
+WrapMemory (BM_HEAP *psBMHeap,
+ IMG_SIZE_T uSize,
+ IMG_SIZE_T 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_INT32 bResult;
+ IMG_SIZE_T const ui32PageSize = HOST_PAGESIZE();
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "WrapMemory(psBMHeap=%08X, size=0x%x, offset=0x%x, bPhysContig=0x%x, pvCPUVAddr = 0x%08x, flags=0x%x)",
+ (IMG_UINTPTR_T)psBMHeap, uSize, ui32BaseOffset, bPhysContig, (IMG_UINTPTR_T)pvCPUVAddr, uFlags));
+
+ PVR_ASSERT((psAddr->uiAddr & (ui32PageSize - 1)) == 0);
+ /* Only need lower 12 bits of the cpu addr - don't care what size a void* is */
+ PVR_ASSERT(((IMG_UINTPTR_T)pvCPUVAddr & (ui32PageSize - 1)) == 0);
+
+ uSize += ui32BaseOffset;
+ uSize = HOST_PAGEALIGN (uSize);
+
+ /* allocate a mocked-up mapping */
+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(*pMapping),
+ (IMG_PVOID *)&pMapping, IMG_NULL,
+ "Mocked-up mapping") != 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->uSizeVM = 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, Size=%d) failed",
+ pMapping->CpuPAddr.uiAddr, 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 Size=%d) failed",
+ pMapping->uSize));
+ goto fail_cleanup;
+ }
+ }
+ }
+ else
+ {
+ if (bPhysContig)
+ {
+ pMapping->eCpuMemoryOrigin = hm_wrapped;
+ pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]);
+
+ if(OSReservePhys(pMapping->CpuPAddr,
+ pMapping->uSize,
+ uFlags,
+ IMG_NULL,
+ &pMapping->CpuVAddr,
+ &pMapping->hOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSReservePhys Phys=0x%08X, Size=%d) failed",
+ pMapping->CpuPAddr.uiAddr, 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;
+ }
+ }
+ }
+
+ /*
+ * Allocate device memory for this buffer. Map wrapped pages as read/write
+ */
+ bResult = DevMemoryAlloc(psBMHeap->pBMContext,
+ pMapping,
+ IMG_NULL,
+ uFlags | PVRSRV_MEM_READ | PVRSRV_MEM_WRITE,
+ IMG_CAST_TO_DEVVADDR_UINT(ui32PageSize),
+ &DevVAddr);
+ if (bResult <= 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "WrapMemory: DevMemoryAlloc(0x%x) failed",
+ pMapping->uSize));
+ goto fail_cleanup;
+ }
+
+ /*
+ * Determine the offset of this allocation within the underlying
+ * dual mapped chunk of memory, we can assume that all three
+ * addresses associated with this allocation are placed at the same
+ * offset within the underlying chunk.
+ */
+ 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 + IMG_CAST_TO_DEVVADDR_UINT(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: DevV=%08X CpuP=%08X uSize=0x%x",
+ pMapping->DevVAddr.uiAddr, pMapping->CpuPAddr.uiAddr, pMapping->uSize));
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "WrapMemory: DevV=%08X CpuP=%08X uSize=0x%x",
+ pBuf->DevVAddr.uiAddr, 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);
+ /*not nulling pointer, out of scope*/
+
+ return IMG_FALSE;
+}
+
+
+static IMG_BOOL
+ZeroBuf(BM_BUF *pBuf, BM_MAPPING *pMapping, IMG_SIZE_T 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_SIZE_T ui32BytesRemaining = ui32Bytes;
+ IMG_SIZE_T ui32CurrentOffset = 0;
+ IMG_CPU_PHYADDR CpuPAddr;
+
+ /* Walk through the pBuf one page at a time and use
+ * transient mappings to zero the memory */
+
+ PVR_ASSERT(pBuf->hOSMemHandle);
+
+ while(ui32BytesRemaining > 0)
+ {
+ IMG_SIZE_T ui32BlockBytes = MIN(ui32BytesRemaining, HOST_PAGESIZE());
+ CpuPAddr = OSMemHandleToCpuPAddr(pBuf->hOSMemHandle, ui32CurrentOffset);
+ /* If the CpuPAddr isn't page aligned then start by writing up to the next page
+ * boundary (or ui32BytesRemaining if less), so that subsequent iterations can
+ * copy full physical pages. */
+ if(CpuPAddr.uiAddr & (HOST_PAGESIZE() -1))
+ {
+ ui32BlockBytes =
+ MIN(ui32BytesRemaining, (IMG_UINT32)(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;
+}
+
+/*!
+******************************************************************************
+
+ @Function FreeBuf
+
+ @Description Free a buffer previously allocated with BM_Alloc() or unwrap
+ one previous wrapped with BM_Wrap().
+ The buffer is identified by the buffer descriptor pBuf
+ returned at allocation. Note the double indirection when
+ passing the buffer.
+
+
+ @Input pBuf - buffer descriptor to free.
+ @Input ui32Flags - flags
+ @Input bFromAllocator - Is this being called by the
+ allocator?
+
+ @Return None.
+
+ *****************************************************************************/
+static IMG_VOID
+FreeBuf (BM_BUF *pBuf, IMG_UINT32 ui32Flags, IMG_BOOL bFromAllocator)
+{
+ BM_MAPPING *pMapping;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "FreeBuf: pBuf=0x%x: DevVAddr=%08X CpuVAddr=0x%x CpuPAddr=%08X",
+ (IMG_UINTPTR_T)pBuf, pBuf->DevVAddr.uiAddr,
+ (IMG_UINTPTR_T)pBuf->CpuVAddr, pBuf->CpuPAddr.uiAddr));
+
+ /* record mapping */
+ pMapping = pBuf->pMapping;
+
+ psDeviceNode = pMapping->pBMHeap->pBMContext->psDeviceNode;
+ if (psDeviceNode->pfnCacheInvalidate)
+ {
+ psDeviceNode->pfnCacheInvalidate(psDeviceNode);
+ }
+
+ if(ui32Flags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR)
+ {
+ /* Submemhandle is required by exported mappings */
+ if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
+ {
+ /* user supplied Device Virtual Address */
+ if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
+ {
+ /* RAM backed allocation */
+ PVR_DPF ((PVR_DBG_ERROR, "FreeBuf: combination of DevVAddr management and RAM backing mode unsupported"));
+ }
+ else
+ {
+ /* free the mocked-up mapping */
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
+ pBuf->pMapping = IMG_NULL; /*nulling pointer alias*/
+ }
+ }
+ }
+ else
+ {
+ /* BM supplied Device Virtual Address */
+ if(pBuf->hOSMemHandle != pMapping->hOSMemHandle)
+ {
+ /* Submemhandle is required by exported mappings */
+ if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
+ {
+ OSReleaseSubMemHandle(pBuf->hOSMemHandle, ui32Flags);
+ }
+ }
+
+ if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
+ {
+ /* Submemhandle is required by exported mappings */
+
+ if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
+ {
+ /*
+ RAM backed allocation
+ Note: currently no need to distinguish between hm_env and hm_contiguous
+ */
+ PVR_ASSERT(pBuf->ui32ExportCount == 0);
+ if (pBuf->pMapping->ui32Flags & (PVRSRV_MEM_SPARSE | PVRSRV_HAP_GPU_PAGEABLE))
+ {
+ IMG_UINT32 ui32FreeSize = 0;
+ IMG_PVOID pvFreePtr = IMG_NULL;
+
+ if(pBuf->pMapping->ui32Flags & PVRSRV_MEM_SPARSE)
+ {
+ ui32FreeSize = sizeof(IMG_BOOL) * pBuf->pMapping->ui32NumVirtChunks;
+ pvFreePtr = pBuf->pMapping->pabMapChunk;
+ }
+
+ /* With sparse and page-able allocations we don't go through the sub-alloc RA */
+ BM_FreeMemory(pBuf->pMapping->pBMHeap, pBuf->DevVAddr.uiAddr, pBuf->pMapping);
+
+ if(pvFreePtr)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ ui32FreeSize,
+ pvFreePtr,
+ IMG_NULL);
+ }
+ }
+ else
+ {
+ RA_Free (pBuf->pMapping->pArena, pBuf->DevVAddr.uiAddr, IMG_FALSE);
+ }
+ }
+ }
+ else
+ {
+ if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
+ {
+ 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;
+ }
+ }
+ if (bFromAllocator)
+ DevMemoryFree (pMapping);
+
+ if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
+ {
+ /* free the mocked-up mapping */
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
+ pBuf->pMapping = IMG_NULL; /*nulling pointer alias*/
+ }
+ }
+ }
+
+
+ if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_BUF), pBuf, IMG_NULL);
+ /*not nulling pointer, copy on stack*/
+ }
+}
+
+/*!
+******************************************************************************
+
+ @Function BM_DestroyContext_AnyCb
+
+ @Description Destroy a buffer manager heap.
+
+ @Input psBMHeap
+
+ @Return PVRSRV_ERROR
+
+ *****************************************************************************/
+static PVRSRV_ERROR BM_DestroyContext_AnyCb(BM_HEAP *psBMHeap)
+{
+ if(psBMHeap->ui32Attribs
+ & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
+ |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
+ {
+ if (psBMHeap->pImportArena)
+ {
+ IMG_BOOL bTestDelete = RA_TestDelete(psBMHeap->pImportArena);
+ if (!bTestDelete)
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext_AnyCb: RA_TestDelete failed"));
+ return PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP;
+ }
+ }
+ }
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function BM_DestroyContext
+
+ @Description Destroy a buffer manager context. All allocated buffers must be
+ free'd before calling this function. This function is called
+ also to perform cleanup during aborted initialisations so it's
+ fairly careful not to assume any given resource has really been
+ created/allocated.
+
+ @Return PVRSRV_ERROR
+
+ *****************************************************************************/
+PVRSRV_ERROR
+BM_DestroyContext(IMG_HANDLE hBMContext,
+ IMG_BOOL *pbDestroyed)
+{
+ PVRSRV_ERROR eError;
+ BM_CONTEXT *pBMContext = (BM_CONTEXT*)hBMContext;
+
+ PVR_DPF ((PVR_DBG_MESSAGE, "BM_DestroyContext"));
+
+ if (pbDestroyed != IMG_NULL)
+ {
+ *pbDestroyed = IMG_FALSE;
+ }
+
+ /*
+ Exit straight away if it's an invalid context handle
+ */
+ if (pBMContext == IMG_NULL)
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: Invalid handle"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ pBMContext->ui32RefCount--;
+
+ if (pBMContext->ui32RefCount > 0)
+ {
+ /* Just return if there are more references to this context */
+ return PVRSRV_OK;
+ }
+
+ /*
+ Check whether there is a bug in the client which brought it here before
+ all the allocations have been freed.
+ */
+ eError = List_BM_HEAP_PVRSRV_ERROR_Any(pBMContext->psBMHeap, &BM_DestroyContext_AnyCb);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: List_BM_HEAP_PVRSRV_ERROR_Any failed"));
+ return eError;
+ }
+ else
+ {
+ /* free the device memory context */
+ eError = ResManFreeResByPtr(pBMContext->hResItem, CLEANUP_WITH_POLL);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: ResManFreeResByPtr failed %d",eError));
+ return eError;
+ }
+
+ /* mark context as destroyed */
+ if (pbDestroyed != IMG_NULL)
+ {
+ *pbDestroyed = IMG_TRUE;
+ }
+ }
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function BM_DestroyContextCallBack_AnyVaCb
+
+ @Description Destroy Device memory context
+
+ @Input psBMHeap - heap to be freed.
+ @Input va - list of variable arguments with the following contents:
+ - psDeviceNode
+ @Return PVRSRV_ERROR
+
+ *****************************************************************************/
+static PVRSRV_ERROR BM_DestroyContextCallBack_AnyVaCb(BM_HEAP *psBMHeap, va_list va)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ psDeviceNode = va_arg(va, PVRSRV_DEVICE_NODE*);
+
+ /* Free up the import arenas */
+ 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_UNSUPPORTED_BACKING_STORE;
+ }
+
+ /* Free up the MMU Heaps */
+ psDeviceNode->pfnMMUDelete(psBMHeap->pMMUHeap);
+
+ /* Free Heap memory */
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
+ /*not nulling pointer, copy on stack*/
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function BM_DestroyContextCallBack
+
+ @Description Destroy Device memory context
+
+ @Input pvParam - opaque void ptr param
+ @Input ui32Param - opaque unsigned long param
+
+ @Return PVRSRV_ERROR
+
+ *****************************************************************************/
+static PVRSRV_ERROR BM_DestroyContextCallBack(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ BM_CONTEXT *pBMContext = pvParam;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ PVRSRV_ERROR eError;
+/* BM_CONTEXT **ppBMContext;
+ BM_HEAP *psBMHeap, *psTmpBMHeap;*/
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ /*
+ Get DeviceNode from BMcontext
+ */
+ psDeviceNode = pBMContext->psDeviceNode;
+
+ /*
+ Free the import arenas and heaps
+ */
+ eError = List_BM_HEAP_PVRSRV_ERROR_Any_va(pBMContext->psBMHeap,
+ &BM_DestroyContextCallBack_AnyVaCb,
+ psDeviceNode);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ /*
+ 'Finalise' the MMU
+ */
+ if (pBMContext->psMMUContext)
+ {
+ psDeviceNode->pfnMMUFinalise(pBMContext->psMMUContext);
+ }
+
+ /*
+ Free up generic, useful resources - if they were allocated.
+ */
+ if (pBMContext->pBufferHash)
+ {
+ HASH_Delete(pBMContext->pBufferHash);
+ }
+
+ if (pBMContext == psDeviceNode->sDevMemoryInfo.pBMKernelContext)
+ {
+ /* Freeing the kernel context */
+ psDeviceNode->sDevMemoryInfo.pBMKernelContext = IMG_NULL;
+ }
+ else
+ {
+ if (pBMContext->ppsThis != IMG_NULL)
+ {
+ /*
+ * Remove context from the linked list
+ */
+ List_BM_CONTEXT_Remove(pBMContext);
+ }
+ }
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_CONTEXT), pBMContext, IMG_NULL);
+ /*not nulling pointer, copy on stack*/
+
+ return PVRSRV_OK;
+}
+
+
+static IMG_HANDLE BM_CreateContext_IncRefCount_AnyVaCb(BM_CONTEXT *pBMContext, va_list va)
+{
+ PRESMAN_CONTEXT hResManContext;
+ hResManContext = va_arg(va, PRESMAN_CONTEXT);
+ if(ResManFindResourceByPtr(hResManContext, pBMContext->hResItem) == PVRSRV_OK)
+ {
+ /* just increment the refcount and return the memory context found for this process */
+ pBMContext->ui32RefCount++;
+ return pBMContext;
+ }
+ return IMG_NULL;
+}
+
+static IMG_VOID BM_CreateContext_InsertHeap_ForEachVaCb(BM_HEAP *psBMHeap, va_list va)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ BM_CONTEXT *pBMContext;
+ psDeviceNode = va_arg(va, PVRSRV_DEVICE_NODE*);
+ pBMContext = va_arg(va, BM_CONTEXT*);
+ switch(psBMHeap->sDevArena.DevMemHeapType)
+ {
+ case DEVICE_MEMORY_HEAP_SHARED:
+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
+ {
+ /* insert the heap into the device's MMU page directory/table */
+ psDeviceNode->pfnMMUInsertHeap(pBMContext->psMMUContext, psBMHeap->pMMUHeap);
+ break;
+ }
+ }
+}
+
+/*!
+******************************************************************************
+
+ @Function BM_CreateContext
+
+ @Description Creates and initialises a buffer manager context. This function must be called
+ before any other buffer manager functions.
+
+ @Return valid BM context handle - Success
+ IMG_NULL - Failed
+
+ *****************************************************************************/
+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;
+ }
+
+ /* setup the device memory info. */
+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+
+ if (bKernelContext == IMG_FALSE)
+ {
+ IMG_HANDLE res = (IMG_HANDLE) List_BM_CONTEXT_Any_va(psDevMemoryInfo->pBMContext,
+ &BM_CreateContext_IncRefCount_AnyVaCb,
+ hResManContext);
+ if (res)
+ {
+ return res;
+ }
+ }
+
+ /* allocate a BM context */
+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof (struct _BM_CONTEXT_),
+ (IMG_PVOID *)&pBMContext, IMG_NULL,
+ "Buffer Manager Context") != PVRSRV_OK)
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: Alloc failed"));
+ return IMG_NULL;
+ }
+ OSMemSet(pBMContext, 0, sizeof (BM_CONTEXT));
+
+ /* store the associated devicenode */
+ pBMContext->psDeviceNode = psDeviceNode;
+
+ /* This hash table is used to store BM_Wraps in a global way */
+ /* INTEGRATION_POINT: 32 is an abitrary limit on the number of hashed BM_wraps */
+ pBMContext->pBufferHash = HASH_Create(32);
+ if (pBMContext->pBufferHash==IMG_NULL)
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: HASH_Create failed"));
+ goto cleanup;
+ }
+
+ if((IMG_NULL == psDeviceNode->pfnMMUInitialise) || (psDeviceNode->pfnMMUInitialise(psDeviceNode,
+ &pBMContext->psMMUContext,
+ psPDDevPAddr) != PVRSRV_OK))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_CreateContext: MMUInitialise failed"));
+ goto cleanup;
+ }
+
+ if(bKernelContext)
+ {
+ /* just save the kernel context */
+ PVR_ASSERT(psDevMemoryInfo->pBMKernelContext == IMG_NULL);
+ psDevMemoryInfo->pBMKernelContext = pBMContext;
+ }
+ else
+ {
+ /*
+ On the creation of each new context we must
+ insert the kernel context's 'shared' and 'shared_exported'
+ heaps into the new context
+ - check the kernel context and heaps exist
+ */
+ 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);
+
+ /*
+ insert the kernel heaps structures into the new context's shared heap list
+ Note. this will include the kernel only heaps but these will not actually
+ be imported into the context nor returned to the client
+ */
+ pBMContext->psBMSharedHeap = psDevMemoryInfo->pBMKernelContext->psBMHeap;
+
+ /*
+ insert the shared heaps into the MMU page directory/table
+ for the new context
+ */
+ List_BM_HEAP_ForEach_va(pBMContext->psBMSharedHeap,
+ &BM_CreateContext_InsertHeap_ForEachVaCb,
+ psDeviceNode,
+ pBMContext);
+
+ /* Finally, insert the new context into the list of BM contexts */
+ List_BM_CONTEXT_Insert(&psDevMemoryInfo->pBMContext, pBMContext);
+ }
+
+ /* Increment the refcount, as creation is successful */
+ pBMContext->ui32RefCount++;
+
+ /* register with resman */
+ 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:
+ (IMG_VOID)BM_DestroyContextCallBack(pBMContext, 0, CLEANUP_WITH_POLL);
+
+ return IMG_NULL;
+}
+
+
+static IMG_VOID *BM_CreateHeap_AnyVaCb(BM_HEAP *psBMHeap, va_list va)
+{
+ DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo;
+ psDevMemHeapInfo = va_arg(va, DEVICE_MEMORY_HEAP_INFO*);
+ if (psBMHeap->sDevArena.ui32HeapID == psDevMemHeapInfo->ui32HeapID)
+ {
+ /* Match - just return already created heap */
+ return psBMHeap;
+ }
+ else
+ {
+ return IMG_NULL;
+ }
+}
+
+/*!
+******************************************************************************
+
+ @Function BM_CreateHeap
+
+ @Description Creates and initialises a BM heap for a given BM context.
+
+ @Return
+ valid heap handle - success
+ IMG_NULL - failure
+
+
+ *****************************************************************************/
+IMG_HANDLE
+BM_CreateHeap (IMG_HANDLE hBMContext,
+ DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo)
+{
+ BM_CONTEXT *pBMContext = (BM_CONTEXT*)hBMContext;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ BM_HEAP *psBMHeap;
+
+ PVR_DPF((PVR_DBG_MESSAGE, "BM_CreateHeap"));
+
+ if(!pBMContext)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: BM_CONTEXT null"));
+ return IMG_NULL;
+ }
+
+ psDeviceNode = pBMContext->psDeviceNode;
+
+ /*
+ * Ensure that the heap size is a multiple of the data page size.
+ */
+ PVR_ASSERT((psDevMemHeapInfo->ui32HeapSize & (psDevMemHeapInfo->ui32DataPageSize - 1)) == 0);
+ PVR_ASSERT(psDevMemHeapInfo->ui32HeapSize > 0);
+
+ /*
+ We may be being asked to create a heap in a context which already has one.
+ Test for refcount > 0 because PVRSRVGetDeviceMemHeapInfoKM doesn't increment the refcount.
+ This does mean that the first call to PVRSRVCreateDeviceMemContextKM will first try to find
+ heaps that we already know don't exist
+ */
+ if(pBMContext->ui32RefCount > 0)
+ {
+ psBMHeap = (BM_HEAP*)List_BM_HEAP_Any_va(pBMContext->psBMHeap,
+ &BM_CreateHeap_AnyVaCb,
+ psDevMemHeapInfo);
+
+ if (psBMHeap)
+ {
+ return psBMHeap;
+ }
+ }
+
+
+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof (BM_HEAP),
+ (IMG_PVOID *)&psBMHeap, IMG_NULL,
+ "Buffer Manager Heap") != 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;
+#if defined(SUPPORT_MEMORY_TILING)
+ psBMHeap->ui32XTileStride = psDevMemHeapInfo->ui32XTileStride;
+#endif
+
+ /* tie the heap to the context */
+ psBMHeap->pBMContext = pBMContext;
+
+ psBMHeap->pMMUHeap = psDeviceNode->pfnMMUCreate (pBMContext->psMMUContext,
+ &psBMHeap->sDevArena,
+ &psBMHeap->pVMArena,
+ &psBMHeap->psMMUAttrib);
+ if (!psBMHeap->pMMUHeap)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: MMUCreate failed"));
+ goto ErrorExit;
+ }
+
+ /* memory is allocated from the OS as required */
+ psBMHeap->pImportArena = RA_Create (psDevMemHeapInfo->pszBSName,
+ 0, 0, IMG_NULL,
+ MAX(HOST_PAGESIZE(), 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)
+ {
+ /*
+ memory comes from a device memory contiguous allocator (ra)
+ Note: these arenas are shared across the system so don't delete
+ as part of heap destroy
+ */
+ psBMHeap->pLocalDevMemArena = psDevMemHeapInfo->psLocalDevMemArena;
+ if(psBMHeap->pLocalDevMemArena == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: LocalDevMemArena null"));
+ goto ErrorExit;
+ }
+ }
+
+ /* insert heap into head of the heap list */
+ List_BM_HEAP_Insert(&pBMContext->psBMHeap, psBMHeap);
+
+ return (IMG_HANDLE)psBMHeap;
+
+ /* handle error case */
+ErrorExit:
+
+ /* Free up the MMU if we created one */
+ if (psBMHeap->pMMUHeap != IMG_NULL)
+ {
+ psDeviceNode->pfnMMUDelete (psBMHeap->pMMUHeap);
+ /* don't finalise psMMUContext as we don't own it */
+ }
+
+ /* Free the Heap memory */
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
+ /*not nulling pointer, out of scope*/
+
+ return IMG_NULL;
+}
+
+/*!
+******************************************************************************
+
+ @Function BM_DestroyHeap
+
+ @Description Destroys a BM heap
+
+ @Return
+ valid heap handle - success
+ IMG_NULL - failure
+
+
+ *****************************************************************************/
+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)
+ {
+ /* Free up the import arenas */
+ 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;
+ }
+
+ /* Free up the MMU Heap */
+ psDeviceNode->pfnMMUDelete (psBMHeap->pMMUHeap);
+
+ /* remove from the heap list */
+ List_BM_HEAP_Remove(psBMHeap);
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
+ }
+ else
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyHeap: invalid heap handle"));
+ }
+}
+
+
+/*!
+******************************************************************************
+
+ @Function BM_Reinitialise
+
+ @Description Reinitialise the buffer manager after a power down event.
+
+ @Return IMG_TRUE - Success
+ IMG_FALSE - Failed
+
+ *****************************************************************************/
+IMG_BOOL
+BM_Reinitialise (PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+
+ PVR_DPF((PVR_DBG_MESSAGE, "BM_Reinitialise"));
+ PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+
+ /* FIXME: Need to reenable all contexts
+ List_BM_CONTEXT_ForEach(psDeviceNode->sDevMemoryInfo.pBMContext, MMU_Enable);
+ */
+
+ return IMG_TRUE;
+}
+
+/*!
+******************************************************************************
+
+ @Function BM_Alloc
+
+ @Description Allocate a buffer mapped into both cpu and device virtual
+ memory maps.
+
+ @Input hDevMemHeap
+ @Input psDevVAddr - device virtual address specified by caller (optional)
+ @Input uSize - require size in bytes of the buffer.
+ @Input pui32Flags - bit mask of buffer property flags.
+ @Input uDevVAddrAlignment - required alignment in bytes, or 0.
+ @Input pvPrivData - opaque private data passed through to allocator
+ @Input ui32PrivDataLength - length of opaque private data
+
+ @Output phBuf - receives buffer handle
+ @Output pui32Flags - bit mask of heap property flags.
+
+ @Return IMG_TRUE - Success
+ IMG_FALSE - Failure
+
+ *****************************************************************************/
+IMG_BOOL
+BM_Alloc ( IMG_HANDLE hDevMemHeap,
+ IMG_DEV_VIRTADDR *psDevVAddr,
+ IMG_SIZE_T uSize,
+ IMG_UINT32 *pui32Flags,
+ IMG_UINT32 uDevVAddrAlignment,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_UINT32 ui32ChunkSize,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_BOOL *pabMapChunk,
+ 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));
+
+ SysAcquireData(&psSysData);
+
+ psBMHeap = (BM_HEAP*)hDevMemHeap;
+ pBMContext = psBMHeap->pBMContext;
+
+ if(uDevVAddrAlignment == 0)
+ {
+ uDevVAddrAlignment = 1;
+ }
+
+ /*
+ * Allocate something in which to record the allocation's details.
+ */
+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof (BM_BUF),
+ (IMG_PVOID *)&pBuf, IMG_NULL,
+ "Buffer Manager buffer") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: BM_Buf alloc FAILED"));
+ return IMG_FALSE;
+ }
+ OSMemSet(pBuf, 0, sizeof (BM_BUF));
+
+ /*
+ * Allocate the memory itself now.
+ */
+ if (AllocMemory(pBMContext,
+ psBMHeap,
+ psDevVAddr,
+ uSize,
+ uFlags,
+ uDevVAddrAlignment,
+ pvPrivData,
+ ui32PrivDataLength,
+ ui32ChunkSize,
+ ui32NumVirtChunks,
+ ui32NumPhysChunks,
+ pabMapChunk,
+ pBuf) != IMG_TRUE)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_BUF), pBuf, IMG_NULL);
+ /* not nulling pointer, out of scope */
+ 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)",
+ uSize, uFlags));
+
+ /*
+ * Assign the handle and return.
+ */
+ pBuf->ui32RefCount = 1;
+ *phBuf = (BM_HANDLE)pBuf;
+ *pui32Flags = uFlags | psBMHeap->ui32Attribs;
+
+ /*
+ * If the user has specified heap CACHETYPE flags themselves,
+ * override any CACHETYPE flags inherited from the heap.
+ */
+ if(uFlags & PVRSRV_HAP_CACHETYPE_MASK)
+ {
+ *pui32Flags &= ~PVRSRV_HAP_CACHETYPE_MASK;
+ *pui32Flags |= (uFlags & PVRSRV_HAP_CACHETYPE_MASK);
+ }
+
+ return IMG_TRUE;
+}
+
+
+
+#if defined(PVR_LMA)
+/*!
+******************************************************************************
+
+ @Function ValidSysPAddrArrayForDev
+
+ @Description Verify the array of system address is accessible
+ by the given device.
+
+ @Input psDeviceNode
+ @Input psSysPAddr - system address array
+ @Input ui32PageSize - size of address array
+
+ @Return IMG_BOOL
+
+ *****************************************************************************/
+static IMG_BOOL
+ValidSysPAddrArrayForDev(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_SYS_PHYADDR *psSysPAddr, IMG_UINT32 ui32PageCount, IMG_SIZE_T 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;
+}
+
+/*!
+******************************************************************************
+
+ @Function ValidSysPAddrRangeForDev
+
+ @Description Verify a system address range is accessible
+ by the given device.
+
+ @Input psDeviceNode
+ @Input sStartSysPAddr - starting system address
+ @Input ui32Range - length of address range
+
+ @Return IMG_BOOL
+
+ *****************************************************************************/
+static IMG_BOOL
+ValidSysPAddrRangeForDev(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_SYS_PHYADDR sStartSysPAddr, IMG_SIZE_T 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
+
+
+/*!
+******************************************************************************
+
+ @Function BM_Wrap
+
+ @Description Create a buffer which wraps user provided system physical
+ memory.
+ The wrapped memory must be page aligned. BM_Wrap will
+ roundup the size to a multiple of cpu pages.
+
+ @Input ui32Size - size of memory to wrap.
+ @Input ui32Offset - Offset into page of memory to wrap.
+ @Input bPhysContig - Is the wrap physically contiguous.
+ @Input psSysAddr - list of system physical page addresses of memory to wrap.
+ @Input pvCPUVAddr - optional CPU kernel virtual address (Page aligned) of memory to wrap.
+ @Input uFlags - bit mask of buffer property flags.
+ @output phBuf - receives the buffer handle.
+
+ @Return IMG_TRUE - Success.
+ IMG_FALSE - Failed
+
+ *****************************************************************************/
+IMG_BOOL
+BM_Wrap ( IMG_HANDLE hDevMemHeap,
+ IMG_SIZE_T ui32Size,
+ IMG_SIZE_T 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 | PVRSRV_HAP_MAPPING_CTRL_MASK);
+
+ if ((pui32Flags != IMG_NULL) && ((*pui32Flags & PVRSRV_HAP_CACHETYPE_MASK) != 0))
+ {
+ uFlags &= ~PVRSRV_HAP_CACHETYPE_MASK;
+ uFlags |= *pui32Flags & PVRSRV_HAP_CACHETYPE_MASK;
+ }
+
+ 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, (IMG_UINTPTR_T)pvCPUVAddr, uFlags));
+
+ SysAcquireData(&psSysData);
+
+#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_SIZE_T 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
+ /*
+ * Insert the System Physical Address of the first page into the hash so we can optimise multiple wraps of the
+ * same memory.
+ */
+ sHashAddress = psSysAddr[0];
+
+ /* Add the in-page offset to ensure a unique hash */
+ sHashAddress.uiAddr += ui32Offset;
+
+ /* See if this address has already been wrapped */
+ pBuf = (BM_BUF *)HASH_Retrieve(psBMContext->pBufferHash, sHashAddress.uiAddr);
+
+ if(pBuf)
+ {
+ IMG_SIZE_T ui32MappingSize = HOST_PAGEALIGN (ui32Size + ui32Offset);
+
+ /* Check base address, size and contiguity type match */
+ 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));
+
+ PVRSRVBMBufIncRef(pBuf);
+ *phBuf = (BM_HANDLE)pBuf;
+ if(pui32Flags)
+ *pui32Flags = uFlags;
+
+ return IMG_TRUE;
+ }
+ else
+ {
+ /* Otherwise removed that item from the hash table
+ (a workaround for buffer device class) */
+ HASH_Remove(psBMContext->pBufferHash, (IMG_UINTPTR_T)sHashAddress.uiAddr);
+ }
+ }
+
+ /*
+ * Allocate something in which to record the allocation's details.
+ */
+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof (BM_BUF),
+ (IMG_PVOID *)&pBuf, IMG_NULL,
+ "Buffer Manager buffer") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: BM_Buf alloc FAILED"));
+ return IMG_FALSE;
+ }
+ OSMemSet(pBuf, 0, sizeof (BM_BUF));
+
+ /*
+ * Actually perform the memory wrap.
+ */
+ 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);
+ /*not nulling pointer, out of scope*/
+ return IMG_FALSE;
+ }
+
+ /* Only insert the buffer in the hash table if it is contiguous - allows for optimisation of multiple wraps
+ * of the same contiguous buffer.
+ */
+ if(pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr)
+ {
+ /* Have we calculated the right Hash key ? */
+ PVR_ASSERT(SysSysPAddrToCpuPAddr(sHashAddress).uiAddr == pBuf->CpuPAddr.uiAddr);
+
+ if (!HASH_Insert (psBMContext->pBufferHash, sHashAddress.uiAddr, (IMG_UINTPTR_T)pBuf))
+ {
+ FreeBuf (pBuf, uFlags, IMG_TRUE);
+ 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, devVAddr=%08X)",
+ ui32Size, uFlags, pBuf->DevVAddr.uiAddr));
+
+ /*
+ * Assign the handle and return.
+ */
+ pBuf->ui32RefCount = 1;
+ *phBuf = (BM_HANDLE)pBuf;
+ if(pui32Flags)
+ {
+ /* need to override the heap attributes SINGLE PROC to MULT_PROC. */
+ *pui32Flags = (uFlags & ~PVRSRV_HAP_MAPTYPE_MASK) | PVRSRV_HAP_MULTI_PROCESS;
+ }
+
+ return IMG_TRUE;
+}
+
+/*!
+******************************************************************************
+
+ @Function BM_Export
+
+ @Description Export a buffer previously allocated via BM_Alloc.
+
+ @Input hBuf - buffer handle.
+ @Input ui32Flags - flags
+
+ @Return None.
+
+ *****************************************************************************/
+
+IMG_VOID
+BM_Export (BM_HANDLE hBuf)
+{
+ BM_BUF *pBuf = (BM_BUF *)hBuf;
+
+ PVRSRVBMBufIncExport(pBuf);
+}
+
+/*!
+******************************************************************************
+ @Function BM_Export
+
+ @Description Export a buffer previously allocated via BM_Alloc.
+
+ @Input hBuf - buffer handle.
+
+ @Return None.
+**************************************************************************/
+IMG_VOID
+BM_FreeExport(BM_HANDLE hBuf,
+ IMG_UINT32 ui32Flags)
+{
+ BM_BUF *pBuf = (BM_BUF *)hBuf;
+
+ PVRSRVBMBufDecExport(pBuf);
+ FreeBuf (pBuf, ui32Flags, IMG_FALSE);
+}
+
+/*!
+******************************************************************************
+ @Function BM_FreeExport
+
+ @Description Free a buffer previously exported via BM_Export.
+
+ @Input hBuf - buffer handle.
+ @Input ui32Flags - flags
+
+ @Return None.
+**************************************************************************/
+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=0x%x)", (IMG_UINTPTR_T)hBuf));
+ PVR_ASSERT (pBuf!=IMG_NULL);
+
+ if (pBuf == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_Free: invalid parameter"));
+ return;
+ }
+
+ SysAcquireData(&psSysData);
+
+ PVRSRVBMBufDecRef(pBuf);
+ 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_TRUE);
+ }
+}
+
+
+/*!
+******************************************************************************
+
+ @Function BM_HandleToCpuVaddr
+
+ @Description Retreive the cpu virtual address associated with a buffer.
+
+ @Input buffer handle.
+
+ @Return buffers cpu virtual address, or NULL if none exists
+
+ *****************************************************************************/
+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=0x%x)=0x%x",
+ (IMG_UINTPTR_T)hBuf, (IMG_UINTPTR_T)pBuf->CpuVAddr));
+ return pBuf->CpuVAddr;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function BM_HandleToDevVaddr
+
+ @Description Retreive the device virtual address associated with a buffer.
+
+ @Input hBuf - buffer handle.
+
+ @Return buffers device virtual address.
+
+ *****************************************************************************/
+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=0x%x)=%08X", (IMG_UINTPTR_T)hBuf, pBuf->DevVAddr.uiAddr));
+ return pBuf->DevVAddr;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function BM_HandleToSysPaddr
+
+ @Description Retreive the system physical address associated with a buffer.
+
+ @Input hBuf - buffer handle.
+
+ @Return buffers device virtual address.
+
+ *****************************************************************************/
+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=0x%x)=%08X", (IMG_UINTPTR_T)hBuf, pBuf->CpuPAddr.uiAddr));
+ return SysCpuPAddrToSysPAddr (pBuf->CpuPAddr);
+}
+
+/*!
+******************************************************************************
+
+ @Function BM_HandleToMemOSHandle
+
+ @Description Retreive the underlying memory handle associated with a buffer.
+
+ @Input hBuf - buffer handle.
+
+ @Return OS Specific memory handle.
+
+ *****************************************************************************/
+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=0x%x)=0x%x",
+ (IMG_UINTPTR_T)hBuf, (IMG_UINTPTR_T)pBuf->hOSMemHandle));
+ return pBuf->hOSMemHandle;
+}
+
+/*----------------------------------------------------------------------------
+<function>
+ FUNCTION: BM_UnmapFromDev
+
+ PURPOSE: Unmaps a buffer from GPU virtual address space, but otherwise
+ leaves buffer intact (ie. not changing any CPU virtual space
+ mappings, etc). This in conjunction with BM_RemapToDev() can
+ be used to migrate buffers in and out of GPU virtual address
+ space to deal with fragmentation and/or limited size of GPU
+ MMU.
+
+ PARAMETERS: In: hBuf - buffer handle.
+ RETURNS: IMG_TRUE - Success
+ IMG_FALSE - Failure
+</function>
+-----------------------------------------------------------------------------*/
+IMG_INT32
+BM_UnmapFromDev(BM_HANDLE hBuf)
+{
+ BM_BUF *pBuf = (BM_BUF *)hBuf;
+ BM_MAPPING *pMapping;
+ IMG_INT32 result;
+
+ PVR_ASSERT (pBuf != IMG_NULL);
+
+ if (pBuf == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_UnmapFromDev: invalid parameter"));
+ return -(PVRSRV_ERROR_INVALID_PARAMS);
+ }
+
+ pMapping = pBuf->pMapping;
+
+ if ((pMapping->ui32Flags & PVRSRV_HAP_GPU_PAGEABLE) == 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_UnmapFromDev: cannot unmap non-pageable buffer"));
+ return -(PVRSRV_ERROR_STILL_MAPPED);
+ }
+
+ result = DevMemoryFree(pMapping);
+
+ if(result == 0)
+ pBuf->DevVAddr.uiAddr = PVRSRV_BAD_DEVICE_ADDRESS;
+
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+<function>
+ FUNCTION: BM_RemapToDev
+
+ PURPOSE: Maps a buffer back into GPU virtual address space, after it
+ has been BM_UnmapFromDev()'d. After this operation, the GPU
+ virtual address may have changed, so BM_HandleToDevVaddr()
+ should be called to get the new address.
+
+ PARAMETERS: In: hBuf - buffer handle.
+ RETURNS: IMG_TRUE - Success
+ IMG_FALSE - Failure
+</function>
+-----------------------------------------------------------------------------*/
+IMG_INT32
+BM_RemapToDev(BM_HANDLE hBuf)
+{
+ BM_BUF *pBuf = (BM_BUF *)hBuf;
+ BM_MAPPING *pMapping;
+ IMG_INT32 mapCount;
+
+ PVR_ASSERT (pBuf != IMG_NULL);
+
+ if (pBuf == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_RemapToDev: invalid parameter"));
+ return -PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ pMapping = pBuf->pMapping;
+
+ if ((pMapping->ui32Flags & PVRSRV_HAP_GPU_PAGEABLE) == 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_RemapToDev: cannot remap non-pageable buffer"));
+ return -PVRSRV_ERROR_BAD_MAPPING;
+ }
+
+ mapCount = DevMemoryAlloc(pMapping->pBMHeap->pBMContext, pMapping, IMG_NULL,
+ pMapping->ui32Flags, pMapping->ui32DevVAddrAlignment, &pBuf->DevVAddr);
+
+ if(mapCount <= 0)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "BM_RemapToDev: failed to allocate device memory"));
+ }
+
+ return mapCount;
+}
+
+/*!
+******************************************************************************
+
+ @Function DevMemoryAlloc
+
+ @Description Allocate device memory for a given physical/virtual memory
+ mapping. We handle the main cases where device MMU mappings
+ are required - these are the dynamic cases: all wrappings of
+ host OS memory and host OS imports for SYS_MMU_NORMAL mode.
+
+ If no MMU support is required then we simply map device virtual
+ space as device physical space.
+
+ @Input pBMContext - the pager to allocate from.
+ @Output pMapping - the mapping descriptor to be filled in for this
+ allocation.
+ @Output pActualSize - the actual size of the block allocated in
+ bytes.
+ @Input uFlags - allocation flags
+ @Input dev_vaddr_alignment - required device virtual address
+ alignment, or 0.
+ @Output pDevVAddr - receives the device virtual base address of the
+ allocated block.
+ @Return IMG_INT32 - Reference count
+ -1 - Failed.
+
+ *****************************************************************************/
+static IMG_INT32
+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 = (IMG_UINT32)pMapping->uSize;
+#endif
+
+ if(pMapping->ui32MappingCount > 0)
+ {
+ pMapping->ui32MappingCount++;
+ *pDevVAddr = pMapping->DevVAddr;
+ return pMapping->ui32MappingCount;
+ }
+
+ psDeviceNode = pBMContext->psDeviceNode;
+
+ pMapping->ui32DevVAddrAlignment = dev_vaddr_alignment;
+
+ if(uFlags & PVRSRV_MEM_INTERLEAVED)
+ {
+ /* double the size */
+ /* don't continue to alter the size each time a buffer is remapped..
+ * we only want to do this the first time
+ */
+ /* TODO: FIXME: There is something wrong with this logic */
+ if (pMapping->ui32MappingCount == 0)
+ pMapping->uSize *= 2;
+ }
+
+#ifdef PDUMP
+ if(uFlags & PVRSRV_MEM_DUMMY)
+ {
+ /* only one page behind a dummy allocation */
+ ui32PDumpSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize;
+ }
+#endif
+
+ /* Check we haven't fall through a gap */
+ PVR_ASSERT(pMapping->uSizeVM != 0);
+ /* allocate device linear space */
+ if (!psDeviceNode->pfnMMUAlloc (pMapping->pBMHeap->pMMUHeap,
+ pMapping->uSizeVM,
+ pActualSize,
+ 0,
+ dev_vaddr_alignment,
+ &(pMapping->DevVAddr)))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DevMemoryAlloc ERROR MMU_Alloc"));
+ pDevVAddr->uiAddr = PVRSRV_BAD_DEVICE_ADDRESS;
+ return -(PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY);
+ }
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+ EnableHostAccess(pBMContext->psMMUContext);
+#endif
+
+#if defined(PDUMP)
+ /* pdump the memory allocate */
+ PDUMPMALLOCPAGES(&psDeviceNode->sDevId,
+ pMapping->DevVAddr.uiAddr,
+ pMapping->CpuVAddr,
+ pMapping->hOSMemHandle,
+ ui32PDumpSize,
+ pMapping->pBMHeap->sDevArena.ui32DataPageSize,
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ psDeviceNode->pfnMMUIsHeapShared(pMapping->pBMHeap->pMMUHeap),
+#else
+ IMG_FALSE, // unused
+#endif /* SUPPORT_PDUMP_MULTI_PROCESS */
+ (IMG_HANDLE)pMapping);
+#endif
+
+ switch (pMapping->eCpuMemoryOrigin)
+ {
+ case hm_wrapped:
+ case hm_wrapped_virtaddr:
+ case hm_contiguous:
+ {
+ if (uFlags & PVRSRV_MEM_SPARSE)
+ {
+ /* Check if this device supports sparse mappings */
+ PVR_ASSERT(psDeviceNode->pfnMMUMapPagesSparse != IMG_NULL);
+ psDeviceNode->pfnMMUMapPagesSparse(pMapping->pBMHeap->pMMUHeap,
+ pMapping->DevVAddr,
+ SysCpuPAddrToSysPAddr (pMapping->CpuPAddr),
+ pMapping->ui32ChunkSize,
+ pMapping->ui32NumVirtChunks,
+ pMapping->ui32NumPhysChunks,
+ pMapping->pabMapChunk,
+ uFlags,
+ (IMG_HANDLE)pMapping);
+ }
+ else
+ {
+ psDeviceNode->pfnMMUMapPages ( pMapping->pBMHeap->pMMUHeap,
+ pMapping->DevVAddr,
+ SysCpuPAddrToSysPAddr (pMapping->CpuPAddr),
+ pMapping->uSize,
+ uFlags,
+ (IMG_HANDLE)pMapping);
+ }
+ *pDevVAddr = pMapping->DevVAddr;
+ break;
+ }
+ case hm_env:
+ {
+ if (uFlags & PVRSRV_MEM_SPARSE)
+ {
+ /* Check if this device supports sparse mappings */
+ PVR_ASSERT(psDeviceNode->pfnMMUMapShadowSparse != IMG_NULL);
+ psDeviceNode->pfnMMUMapShadowSparse(pMapping->pBMHeap->pMMUHeap,
+ pMapping->DevVAddr,
+ pMapping->ui32ChunkSize,
+ pMapping->ui32NumVirtChunks,
+ pMapping->ui32NumPhysChunks,
+ pMapping->pabMapChunk,
+ pMapping->CpuVAddr,
+ pMapping->hOSMemHandle,
+ pDevVAddr,
+ uFlags,
+ (IMG_HANDLE)pMapping);
+ }
+ else
+ {
+ 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 -(PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE);
+ }
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+ DisableHostAccess(pBMContext->psMMUContext);
+#endif
+
+ pMapping->ui32MappingCount = 1;
+
+ return pMapping->ui32MappingCount;
+}
+
+static IMG_INT32
+DevMemoryFree (BM_MAPPING *pMapping)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_DEV_PHYADDR sDevPAddr;
+#ifdef PDUMP
+ IMG_UINT32 ui32PSize;
+#endif
+
+ if(pMapping->ui32MappingCount > 1)
+ {
+ pMapping->ui32MappingCount--;
+
+ /* Nothing else to do for now */
+ return pMapping->ui32MappingCount;
+ }
+
+ if (pMapping->ui32MappingCount == 0)
+ {
+ /* already unmapped from GPU.. bail */
+ return -(PVRSRV_ERROR_MAPPING_NOT_FOUND);
+ }
+
+ /* Then pMapping->ui32MappingCount is 1
+ * ready to release GPU mapping */
+
+ psDeviceNode = pMapping->pBMHeap->pBMContext->psDeviceNode;
+ sDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(pMapping->pBMHeap->pMMUHeap, pMapping->DevVAddr);
+
+ if (sDevPAddr.uiAddr != 0)
+ {
+#ifdef PDUMP
+ /* pdump the memory free */
+ if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
+ {
+ /* physical memory size differs in the case of Dummy allocations */
+ ui32PSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize;
+ }
+ else
+ {
+ ui32PSize = (IMG_UINT32)pMapping->uSize;
+ }
+
+ PDUMPFREEPAGES(pMapping->pBMHeap,
+ pMapping->DevVAddr,
+ ui32PSize,
+ pMapping->pBMHeap->sDevArena.ui32DataPageSize,
+ (IMG_HANDLE)pMapping,
+ (pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) ? IMG_TRUE : IMG_FALSE,
+ (pMapping->ui32Flags & PVRSRV_MEM_SPARSE) ? IMG_TRUE : IMG_FALSE);
+#endif
+ }
+ PVR_ASSERT(pMapping->uSizeVM != 0);
+ psDeviceNode->pfnMMUFree (pMapping->pBMHeap->pMMUHeap, pMapping->DevVAddr, IMG_CAST_TO_DEVVADDR_UINT(pMapping->uSizeVM));
+
+ pMapping->ui32MappingCount = 0;
+
+ return pMapping->ui32MappingCount;
+}
+
+/* If this array grows larger, it might be preferable to use a hashtable rather than an array. */
+#ifndef XPROC_WORKAROUND_NUM_SHAREABLES
+#define XPROC_WORKAROUND_NUM_SHAREABLES 500
+#endif
+
+#define XPROC_WORKAROUND_BAD_SHAREINDEX 0773407734
+
+#define XPROC_WORKAROUND_UNKNOWN 0
+#define XPROC_WORKAROUND_ALLOC 1
+#define XPROC_WORKAROUND_MAP 2
+
+static IMG_UINT32 gXProcWorkaroundShareIndex = XPROC_WORKAROUND_BAD_SHAREINDEX;
+static IMG_UINT32 gXProcWorkaroundState = XPROC_WORKAROUND_UNKNOWN;
+
+/* PRQA S 0686 10 */ /* force compiler to init structure */
+XPROC_DATA gXProcWorkaroundShareData[XPROC_WORKAROUND_NUM_SHAREABLES] = {{0}};
+
+IMG_INT32 BM_XProcGetShareDataRefCount(IMG_UINT32 ui32Index)
+{
+ if(ui32Index >= XPROC_WORKAROUND_NUM_SHAREABLES)
+ return -1;
+
+ return gXProcWorkaroundShareData[ui32Index].ui32RefCount;
+}
+
+PVRSRV_ERROR BM_XProcWorkaroundSetShareIndex(IMG_UINT32 ui32Index)
+{
+ /* if you fail this assertion - did you acquire the mutex?
+ did you call "set" exactly once?
+ did you call "unset" exactly once per set?
+ */
+ if (gXProcWorkaroundShareIndex != XPROC_WORKAROUND_BAD_SHAREINDEX)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "No, it's already set!"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ gXProcWorkaroundShareIndex = ui32Index;
+ gXProcWorkaroundState = XPROC_WORKAROUND_MAP;
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR BM_XProcWorkaroundUnsetShareIndex(IMG_UINT32 ui32Index)
+{
+ /* if you fail this assertion - did you acquire the mutex?
+ did you call "set" exactly once?
+ did you call "unset" exactly once per set?
+ */
+ if (gXProcWorkaroundShareIndex == XPROC_WORKAROUND_BAD_SHAREINDEX)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "huh? how can it be bad??"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ if (gXProcWorkaroundShareIndex != ui32Index)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "gXProcWorkaroundShareIndex == 0x%08x != 0x%08x == ui32Index", gXProcWorkaroundShareIndex, ui32Index));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ gXProcWorkaroundShareIndex = XPROC_WORKAROUND_BAD_SHAREINDEX;
+ gXProcWorkaroundState = XPROC_WORKAROUND_UNKNOWN;
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR BM_XProcWorkaroundFindNewBufferAndSetShareIndex(IMG_UINT32 *pui32Index)
+{
+ /* if you fail this assertion - did you acquire the mutex?
+ did you call "set" exactly once?
+ did you call "unset" exactly once per set?
+ */
+ if (gXProcWorkaroundShareIndex != XPROC_WORKAROUND_BAD_SHAREINDEX)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ for (*pui32Index = 0; *pui32Index < XPROC_WORKAROUND_NUM_SHAREABLES; (*pui32Index)++)
+ {
+ if (gXProcWorkaroundShareData[*pui32Index].ui32RefCount == 0)
+ {
+ gXProcWorkaroundShareIndex = *pui32Index;
+ gXProcWorkaroundState = XPROC_WORKAROUND_ALLOC;
+ return PVRSRV_OK;
+ }
+ }
+
+ PVR_DPF((PVR_DBG_ERROR, "ran out of shared buffers"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+}
+
+static PVRSRV_ERROR
+XProcWorkaroundAllocShareable(RA_ARENA *psArena,
+ IMG_UINT32 ui32AllocFlags,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32PageSize,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_VOID **ppvCpuVAddr,
+ IMG_HANDLE *phOSMemHandle)
+{
+ if ((ui32AllocFlags & PVRSRV_MEM_XPROC) == 0)
+ {
+ PVR_DPF((PVR_DBG_VERBOSE, "XProcWorkaroundAllocShareable: bad flags"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if (gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32RefCount > 0)
+ {
+ PVR_DPF((PVR_DBG_VERBOSE,
+ "XProcWorkaroundAllocShareable: re-using previously allocated pages"));
+
+ ui32AllocFlags &= ~PVRSRV_HAP_MAPTYPE_MASK;
+ ui32AllocFlags |= PVRSRV_HAP_SINGLE_PROCESS;
+
+ if (ui32AllocFlags != gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32AllocFlags)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s ERROR: Flags don't match (Shared 0x%08x, Requested 0x%08x)!",
+ __FUNCTION__,
+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32AllocFlags,
+ ui32AllocFlags));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if (ui32Size != gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32Size)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s ERROR: Size doesn't match (Shared %d, Requested %d) with flags 0x%08x - 0x%08x!",
+ __FUNCTION__,
+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32Size,
+ ui32Size,
+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32AllocFlags,
+ ui32AllocFlags));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if (ui32PageSize != gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32PageSize)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s ERROR: Page Size doesn't match (Shared %d, Requested %d) with flags 0x%08x - 0x%08x!",
+ __FUNCTION__,
+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32PageSize,
+ ui32PageSize,
+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32AllocFlags,
+ ui32AllocFlags));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ *ppvCpuVAddr = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr;
+ *phOSMemHandle = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle;
+
+ BM_XProcIndexAcquire(gXProcWorkaroundShareIndex);
+
+ return PVRSRV_OK;
+ }
+ else
+ {
+ if (gXProcWorkaroundState != XPROC_WORKAROUND_ALLOC)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "XPROC workaround in bad state! About to allocate memory from non-alloc state! (%d)",
+ gXProcWorkaroundState));
+ }
+ PVR_ASSERT(gXProcWorkaroundState == XPROC_WORKAROUND_ALLOC);
+
+ if (psArena != IMG_NULL)
+ {
+ IMG_CPU_PHYADDR sCpuPAddr;
+ IMG_SYS_PHYADDR sSysPAddr;
+
+ PVR_DPF((PVR_DBG_VERBOSE,
+ "XProcWorkaroundAllocShareable: making a NEW allocation from local mem"));
+
+ if (!RA_Alloc (psArena,
+ ui32Size,
+ IMG_NULL,
+ IMG_NULL,
+ 0,
+ ui32PageSize,
+ 0,
+ pvPrivData,
+ ui32PrivDataLength,
+ (IMG_UINTPTR_T *)&sSysPAddr.uiAddr))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "XProcWorkaroundAllocShareable: RA_Alloc(0x%x) FAILED", ui32Size));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+ if(OSReservePhys(sCpuPAddr,
+ ui32Size,
+ ui32AllocFlags,
+ IMG_NULL,
+ (IMG_VOID **)&gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr,
+ &gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "XProcWorkaroundAllocShareable: OSReservePhys failed"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].sSysPAddr = sSysPAddr;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_VERBOSE,
+ "XProcWorkaroundAllocShareable: making a NEW allocation from OS"));
+
+ ui32AllocFlags &= ~PVRSRV_HAP_MAPTYPE_MASK;
+ ui32AllocFlags |= PVRSRV_HAP_SINGLE_PROCESS;
+
+ /* allocate pages from the OS RAM */
+ if (OSAllocPages(ui32AllocFlags,
+ ui32Size,
+ ui32PageSize,
+ pvPrivData,
+ ui32PrivDataLength,
+ IMG_NULL, /* FIXME: to support cross process sparse allocations */
+ (IMG_VOID **)&gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr,
+ &gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "XProcWorkaroundAllocShareable: OSAllocPages(0x%x) failed",
+ ui32PageSize));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ }
+
+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].psArena = psArena;
+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32AllocFlags = ui32AllocFlags;
+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32Size = ui32Size;
+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32PageSize = ui32PageSize;
+
+ *ppvCpuVAddr = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr;
+ *phOSMemHandle = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle;
+
+ BM_XProcIndexAcquire(gXProcWorkaroundShareIndex);
+
+ return PVRSRV_OK;
+ }
+}
+
+static PVRSRV_ERROR XProcWorkaroundHandleToSI(IMG_HANDLE hOSMemHandle, IMG_UINT32 *pui32SI)
+{
+ IMG_UINT32 ui32SI;
+ IMG_BOOL bFound;
+ IMG_BOOL bErrorDups;
+
+ bFound = IMG_FALSE;
+ bErrorDups = IMG_FALSE;
+
+ for (ui32SI = 0; ui32SI < XPROC_WORKAROUND_NUM_SHAREABLES; ui32SI++)
+ {
+ if (gXProcWorkaroundShareData[ui32SI].ui32RefCount>0 && gXProcWorkaroundShareData[ui32SI].hOSMemHandle == hOSMemHandle)
+ {
+ if (bFound)
+ {
+ bErrorDups = IMG_TRUE;
+ }
+ else
+ {
+ *pui32SI = ui32SI;
+ bFound = IMG_TRUE;
+ }
+ }
+ }
+
+ if (bErrorDups || !bFound)
+ {
+ return PVRSRV_ERROR_BM_BAD_SHAREMEM_HANDLE;
+ }
+
+ return PVRSRV_OK;
+}
+
+#if defined(PVRSRV_REFCOUNT_DEBUG)
+IMG_VOID _BM_XProcIndexAcquireDebug(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index)
+#else
+IMG_VOID _BM_XProcIndexAcquire(IMG_UINT32 ui32Index)
+#endif
+{
+#if defined(PVRSRV_REFCOUNT_DEBUG)
+ PVRSRVBMXProcIncRef2(pszFile, iLine, ui32Index);
+#else
+ PVRSRVBMXProcIncRef(ui32Index);
+#endif
+}
+
+#if defined(PVRSRV_REFCOUNT_DEBUG)
+IMG_VOID _BM_XProcIndexReleaseDebug(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index)
+#else
+IMG_VOID _BM_XProcIndexRelease(IMG_UINT32 ui32Index)
+#endif
+{
+#if defined(PVRSRV_REFCOUNT_DEBUG)
+ PVRSRVBMXProcDecRef2(pszFile, iLine, ui32Index);
+#else
+ PVRSRVBMXProcDecRef(ui32Index);
+#endif
+
+ PVR_DPF((PVR_DBG_VERBOSE, "Reduced refcount of SI[%d] from %d to %d",
+ ui32Index, gXProcWorkaroundShareData[ui32Index].ui32RefCount+1, gXProcWorkaroundShareData[ui32Index].ui32RefCount));
+
+ if (gXProcWorkaroundShareData[ui32Index].ui32RefCount == 0)
+ {
+ if (gXProcWorkaroundShareData[ui32Index].psArena != IMG_NULL)
+ {
+ IMG_SYS_PHYADDR sSysPAddr;
+
+ if (gXProcWorkaroundShareData[ui32Index].pvCpuVAddr != IMG_NULL)
+ {
+ OSUnReservePhys(gXProcWorkaroundShareData[ui32Index].pvCpuVAddr,
+ gXProcWorkaroundShareData[ui32Index].ui32Size,
+ gXProcWorkaroundShareData[ui32Index].ui32AllocFlags,
+ gXProcWorkaroundShareData[ui32Index].hOSMemHandle);
+ }
+ sSysPAddr = gXProcWorkaroundShareData[ui32Index].sSysPAddr;
+ RA_Free (gXProcWorkaroundShareData[ui32Index].psArena,
+ sSysPAddr.uiAddr,
+ IMG_FALSE);
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_VERBOSE, "freeing OS memory"));
+ OSFreePages(gXProcWorkaroundShareData[ui32Index].ui32AllocFlags,
+ gXProcWorkaroundShareData[ui32Index].ui32PageSize,
+ gXProcWorkaroundShareData[ui32Index].pvCpuVAddr,
+ gXProcWorkaroundShareData[ui32Index].hOSMemHandle);
+ }
+ }
+}
+
+static IMG_VOID XProcWorkaroundFreeShareable(IMG_HANDLE hOSMemHandle)
+{
+ IMG_UINT32 ui32SI = (IMG_UINT32)((IMG_UINTPTR_T)hOSMemHandle & 0xffffU);
+ PVRSRV_ERROR eError;
+
+ eError = XProcWorkaroundHandleToSI(hOSMemHandle, &ui32SI);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "bad handle"));
+ return;
+ }
+
+ BM_XProcIndexRelease(ui32SI);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function BM_ImportMemory
+
+ @Description Provide a resource allocator with a source of pages of memory
+ from the Host OS's own allocation. Allocates a block of pages
+ larger than requested, allowing the resource allocator to
+ operate a small cache of pre allocated pages.
+
+ @Input pH - buffer manager handle, not the void type is dictated
+ by the generic nature of the resource allocator interface.
+ @Input uRequestSize - requested size in bytes
+ @Output pActualSize - receives the actual size allocated in bytes
+ which may be >= requested size
+ @Output ppsMapping - receives the arbitrary user reference
+ associated with the underlying storage.
+ @Input uFlags - bit mask of allocation flags
+ @Input pvPrivData - opaque private data passed through to allocator
+ @Input ui32PrivDataLength - length of opaque private data
+ @Output pBase - receives a pointer to the allocated storage.
+
+ @Return IMG_TRUE - success
+ IMG_FALSE - failed
+
+ *****************************************************************************/
+static IMG_BOOL
+BM_ImportMemory (IMG_VOID *pH,
+ IMG_SIZE_T uRequestSize,
+ IMG_SIZE_T *pActualSize,
+ BM_MAPPING **ppsMapping,
+ IMG_UINT32 uFlags,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_UINTPTR_T *pBase)
+{
+ BM_MAPPING *pMapping;
+ BM_HEAP *pBMHeap = pH;
+ BM_CONTEXT *pBMContext = pBMHeap->pBMContext;
+ IMG_INT32 uResult;
+ IMG_SIZE_T uSize;
+ IMG_SIZE_T uPSize;
+ IMG_SIZE_T uDevVAddrAlignment = 0; /* ? */
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "BM_ImportMemory (pBMContext=0x%x, uRequestSize=0x%x, uFlags=0x%x, uAlign=0x%x)",
+ (IMG_UINTPTR_T)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,
+ "Buffer Manager Mapping") != 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->ui32MappingCount = 0;
+ pMapping->CpuPAddr.uiAddr = 0;
+ pMapping->uSize = uSize;
+ if ((uFlags & PVRSRV_MEM_SPARSE) == 0)
+ {
+ pMapping->uSizeVM = uSize;
+ }
+ pMapping->pBMHeap = pBMHeap;
+ pMapping->ui32Flags = uFlags;
+
+ /*
+ * If anyone want's to know, pass back the actual size of our allocation.
+ * There could be up to an extra page's worth of memory which will be marked
+ * as free in the RA.
+ */
+ if (pActualSize)
+ {
+ *pActualSize = uSize;
+ }
+
+ /* if it's a dummy allocation only use one physical page */
+ if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
+ {
+ uPSize = pBMHeap->sDevArena.ui32DataPageSize;
+ }
+ else
+ {
+ uPSize = pMapping->uSize;
+ }
+
+ if (uFlags & PVRSRV_MEM_XPROC)
+ {
+ IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs | PVRSRV_MEM_XPROC;
+ IMG_BOOL bBadBackingStoreType;
+
+ if(uFlags & PVRSRV_MEM_ION)
+ {
+ ui32Attribs |= PVRSRV_MEM_ION;
+ }
+
+ bBadBackingStoreType = IMG_TRUE;
+
+ if ((ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG) != 0)
+ {
+ uDevVAddrAlignment = MAX(pBMHeap->sDevArena.ui32DataPageSize, HOST_PAGESIZE());
+
+
+ if (uPSize % uDevVAddrAlignment != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Cannot use use this memory sharing workaround with allocations that might be suballocated"));
+ goto fail_mapping_alloc;
+ }
+ uDevVAddrAlignment = 0; /* FIXME: find out why it doesn't work if alignment is specified */
+
+ /* If the user has specified heap CACHETYPE flags, use them to
+ * override the flags inherited from the heap.
+ */
+ if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
+ {
+ ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
+ ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
+ }
+
+ /* allocate "shared" pages. */
+ if (XProcWorkaroundAllocShareable(IMG_NULL,
+ ui32Attribs,
+ (IMG_UINT32)uPSize,
+ pBMHeap->sDevArena.ui32DataPageSize,
+ pvPrivData,
+ ui32PrivDataLength,
+ (IMG_VOID **)&pMapping->CpuVAddr,
+ &pMapping->hOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "BM_ImportMemory: XProcWorkaroundAllocShareable(0x%x) failed",
+ uPSize));
+ goto fail_mapping_alloc;
+ }
+
+ /* specify how page addresses are derived */
+ /* it works just like "env" now - no need to record
+ it as shareable, as we use the actual hOSMemHandle
+ and only divert to our wrapper layer based on Attribs */
+ pMapping->eCpuMemoryOrigin = hm_env;
+ bBadBackingStoreType = IMG_FALSE;
+ }
+
+ if ((ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG) != 0)
+ {
+ uDevVAddrAlignment = pBMHeap->sDevArena.ui32DataPageSize;
+
+ if (uPSize % uDevVAddrAlignment != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Cannot use use this memory sharing workaround with allocations that might be suballocated"));
+ goto fail_mapping_alloc;
+ }
+ uDevVAddrAlignment = 0; /* FIXME: find out why it doesn't work if alignment is specified */
+
+ /* If the user has specified heap CACHETYPE flags, use them to
+ * override the flags inherited from the heap.
+ */
+ if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
+ {
+ ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
+ ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
+ }
+
+ /* allocate "shared" pages. */
+ if (XProcWorkaroundAllocShareable(pBMHeap->pLocalDevMemArena,
+ ui32Attribs,
+ (IMG_UINT32)uPSize,
+ pBMHeap->sDevArena.ui32DataPageSize,
+ pvPrivData,
+ ui32PrivDataLength,
+ (IMG_VOID **)&pMapping->CpuVAddr,
+ &pMapping->hOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "BM_ImportMemory: XProcWorkaroundAllocShareable(0x%x) failed",
+ uPSize));
+ goto fail_mapping_alloc;
+ }
+
+ /* specify how page addresses are derived */
+ /* it works just like "env" now - no need to record
+ it as shareable, as we use the actual hOSMemHandle
+ and only divert to our wrapper layer based on Attribs */
+ pMapping->eCpuMemoryOrigin = hm_env;
+ bBadBackingStoreType = IMG_FALSE;
+ }
+
+ if (bBadBackingStoreType)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Cannot use this memory sharing workaround with this type of backing store"));
+ goto fail_mapping_alloc;
+ }
+ }
+ else
+
+ /*
+ What type of backing store do we have?
+ */
+ if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG)
+ {
+ IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs;
+
+ /* The allocation code needs to know this is a sparse mapping */
+ if (pMapping->ui32Flags & PVRSRV_MEM_SPARSE)
+ {
+ ui32Attribs |= PVRSRV_MEM_SPARSE;
+ }
+
+ /* If the user has specified heap CACHETYPE flags, use them to
+ * override the flags inherited from the heap.
+ */
+ if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
+ {
+ ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
+ ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
+ }
+
+ if (pMapping->ui32Flags & PVRSRV_MEM_ALLOCATENONCACHEDMEM)
+ {
+ ui32Attribs &= ~PVRSRV_MEM_ALLOCATENONCACHEDMEM;
+ ui32Attribs |= (pMapping->ui32Flags & PVRSRV_MEM_ALLOCATENONCACHEDMEM);
+ }
+
+ /* allocate pages from the OS RAM */
+ if (OSAllocPages(ui32Attribs,
+ uPSize,
+ pBMHeap->sDevArena.ui32DataPageSize,
+ pvPrivData,
+ ui32PrivDataLength,
+ pMapping,
+ (IMG_VOID **)&pMapping->CpuVAddr,
+ &pMapping->hOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "BM_ImportMemory: OSAllocPages(0x%x) failed",
+ uPSize));
+ goto fail_mapping_alloc;
+ }
+
+ /* specify how page addresses are derived */
+ pMapping->eCpuMemoryOrigin = hm_env;
+ }
+ else if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)
+ {
+ IMG_SYS_PHYADDR sSysPAddr;
+ IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs;
+
+ /* The allocation code needs to know this is a sparse mapping */
+ if (pMapping->ui32Flags & PVRSRV_MEM_SPARSE)
+ {
+ ui32Attribs |= PVRSRV_MEM_SPARSE;
+ }
+
+ /* allocate pages from the local device memory allocator */
+ PVR_ASSERT(pBMHeap->pLocalDevMemArena != IMG_NULL);
+
+ /* If the user has specified heap CACHETYPE flags, use them to
+ * override the flags inherited from the heap.
+ */
+ if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
+ {
+ ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
+ ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
+ }
+
+ if (!RA_Alloc (pBMHeap->pLocalDevMemArena,
+ uPSize,
+ IMG_NULL,
+ IMG_NULL,
+ 0,
+ pBMHeap->sDevArena.ui32DataPageSize,
+ 0,
+ pvPrivData,
+ ui32PrivDataLength,
+ (IMG_UINTPTR_T *)&sSysPAddr.uiAddr))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: RA_Alloc(0x%x) FAILED", uPSize));
+ goto fail_mapping_alloc;
+ }
+
+ /* derive the CPU virtual address */
+ pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+ if(OSReservePhys(pMapping->CpuPAddr,
+ uPSize,
+ ui32Attribs,
+ pMapping,
+ &pMapping->CpuVAddr,
+ &pMapping->hOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: OSReservePhys failed"));
+ goto fail_dev_mem_alloc;
+ }
+
+ /* specify how page addresses are derived */
+ pMapping->eCpuMemoryOrigin = hm_contiguous;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: Invalid backing store type"));
+ goto fail_mapping_alloc;
+ }
+
+ if(uFlags & PVRSRV_MEM_ION)
+ {
+ IMG_UINT32 ui32AddressOffsets[PVRSRV_MAX_NUMBER_OF_MM_BUFFER_PLANES];
+ IMG_UINT32 ui32NumAddrOffsets = PVRSRV_MAX_NUMBER_OF_MM_BUFFER_PLANES;
+
+ IMG_INT32 retSize = OSGetMemMultiPlaneInfo(pMapping->hOSMemHandle,
+ ui32AddressOffsets, &ui32NumAddrOffsets);
+
+ if(retSize > 0 && pActualSize)
+ {
+ *pActualSize = pMapping->uSize = retSize;
+ }
+ }
+
+ /*
+ * Allocate some device memory for what we just allocated.
+ */
+ /*
+ * Do not allocate GPU mapping if NO_GPU_VIRTUAL_ON_ALLOC is requested.
+ * In the case where CBI is enabled, this allows for late
+ * GPU mapping. This flag is, otherwise, used in cases where only
+ * the memory management feature of the driver is utilized, without
+ * a need for GPU rendering
+ */
+ if ((uFlags & (PVRSRV_MEM_SPARSE | PVRSRV_HAP_NO_GPU_VIRTUAL_ON_ALLOC)) == 0)
+ {
+ uResult = DevMemoryAlloc (pBMContext,
+ pMapping,
+ IMG_NULL,
+ uFlags,
+ (IMG_UINT32)uDevVAddrAlignment,
+ &pMapping->DevVAddr);
+ if (uResult <= 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "BM_ImportMemory: DevMemoryAlloc(0x%x) failed",
+ pMapping->uSize));
+ goto fail_dev_mem_alloc;
+ }
+
+ /* uDevVAddrAlignment is currently set to zero so QAC generates warning which we override */
+ /* PRQA S 3356,3358 1 */
+ PVR_ASSERT (uDevVAddrAlignment>1?(pMapping->DevVAddr.uiAddr%uDevVAddrAlignment)==0:1);
+ PVR_ASSERT(pBase);
+ }
+
+ if(pBase)
+ *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))
+ {
+ /* the size is double the actual size for interleaved allocations */
+ if(pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED)
+ {
+ pMapping->uSize /= 2;
+ }
+
+ if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
+ {
+ uPSize = pBMHeap->sDevArena.ui32DataPageSize;
+ }
+ else
+ {
+ uPSize = pMapping->uSize;
+ }
+
+ if (uFlags & PVRSRV_MEM_XPROC)
+ {
+ XProcWorkaroundFreeShareable(pMapping->hOSMemHandle);
+ }
+ else
+ 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);
+ /*not nulling pointer, out of scope*/
+fail_exit:
+ return IMG_FALSE;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function BM_FreeMemory
+
+ @Description Free a block of pages previously allocated via
+ BM_ImportMemory.
+
+ @Input h - buffer manager handle, not the void type as dictated by
+ the generic nature of the resource allocator interface.
+ @Input _base - base address of blocks to free.
+ @Input psMapping - arbitrary user reference associated with the
+ underlying storage provided by BM_ImportMemory
+ @Return None
+
+ *****************************************************************************/
+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=0x%x, base=0x%x, psMapping=0x%x)",
+ (IMG_UINTPTR_T)h, _base, (IMG_UINTPTR_T)psMapping));
+
+ PVR_ASSERT (psMapping != IMG_NULL);
+
+ if (psMapping == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BM_FreeMemory: invalid parameter"));
+ return;
+ }
+
+ /*
+ Only free the virtual memory if we got as far a allocating it.
+ This NULL check should be safe as we always have a guard page
+ at virtual address 0x00000000
+ */
+ if (psMapping->DevVAddr.uiAddr)
+ {
+ DevMemoryFree (psMapping);
+ }
+
+ /* the size is double the actual for interleaved */
+ 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 (psMapping->ui32Flags & PVRSRV_MEM_XPROC)
+ {
+ XProcWorkaroundFreeShareable(psMapping->hOSMemHandle);
+ }
+ else
+ 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);
+ /*not nulling pointer, copy on stack*/
+
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "..BM_FreeMemory (h=0x%x, base=0x%x)",
+ (IMG_UINTPTR_T)h, _base));
+}
+
+/*!
+******************************************************************************
+
+ @Function BM_GetPhysPageAddr
+
+ @Description
+
+ @Input psMemInfo
+
+ @Input sDevVPageAddr
+
+ @Output psDevPAddr
+
+ @Return IMG_VOID
+
+******************************************************************************/
+
+IMG_VOID 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"));
+
+ PVR_ASSERT(psMemInfo && psDevPAddr);
+
+ /* check it's a page address */
+ PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
+
+ /* PRQA S 0505 4 */ /* PVR_ASSERT should catch NULL ptrs */
+ psDeviceNode = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->pBMContext->psDeviceNode;
+
+ *psDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->pMMUHeap,
+ sDevVPageAddr);
+}
+
+
+/*!
+******************************************************************************
+ @Function BM_GetMMUContext
+
+ @Description utility function to return the MMU context
+
+ @Input hDevMemHeap - the Dev mem heap handle
+
+ @Return MMU context, else NULL
+**************************************************************************/
+MMU_CONTEXT* BM_GetMMUContext(IMG_HANDLE hDevMemHeap)
+{
+ BM_HEAP *pBMHeap = (BM_HEAP*)hDevMemHeap;
+
+ PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMMUContext"));
+
+ return pBMHeap->pBMContext->psMMUContext;
+}
+
+/*!
+******************************************************************************
+ @Function BM_GetMMUContextFromMemContext
+
+ @Description utility function to return the MMU context
+
+ @Input hDevMemContext - the Dev mem context handle
+
+ @Return MMU context, else NULL
+**************************************************************************/
+MMU_CONTEXT* BM_GetMMUContextFromMemContext(IMG_HANDLE hDevMemContext)
+{
+ BM_CONTEXT *pBMContext = (BM_CONTEXT*)hDevMemContext;
+
+ PVR_DPF ((PVR_DBG_VERBOSE, "BM_GetMMUContextFromMemContext"));
+
+ return pBMContext->psMMUContext;
+}
+
+/*!
+******************************************************************************
+ @Function BM_GetMMUHeap
+
+ @Description utility function to return the MMU heap handle
+
+ @Input hDevMemHeap - the Dev mem heap handle
+
+ @Return MMU heap handle, else NULL
+**************************************************************************/
+IMG_HANDLE BM_GetMMUHeap(IMG_HANDLE hDevMemHeap)
+{
+ PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMMUHeap"));
+
+ return (IMG_HANDLE)((BM_HEAP*)hDevMemHeap)->pMMUHeap;
+}
+
+
+/*!
+******************************************************************************
+ @Function BM_GetDeviceNode
+
+ @Description utility function to return the devicenode from the BM Context
+
+ @Input hDevMemContext - the Dev Mem Context
+
+ @Return MMU heap handle, else NULL
+**************************************************************************/
+PVRSRV_DEVICE_NODE* BM_GetDeviceNode(IMG_HANDLE hDevMemContext)
+{
+ PVR_DPF((PVR_DBG_VERBOSE, "BM_GetDeviceNode"));
+
+ return ((BM_CONTEXT*)hDevMemContext)->psDeviceNode;
+}
+
+
+/*!
+******************************************************************************
+ @Function BM_GetMappingHandle
+
+ @Description utility function to return the mapping handle from a meminfo
+
+ @Input psMemInfo - kernel meminfo
+
+ @Return mapping handle, else NULL
+**************************************************************************/
+IMG_HANDLE BM_GetMappingHandle(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+ PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMappingHandle"));
+
+ return ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->hOSMemHandle;
+}
+
+/*!
+******************************************************************************
+ @Function BM_MappingHandleFromBuffer
+
+ @Description utility function to get the BM mapping handle from a BM buffer
+
+ @Input hBuffer - Handle to BM buffer
+
+ @Return BM mapping handle
+**************************************************************************/
+IMG_HANDLE BM_MappingHandleFromBuffer(IMG_HANDLE hBuffer)
+{
+ BM_BUF *psBuffer;
+
+ PVR_ASSERT(hBuffer != IMG_NULL);
+ psBuffer = hBuffer;
+ return psBuffer->pMapping;
+}
+
+/*!
+******************************************************************************
+ @Function BM_GetVirtualSize
+
+ @Description utility function to get the VM size of a BM mapping
+
+ @Input hBMHandle - Handle to BM mapping
+
+ @Return VM size of mapping
+**************************************************************************/
+IMG_UINT32 BM_GetVirtualSize(IMG_HANDLE hBMHandle)
+{
+ BM_MAPPING *psMapping;
+
+ PVR_ASSERT(hBMHandle != IMG_NULL);
+ psMapping = hBMHandle;
+ return psMapping->ui32ChunkSize * psMapping->ui32NumVirtChunks;
+}
+
+/*!
+******************************************************************************
+ @Function BM_MapPageAtOffset
+
+ @Description utility function check if the specificed offset in a BM mapping
+ is a page that needs tp be mapped
+
+ @Input hBMHandle - Handle to BM mapping
+
+ @Input ui32Offset - Offset into allocation
+
+ @Return IMG_TRUE if the page should be mapped
+**************************************************************************/
+IMG_BOOL BM_MapPageAtOffset(IMG_HANDLE hBMHandle, IMG_UINT32 ui32Offset)
+{
+ BM_MAPPING *psMapping;
+ IMG_UINT32 ui32ChunkIndex;
+
+ PVR_ASSERT(hBMHandle != IMG_NULL);
+ psMapping = hBMHandle;
+
+ ui32ChunkIndex = ui32Offset / psMapping->ui32ChunkSize;
+ /* Check for overrun */
+ PVR_ASSERT(ui32ChunkIndex <= psMapping->ui32NumVirtChunks);
+ return psMapping->pabMapChunk[ui32ChunkIndex];
+}
+
+/*!
+******************************************************************************
+ @Function BM_VirtOffsetToPhyscial
+
+ @Description utility function find of physical offset of a sparse allocation
+ from it's virtual offset.
+
+ @Input hBMHandle - Handle to BM mapping
+
+ @Input ui32VirtOffset - Virtual offset into allocation
+
+ @Output pui32PhysOffset - Physical offset
+
+ @Return IMG_TRUE if the virtual offset is physically backed
+**************************************************************************/
+IMG_BOOL BM_VirtOffsetToPhysical(IMG_HANDLE hBMHandle,
+ IMG_UINT32 ui32VirtOffset,
+ IMG_UINT32 *pui32PhysOffset)
+{
+ BM_MAPPING *psMapping;
+ IMG_UINT32 ui32ChunkOffset;
+ IMG_UINT32 ui32PhysOffset = 0;
+ IMG_UINT32 i;
+
+ PVR_ASSERT(hBMHandle != IMG_NULL);
+ psMapping = hBMHandle;
+
+ ui32ChunkOffset = ui32VirtOffset / psMapping->ui32ChunkSize;
+ if (!psMapping->pabMapChunk[ui32ChunkOffset])
+ {
+ return IMG_FALSE;
+ }
+
+ for (i=0;i<ui32ChunkOffset;i++)
+ {
+ if (psMapping->pabMapChunk[i])
+ {
+ ui32PhysOffset += psMapping->ui32ChunkSize;
+ }
+ }
+ *pui32PhysOffset = ui32PhysOffset;
+
+ return IMG_TRUE;
+}
+/******************************************************************************
+ End of file (buffer_manager.c)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/common/deviceclass.c b/pvr-source/services4/srvkm/common/deviceclass.c
new file mode 100644
index 0000000..d047c78
--- /dev/null
+++ b/pvr-source/services4/srvkm/common/deviceclass.c
@@ -0,0 +1,2863 @@
+/*************************************************************************/ /*!
+@Title Device class services functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Kernel services functions for device class devices
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "services_headers.h"
+#include "buffer_manager.h"
+#include "kernelbuffer.h"
+#include "kerneldisplay.h"
+#include "pvr_bridge_km.h"
+#include "pdump_km.h"
+#include "deviceid.h"
+
+#include "lists.h"
+#if defined(CONFIG_GCBV)
+#include "gc_bvmapping.h"
+#endif
+
+PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID);
+PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID);
+
+#if defined(SUPPORT_MISR_IN_THREAD)
+void OSVSyncMISR(IMG_HANDLE, IMG_BOOL);
+#endif
+
+#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
+IMG_VOID PVRSRVFreeCommandCompletePacketKM(IMG_HANDLE hCmdCookie,
+ IMG_BOOL bScheduleMISR);
+#endif
+/***********************************************************************
+ Local Display Class Structures
+************************************************************************/
+typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG *PPVRSRV_DC_SRV2DISP_KMJTABLE;
+
+/*
+ Display Class Buffer Info
+*/
+typedef struct PVRSRV_DC_BUFFER_TAG
+{
+ /* BC/DC common details - THIS MUST BE THE FIRST MEMBER */
+ PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer;
+
+ struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo;
+ struct PVRSRV_DC_SWAPCHAIN_TAG *psSwapChain;
+} PVRSRV_DC_BUFFER;
+
+/*
+ Display Device Class kernel swapchain information structure
+*/
+typedef struct PVRSRV_DC_SWAPCHAIN_TAG
+{
+ IMG_HANDLE hExtSwapChain;
+ IMG_UINT32 ui32SwapChainID;
+ IMG_UINT32 ui32RefCount;
+ IMG_UINT32 ui32Flags;
+ PVRSRV_QUEUE_INFO *psQueue;
+ PVRSRV_DC_BUFFER asBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
+ IMG_UINT32 ui32BufferCount;
+ PVRSRV_DC_BUFFER *psLastFlipBuffer;
+ IMG_UINT32 ui32MinSwapInterval;
+ IMG_UINT32 ui32MaxSwapInterval;
+#if !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED)
+ PVRSRV_KERNEL_SYNC_INFO **ppsLastSyncInfos;
+ IMG_UINT32 ui32LastNumSyncInfos;
+#endif /* !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) */
+ struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo;
+ struct PVRSRV_DC_SWAPCHAIN_TAG *psNext;
+} PVRSRV_DC_SWAPCHAIN;
+
+
+/*
+ Display Device Class kernel swapchain referecne structure
+*/
+typedef struct PVRSRV_DC_SWAPCHAIN_REF_TAG
+{
+ struct PVRSRV_DC_SWAPCHAIN_TAG *psSwapChain;
+ IMG_HANDLE hResItem;
+} PVRSRV_DC_SWAPCHAIN_REF;
+
+
+/*
+ Display Device Class kernel services information structure
+*/
+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;
+ struct PVRSRV_DC_SWAPCHAIN_TAG *psDCSwapChainShared;
+} PVRSRV_DISPLAYCLASS_INFO;
+
+
+/*
+ Per-context Display Device Class kernel services information structure
+*/
+typedef struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO_TAG
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PRESMAN_ITEM hResItem;
+} PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO;
+
+
+/***********************************************************************
+ Local Buffer Class Structures
+************************************************************************/
+typedef struct PVRSRV_BC_SRV2BUFFER_KMJTABLE_TAG *PPVRSRV_BC_SRV2BUFFER_KMJTABLE;
+
+/*
+ Buffer Class Buffer Info
+*/
+typedef struct PVRSRV_BC_BUFFER_TAG
+{
+ /* BC/DC common details - THIS MUST BE THE FIRST MEMBER */
+ PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer;
+
+ struct PVRSRV_BUFFERCLASS_INFO_TAG *psBCInfo;
+} PVRSRV_BC_BUFFER;
+
+
+/*
+ Buffer Device Class kernel services information structure
+*/
+typedef struct PVRSRV_BUFFERCLASS_INFO_TAG
+{
+ IMG_UINT32 ui32RefCount;
+ IMG_UINT32 ui32DeviceID;
+ IMG_HANDLE hExtDevice;
+ PPVRSRV_BC_SRV2BUFFER_KMJTABLE psFuncTable;
+ IMG_HANDLE hDevMemContext;
+ /* buffer info returned from 3rd party driver */
+ IMG_UINT32 ui32BufferCount;
+ PVRSRV_BC_BUFFER *psBuffer;
+
+} PVRSRV_BUFFERCLASS_INFO;
+
+
+/*
+ Per-context Buffer Device Class kernel services information structure
+*/
+typedef struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO_TAG
+{
+ PVRSRV_BUFFERCLASS_INFO *psBCInfo;
+ IMG_HANDLE hResItem;
+} PVRSRV_BUFFERCLASS_PERCONTEXT_INFO;
+
+
+/*!
+******************************************************************************
+ @Function DCDeviceHandleToDCInfo
+
+ @Description
+
+ Convert a client-visible 3rd party device class handle to an internal
+ PVRSRV_DISPLAYCLASS_INFO pointer.
+
+ @Input hDeviceKM - handle to display class device, returned from OpenDCDevice
+
+ @Return
+ success: pointer to PVRSRV_DISPLAYCLASS_INFO
+ failure: IMG_NULL
+******************************************************************************/
+static PVRSRV_DISPLAYCLASS_INFO* DCDeviceHandleToDCInfo (IMG_HANDLE hDeviceKM)
+{
+ PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
+
+ psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)hDeviceKM;
+
+ return psDCPerContextInfo->psDCInfo;
+}
+
+
+/*!
+******************************************************************************
+ @Function BCDeviceHandleToBCInfo
+
+ @Description
+
+ Convert a client-visible 3rd party buffer class handle to an internal
+ PVRSRV_BUFFERCLASS_INFO pointer.
+
+ @Input hDeviceKM - handle to buffer class device, returned from OpenBCDevice
+
+ @Return
+ success: pointer to PVRSRV_BUFFERCLASS_INFO
+ failure: IMG_NULL
+******************************************************************************/
+static PVRSRV_BUFFERCLASS_INFO* BCDeviceHandleToBCInfo (IMG_HANDLE hDeviceKM)
+{
+ PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
+
+ psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)hDeviceKM;
+
+ return psBCPerContextInfo->psBCInfo;
+}
+
+/*!
+******************************************************************************
+ @Function PVRSRVEnumerateDCKM_ForEachVaCb
+
+ @Description
+
+ Enumerates the device node (if is of the same class as given).
+
+ @Input psDeviceNode - The device node to be enumerated
+ va - variable arguments list, with:
+ pui32DevCount - The device count pointer (to be increased)
+ ppui32DevID - The pointer to the device IDs pointer (to be updated and increased)
+ peDeviceClass - The pointer to the device class of the psDeviceNode's to be enumerated.
+******************************************************************************/
+static IMG_VOID PVRSRVEnumerateDCKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+ IMG_UINT *pui32DevCount;
+ IMG_UINT32 **ppui32DevID;
+ PVRSRV_DEVICE_CLASS peDeviceClass;
+
+ pui32DevCount = va_arg(va, IMG_UINT*);
+ ppui32DevID = va_arg(va, IMG_UINT32**);
+ peDeviceClass = va_arg(va, PVRSRV_DEVICE_CLASS);
+
+ if ((psDeviceNode->sDevId.eDeviceClass == peDeviceClass)
+ && (psDeviceNode->sDevId.eDeviceType == PVRSRV_DEVICE_TYPE_EXT))
+ {
+ (*pui32DevCount)++;
+ if(*ppui32DevID)
+ {
+ *(*ppui32DevID)++ = psDeviceNode->sDevId.ui32DeviceIndex;
+ }
+ }
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVEnumerateDCKM
+
+ @Description
+
+ Enumerates devices available in a given class.
+ On first call, pass valid ptr for pui32DevCount and IMG_NULL for pui32DevID,
+ On second call, pass same ptr for pui32DevCount and client allocated ptr
+ for pui32DevID device id list
+
+ @Input hServices - handle for services connection
+ @Input ui32DevClass - device class identifier
+ @Output pui32DevCount - number of devices available in class
+ @Output pui32DevID - list of device ids in the device class
+
+ @Return
+ success: handle to matching display class device
+ failure: IMG_NULL
+
+******************************************************************************/
+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;
+
+ SysAcquireData(&psSysData);
+
+ /* search devonode list for devices in specified class and return the device ids */
+ List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
+ &PVRSRVEnumerateDCKM_ForEachVaCb,
+ &ui32DevCount,
+ &pui32DevID,
+ DeviceClass);
+
+ 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;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVRegisterDCDeviceKM
+
+ @Description
+
+ registers an external device with the system
+
+ @Input psFuncTable : device function table
+
+ @Output pui32DeviceID : unique device key (for case of multiple identical devices)
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+static
+PVRSRV_ERROR PVRSRVRegisterDCDeviceKM (PVRSRV_DC_SRV2DISP_KMJTABLE *psFuncTable,
+ IMG_UINT32 *pui32DeviceID)
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo = IMG_NULL;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ SYS_DATA *psSysData;
+
+ /*
+ IN:
+ - name of client side ext. device driver library for subsequent loading
+ - predefined list of callbacks into kernel ext. device driver (based on class type)
+
+ FUNCTION TASKS:
+ - allocate display device class info structure
+ - hang ext.device kernel callbacks on this structure (pfnKSwapToSystem)
+
+ OUT:
+ - DEVICE_ID
+ - pass back devinfo? no
+
+ Q&A:
+ - DEVICE_ID passed in or allocated - assume allocate
+ */
+
+ SysAcquireData(&psSysData);
+
+ /*
+ If we got this far we're doing dynamic enumeration
+ or first time static registration
+ */
+
+ /* Allocate device control block */
+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(*psDCInfo),
+ (IMG_VOID **)&psDCInfo, IMG_NULL,
+ "Display Class Info") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psDCInfo alloc"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ OSMemSet (psDCInfo, 0, sizeof(*psDCInfo));
+
+ /* setup the display device information structure */
+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE),
+ (IMG_VOID **)&psDCInfo->psFuncTable, IMG_NULL,
+ "Function table for SRVKM->DISPLAY") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psFuncTable alloc"));
+ goto ErrorExit;
+ }
+ OSMemSet (psDCInfo->psFuncTable, 0, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE));
+
+ /* copy the jump table */
+ *psDCInfo->psFuncTable = *psFuncTable;
+
+ /* Allocate device node */
+ if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_DEVICE_NODE),
+ (IMG_VOID **)&psDeviceNode, IMG_NULL,
+ "Device Node") != 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;
+
+ /* allocate a unique device id */
+ if (AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed to allocate Device ID"));
+ goto ErrorExit;
+ }
+ psDCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
+ if (pui32DeviceID)
+ {
+ *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
+ }
+
+ /* Register the device with the system */
+ SysRegisterExternalDevice(psDeviceNode);
+
+ /* and finally insert the device into the dev-list */
+ List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
+
+ return PVRSRV_OK;
+
+ErrorExit:
+
+ if(psDCInfo->psFuncTable)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), psDCInfo->psFuncTable, IMG_NULL);
+ psDCInfo->psFuncTable = IMG_NULL;
+ }
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO), psDCInfo, IMG_NULL);
+ /*not nulling pointer, out of scope*/
+
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVRemoveDCDeviceKM
+
+ @Description
+
+ Removes external device from services system record
+
+ @Input ui32DeviceIndex : unique device key (for case of multiple identical devices)
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+static PVRSRV_ERROR PVRSRVRemoveDCDeviceKM(IMG_UINT32 ui32DevIndex)
+{
+ SYS_DATA *psSysData;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+
+ SysAcquireData(&psSysData);
+
+ /*search the node matching the devindex and display class*/
+ psDeviceNode = (PVRSRV_DEVICE_NODE*)
+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+ &MatchDeviceKM_AnyVaCb,
+ ui32DevIndex,
+ IMG_FALSE,
+ PVRSRV_DEVICE_CLASS_DISPLAY);
+ if (!psDeviceNode)
+ {
+ /*device not found*/
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: requested device %d not present", ui32DevIndex));
+ return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
+ }
+
+ /* setup DCInfo ptr */
+ psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice;
+
+ /*
+ The device can only be removed if there are
+ no open connections in the Services interface
+ */
+ if(psDCInfo->ui32RefCount == 0)
+ {
+ /*
+ Remove from the device list.
+ */
+ List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode);
+
+ /* Unregister the device with the system */
+ SysRemoveExternalDevice(psDeviceNode);
+
+ /*
+ OK found a device with a matching devindex
+ remove registration information
+ */
+ PVR_ASSERT(psDCInfo->ui32RefCount == 0);
+ (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
+ (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), psDCInfo->psFuncTable, IMG_NULL);
+ psDCInfo->psFuncTable = IMG_NULL;
+ (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO), psDCInfo, IMG_NULL);
+ /*not nulling original pointer, overwritten*/
+ (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
+ /*not nulling pointer, out of scope*/
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: failed as %d Services DC API connections are still open", psDCInfo->ui32RefCount));
+ return PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVRegisterBCDeviceKM
+
+ @Description
+
+ registers an external device with the system
+
+ @Input psFuncTable : device function table
+ @Input ui32DeviceIndex : unique device key (for case of multiple identical devices)
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+static
+PVRSRV_ERROR PVRSRVRegisterBCDeviceKM (PVRSRV_BC_SRV2BUFFER_KMJTABLE *psFuncTable,
+ IMG_UINT32 *pui32DeviceID)
+{
+ PVRSRV_BUFFERCLASS_INFO *psBCInfo = IMG_NULL;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ SYS_DATA *psSysData;
+ /*
+ IN:
+ - name of client side ext. device driver library for subsequent loading
+ - predefined list of callbacks into kernel ext. device driver (based on class type)
+
+ FUNCTION TASKS:
+ - allocate buffer device class info structure
+
+ OUT:
+ - DEVICE_ID
+ - pass back devinfo? no
+
+ Q&A:
+ - DEVICE_ID passed in or allocated - assume allcoate
+ */
+
+ SysAcquireData(&psSysData);
+
+ /*
+ If we got this far we're doing dynamic enumeration
+ or first time static registration
+ */
+
+ /* Allocate device control block */
+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(*psBCInfo),
+ (IMG_VOID **)&psBCInfo, IMG_NULL,
+ "Buffer Class Info") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psBCInfo alloc"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ OSMemSet (psBCInfo, 0, sizeof(*psBCInfo));
+
+ /* setup the buffer device information structure */
+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE),
+ (IMG_VOID **)&psBCInfo->psFuncTable, IMG_NULL,
+ "Function table for SRVKM->BUFFER") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psFuncTable alloc"));
+ goto ErrorExit;
+ }
+ OSMemSet (psBCInfo->psFuncTable, 0, sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE));
+
+ /* copy the jump table */
+ *psBCInfo->psFuncTable = *psFuncTable;
+
+ /* Allocate device node */
+ if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_DEVICE_NODE),
+ (IMG_VOID **)&psDeviceNode, IMG_NULL,
+ "Device Node") != 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;
+
+ /* allocate a unique device id */
+ if (AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed to allocate Device ID"));
+ goto ErrorExit;
+ }
+ psBCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
+ if (pui32DeviceID)
+ {
+ *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex;
+ }
+
+ /* and finally insert the device into the dev-list */
+ List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
+
+ return PVRSRV_OK;
+
+ErrorExit:
+
+ if(psBCInfo->psFuncTable)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PPVRSRV_BC_SRV2BUFFER_KMJTABLE), psBCInfo->psFuncTable, IMG_NULL);
+ psBCInfo->psFuncTable = IMG_NULL;
+ }
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO), psBCInfo, IMG_NULL);
+ /*not nulling shared pointer, wasn't allocated to this point*/
+
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVRemoveBCDeviceKM
+
+ @Description
+
+ Removes external device from services system record
+
+ @Input ui32DeviceIndex : unique device key (for case of multiple identical devices)
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+static PVRSRV_ERROR PVRSRVRemoveBCDeviceKM(IMG_UINT32 ui32DevIndex)
+{
+ SYS_DATA *psSysData;
+ PVRSRV_DEVICE_NODE *psDevNode;
+ PVRSRV_BUFFERCLASS_INFO *psBCInfo;
+
+ SysAcquireData(&psSysData);
+
+ /*search the device node with the devindex and buffer class*/
+ psDevNode = (PVRSRV_DEVICE_NODE*)
+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+ &MatchDeviceKM_AnyVaCb,
+ ui32DevIndex,
+ IMG_FALSE,
+ PVRSRV_DEVICE_CLASS_BUFFER);
+
+ if (!psDevNode)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: requested device %d not present", ui32DevIndex));
+ return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
+ }
+
+ /* set-up devnode ptr */
+/* psDevNode = *(ppsDevNode); */
+ /* setup BCInfo ptr */
+ psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDevNode->pvDevice;
+
+ /*
+ The device can only be removed if there are
+ no open connections in the Services interface
+ */
+ if(psBCInfo->ui32RefCount == 0)
+ {
+ /*
+ Remove from the device list.
+ */
+ List_PVRSRV_DEVICE_NODE_Remove(psDevNode);
+
+ /*
+ OK found a device with a matching devindex
+ remove registration information
+ */
+ (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
+ (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE), psBCInfo->psFuncTable, IMG_NULL);
+ psBCInfo->psFuncTable = IMG_NULL;
+ (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO), psBCInfo, IMG_NULL);
+ /*not nulling pointer, copy on stack*/
+ (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDevNode, IMG_NULL);
+ /*not nulling pointer, out of scope*/
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: failed as %d Services BC API connections are still open", psBCInfo->ui32RefCount));
+ return PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVCloseDCDeviceKM
+
+ @Description
+
+ Closes a connection to the Display Class device
+
+ @Input hDeviceKM : device handle
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVCloseDCDeviceKM (IMG_HANDLE hDeviceKM)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
+
+ psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)hDeviceKM;
+
+ /* Remove the item from the resman list and trigger the callback. */
+ eError = ResManFreeResByPtr(psDCPerContextInfo->hResItem, CLEANUP_WITH_POLL);
+
+ return eError;
+}
+
+
+static PVRSRV_ERROR CloseDCDeviceCallBack(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)pvParam;
+ psDCInfo = psDCPerContextInfo->psDCInfo;
+
+ if(psDCInfo->sSystemBuffer.sDeviceClassBuffer.ui32MemMapRefCount != 0)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,"CloseDCDeviceCallBack: system buffer (0x%p) still mapped (refcount = %d)",
+ &psDCInfo->sSystemBuffer.sDeviceClassBuffer,
+ psDCInfo->sSystemBuffer.sDeviceClassBuffer.ui32MemMapRefCount));
+ }
+
+ psDCInfo->ui32RefCount--;
+ if(psDCInfo->ui32RefCount == 0)
+ {
+ /* close the external device */
+ psDCInfo->psFuncTable->pfnCloseDCDevice(psDCInfo->hExtDevice);
+
+ PVRSRVKernelSyncInfoDecRef(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
+
+ psDCInfo->hDevMemContext = IMG_NULL;
+ psDCInfo->hExtDevice = IMG_NULL;
+ }
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO), psDCPerContextInfo, IMG_NULL);
+ /*not nulling pointer, copy on stack*/
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVOpenDCDeviceKM
+
+ @Description
+
+ Opens a connection to the Display Class device, associating the connection
+ with a Device Memory Context for a services managed device
+
+ @Input psPerProc : Per-process data
+ @Input ui32DeviceID : unique device index
+ @Input hDevCookie : devcookie used to derive the Device Memory
+ Context into BC surfaces will be mapped into
+ @Outut phDeviceKM : handle to the DC device
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+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;
+ PVRSRV_ERROR eError;
+
+ if(!phDeviceKM || !hDevCookie)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Invalid params"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ SysAcquireData(&psSysData);
+
+ /* find the matching devicenode */
+ psDeviceNode = (PVRSRV_DEVICE_NODE*)
+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+ &MatchDeviceKM_AnyVaCb,
+ ui32DeviceID,
+ IMG_FALSE,
+ PVRSRV_DEVICE_CLASS_DISPLAY);
+ if (!psDeviceNode)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: no devnode matching index %d", ui32DeviceID));
+ return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
+ }
+ psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice;
+
+ /*
+ Allocate the per-context DC Info before calling the external device,
+ to make error handling easier.
+ */
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(*psDCPerContextInfo),
+ (IMG_VOID **)&psDCPerContextInfo, IMG_NULL,
+ "Display Class per Context Info") != 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)
+ {
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
+
+ /* store the device kernel context to map into */
+ psDCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext;
+
+ /* create a syncinfo for the device's system surface */
+ 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;
+ }
+
+ /* open the external device */
+ 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--;
+ PVRSRVKernelSyncInfoDecRef(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
+ return eError;
+ }
+
+ psDCPerContextInfo->psDCInfo = psDCInfo;
+ eError = PVRSRVGetDCSystemBufferKM(psDCPerContextInfo, IMG_NULL);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed to get system buffer"));
+ psDCInfo->ui32RefCount--;
+ PVRSRVKernelSyncInfoDecRef(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
+ return eError;
+ }
+ psDCInfo->sSystemBuffer.sDeviceClassBuffer.ui32MemMapRefCount = 0;
+ }
+ else
+ {
+ psDCPerContextInfo->psDCInfo = psDCInfo;
+ }
+
+ psDCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_DISPLAYCLASS_DEVICE,
+ psDCPerContextInfo,
+ 0,
+ &CloseDCDeviceCallBack);
+
+ /* return a reference to the DCPerContextInfo */
+ *phDeviceKM = (IMG_HANDLE)psDCPerContextInfo;
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVEnumDCFormatsKM
+
+ @Description
+
+ Enumerates the devices pixel formats
+
+ @Input hDeviceKM : device handle
+ @Output pui32Count : number of pixel formats
+ @Output psFormat : format list
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+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);
+
+ /* call into the display device driver to get info */
+ return psDCInfo->psFuncTable->pfnEnumDCFormats(psDCInfo->hExtDevice, pui32Count, psFormat);
+}
+
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVEnumDCDimsKM
+
+ @Description
+
+ Enumerates the devices mode dimensions for a given pixel format
+
+ @Input hDeviceKM : device handle
+ @Input psFormat : pixel format
+ @Output pui32Count : number of dimensions
+ @Output psDim : dimensions list
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+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) // psDim==NULL to query number of dims
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumDCDimsKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+
+ /* call into the display device driver to get info */
+ return psDCInfo->psFuncTable->pfnEnumDCDims(psDCInfo->hExtDevice, psFormat, pui32Count, psDim);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVGetDCSystemBufferKM
+
+ @Description
+
+ Get the primary surface and optionally return its buffer handle
+
+ @Input hDeviceKM : device handle
+ @Output phBuffer : Optional buffer handle
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVGetDCSystemBufferKM (IMG_HANDLE hDeviceKM,
+ IMG_HANDLE *phBuffer)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ IMG_HANDLE hExtBuffer;
+
+ if(!hDeviceKM)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCSystemBufferKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+
+ /* call into the display device driver to get info */
+ 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;
+ }
+
+ /* save the new info */
+ 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;
+
+ /* return handle */
+ if (phBuffer)
+ {
+ *phBuffer = (IMG_HANDLE)&(psDCInfo->sSystemBuffer);
+ }
+
+ return PVRSRV_OK;
+}
+
+
+/******************************************************************************
+
+ @Function PVRSRVGetDCInfoKM
+
+ @Description
+
+ Gets Display Class device Info
+
+ @Input hDeviceKM : device handle
+ @Output psDisplayInfo
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+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);
+
+ /* call into the display device driver to get info */
+ 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 hSwapChainRef)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef;
+
+ if(!hSwapChainRef)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyDCSwapChainKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psSwapChainRef = hSwapChainRef;
+
+ eError = ResManFreeResByPtr(psSwapChainRef->hResItem, CLEANUP_WITH_POLL);
+
+ return eError;
+}
+
+
+static PVRSRV_ERROR DestroyDCSwapChain(PVRSRV_DC_SWAPCHAIN *psSwapChain)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo = psSwapChain->psDCInfo;
+ IMG_UINT32 i;
+
+ /* Update shared swapchains list */
+ if( psDCInfo->psDCSwapChainShared )
+ {
+ if( psDCInfo->psDCSwapChainShared == psSwapChain )
+ {
+ psDCInfo->psDCSwapChainShared = psSwapChain->psNext;
+ }
+ else
+ {
+ PVRSRV_DC_SWAPCHAIN *psCurrentSwapChain;
+ psCurrentSwapChain = psDCInfo->psDCSwapChainShared;
+ while( psCurrentSwapChain->psNext )
+ {
+ if( psCurrentSwapChain->psNext != psSwapChain )
+ {
+ psCurrentSwapChain = psCurrentSwapChain->psNext;
+ continue;
+ }
+ psCurrentSwapChain->psNext = psSwapChain->psNext;
+ break;
+ }
+ }
+ }
+
+ /* Destroy command queue before swapchain - it may use the swapchain when commands are flushed. */
+ PVRSRVDestroyCommandQueueKM(psSwapChain->psQueue);
+
+ /* call into the display device driver to destroy a swapchain */
+ 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;
+ }
+
+ /* free the resources */
+ for(i=0; i<psSwapChain->ui32BufferCount; i++)
+ {
+ if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoDecRef(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
+ }
+ }
+
+#if !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED)
+ if (psSwapChain->ppsLastSyncInfos)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_SYNC_INFO *) * psSwapChain->ui32LastNumSyncInfos,
+ psSwapChain->ppsLastSyncInfos, IMG_NULL);
+ }
+#endif /* !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) */
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN), psSwapChain, IMG_NULL);
+ /*not nulling pointer, copy on stack*/
+
+ return eError;
+}
+
+
+static PVRSRV_ERROR DestroyDCSwapChainRefCallBack(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = (PVRSRV_DC_SWAPCHAIN_REF *) pvParam;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ IMG_UINT32 i;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ for (i = 0; i < psSwapChainRef->psSwapChain->ui32BufferCount; i++)
+ {
+ if (psSwapChainRef->psSwapChain->asBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DestroyDCSwapChainRefCallBack: swapchain (0x%p) still mapped (ui32MemMapRefCount = %d)",
+ &psSwapChainRef->psSwapChain->asBuffer[i].sDeviceClassBuffer,
+ psSwapChainRef->psSwapChain->asBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount));
+ }
+ }
+
+ if(--psSwapChainRef->psSwapChain->ui32RefCount == 0)
+ {
+ eError = DestroyDCSwapChain(psSwapChainRef->psSwapChain);
+ }
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN_REF), psSwapChainRef, IMG_NULL);
+ return eError;
+}
+
+static PVRSRV_DC_SWAPCHAIN* PVRSRVFindSharedDCSwapChainKM(PVRSRV_DISPLAYCLASS_INFO *psDCInfo,
+ IMG_UINT32 ui32SwapChainID)
+{
+ PVRSRV_DC_SWAPCHAIN *psCurrentSwapChain;
+
+ for(psCurrentSwapChain = psDCInfo->psDCSwapChainShared;
+ psCurrentSwapChain;
+ psCurrentSwapChain = psCurrentSwapChain->psNext)
+ {
+ if(psCurrentSwapChain->ui32SwapChainID == ui32SwapChainID)
+ return psCurrentSwapChain;
+ }
+ return IMG_NULL;
+}
+
+static PVRSRV_ERROR PVRSRVCreateDCSwapChainRefKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ PVRSRV_DC_SWAPCHAIN *psSwapChain,
+ PVRSRV_DC_SWAPCHAIN_REF **ppsSwapChainRef)
+{
+ PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = IMG_NULL;
+
+ /* Allocate swapchain reference structre*/
+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_DC_SWAPCHAIN_REF),
+ (IMG_VOID **)&psSwapChainRef, IMG_NULL,
+ "Display Class Swapchain Reference") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainRefKM: Failed psSwapChainRef alloc"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ OSMemSet (psSwapChainRef, 0, sizeof(PVRSRV_DC_SWAPCHAIN_REF));
+
+ /* Bump refcount */
+ psSwapChain->ui32RefCount++;
+
+ /* Create reference resource */
+ psSwapChainRef->psSwapChain = psSwapChain;
+ psSwapChainRef->hResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF,
+ psSwapChainRef,
+ 0,
+ &DestroyDCSwapChainRefCallBack);
+ *ppsSwapChainRef = psSwapChainRef;
+
+ return PVRSRV_OK;
+}
+
+
+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 *phSwapChainRef,
+ IMG_UINT32 *pui32SwapChainID)
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PVRSRV_DC_SWAPCHAIN *psSwapChain = IMG_NULL;
+ PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = IMG_NULL;
+ PVRSRV_SYNC_DATA *apsSyncData[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
+ PVRSRV_QUEUE_INFO *psQueue = IMG_NULL;
+ PVRSRV_ERROR eError;
+ IMG_UINT32 i;
+ DISPLAY_INFO sDisplayInfo;
+
+
+ if(!hDeviceKM
+ || !psDstSurfAttrib
+ || !psSrcSurfAttrib
+ || !phSwapChainRef
+ || !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( ui32Flags & PVRSRV_CREATE_SWAPCHAIN_QUERY )
+ {
+ /* Query - use pui32SwapChainID as input */
+ psSwapChain = PVRSRVFindSharedDCSwapChainKM(psDCInfo, *pui32SwapChainID );
+ if( psSwapChain )
+ {
+ /* Create new reference */
+ eError = PVRSRVCreateDCSwapChainRefKM(psPerProc,
+ psSwapChain,
+ &psSwapChainRef);
+ if( eError != PVRSRV_OK )
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Couldn't create swap chain reference"));
+ return eError;
+ }
+
+ *phSwapChainRef = (IMG_HANDLE)psSwapChainRef;
+ return PVRSRV_OK;
+ }
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: No shared SwapChain found for query"));
+ return PVRSRV_ERROR_FLIP_CHAIN_EXISTS;
+ }
+
+ /* Allocate swapchain control structure for srvkm */
+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_DC_SWAPCHAIN),
+ (IMG_VOID **)&psSwapChain, IMG_NULL,
+ "Display Class Swapchain") != 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));
+
+ /* Create a command queue for the swapchain */
+ eError = PVRSRVCreateCommandQueueKM(1024, &psQueue);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to create CmdQueue"));
+ goto ErrorExit;
+ }
+
+ /* store the Queue */
+ psSwapChain->psQueue = psQueue;
+
+ /* Create a Sync Object for each surface in the swapchain */
+ 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;
+ }
+
+ /* setup common device class info */
+ psSwapChain->asBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr;
+ psSwapChain->asBuffer[i].sDeviceClassBuffer.hDevMemContext = psDCInfo->hDevMemContext;
+ psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtDevice = psDCInfo->hExtDevice;
+
+ /* save off useful ptrs */
+ psSwapChain->asBuffer[i].psDCInfo = psDCInfo;
+ psSwapChain->asBuffer[i].psSwapChain = psSwapChain;
+
+ /* syncinfos must be passed as array of syncdata ptrs to the 3rd party driver */
+ apsSyncData[i] = (PVRSRV_SYNC_DATA*)psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM;
+ }
+
+ psSwapChain->ui32BufferCount = ui32BufferCount;
+ psSwapChain->psDCInfo = psDCInfo;
+
+#if defined(PDUMP)
+ PDUMPCOMMENT("Allocate DC swap chain (SwapChainID == %u, BufferCount == %u)",
+ *pui32SwapChainID,
+ ui32BufferCount);
+ PDUMPCOMMENT(" Src surface dimensions == %u x %u",
+ psSrcSurfAttrib->sDims.ui32Width,
+ psSrcSurfAttrib->sDims.ui32Height);
+ PDUMPCOMMENT(" Dst surface dimensions == %u x %u",
+ psDstSurfAttrib->sDims.ui32Width,
+ psDstSurfAttrib->sDims.ui32Height);
+#endif
+
+ eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice, &sDisplayInfo);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to get DC info"));
+ return eError;
+ }
+
+ psSwapChain->ui32MinSwapInterval = sDisplayInfo.ui32MinSwapInterval;
+ psSwapChain->ui32MaxSwapInterval = sDisplayInfo.ui32MaxSwapInterval;
+
+ /* call into the display device driver to create a swapchain */
+ eError = psDCInfo->psFuncTable->pfnCreateDCSwapChain(psDCInfo->hExtDevice,
+ ui32Flags,
+ psDstSurfAttrib,
+ psSrcSurfAttrib,
+ ui32BufferCount,
+ apsSyncData,
+ ui32OEMFlags,
+ &psSwapChain->hExtSwapChain,
+ &psSwapChain->ui32SwapChainID);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to create 3rd party SwapChain"));
+ PDUMPCOMMENT("Swapchain allocation failed.");
+ goto ErrorExit;
+ }
+
+ /* Create new reference */
+ eError = PVRSRVCreateDCSwapChainRefKM(psPerProc,
+ psSwapChain,
+ &psSwapChainRef);
+ if( eError != PVRSRV_OK )
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Couldn't create swap chain reference"));
+ PDUMPCOMMENT("Swapchain allocation failed.");
+ goto ErrorExit;
+ }
+
+ psSwapChain->ui32RefCount = 1;
+ psSwapChain->ui32Flags = ui32Flags;
+
+ /* Save pointer in DC structure if ti's shared struct */
+ if( ui32Flags & PVRSRV_CREATE_SWAPCHAIN_SHARED )
+ {
+ if(! psDCInfo->psDCSwapChainShared )
+ {
+ psDCInfo->psDCSwapChainShared = psSwapChain;
+ }
+ else
+ {
+ PVRSRV_DC_SWAPCHAIN *psOldHead = psDCInfo->psDCSwapChainShared;
+ psDCInfo->psDCSwapChainShared = psSwapChain;
+ psSwapChain->psNext = psOldHead;
+ }
+ }
+
+ /* We create swapchain - pui32SwapChainID is output */
+ *pui32SwapChainID = psSwapChain->ui32SwapChainID;
+
+ /* return the swapchain reference handle */
+ *phSwapChainRef= (IMG_HANDLE)psSwapChainRef;
+
+ return eError;
+
+ErrorExit:
+
+ for(i=0; i<ui32BufferCount; i++)
+ {
+ if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoDecRef(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
+ }
+ }
+
+ if(psQueue)
+ {
+ PVRSRVDestroyCommandQueueKM(psQueue);
+ }
+
+ if(psSwapChain)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN), psSwapChain, IMG_NULL);
+ /*not nulling pointer, out of scope*/
+ }
+
+ return eError;
+}
+
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetDCDstRectKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hSwapChainRef,
+ IMG_RECT *psRect)
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PVRSRV_DC_SWAPCHAIN *psSwapChain;
+
+ if(!hDeviceKM || !hSwapChainRef)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstRectKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+ psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
+
+ return psDCInfo->psFuncTable->pfnSetDCDstRect(psDCInfo->hExtDevice,
+ psSwapChain->hExtSwapChain,
+ psRect);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetDCSrcRectKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hSwapChainRef,
+ IMG_RECT *psRect)
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PVRSRV_DC_SWAPCHAIN *psSwapChain;
+
+ if(!hDeviceKM || !hSwapChainRef)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCSrcRectKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+ psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
+
+ return psDCInfo->psFuncTable->pfnSetDCSrcRect(psDCInfo->hExtDevice,
+ psSwapChain->hExtSwapChain,
+ psRect);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetDCDstColourKeyKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hSwapChainRef,
+ IMG_UINT32 ui32CKColour)
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PVRSRV_DC_SWAPCHAIN *psSwapChain;
+
+ if(!hDeviceKM || !hSwapChainRef)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstColourKeyKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+ psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
+
+ return psDCInfo->psFuncTable->pfnSetDCDstColourKey(psDCInfo->hExtDevice,
+ psSwapChain->hExtSwapChain,
+ ui32CKColour);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hSwapChainRef,
+ IMG_UINT32 ui32CKColour)
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PVRSRV_DC_SWAPCHAIN *psSwapChain;
+
+ if(!hDeviceKM || !hSwapChainRef)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCSrcColourKeyKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+ psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
+
+ return psDCInfo->psFuncTable->pfnSetDCSrcColourKey(psDCInfo->hExtDevice,
+ psSwapChain->hExtSwapChain,
+ ui32CKColour);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVGetDCBuffersKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hSwapChainRef,
+ IMG_UINT32 *pui32BufferCount,
+ IMG_HANDLE *phBuffer,
+ IMG_SYS_PHYADDR *psPhyAddr)
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PVRSRV_DC_SWAPCHAIN *psSwapChain;
+ IMG_HANDLE ahExtBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
+ PVRSRV_ERROR eError;
+ IMG_UINT32 i;
+
+ if(!hDeviceKM || !hSwapChainRef || !phBuffer || !psPhyAddr)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCBuffersKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+ psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain;
+
+ /* call into the display device driver to get info */
+ eError = psDCInfo->psFuncTable->pfnGetDCBuffers(psDCInfo->hExtDevice,
+ psSwapChain->hExtSwapChain,
+ pui32BufferCount,
+ ahExtBuffer);
+
+ PVR_ASSERT(*pui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);
+
+ /*
+ populate the srvkm's buffer structure with the 3rd party buffer handles
+ and return the services buffer handles
+ */
+ for(i=0; i<*pui32BufferCount; i++)
+ {
+ psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtBuffer = ahExtBuffer[i];
+ phBuffer[i] = (IMG_HANDLE)&psSwapChain->asBuffer[i];
+ }
+
+#if defined(SUPPORT_GET_DC_BUFFERS_SYS_PHYADDRS)
+ for(i = 0; i < *pui32BufferCount; i++)
+ {
+ IMG_UINT32 ui32ByteSize, ui32TilingStride;
+ IMG_SYS_PHYADDR *pPhyAddr;
+ IMG_BOOL bIsContiguous;
+ IMG_HANDLE hOSMapInfo;
+ IMG_VOID *pvVAddr;
+
+ eError = psDCInfo->psFuncTable->pfnGetBufferAddr(psDCInfo->hExtDevice,
+ ahExtBuffer[i],
+ &pPhyAddr,
+ &ui32ByteSize,
+ &pvVAddr,
+ &hOSMapInfo,
+ &bIsContiguous,
+ &ui32TilingStride);
+ if(eError != PVRSRV_OK)
+ {
+ break;
+ }
+
+ psPhyAddr[i] = *pPhyAddr;
+ }
+#endif /* defined(SUPPORT_GET_DC_BUFFERS_SYS_PHYADDRS) */
+
+ 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_BOOL bAddReferenceToLast = IMG_TRUE;
+ IMG_UINT16 ui16SwapCommandID = DC_FLIP_COMMAND;
+ IMG_UINT32 ui32NumSrcSyncs = 1;
+ PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
+ PVRSRV_COMMAND *psCommand;
+ SYS_DATA *psSysData;
+
+ if(!hDeviceKM || !hBuffer || !psClipRect)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psBuffer = (PVRSRV_DC_BUFFER*)hBuffer;
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+
+ /* Validate swap interval against limits */
+ if(ui32SwapInterval < psBuffer->psSwapChain->ui32MinSwapInterval ||
+ ui32SwapInterval > psBuffer->psSwapChain->ui32MaxSwapInterval)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Invalid swap interval. Requested %u, Allowed range %u-%u",
+ ui32SwapInterval, psBuffer->psSwapChain->ui32MinSwapInterval, psBuffer->psSwapChain->ui32MaxSwapInterval));
+ return PVRSRV_ERROR_INVALID_SWAPINTERVAL;
+ }
+
+#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
+
+ if(psDCInfo->psFuncTable->pfnQuerySwapCommandID != IMG_NULL)
+ {
+ psDCInfo->psFuncTable->pfnQuerySwapCommandID(psDCInfo->hExtDevice,
+ psBuffer->psSwapChain->hExtSwapChain,
+ psBuffer->sDeviceClassBuffer.hExtBuffer,
+ hPrivateTag,
+ &ui16SwapCommandID,
+ &bAddReferenceToLast);
+
+ }
+
+#endif
+
+ /* get the queue from the buffer structure */
+ psQueue = psBuffer->psSwapChain->psQueue;
+
+ /* specify the syncs */
+ apsSrcSync[0] = psBuffer->sDeviceClassBuffer.psKernelSyncInfo;
+ if(bAddReferenceToLast && psBuffer->psSwapChain->psLastFlipBuffer &&
+ psBuffer != psBuffer->psSwapChain->psLastFlipBuffer)
+ {
+ apsSrcSync[1] = psBuffer->psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo;
+ ui32NumSrcSyncs++;
+ }
+
+ /* insert the command (header) */
+ eError = PVRSRVInsertCommandKM (psQueue,
+ &psCommand,
+ psDCInfo->ui32DeviceID,
+ ui16SwapCommandID,
+ 0,
+ IMG_NULL,
+ ui32NumSrcSyncs,
+ apsSrcSync,
+ sizeof(DISPLAYCLASS_FLIP_COMMAND) + (sizeof(IMG_RECT) * ui32ClipRectCount),
+ IMG_NULL,
+ IMG_NULL);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to get space in queue"));
+ goto Exit;
+ }
+
+ /* setup the flip command */
+ psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData;
+
+ /* Ext Device Handle */
+ psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
+
+ /* Ext SwapChain Handle */
+ psFlipCmd->hExtSwapChain = psBuffer->psSwapChain->hExtSwapChain;
+
+ /* Ext Buffer Handle (Buffer to Flip to) */
+ psFlipCmd->hExtBuffer = psBuffer->sDeviceClassBuffer.hExtBuffer;
+
+ /* private tag */
+ psFlipCmd->hPrivateTag = hPrivateTag;
+
+ /* setup the clip rects */
+ psFlipCmd->ui32ClipRectCount = ui32ClipRectCount;
+ /* cliprect memory appends the command structure */
+ psFlipCmd->psClipRect = (IMG_RECT*)((IMG_UINT8*)psFlipCmd + sizeof(DISPLAYCLASS_FLIP_COMMAND)); // PRQA S 3305
+ /* copy the clip rects */
+ for(i=0; i<ui32ClipRectCount; i++)
+ {
+ psFlipCmd->psClipRect[i] = psClipRect[i];
+ }
+
+ /* number of vsyncs between successive flips */
+ psFlipCmd->ui32SwapInterval = ui32SwapInterval;
+
+ SysAcquireData(&psSysData);
+
+ /* Because we might be composing just software surfaces, without
+ * any SGX renders since the last frame, we won't necessarily
+ * have cleaned/flushed the CPU caches before the buffers need
+ * to be displayed.
+ *
+ * Doing so now is safe because InsertCommand bumped ROP2 on the
+ * affected buffers (preventing more SW renders starting) but the
+ * display won't start to process the buffers until SubmitCommand.
+ */
+ {
+ if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH)
+ {
+ OSFlushCPUCacheKM();
+ }
+ else if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN)
+ {
+ OSCleanCPUCacheKM();
+ }
+
+ psSysData->ePendingCacheOpType = PVRSRV_MISC_INFO_CPUCACHEOP_NONE;
+ }
+
+ /* submit the command */
+ eError = PVRSRVSubmitCommandKM (psQueue, psCommand);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to submit command"));
+ goto Exit;
+ }
+
+ /*
+ Schedule an MISR to process it
+ */
+ eError = OSScheduleMISR(psSysData);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to schedule MISR"));
+ goto Exit;
+ }
+
+ /* update the last flip buffer */
+ psBuffer->psSwapChain->psLastFlipBuffer = psBuffer;
+
+Exit:
+
+ if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE)
+ {
+ eError = PVRSRV_ERROR_RETRY;
+ }
+
+ return eError;
+}
+
+typedef struct _CALLBACK_DATA_
+{
+ IMG_PVOID pvPrivData;
+ IMG_UINT32 ui32PrivDataLength;
+ IMG_PVOID ppvMemInfos;
+ IMG_UINT32 ui32NumMemInfos;
+} CALLBACK_DATA;
+
+static IMG_VOID FreePrivateData(IMG_HANDLE hCallbackData)
+{
+ CALLBACK_DATA *psCallbackData = hCallbackData;
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psCallbackData->ui32PrivDataLength,
+ psCallbackData->pvPrivData, IMG_NULL);
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(IMG_VOID *) * psCallbackData->ui32NumMemInfos,
+ psCallbackData->ppvMemInfos, IMG_NULL);
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(CALLBACK_DATA), hCallbackData, IMG_NULL);
+}
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSwapToDCBuffer2KM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hSwapChain,
+ IMG_UINT32 ui32SwapInterval,
+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfos,
+ PVRSRV_KERNEL_SYNC_INFO **ppsSyncInfos,
+ IMG_UINT32 ui32NumMemSyncInfos,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength)
+{
+ PVRSRV_KERNEL_SYNC_INFO **ppsCompiledSyncInfos;
+ IMG_UINT32 i, ui32NumCompiledSyncInfos;
+ DISPLAYCLASS_FLIP_COMMAND2 *psFlipCmd;
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PVRSRV_DC_SWAPCHAIN *psSwapChain;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ CALLBACK_DATA *psCallbackData;
+ PVRSRV_QUEUE_INFO *psQueue;
+ PVRSRV_COMMAND *psCommand;
+ IMG_PVOID *ppvMemInfos;
+ SYS_DATA *psSysData;
+
+ if(!hDeviceKM || !hSwapChain || !ppsMemInfos || !ppsSyncInfos || ui32NumMemSyncInfos < 1)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChain)->psSwapChain;
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+
+ /* Validate swap interval against limits */
+ if(ui32SwapInterval < psSwapChain->ui32MinSwapInterval ||
+ ui32SwapInterval > psSwapChain->ui32MaxSwapInterval)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Invalid swap interval. Requested %u, Allowed range %u-%u",
+ ui32SwapInterval, psSwapChain->ui32MinSwapInterval, psSwapChain->ui32MaxSwapInterval));
+ return PVRSRV_ERROR_INVALID_SWAPINTERVAL;
+ }
+
+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(CALLBACK_DATA),
+ (IMG_VOID **)&psCallbackData, IMG_NULL,
+ "PVRSRVSwapToDCBuffer2KM callback data");
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ psCallbackData->pvPrivData = pvPrivData;
+ psCallbackData->ui32PrivDataLength = ui32PrivDataLength;
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(IMG_VOID *) * ui32NumMemSyncInfos,
+ (IMG_VOID **)&ppvMemInfos, IMG_NULL,
+ "Swap Command Meminfos") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to allocate space for meminfo list"));
+ psCallbackData->ppvMemInfos = IMG_NULL;
+ goto Exit;
+ }
+
+ for(i = 0; i < ui32NumMemSyncInfos; i++)
+ {
+ ppvMemInfos[i] = ppsMemInfos[i];
+ }
+
+ psCallbackData->ppvMemInfos = ppvMemInfos;
+ psCallbackData->ui32NumMemInfos = ui32NumMemSyncInfos;
+
+ /* get the queue from the buffer structure */
+ psQueue = psSwapChain->psQueue;
+
+#if !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED)
+ if(psSwapChain->ppsLastSyncInfos)
+ {
+ IMG_UINT32 ui32NumUniqueSyncInfos = psSwapChain->ui32LastNumSyncInfos;
+ IMG_UINT32 j;
+
+ for(j = 0; j < psSwapChain->ui32LastNumSyncInfos; j++)
+ {
+ for(i = 0; i < ui32NumMemSyncInfos; i++)
+ {
+ if(psSwapChain->ppsLastSyncInfos[j] == ppsSyncInfos[i])
+ {
+ psSwapChain->ppsLastSyncInfos[j] = IMG_NULL;
+ ui32NumUniqueSyncInfos--;
+ }
+ }
+ }
+
+ ui32NumCompiledSyncInfos = ui32NumMemSyncInfos + ui32NumUniqueSyncInfos;
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_KERNEL_SYNC_INFO *) * ui32NumCompiledSyncInfos,
+ (IMG_VOID **)&ppsCompiledSyncInfos, IMG_NULL,
+ "Compiled syncinfos") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to allocate space for meminfo list"));
+ goto Exit;
+ }
+
+ OSMemCopy(ppsCompiledSyncInfos, ppsSyncInfos, sizeof(PVRSRV_KERNEL_SYNC_INFO *) * ui32NumMemSyncInfos);
+ for(j = 0, i = ui32NumMemSyncInfos; j < psSwapChain->ui32LastNumSyncInfos; j++)
+ {
+ if(psSwapChain->ppsLastSyncInfos[j])
+ {
+ ppsCompiledSyncInfos[i] = psSwapChain->ppsLastSyncInfos[j];
+ i++;
+ }
+ }
+ }
+ else
+#endif /* !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) */
+ {
+ ppsCompiledSyncInfos = ppsSyncInfos;
+ ui32NumCompiledSyncInfos = ui32NumMemSyncInfos;
+ }
+
+ /* insert the command (header) */
+ eError = PVRSRVInsertCommandKM (psQueue,
+ &psCommand,
+ psDCInfo->ui32DeviceID,
+ DC_FLIP_COMMAND,
+ 0,
+ IMG_NULL,
+ ui32NumCompiledSyncInfos,
+ ppsCompiledSyncInfos,
+ sizeof(DISPLAYCLASS_FLIP_COMMAND2),
+ FreePrivateData,
+ psCallbackData);
+
+ if (ppsCompiledSyncInfos != ppsSyncInfos)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_KERNEL_SYNC_INFO *) * ui32NumCompiledSyncInfos,
+ (IMG_VOID *)ppsCompiledSyncInfos,
+ IMG_NULL);
+ }
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to get space in queue"));
+ goto Exit;
+ }
+
+ /* setup the flip command */
+ psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND2*)psCommand->pvData;
+
+ /* Ext Device Handle */
+ psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
+
+ /* Ext SwapChain Handle */
+ psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain;
+
+ /* number of vsyncs between successive flips */
+ psFlipCmd->ui32SwapInterval = ui32SwapInterval;
+
+ /* Opaque private data, if supplied */
+ psFlipCmd->pvPrivData = pvPrivData;
+ psFlipCmd->ui32PrivDataLength = ui32PrivDataLength;
+
+ psFlipCmd->ppsMemInfos = (PDC_MEM_INFO *)ppvMemInfos;
+ psFlipCmd->ui32NumMemInfos = ui32NumMemSyncInfos;
+
+ /* Even though this is "unused", we have to initialize it,
+ * as the display controller might NULL-test it.
+ */
+ psFlipCmd->hUnused = IMG_NULL;
+
+ SysAcquireData(&psSysData);
+
+ /* Because we might be composing just software surfaces, without
+ * any SGX renders since the last frame, we won't necessarily
+ * have cleaned/flushed the CPU caches before the buffers need
+ * to be displayed.
+ *
+ * Doing so now is safe because InsertCommand bumped ROP2 on the
+ * affected buffers (preventing more SW renders starting) but the
+ * display won't start to process the buffers until SubmitCommand.
+ */
+ {
+ if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH)
+ {
+ OSFlushCPUCacheKM();
+ }
+ else if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN)
+ {
+ OSCleanCPUCacheKM();
+ }
+
+ psSysData->ePendingCacheOpType = PVRSRV_MISC_INFO_CPUCACHEOP_NONE;
+ }
+
+ /* submit the command */
+ eError = PVRSRVSubmitCommandKM (psQueue, psCommand);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to submit command"));
+ goto Exit;
+ }
+
+ /* The command has been submitted and so psCallbackData will be freed by the callback */
+ psCallbackData = IMG_NULL;
+
+ /*
+ Schedule an MISR to process it
+ */
+ eError = OSScheduleMISR(psSysData);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to schedule MISR"));
+ goto Exit;
+ }
+
+#if !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED)
+ /* Reallocate the syncinfo list if it was too small */
+ if (psSwapChain->ui32LastNumSyncInfos < ui32NumMemSyncInfos)
+ {
+ if (psSwapChain->ppsLastSyncInfos)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_SYNC_INFO *) * psSwapChain->ui32LastNumSyncInfos,
+ psSwapChain->ppsLastSyncInfos, IMG_NULL);
+ }
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_KERNEL_SYNC_INFO *) * ui32NumMemSyncInfos,
+ (IMG_VOID **)&psSwapChain->ppsLastSyncInfos, IMG_NULL,
+ "Last syncinfos") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to allocate space for meminfo list"));
+ goto Exit;
+ }
+ }
+
+ psSwapChain->ui32LastNumSyncInfos = ui32NumMemSyncInfos;
+
+ for(i = 0; i < ui32NumMemSyncInfos; i++)
+ {
+ psSwapChain->ppsLastSyncInfos[i] = ppsSyncInfos[i];
+ }
+#endif /* !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) */
+
+Exit:
+ if (psCallbackData)
+ {
+ if(psCallbackData->ppvMemInfos)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(IMG_VOID *) * psCallbackData->ui32NumMemInfos,
+ psCallbackData->ppvMemInfos, IMG_NULL);
+ }
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(CALLBACK_DATA), psCallbackData, IMG_NULL);
+ }
+ if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE)
+ {
+ eError = PVRSRV_ERROR_RETRY;
+ }
+
+ return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSwapToDCSystemKM(IMG_HANDLE hDeviceKM,
+ IMG_HANDLE hSwapChainRef)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_QUEUE_INFO *psQueue;
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PVRSRV_DC_SWAPCHAIN *psSwapChain;
+ PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef;
+ DISPLAYCLASS_FLIP_COMMAND *psFlipCmd;
+ IMG_UINT32 ui32NumSrcSyncs = 1;
+ PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2];
+ PVRSRV_COMMAND *psCommand;
+ IMG_BOOL bAddReferenceToLast = IMG_TRUE;
+ IMG_UINT16 ui16SwapCommandID = DC_FLIP_COMMAND;
+ SYS_DATA *psSysData;
+
+ if(!hDeviceKM || !hSwapChainRef)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);
+ psSwapChainRef = (PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef;
+ psSwapChain = psSwapChainRef->psSwapChain;
+
+ /*
+ If more then 1 reference to the swapchain exist then
+ ignore any request to swap to the system buffer
+ */
+ if (psSwapChain->ui32RefCount > 1)
+ {
+ return PVRSRV_OK;
+ }
+
+ /* get the queue from the buffer structure */
+ psQueue = psSwapChain->psQueue;
+
+#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
+
+ if(psDCInfo->psFuncTable->pfnQuerySwapCommandID != IMG_NULL)
+ {
+ psDCInfo->psFuncTable->pfnQuerySwapCommandID(psDCInfo->hExtDevice,
+ psSwapChain->hExtSwapChain,
+ psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer,
+ 0,
+ &ui16SwapCommandID,
+ &bAddReferenceToLast);
+
+ }
+
+#endif
+
+ /* specify the syncs */
+ apsSrcSync[0] = psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo;
+ if(bAddReferenceToLast && psSwapChain->psLastFlipBuffer)
+ {
+ /* Make sure we don't make a double dependency on the same server */
+ if (apsSrcSync[0] != psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo)
+ {
+ apsSrcSync[1] = psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo;
+ ui32NumSrcSyncs++;
+ }
+ }
+
+ /* insert the command (header) */
+ eError = PVRSRVInsertCommandKM (psQueue,
+ &psCommand,
+ psDCInfo->ui32DeviceID,
+ ui16SwapCommandID,
+ 0,
+ IMG_NULL,
+ ui32NumSrcSyncs,
+ apsSrcSync,
+ sizeof(DISPLAYCLASS_FLIP_COMMAND),
+ IMG_NULL,
+ IMG_NULL);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to get space in queue"));
+ goto Exit;
+ }
+
+ /* setup the flip command */
+ psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData;
+
+ /* Ext Device Handle */
+ psFlipCmd->hExtDevice = psDCInfo->hExtDevice;
+
+ /* Ext SwapChain Handle */
+ psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain;
+
+ /* Ext Buffer Handle (Buffer to Flip to) */
+ psFlipCmd->hExtBuffer = psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer;
+
+ /* private tag */
+ psFlipCmd->hPrivateTag = IMG_NULL;
+
+ /* setup the clip rects */
+ psFlipCmd->ui32ClipRectCount = 0;
+
+ psFlipCmd->ui32SwapInterval = 1;
+
+ /* submit the command */
+ eError = PVRSRVSubmitCommandKM (psQueue, psCommand);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to submit command"));
+ goto Exit;
+ }
+
+ /* Schedule an MISR to process it */
+ SysAcquireData(&psSysData);
+ eError = OSScheduleMISR(psSysData);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to schedule MISR"));
+ goto Exit;
+ }
+
+ /* update the last flip buffer */
+ psSwapChain->psLastFlipBuffer = &psDCInfo->sSystemBuffer;
+
+ eError = PVRSRV_OK;
+
+Exit:
+
+ if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE)
+ {
+ eError = PVRSRV_ERROR_RETRY;
+ }
+
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVRegisterSystemISRHandler
+
+ @Description
+
+ registers an external ISR to be called of the back of a system ISR
+
+ @Input ppfnISRHandler : ISR pointer
+
+ @Input hISRHandlerData : Callback data
+
+ @Input ui32ISRSourceMask : ISR Mask
+
+ @Input ui32DeviceID : unique device key
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+static
+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);
+
+ SysAcquireData(&psSysData);
+
+ /* Find Dev Node (just using the device id, ignore the class) */
+ psDevNode = (PVRSRV_DEVICE_NODE*)
+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+ &MatchDeviceKM_AnyVaCb,
+ ui32DeviceID,
+ IMG_TRUE);
+
+ if (psDevNode == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterSystemISRHandler: Failed to get psDevNode"));
+ PVR_DBG_BREAK;
+ return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
+ }
+
+ /* set up data before enabling the ISR */
+ psDevNode->pvISRData = (IMG_VOID*) pvISRHandlerData;
+
+ /* enable the ISR */
+ psDevNode->pfnDeviceISR = pfnISRHandler;
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVSetDCState_ForEachVaCb
+
+ @Description
+
+ If the device node is a display, calls its set state function.
+
+ @Input psDeviceNode - the device node
+ va - variable argument list with:
+ ui32State - the state to be set.
+
+******************************************************************************/
+static
+IMG_VOID PVRSRVSetDCState_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ IMG_UINT32 ui32State;
+ ui32State = va_arg(va, IMG_UINT32);
+
+ 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);
+ }
+ }
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVSetDCState
+
+ @Description
+
+ Calls the display driver(s) to put them into the specified state.
+
+ @Input ui32State: new DC state - one of DC_STATE_*
+
+******************************************************************************/
+IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State)
+{
+/* PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
+ PVRSRV_DEVICE_NODE *psDeviceNode; */
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+
+ List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
+ &PVRSRVSetDCState_ForEachVaCb,
+ ui32State);
+}
+
+static PVRSRV_ERROR
+PVRSRVDCMemInfoGetCpuVAddr(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo,
+ IMG_CPU_VIRTADDR *pVAddr)
+{
+ *pVAddr = psKernelMemInfo->pvLinAddrKM;
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR
+PVRSRVDCMemInfoGetCpuPAddr(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo,
+ IMG_SIZE_T uByteOffset, IMG_CPU_PHYADDR *pPAddr)
+{
+ *pPAddr = OSMemHandleToCpuPAddr(psKernelMemInfo->sMemBlk.hOSMemHandle, uByteOffset);
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR
+PVRSRVDCMemInfoGetByteSize(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo,
+ IMG_SIZE_T *uByteSize)
+{
+ *uByteSize = psKernelMemInfo->uAllocSize;
+ return PVRSRV_OK;
+}
+
+static IMG_BOOL
+PVRSRVDCMemInfoIsPhysContig(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ return OSMemHandleIsPhysContig(psKernelMemInfo->sMemBlk.hOSMemHandle);
+}
+
+static PVRSRV_ERROR PVRSRVDCMemInfoGetBvHandle(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo, IMG_VOID **handle)
+{
+#if !defined(CONFIG_GCBV)
+ *handle = NULL;
+ return PVRSRV_ERROR_NOT_SUPPORTED;
+#else
+ *handle = gc_meminfo_to_hndl(psKernelMemInfo);
+ return PVRSRV_OK;
+#endif
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVDCMemInfoGetCpuMultiPlanePAddr
+
+ @Description returns physical addresses of a multi-plane buffer
+
+
+ @Input psKernelMemInfo - Pointer to Kernel Memory Info structure
+ puPlaneByteOffsets - requested offset inside the plane.
+ If the array is a NULL pointer, 0 requested offsets
+ are assumed for all planes;
+ pui32NumAddrOffsets - specifying the size of the user array.
+ If the array is smaller than the number of the planes
+ for this buffer, the correct size will be set and an
+ error returned back;
+
+@Output pPlanePAddrs - array of plane physical addresses of the returned size
+ in pui32NumAddrOffsets;
+ pui32NumAddrOffsets - contains the real number of planes for the buffer;
+
+@Return IMG_INT32 : size of the entire buffer or negative number on ERROR
+
+******************************************************************************/
+static IMG_INT32
+PVRSRVDCMemInfoGetCpuMultiPlanePAddr(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo,
+ IMG_SIZE_T* puPlaneByteOffsets, IMG_CPU_PHYADDR* pPlanePAddrs,
+ IMG_UINT32* pui32NumAddrOffsets)
+{
+ IMG_UINT32 aui32PlaneAddressOffsets[PVRSRV_MAX_NUMBER_OF_MM_BUFFER_PLANES];
+ IMG_INT32 i32Ret;
+ IMG_UINT32 i;
+
+ i32Ret = OSGetMemMultiPlaneInfo(psKernelMemInfo->sMemBlk.hOSMemHandle,
+ aui32PlaneAddressOffsets,
+ pui32NumAddrOffsets);
+
+ if((i32Ret < 0) || (pPlanePAddrs == IMG_NULL))
+ return i32Ret;
+
+ for (i = 0; i < *pui32NumAddrOffsets; i++)
+ {
+ IMG_SIZE_T uiReqByteOffsets = puPlaneByteOffsets ? puPlaneByteOffsets[i] : 0;
+
+ uiReqByteOffsets += aui32PlaneAddressOffsets[i];
+
+ pPlanePAddrs[i] = OSMemHandleToCpuPAddr(psKernelMemInfo->sMemBlk.hOSMemHandle, uiReqByteOffsets);
+ }
+
+ return i32Ret;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRGetDisplayClassJTable
+
+ @Description
+
+ Sets up function table for 3rd party Display Class Device to call through
+
+ @Input psJTable : pointer to function pointer table memory
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+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;
+#if defined(SUPPORT_MISR_IN_THREAD)
+ psJTable->pfnPVRSRVCmdComplete = &OSVSyncMISR;
+#else
+ psJTable->pfnPVRSRVCmdComplete = &PVRSRVCommandCompleteKM;
+#endif
+ psJTable->pfnPVRSRVRegisterSystemISRHandler = &PVRSRVRegisterSystemISRHandler;
+ psJTable->pfnPVRSRVRegisterPowerDevice = &PVRSRVRegisterPowerDevice;
+#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
+ psJTable->pfnPVRSRVFreeCmdCompletePacket = &PVRSRVFreeCommandCompletePacketKM;
+#endif
+ psJTable->pfnPVRSRVDCMemInfoGetCpuVAddr = &PVRSRVDCMemInfoGetCpuVAddr;
+ psJTable->pfnPVRSRVDCMemInfoGetCpuPAddr = &PVRSRVDCMemInfoGetCpuPAddr;
+ psJTable->pfnPVRSRVDCMemInfoGetByteSize = &PVRSRVDCMemInfoGetByteSize;
+ psJTable->pfnPVRSRVDCMemInfoIsPhysContig = &PVRSRVDCMemInfoIsPhysContig;
+ psJTable->pfnPVRSRVDCMemInfoGetBvHandle = &PVRSRVDCMemInfoGetBvHandle;
+ psJTable->pfnPVRSRVDCMemInfoGetCpuMultiPlanePAddr = PVRSRVDCMemInfoGetCpuMultiPlanePAddr;
+ return IMG_TRUE;
+}
+
+
+
+/******************************************************************************
+
+ @Function PVRSRVCloseBCDeviceKM
+
+ @Description
+
+ Closes a connection to the Buffer Class device
+
+ @Input hDeviceKM : device handle
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVCloseBCDeviceKM (IMG_HANDLE hDeviceKM)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
+
+ psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)hDeviceKM;
+
+ /* Remove the item from the resman list and trigger the callback. */
+ eError = ResManFreeResByPtr(psBCPerContextInfo->hResItem, CLEANUP_WITH_POLL);
+
+ return eError;
+}
+
+
+static PVRSRV_ERROR CloseBCDeviceCallBack(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
+ PVRSRV_BUFFERCLASS_INFO *psBCInfo;
+ IMG_UINT32 i;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)pvParam;
+
+ psBCInfo = psBCPerContextInfo->psBCInfo;
+
+ for (i = 0; i < psBCInfo->ui32BufferCount; i++)
+ {
+ if (psBCInfo->psBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CloseBCDeviceCallBack: buffer %d (0x%p) still mapped (ui32MemMapRefCount = %d)",
+ i,
+ &psBCInfo->psBuffer[i].sDeviceClassBuffer,
+ psBCInfo->psBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount));
+ return PVRSRV_ERROR_STILL_MAPPED;
+ }
+ }
+
+ psBCInfo->ui32RefCount--;
+ if(psBCInfo->ui32RefCount == 0)
+ {
+ /* close the external device */
+ psBCInfo->psFuncTable->pfnCloseBCDevice(psBCInfo->ui32DeviceID, psBCInfo->hExtDevice);
+
+ /* free syncinfos */
+ for(i=0; i<psBCInfo->ui32BufferCount; i++)
+ {
+ if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoDecRef(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
+ }
+ }
+
+ /* free buffers */
+ if(psBCInfo->psBuffer)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER) * psBCInfo->ui32BufferCount, psBCInfo->psBuffer, IMG_NULL);
+ psBCInfo->psBuffer = IMG_NULL;
+ }
+ }
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_PERCONTEXT_INFO), psBCPerContextInfo, IMG_NULL);
+ /*not nulling pointer, copy on stack*/
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVOpenBCDeviceKM
+
+ @Description
+
+ Opens a connection to the Buffer Class device, associating the connection
+ with a Device Memory Context for a services managed device
+
+ @Input psPerProc : Per-process data
+ @Input ui32DeviceID : unique device index
+ @Input hDevCookie : devcookie used to derive the Device Memory
+ Context into BC surfaces will be mapped into
+ @Outut phDeviceKM : handle to the DC device
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+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_INVALID_PARAMS;
+ }
+
+ SysAcquireData(&psSysData);
+
+ /* find the matching devicenode */
+ psDeviceNode = (PVRSRV_DEVICE_NODE*)
+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+ &MatchDeviceKM_AnyVaCb,
+ ui32DeviceID,
+ IMG_FALSE,
+ PVRSRV_DEVICE_CLASS_BUFFER);
+ if (!psDeviceNode)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: No devnode matching index %d", ui32DeviceID));
+ return PVRSRV_ERROR_NO_DEVICENODE_FOUND;
+ }
+ psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDeviceNode->pvDevice;
+
+/*
+FoundDevice:
+*/
+ /*
+ Allocate the per-context BC Info before calling the external device,
+ to make error handling easier.
+ */
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(*psBCPerContextInfo),
+ (IMG_VOID **)&psBCPerContextInfo, IMG_NULL,
+ "Buffer Class per Context Info") != 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;
+
+ /* store the device kernel context to map into */
+ psBCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext;
+
+ /* open the external device */
+ eError = psBCInfo->psFuncTable->pfnOpenBCDevice(ui32DeviceID, &psBCInfo->hExtDevice);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to open external BC device"));
+ return eError;
+ }
+
+ /* get information about the buffers */
+ eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, &sBufferInfo);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM : Failed to get BC Info"));
+ return eError;
+ }
+
+ /* interpret and store info */
+ psBCInfo->ui32BufferCount = sBufferInfo.ui32BufferCount;
+
+ /* allocate BC buffers */
+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount,
+ (IMG_VOID **)&psBCInfo->psBuffer,
+ IMG_NULL,
+ "Array of Buffer Class Buffer");
+ 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++)
+ {
+ /* create a syncinfo for the device's system surface */
+ 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;
+ }
+
+ /*
+ get the buffers from the buffer class
+ drivers by index, passing-in the syncdata objects
+ */
+ 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;
+ }
+
+ /* setup common device class info */
+ psBCInfo->psBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psBCInfo->psFuncTable->pfnGetBufferAddr;
+ psBCInfo->psBuffer[i].sDeviceClassBuffer.hDevMemContext = psBCInfo->hDevMemContext;
+ psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtDevice = psBCInfo->hExtDevice;
+ psBCInfo->psBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount = 0;
+ }
+ }
+
+ psBCPerContextInfo->psBCInfo = psBCInfo;
+ psBCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_BUFFERCLASS_DEVICE,
+ psBCPerContextInfo,
+ 0,
+ &CloseBCDeviceCallBack);
+
+ /* return a reference to the BCPerContextInfo */
+ *phDeviceKM = (IMG_HANDLE)psBCPerContextInfo;
+
+ return PVRSRV_OK;
+
+ErrorExit:
+
+ /* free syncinfos */
+ for(i=0; i<psBCInfo->ui32BufferCount; i++)
+ {
+ if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoDecRef(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
+ }
+ }
+
+ /* free buffers */
+ if(psBCInfo->psBuffer)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER), psBCInfo->psBuffer, IMG_NULL);
+ psBCInfo->psBuffer = IMG_NULL;
+ }
+
+ return eError;
+}
+
+
+
+
+/******************************************************************************
+
+ @Function PVRSRVGetBCInfoKM
+
+ @Description
+
+ Gets Buffer Class device Info
+
+ @Input hDeviceKM : device handle
+ @Output psBufferInfo
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+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;
+}
+
+
+/******************************************************************************
+
+ @Function PVRSRVGetBCBufferKM
+
+ @Description
+
+ Gets Buffer Class Buffer Handle
+
+ @Input hDeviceKM : device handle
+ @Output psBufferInfo
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+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;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRGetBufferClassJTable
+
+ @Description
+
+ Sets up function table for 3rd party Buffer Class Device to call through
+
+ @Input psJTable : pointer to function pointer table memory
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+IMG_EXPORT
+IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable)
+{
+ psJTable->ui32TableSize = sizeof(PVRSRV_BC_BUFFER2SRV_KMJTABLE);
+
+ psJTable->pfnPVRSRVRegisterBCDevice = &PVRSRVRegisterBCDeviceKM;
+ psJTable->pfnPVRSRVScheduleDevices = &PVRSRVScheduleDevicesKM;
+ psJTable->pfnPVRSRVRemoveBCDevice = &PVRSRVRemoveBCDeviceKM;
+
+ return IMG_TRUE;
+}
+
+/******************************************************************************
+ End of file (deviceclass.c)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/common/deviceid.h b/pvr-source/services4/srvkm/common/deviceid.h
new file mode 100644
index 0000000..1cf9f0f
--- /dev/null
+++ b/pvr-source/services4/srvkm/common/deviceid.h
@@ -0,0 +1,51 @@
+/*************************************************************************/ /*!
+@Title Device ID helpers
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __DEVICEID_H__
+#define __DEVICEID_H__
+
+#include "services.h"
+#include "syscommon.h"
+
+PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID);
+PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID);
+
+#endif /* __DEVICEID_H__ */
diff --git a/pvr-source/services4/srvkm/common/devicemem.c b/pvr-source/services4/srvkm/common/devicemem.c
new file mode 100644
index 0000000..872c0ba
--- /dev/null
+++ b/pvr-source/services4/srvkm/common/devicemem.c
@@ -0,0 +1,2580 @@
+/*************************************************************************/ /*!
+@Title Device addressable memory functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Device addressable memory APIs
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+
+#include "services_headers.h"
+#include "buffer_manager.h"
+#include "pdump_km.h"
+#include "pvr_bridge_km.h"
+#include "osfunc.h"
+#if defined(CONFIG_GCBV)
+#include "gc_bvmapping.h"
+#endif
+
+#if defined(SUPPORT_ION)
+#include "ion.h"
+#include "env_perproc.h"
+#endif
+
+/* local function prototypes */
+static PVRSRV_ERROR AllocDeviceMem(IMG_HANDLE hDevCookie,
+ IMG_HANDLE hDevMemHeap,
+ IMG_UINT32 ui32Flags,
+ IMG_SIZE_T ui32Size,
+ IMG_SIZE_T ui32Alignment,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_UINT32 ui32ChunkSize,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_BOOL *pabMapChunk,
+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo);
+
+/* local structures */
+
+/*
+ structure stored in resman to store references
+ to the SRC and DST meminfo
+*/
+typedef struct _RESMAN_MAP_DEVICE_MEM_DATA_
+{
+ /* the DST meminfo created by the map */
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo;
+ /* SRC meminfo */
+ PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo;
+} RESMAN_MAP_DEVICE_MEM_DATA;
+
+/*
+ map device class resman memory storage structure
+*/
+typedef struct _PVRSRV_DC_MAPINFO_
+{
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ IMG_UINT32 ui32RangeIndex;
+ IMG_UINT32 ui32TilingStride;
+ PVRSRV_DEVICECLASS_BUFFER *psDeviceClassBuffer;
+} PVRSRV_DC_MAPINFO;
+
+static IMG_UINT32 g_ui32SyncUID = 0;
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVGetDeviceMemHeapsKM
+
+ @Description
+
+ Gets the device shared memory heaps
+
+ @Input hDevCookie :
+ @Output phDevMemContext : ptr to handle to memory context
+ @Output psHeapInfo : ptr to array of heap info
+
+ @Return PVRSRV_DEVICE_NODE, valid devnode or IMG_NULL
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapsKM(IMG_HANDLE hDevCookie,
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_HEAP_INFO_KM *psHeapInfo)
+#else
+ PVRSRV_HEAP_INFO *psHeapInfo)
+#endif
+{
+ 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;
+
+ /* Setup useful pointers */
+ ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
+ psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
+
+ /* check we don't exceed the max number of heaps */
+ PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
+
+ /* retrieve heap information */
+ for(i=0; i<ui32HeapCount; i++)
+ {
+ /* return information about the heap */
+ 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;
+ /* (XTileStride > 0) denotes a tiled heap */
+ psHeapInfo[i].ui32XTileStride = psDeviceMemoryHeap[i].ui32XTileStride;
+ }
+
+ 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;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVCreateDeviceMemContextKM
+
+ @Description
+
+ Creates a device memory context
+
+ @Input hDevCookie :
+ @Input psPerProc : Per-process data
+ @Output phDevMemContext : ptr to handle to memory context
+ @Output pui32ClientHeapCount : ptr to heap count
+ @Output psHeapInfo : ptr to array of heap info
+
+ @Return PVRSRV_DEVICE_NODE, valid devnode or IMG_NULL
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContextKM(IMG_HANDLE hDevCookie,
+ PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE *phDevMemContext,
+ IMG_UINT32 *pui32ClientHeapCount,
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_HEAP_INFO_KM *psHeapInfo,
+#else
+ PVRSRV_HEAP_INFO *psHeapInfo,
+#endif
+ 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) && !defined (SUPPORT_SID_INTERFACE)
+ 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;
+
+ /*
+ Setup useful pointers
+ */
+ ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
+ psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
+
+ /*
+ check we don't exceed the max number of heaps
+ */
+ PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
+
+ /*
+ Create a memory context for the caller
+ */
+ 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;
+ }
+
+ /* create the per context heaps */
+ for(i=0; i<ui32HeapCount; i++)
+ {
+ switch(psDeviceMemoryHeap[i].DevMemHeapType)
+ {
+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
+ {
+ /* return information about the heap */
+ 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(SUPPORT_MEMORY_TILING)
+ psHeapInfo[ui32ClientHeapCount].ui32XTileStride = psDeviceMemoryHeap[i].ui32XTileStride;
+ #else
+ psHeapInfo[ui32ClientHeapCount].ui32XTileStride = 0;
+ #endif
+
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ pbShared[ui32ClientHeapCount] = IMG_TRUE;
+#endif
+ ui32ClientHeapCount++;
+ break;
+ }
+ case DEVICE_MEMORY_HEAP_PERCONTEXT:
+ {
+ if (psDeviceMemoryHeap[i].ui32HeapSize > 0)
+ {
+ hDevMemHeap = BM_CreateHeap(hDevMemContext,
+ &psDeviceMemoryHeap[i]);
+ if (hDevMemHeap == IMG_NULL)
+ {
+ BM_DestroyContext(hDevMemContext, IMG_NULL);
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ }
+ else
+ {
+ hDevMemHeap = IMG_NULL;
+ }
+
+ /* return information about the heap */
+ 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(SUPPORT_MEMORY_TILING)
+ psHeapInfo[ui32ClientHeapCount].ui32XTileStride = psDeviceMemoryHeap[i].ui32XTileStride;
+ #else
+ psHeapInfo[ui32ClientHeapCount].ui32XTileStride = 0;
+ #endif
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ pbShared[ui32ClientHeapCount] = IMG_FALSE;
+#endif
+
+ ui32ClientHeapCount++;
+ break;
+ }
+ }
+ }
+
+ /* return shared_exported and per context heap information to the caller */
+ *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);
+}
+
+
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVGetDeviceMemHeapInfoKM
+
+ @Description
+
+ gets heap info
+
+ @Input hDevCookie :
+ @Input hDevMemContext : ptr to handle to memory context
+ @Output pui32ClientHeapCount : ptr to heap count
+ @Output psHeapInfo : ptr to array of heap info
+
+ @Return
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfoKM(IMG_HANDLE hDevCookie,
+ IMG_HANDLE hDevMemContext,
+ IMG_UINT32 *pui32ClientHeapCount,
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_HEAP_INFO_KM *psHeapInfo,
+#else
+ PVRSRV_HEAP_INFO *psHeapInfo,
+#endif
+ 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) && !defined (SUPPORT_SID_INTERFACE)
+ 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;
+
+ /*
+ Setup useful pointers
+ */
+ ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
+ psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
+
+ /*
+ check we don't exceed the max number of heaps
+ */
+ PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
+
+ /* create the per context heaps */
+ for(i=0; i<ui32HeapCount; i++)
+ {
+ switch(psDeviceMemoryHeap[i].DevMemHeapType)
+ {
+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
+ {
+ /* return information about the heap */
+ 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;
+ psHeapInfo[ui32ClientHeapCount].ui32XTileStride = psDeviceMemoryHeap[i].ui32XTileStride;
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ pbShared[ui32ClientHeapCount] = IMG_TRUE;
+#endif
+ ui32ClientHeapCount++;
+ break;
+ }
+ case DEVICE_MEMORY_HEAP_PERCONTEXT:
+ {
+ if (psDeviceMemoryHeap[i].ui32HeapSize > 0)
+ {
+ hDevMemHeap = BM_CreateHeap(hDevMemContext,
+ &psDeviceMemoryHeap[i]);
+
+ if (hDevMemHeap == IMG_NULL)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ }
+ else
+ {
+ hDevMemHeap = IMG_NULL;
+ }
+
+ /* return information about the heap */
+ 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;
+ psHeapInfo[ui32ClientHeapCount].ui32XTileStride = psDeviceMemoryHeap[i].ui32XTileStride;
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+ pbShared[ui32ClientHeapCount] = IMG_FALSE;
+#endif
+
+ ui32ClientHeapCount++;
+ break;
+ }
+ }
+ }
+
+ /* return shared_exported and per context heap information to the caller */
+ *pui32ClientHeapCount = ui32ClientHeapCount;
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR UpdateDeviceMemoryPlaneOffsets(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+ if(psMemInfo->ui32Flags & PVRSRV_MEM_ION)
+ {
+
+ PVRSRV_MEMBLK *psMemBlock = &(psMemInfo->sMemBlk);
+ IMG_UINT32 ui32AddressOffsets[PVRSRV_MAX_NUMBER_OF_MM_BUFFER_PLANES];
+ IMG_UINT32 ui32NumAddrOffsets = PVRSRV_MAX_NUMBER_OF_MM_BUFFER_PLANES;
+
+ IMG_INT32 retSize = OSGetMemMultiPlaneInfo(psMemBlock->hOSMemHandle,
+ ui32AddressOffsets, &ui32NumAddrOffsets);
+
+ if((retSize > 0) && ui32NumAddrOffsets)
+ {
+ int i;
+ for(i = 0; i < PVRSRV_MAX_NUMBER_OF_MM_BUFFER_PLANES; i++)
+ {
+ if(i < ui32NumAddrOffsets)
+ psMemInfo->planeOffsets[i] = ui32AddressOffsets[i];
+ else
+ psMemInfo->planeOffsets[i] = (IMG_INT32)-1;
+ }
+ }
+ }
+
+ return PVRSRV_OK;
+
+}
+
+/*!
+******************************************************************************
+
+ @Function AllocDeviceMem
+
+ @Description
+
+ Allocates device memory
+
+ @Input hDevCookie :
+
+ @Input hDevMemHeap
+
+ @Input ui32Flags : Some combination of PVRSRV_MEM_ flags
+
+ @Input ui32Size : Number of bytes to allocate
+
+ @Input ui32Alignment : Alignment of allocation
+
+ @Input pvPrivData : Opaque private data passed through to allocator
+
+ @Input ui32PrivDataLength : Length of opaque private data
+
+ @Output **ppsMemInfo : On success, receives a pointer to the created MEM_INFO structure
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+static PVRSRV_ERROR AllocDeviceMem(IMG_HANDLE hDevCookie,
+ IMG_HANDLE hDevMemHeap,
+ IMG_UINT32 ui32Flags,
+ IMG_SIZE_T ui32Size,
+ IMG_SIZE_T ui32Alignment,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_UINT32 ui32ChunkSize,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_BOOL *pabMapChunk,
+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo)
+{
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo;
+ BM_HANDLE hBuffer;
+ /* Pointer to implementation details within the mem_info */
+ 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,
+ "Kernel Memory Info") != 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);
+
+ /* ION and DYNAMIC re-mapping
+ * require the PAGEABLE FLAG set
+ */
+ if (ui32Flags & (PVRSRV_MEM_ION |
+ PVRSRV_HAP_NO_GPU_VIRTUAL_ON_ALLOC))
+ {
+ ui32Flags |= PVRSRV_HAP_GPU_PAGEABLE;
+ }
+
+ /* BM supplied Device Virtual Address with physical backing RAM */
+ psMemInfo->ui32Flags = ui32Flags | PVRSRV_MEM_RAM_BACKED_ALLOCATION;
+
+ bBMError = BM_Alloc (hDevMemHeap,
+ IMG_NULL,
+ ui32Size,
+ &psMemInfo->ui32Flags,
+ IMG_CAST_TO_DEVVADDR_UINT(ui32Alignment),
+ pvPrivData,
+ ui32PrivDataLength,
+ ui32ChunkSize,
+ ui32NumVirtChunks,
+ ui32NumPhysChunks,
+ pabMapChunk,
+ &hBuffer);
+
+ if (!bBMError)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"AllocDeviceMem: BM_Alloc Failed"));
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
+ /*not nulling pointer, out of scope*/
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ /* Fill in "Implementation dependant" section of mem info */
+ psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
+ psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
+
+ /* Convert from BM_HANDLE to external IMG_HANDLE */
+ psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
+
+ /* Fill in the public fields of the MEM_INFO structure */
+
+ psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
+
+ psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
+
+ if (ui32Flags & PVRSRV_MEM_SPARSE)
+ {
+ psMemInfo->uAllocSize = ui32ChunkSize * ui32NumVirtChunks;
+ }
+ else
+ {
+ psMemInfo->uAllocSize = ui32Size;
+ }
+
+ /* Clear the Backup buffer pointer as we do not have one at this point. We only allocate this as we are going up/down */
+ psMemInfo->pvSysBackupBuffer = IMG_NULL;
+
+ /* Update the Multimedia plane offsets */
+ UpdateDeviceMemoryPlaneOffsets(psMemInfo);
+
+ /*
+ * Setup the output.
+ */
+ *ppsMemInfo = psMemInfo;
+
+ /*
+ * And I think we're done for now....
+ */
+ return (PVRSRV_OK);
+}
+
+static PVRSRV_ERROR FreeDeviceMem2(PVRSRV_KERNEL_MEM_INFO *psMemInfo, PVRSRV_FREE_CALLBACK_ORIGIN eCallbackOrigin)
+{
+ BM_HANDLE hBuffer;
+
+ if (!psMemInfo)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ hBuffer = psMemInfo->sMemBlk.hBuffer;
+
+ switch(eCallbackOrigin)
+ {
+ case PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR:
+ BM_Free(hBuffer, psMemInfo->ui32Flags);
+ break;
+ case PVRSRV_FREE_CALLBACK_ORIGIN_IMPORTER:
+ BM_FreeExport(hBuffer, psMemInfo->ui32Flags);
+ break;
+ default:
+ break;
+ }
+
+ if (psMemInfo->pvSysBackupBuffer &&
+ eCallbackOrigin == PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psMemInfo->uAllocSize, psMemInfo->pvSysBackupBuffer, IMG_NULL);
+ psMemInfo->pvSysBackupBuffer = IMG_NULL;
+ }
+
+ if (psMemInfo->ui32RefCount == 0)
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
+
+ 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->uAllocSize, psMemInfo->pvSysBackupBuffer, IMG_NULL);
+ psMemInfo->pvSysBackupBuffer = IMG_NULL;
+ }
+
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
+
+ return(PVRSRV_OK);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVAllocSyncInfoKM
+
+ @Description
+
+ Allocates a sync info
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+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,
+ "Kernel Synchronization Info");
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ eError = OSAtomicAlloc(&psKernelSyncInfo->pvRefCount);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to allocate atomic"));
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL);
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+
+ /* Get the devnode from the devheap */
+ pBMContext = (BM_CONTEXT*)hDevMemContext;
+ psDevMemoryInfo = &pBMContext->psDeviceNode->sDevMemoryInfo;
+
+ /* and choose a heap for the syncinfo */
+ hSyncDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[psDevMemoryInfo->ui32SyncHeapID].hDevMemHeap;
+
+ /*
+ Cache consistent flag would be unnecessary if the heap attributes were
+ changed to specify it.
+ */
+ eError = AllocDeviceMem(hDevCookie,
+ hSyncDevMemHeap,
+ PVRSRV_MEM_CACHE_CONSISTENT,
+ sizeof(PVRSRV_SYNC_DATA),
+ sizeof(IMG_UINT32),
+ IMG_NULL,
+ 0,
+ 0, 0, 0, IMG_NULL, /* Sparse mapping args, not required */
+ &psKernelSyncInfo->psSyncDataMemInfoKM);
+
+ if (eError != PVRSRV_OK)
+ {
+
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory"));
+ OSAtomicFree(psKernelSyncInfo->pvRefCount);
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL);
+ /*not nulling pointer, out of scope*/
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ /* init sync data */
+ psKernelSyncInfo->psSyncData = psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM;
+ psSyncData = psKernelSyncInfo->psSyncData;
+
+ psSyncData->ui32WriteOpsPending = 0;
+ psSyncData->ui32WriteOpsComplete = 0;
+ psSyncData->ui32ReadOpsPending = 0;
+ psSyncData->ui32ReadOpsComplete = 0;
+ psSyncData->ui32ReadOps2Pending = 0;
+ psSyncData->ui32ReadOps2Complete = 0;
+ psSyncData->ui32LastOpDumpVal = 0;
+ psSyncData->ui32LastReadOpDumpVal = 0;
+ psSyncData->ui64LastWrite = 0;
+
+#if defined(PDUMP)
+ PDUMPCOMMENT("Allocating kernel sync object");
+ PDUMPMEM(psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM,
+ psKernelSyncInfo->psSyncDataMemInfoKM,
+ 0,
+ (IMG_UINT32)psKernelSyncInfo->psSyncDataMemInfoKM->uAllocSize,
+ PDUMP_FLAGS_CONTINUOUS,
+ 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->sReadOps2CompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32ReadOps2Complete);
+ psKernelSyncInfo->ui32UID = g_ui32SyncUID++;
+
+ /* syncinfo meminfo has no syncinfo! */
+ psKernelSyncInfo->psSyncDataMemInfoKM->psKernelSyncInfo = IMG_NULL;
+
+ OSAtomicInc(psKernelSyncInfo->pvRefCount);
+
+ /* return result */
+ *ppsKernelSyncInfo = psKernelSyncInfo;
+
+ return PVRSRV_OK;
+}
+
+IMG_EXPORT
+IMG_VOID PVRSRVAcquireSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo)
+{
+ OSAtomicInc(psKernelSyncInfo->pvRefCount);
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVFreeSyncInfoKM
+
+ @Description
+
+ Frees a sync info
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+IMG_EXPORT
+IMG_VOID IMG_CALLCONV PVRSRVReleaseSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo)
+{
+ if (OSAtomicDecAndTest(psKernelSyncInfo->pvRefCount))
+ {
+ FreeDeviceMem(psKernelSyncInfo->psSyncDataMemInfoKM);
+
+ /* Catch anyone who is trying to access the freed structure */
+ psKernelSyncInfo->psSyncDataMemInfoKM = IMG_NULL;
+ psKernelSyncInfo->psSyncData = IMG_NULL;
+ OSAtomicFree(psKernelSyncInfo->pvRefCount);
+ (IMG_VOID)OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL);
+ /*not nulling pointer, copy on stack*/
+ }
+}
+
+/*!
+******************************************************************************
+
+ @Function freeExternal
+
+ @Description
+
+ Code for freeing meminfo elements that are specific to external types memory
+
+ @Input psMemInfo : Kernel meminfo
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+
+static IMG_VOID freeExternal(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+ IMG_HANDLE hOSWrapMem = psMemInfo->sMemBlk.hOSWrapMem;
+
+ /* free the page addr array if req'd */
+ if(psMemInfo->sMemBlk.psIntSysPAddr)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psMemInfo->sMemBlk.psIntSysPAddr, IMG_NULL);
+ psMemInfo->sMemBlk.psIntSysPAddr = IMG_NULL;
+ }
+
+ /* Mem type dependent stuff */
+ if (psMemInfo->memType == PVRSRV_MEMTYPE_WRAPPED)
+ {
+ if(hOSWrapMem)
+ {
+ OSReleasePhysPageAddr(hOSWrapMem);
+ }
+ }
+#if defined(SUPPORT_ION)
+ else if (psMemInfo->memType == PVRSRV_MEMTYPE_ION)
+ {
+ if (hOSWrapMem)
+ {
+ IonUnimportBufferAndReleasePhysAddr(hOSWrapMem);
+ }
+ }
+#endif
+}
+
+/*!
+******************************************************************************
+
+ @Function FreeMemCallBackCommon
+
+ @Description
+
+ Common code for freeing device mem (called for freeing, unwrapping and unmapping)
+
+ @Input psMemInfo : Kernel meminfo
+ @Input ui32Param : packet size
+ @Input uibFromAllocatorParam : Are we being called by the original allocator?
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR FreeMemCallBackCommon(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32Param,
+ PVRSRV_FREE_CALLBACK_ORIGIN eCallbackOrigin)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+
+ /* decrement the refcount */
+ PVRSRVKernelMemInfoDecRef(psMemInfo);
+
+ /* check no other processes has this meminfo mapped */
+ if (psMemInfo->ui32RefCount == 0)
+ {
+ if((psMemInfo->ui32Flags & PVRSRV_MEM_EXPORTED) != 0)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMemInfo = 0;
+#else
+ IMG_HANDLE hMemInfo = IMG_NULL;
+#endif
+
+ /* find the handle */
+ eError = PVRSRVFindHandle(KERNEL_HANDLE_BASE,
+ &hMemInfo,
+ psMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: can't find exported meminfo in the global handle list"));
+ return eError;
+ }
+
+ /* release the handle */
+ eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE,
+ hMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: PVRSRVReleaseHandle failed for exported meminfo"));
+ return eError;
+ }
+ }
+
+ switch(psMemInfo->memType)
+ {
+ /* Fall through: Free only what we should for each memory type */
+ case PVRSRV_MEMTYPE_WRAPPED:
+ case PVRSRV_MEMTYPE_ION:
+ freeExternal(psMemInfo);
+ case PVRSRV_MEMTYPE_DEVICE:
+ case PVRSRV_MEMTYPE_DEVICECLASS:
+ if (psMemInfo->psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoDecRef(psMemInfo->psKernelSyncInfo, psMemInfo);
+ }
+ break;
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: Unknown memType"));
+ eError = PVRSRV_ERROR_INVALID_MEMINFO;
+ }
+ }
+
+#if defined(CONFIG_GCBV)
+ if (psMemInfo->ui32Flags & PVRSRV_MAP_GC_MMU)
+ gc_bvunmap_meminfo(psMemInfo);
+#endif
+
+ /*
+ * FreeDeviceMem2 will do the right thing, freeing
+ * the virtual memory info when the allocator calls
+ * but only releaseing the physical pages when everyone
+ * is done.
+ */
+
+ if (eError == PVRSRV_OK)
+ {
+ eError = FreeDeviceMem2(psMemInfo, eCallbackOrigin);
+ }
+
+ return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function FreeDeviceMemCallBack
+
+ @Description
+
+ ResMan call back to free device memory
+
+ @Input pvParam : data packet
+ @Input ui32Param : packet size
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+static PVRSRV_ERROR FreeDeviceMemCallBack(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)pvParam;
+
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ return FreeMemCallBackCommon(psMemInfo, ui32Param,
+ PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVFreeDeviceMemKM
+
+ @Description
+
+ Frees memory allocated with PVRAllocDeviceMem, including the mem_info structure
+
+ @Input psMemInfo :
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMemKM(IMG_HANDLE hDevCookie,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+ PVRSRV_ERROR eError;
+
+ PVR_UNREFERENCED_PARAMETER(hDevCookie);
+
+ if (!psMemInfo)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if (psMemInfo->sMemBlk.hResItem != IMG_NULL)
+ {
+ eError = ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL);
+ }
+ else
+ {
+ /* PVRSRV_MEM_NO_RESMAN */
+ eError = FreeDeviceMemCallBack(psMemInfo, 0, CLEANUP_WITH_POLL);
+ }
+
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVRemapToDevKM
+
+ @Description
+
+ Remaps buffer to GPU virtual address space
+
+ @Input psMemInfo
+
+ @Return PVRSRV_ERROR : 0 means the memory is still unmapped - ERROR,
+ * bigger than 0 (mapping reference count) - success mapping
+ * smaller than 0 - PVRSRV error
+******************************************************************************/
+IMG_EXPORT
+IMG_INT32 IMG_CALLCONV PVRSRVRemapToDevKM(IMG_HANDLE hDevCookie,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo, IMG_DEV_VIRTADDR *psDevVAddr)
+{
+ PVRSRV_MEMBLK *psMemBlock;
+ IMG_INT32 result;
+
+ PVR_UNREFERENCED_PARAMETER(hDevCookie);
+
+ if (!psMemInfo)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemapToDevKM: invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psMemBlock = &(psMemInfo->sMemBlk);
+
+ result = BM_RemapToDev(psMemBlock->hBuffer);
+
+ if(result <= 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemapToDevKM: could not remap"));
+ }
+
+ *psDevVAddr = psMemInfo->sDevVAddr =
+ psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(psMemBlock->hBuffer);
+
+ UpdateDeviceMemoryPlaneOffsets(psMemInfo);
+
+ return result;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVUnmapFromDevKM
+
+ @Description
+
+ Unmaps buffer from GPU virtual address space
+
+ @Input psMemInfo
+
+ @Return PVRSRV_ERROR : 0 means the memory is unmapped,
+ * bigger than 0 (mapping reference count) still mapped
+ * smaller than 0 - PVRSRV error
+******************************************************************************/
+IMG_EXPORT
+IMG_INT32 IMG_CALLCONV PVRSRVUnmapFromDevKM(IMG_HANDLE hDevCookie,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+ PVRSRV_MEMBLK *psMemBlock;
+ IMG_INT32 result;
+
+ PVR_UNREFERENCED_PARAMETER(hDevCookie);
+
+ if (!psMemInfo)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVUnmapFromDevKM: invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psMemBlock = &(psMemInfo->sMemBlk);
+
+ result = BM_UnmapFromDev(psMemBlock->hBuffer);
+ /* 0 means the memory is unmapped,
+ * bigger than 0 (mapping ref count) still mapped
+ * smaller than 0 PVRSRV error
+ */
+ if(result < 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVUnmapFromDevKM: could not unmap"));
+ }
+
+ psMemInfo->sDevVAddr =
+ psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(psMemBlock->hBuffer);
+
+ return result;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVAllocDeviceMemKM
+
+ @Description
+
+ Allocates device memory
+
+ @Input hDevCookie :
+ @Input psPerProc : Per-process data
+ @Input hDevMemHeap
+ @Input ui32Flags : Some combination of PVRSRV_MEM_ flags
+ @Input ui32Size : Number of bytes to allocate
+ @Input ui32Alignment :
+ @Output **ppsMemInfo : On success, receives a pointer to the created MEM_INFO structure
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV _PVRSRVAllocDeviceMemKM(IMG_HANDLE hDevCookie,
+ PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE hDevMemHeap,
+ IMG_UINT32 ui32Flags,
+ IMG_SIZE_T ui32Size,
+ IMG_SIZE_T ui32Alignment,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_UINT32 ui32ChunkSize,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_BOOL *pabMapChunk,
+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo)
+{
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo;
+ PVRSRV_ERROR eError;
+ BM_HEAP *psBMHeap;
+ IMG_HANDLE hDevMemContext;
+
+ if (!hDevMemHeap ||
+ ((ui32Size == 0) && ((ui32Flags & PVRSRV_MEM_SPARSE) == 0)) ||
+ (((ui32ChunkSize == 0) || (ui32NumVirtChunks == 0) || (ui32NumPhysChunks == 0) ||
+ (pabMapChunk == IMG_NULL )) && (ui32Flags & PVRSRV_MEM_SPARSE)))
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ /* Sprase alloc input validation */
+ if (ui32Flags & PVRSRV_MEM_SPARSE)
+ {
+ IMG_UINT32 i;
+ IMG_UINT32 ui32Check = 0;
+
+ if (ui32NumVirtChunks < ui32NumPhysChunks)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ for (i=0;i<ui32NumVirtChunks;i++)
+ {
+ if (pabMapChunk[i])
+ {
+ ui32Check++;
+ }
+ }
+ if (ui32NumPhysChunks != ui32Check)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ }
+
+ /* FIXME: At the moment we force CACHETYPE override allocations to
+ * be multiples of PAGE_SIZE and page aligned. If the RA/BM
+ * is fixed, this limitation can be removed.
+ *
+ * INTEGRATION_POINT: HOST_PAGESIZE() is not correct, should be device-specific.
+ */
+ if (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
+ {
+ /* PRQA S 3415 1 */ /* order of evaluation is not important */
+ if (((ui32Size % HOST_PAGESIZE()) != 0) ||
+ ((ui32Alignment % HOST_PAGESIZE()) != 0))
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ }
+
+ eError = AllocDeviceMem(hDevCookie,
+ hDevMemHeap,
+ ui32Flags,
+ ui32Size,
+ ui32Alignment,
+ pvPrivData,
+ ui32PrivDataLength,
+ ui32ChunkSize,
+ ui32NumVirtChunks,
+ ui32NumPhysChunks,
+ pabMapChunk,
+ &psMemInfo);
+
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+#if defined(CONFIG_GCBV)
+ if (ui32Flags & PVRSRV_MAP_GC_MMU)
+ gc_bvmap_meminfo(psMemInfo);
+#endif
+
+ if (ui32Flags & PVRSRV_MEM_NO_SYNCOBJ)
+ {
+ psMemInfo->psKernelSyncInfo = IMG_NULL;
+ }
+ else
+ {
+ /*
+ allocate a syncinfo but don't register with resman
+ because the holding devicemem will handle the syncinfo
+ */
+ psBMHeap = (BM_HEAP*)hDevMemHeap;
+ hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext;
+ eError = PVRSRVAllocSyncInfoKM(hDevCookie,
+ hDevMemContext,
+ &psMemInfo->psKernelSyncInfo);
+ if(eError != PVRSRV_OK)
+ {
+ goto free_mainalloc;
+ }
+ }
+
+ /*
+ * Setup the output.
+ */
+ *ppsMemInfo = psMemInfo;
+
+ if (ui32Flags & PVRSRV_MEM_NO_RESMAN)
+ {
+ psMemInfo->sMemBlk.hResItem = IMG_NULL;
+ }
+ else
+ {
+ /* register with the resman */
+ 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;
+ }
+ }
+
+ /* increment the refcount */
+ PVRSRVKernelMemInfoIncRef(psMemInfo);
+
+ psMemInfo->memType = PVRSRV_MEMTYPE_DEVICE;
+
+ /*
+ * And I think we're done for now....
+ */
+ return (PVRSRV_OK);
+
+free_mainalloc:
+ if (psMemInfo->psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoDecRef(psMemInfo->psKernelSyncInfo, psMemInfo);
+ }
+ FreeDeviceMem(psMemInfo);
+
+ return eError;
+}
+
+#if defined(SUPPORT_ION)
+static PVRSRV_ERROR IonUnmapCallback(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)pvParam;
+
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ return FreeMemCallBackCommon(psMemInfo, ui32Param, PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR);
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVMapIonHandleKM
+
+ @Description
+
+ Map an ION buffer into the specified device memory context
+
+ @Input psPerProc : PerProcess data
+ @Input hDevCookie : Device node cookie
+ @Input hDevMemContext : Device memory context cookie
+ @Input hIon : Handle to ION buffer
+ @Input ui32Flags : Mapping flags
+ @Input ui32Size : Mapping size
+ @Output ppsKernelMemInfo: Output kernel meminfo if successful
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVMapIonHandleKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE hDevCookie,
+ IMG_HANDLE hDevMemContext,
+ IMG_HANDLE hIon,
+ IMG_UINT32 ui32Flags,
+ IMG_UINT32 ui32Size,
+ PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo)
+{
+ PVRSRV_ENV_PER_PROCESS_DATA *psPerProcEnv = PVRSRVProcessPrivateData(psPerProc);
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ PVRSRV_KERNEL_MEM_INFO *psNewKernelMemInfo;
+ DEVICE_MEMORY_INFO *psDevMemoryInfo;
+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+ IMG_SYS_PHYADDR *pasSysPhysAddr;
+ PVRSRV_MEMBLK *psMemBlock;
+ PVRSRV_ERROR eError;
+ IMG_HANDLE hDevMemHeap = IMG_NULL;
+ IMG_HANDLE hPriv;
+ BM_HANDLE hBuffer;
+ IMG_UINT32 ui32HeapCount;
+ IMG_UINT32 ui32PageCount;
+ IMG_UINT32 i;
+ IMG_BOOL bAllocSync = (ui32Flags & PVRSRV_MEM_NO_SYNCOBJ)?IMG_FALSE:IMG_TRUE;
+
+ if ((hDevCookie == IMG_NULL) || (ui32Size == 0)
+ || (hDevMemContext == IMG_NULL) || (ppsKernelMemInfo == IMG_NULL))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Invalid params", __FUNCTION__));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
+
+ if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+ sizeof(PVRSRV_KERNEL_MEM_INFO),
+ (IMG_VOID **)&psNewKernelMemInfo, IMG_NULL,
+ "Kernel Memory Info") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"%s: Failed to alloc memory for block", __FUNCTION__));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ OSMemSet(psNewKernelMemInfo, 0, sizeof(PVRSRV_KERNEL_MEM_INFO));
+
+ /* Choose the heap to map to */
+ ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+ psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
+ for(i=0; i<PVRSRV_MAX_CLIENT_HEAPS; i++)
+ {
+ if(HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == psDevMemoryInfo->ui32IonHeapID)
+ {
+ if(psDeviceMemoryHeap[i].DevMemHeapType == DEVICE_MEMORY_HEAP_PERCONTEXT)
+ {
+ if (psDeviceMemoryHeap[i].ui32HeapSize > 0)
+ {
+ hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]);
+ }
+ else
+ {
+ hDevMemHeap = IMG_NULL;
+ }
+ }
+ else
+ {
+ hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap;
+ }
+ break;
+ }
+ }
+
+ if (hDevMemHeap == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to get ION heap", __FUNCTION__));
+ eError = PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO;
+ goto exitFailedHeap;
+ }
+
+ /* Import the ION buffer into our ion_client and DMA map it */
+ eError = IonImportBufferAndAquirePhysAddr(psPerProcEnv->psIONClient,
+ hIon,
+ &ui32PageCount,
+ &pasSysPhysAddr,
+ &psNewKernelMemInfo->pvLinAddrKM,
+ &hPriv);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to get ion buffer/buffer phys addr", __FUNCTION__));
+ goto exitFailedHeap;
+ }
+
+ /* Wrap the returned addresses into our memory context */
+ if (!BM_Wrap(hDevMemHeap,
+ ui32Size,
+ 0,
+ IMG_FALSE,
+ pasSysPhysAddr,
+ IMG_NULL,
+ &ui32Flags, /* This function clobbers our bits in ui32Flags */
+ &hBuffer))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to wrap ion buffer", __FUNCTION__));
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto exitFailedWrap;
+ }
+
+ /* Fill in "Implementation dependant" section of mem info */
+ psMemBlock = &psNewKernelMemInfo->sMemBlk;
+ psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
+ psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
+ psMemBlock->hBuffer = (IMG_HANDLE) hBuffer;
+ psMemBlock->hOSWrapMem = hPriv; /* Saves creating a new element as we know hOSWrapMem will not be used */
+ psMemBlock->psIntSysPAddr = pasSysPhysAddr;
+
+ psNewKernelMemInfo->ui32Flags = ui32Flags;
+ psNewKernelMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
+ psNewKernelMemInfo->uAllocSize = ui32Size;
+ psNewKernelMemInfo->memType = PVRSRV_MEMTYPE_ION;
+ PVRSRVKernelMemInfoIncRef(psNewKernelMemInfo);
+
+ /* Clear the Backup buffer pointer as we do not have one at this point. We only allocate this as we are going up/down */
+ psNewKernelMemInfo->pvSysBackupBuffer = IMG_NULL;
+
+ if (!bAllocSync)
+ {
+ psNewKernelMemInfo->psKernelSyncInfo = IMG_NULL;
+ }
+ else
+ {
+ eError = PVRSRVAllocSyncInfoKM(hDevCookie,
+ hDevMemContext,
+ &psNewKernelMemInfo->psKernelSyncInfo);
+ if(eError != PVRSRV_OK)
+ {
+ goto exitFailedSync;
+ }
+ }
+
+ /* register with the resman */
+ psNewKernelMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_DEVICEMEM_ION,
+ psNewKernelMemInfo,
+ 0,
+ &IonUnmapCallback);
+ if (psNewKernelMemInfo->sMemBlk.hResItem == IMG_NULL)
+ {
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto exitFailedResman;
+ }
+
+ psNewKernelMemInfo->memType = PVRSRV_MEMTYPE_ION;
+
+ *ppsKernelMemInfo = psNewKernelMemInfo;
+ return PVRSRV_OK;
+
+exitFailedResman:
+ if (psNewKernelMemInfo->psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoDecRef(psNewKernelMemInfo->psKernelSyncInfo, psNewKernelMemInfo);
+ }
+exitFailedSync:
+ BM_Free(hBuffer, ui32Flags);
+exitFailedWrap:
+ IonUnimportBufferAndReleasePhysAddr(hPriv);
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT,
+ sizeof(IMG_SYS_PHYADDR) * ui32PageCount,
+ pasSysPhysAddr,
+ IMG_NULL);
+exitFailedHeap:
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT,
+ sizeof(PVRSRV_KERNEL_MEM_INFO),
+ psNewKernelMemInfo,
+ IMG_NULL);
+
+ return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVUnmapIonHandleKM
+
+ @Description
+
+ Frees an ion buffer mapped with PVRSRVMapIonHandleKM, including the mem_info structure
+
+ @Input psMemInfo :
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapIonHandleKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+ if (!psMemInfo)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL);
+}
+#endif /* SUPPORT_ION */
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVDissociateDeviceMemKM
+
+ @Description
+
+ Dissociates memory from the process that allocates it. Intended for
+ transfering the ownership of device memory from a particular process
+ to the kernel.
+
+ @Input psMemInfo :
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+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;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVGetFreeDeviceMemKM
+
+ @Description
+
+ Determines how much memory remains available in the system with the specified
+ capabilities.
+
+ @Input ui32Flags :
+
+ @Output pui32Total :
+
+ @Output pui32Free :
+
+ @Output pui32LargestBlock :
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetFreeDeviceMemKM(IMG_UINT32 ui32Flags,
+ IMG_SIZE_T *pui32Total,
+ IMG_SIZE_T *pui32Free,
+ IMG_SIZE_T *pui32LargestBlock)
+{
+ /* TO BE IMPLEMENTED */
+
+ PVR_UNREFERENCED_PARAMETER(ui32Flags);
+ PVR_UNREFERENCED_PARAMETER(pui32Total);
+ PVR_UNREFERENCED_PARAMETER(pui32Free);
+ PVR_UNREFERENCED_PARAMETER(pui32LargestBlock);
+
+ return PVRSRV_OK;
+}
+
+
+
+
+/*!
+******************************************************************************
+ @Function PVRSRVUnwrapExtMemoryKM
+
+ @Description On last unwrap of a given meminfo, unmaps physical pages from a
+ wrapped allocation, and frees the associated device address space.
+ Note: this can only unmap memory mapped by PVRSRVWrapExtMemory
+
+ @Input psMemInfo - mem info describing the wrapped allocation
+ @Return None
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemoryKM (PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+ if (!psMemInfo)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL);
+}
+
+
+/*!
+******************************************************************************
+ @Function UnwrapExtMemoryCallBack
+
+ @Description Resman callback to unwrap memory
+
+ @Input pvParam - opaque void ptr param
+ @Input ui32Param - opaque unsigned long param
+ @Return PVRSRV_ERROR
+******************************************************************************/
+static PVRSRV_ERROR UnwrapExtMemoryCallBack(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)pvParam;
+
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ return FreeMemCallBackCommon(psMemInfo, ui32Param,
+ PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR);
+}
+
+
+/*!
+******************************************************************************
+ @Function PVRSRVWrapExtMemoryKM
+
+ @Description Allocates a Device Virtual Address in the shared mapping heap
+ and maps physical pages into that allocation. Note, if the pages are
+ already mapped into the heap, the existing allocation is returned.
+
+ @Input hDevCookie - Device cookie
+ @Input psPerProc - Per-process data
+ @Input hDevMemContext - device memory context
+ @Input uByteSize - Size of allocation
+ @Input uPageOffset - Offset into the first page of the memory to be wrapped
+ @Input bPhysContig - whether the underlying memory is physically contiguous
+ @Input psExtSysPAddr - The list of Device Physical page addresses
+ @Input pvLinAddr - ptr to buffer to wrap
+ @Output ppsMemInfo - mem info describing the wrapped allocation
+ @Return None
+******************************************************************************/
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemoryKM(IMG_HANDLE hDevCookie,
+ PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE hDevMemContext,
+ IMG_SIZE_T uByteSize,
+ IMG_SIZE_T uPageOffset,
+ IMG_BOOL bPhysContig,
+ IMG_SYS_PHYADDR *psExtSysPAddr,
+ IMG_VOID *pvLinAddr,
+ IMG_UINT32 ui32Flags,
+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo)
+{
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL;
+ DEVICE_MEMORY_INFO *psDevMemoryInfo;
+ IMG_SIZE_T 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 i;
+ IMG_SIZE_T uPageCount = 0;
+
+
+ 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)
+ {
+ /* derive the page offset from the cpu ptr (in case it's not supplied) */
+ uPageOffset = (IMG_UINTPTR_T)pvLinAddr & (ui32HostPageSize - 1);
+
+ /* get the pagecount and the page aligned base ptr */
+ uPageCount = HOST_PAGEALIGN(uByteSize + uPageOffset) / ui32HostPageSize;
+ pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)pvLinAddr - uPageOffset);
+
+ /* allocate array of SysPAddr to hold page addresses */
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ uPageCount * sizeof(IMG_SYS_PHYADDR),
+ (IMG_VOID **)&psIntSysPAddr, IMG_NULL,
+ "Array of Page Addresses") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr,
+ uPageCount * 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;//FIXME: need better error code
+ goto ErrorExitPhase1;
+ }
+
+ /* replace the supplied page address list */
+ psExtSysPAddr = psIntSysPAddr;
+
+ /* assume memory is not physically contiguous;
+ we shouldn't trust what the user says here
+ */
+ bPhysContig = IMG_FALSE;
+ }
+
+ /* Choose the heap to map to */
+ 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)
+ {
+ if (psDeviceMemoryHeap[i].ui32HeapSize > 0)
+ {
+ hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]);
+ }
+ else
+ {
+ hDevMemHeap = IMG_NULL;
+ }
+ }
+ 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_UNABLE_TO_FIND_MAPPING_HEAP;
+ goto ErrorExitPhase2;
+ }
+
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_KERNEL_MEM_INFO),
+ (IMG_VOID **)&psMemInfo, IMG_NULL,
+ "Kernel Memory Info") != 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));
+ psMemInfo->ui32Flags = ui32Flags;
+
+ psMemBlock = &(psMemInfo->sMemBlk);
+
+ bBMError = BM_Wrap(hDevMemHeap,
+ uByteSize,
+ uPageOffset,
+ 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;
+ }
+
+ /* Fill in "Implementation dependant" section of mem info */
+ psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
+ psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
+ psMemBlock->hOSWrapMem = hOSWrapMem;
+ psMemBlock->psIntSysPAddr = psIntSysPAddr;
+
+ /* Convert from BM_HANDLE to external IMG_HANDLE */
+ psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
+
+ /* Fill in the public fields of the MEM_INFO structure */
+ psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
+ psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
+ psMemInfo->uAllocSize = uByteSize;
+
+ /* Clear the Backup buffer pointer as we do not have one at this point.
+ We only allocate this as we are going up/down
+ */
+ psMemInfo->pvSysBackupBuffer = IMG_NULL;
+
+ /*
+ allocate a syncinfo but don't register with resman
+ because the holding devicemem will handle the syncinfo
+ */
+ psBMHeap = (BM_HEAP*)hDevMemHeap;
+ hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext;
+ eError = PVRSRVAllocSyncInfoKM(hDevCookie,
+ hDevMemContext,
+ &psMemInfo->psKernelSyncInfo);
+ if(eError != PVRSRV_OK)
+ {
+ goto ErrorExitPhase4;
+ }
+
+ /* increment the refcount */
+ PVRSRVKernelMemInfoIncRef(psMemInfo);
+
+ psMemInfo->memType = PVRSRV_MEMTYPE_WRAPPED;
+
+ /* Register Resource */
+ psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_DEVICEMEM_WRAP,
+ psMemInfo,
+ 0,
+ &UnwrapExtMemoryCallBack);
+
+ /* return the meminfo */
+ *ppsMemInfo = psMemInfo;
+
+ return PVRSRV_OK;
+
+ /* error handling: */
+
+ErrorExitPhase4:
+ if(psMemInfo)
+ {
+ FreeDeviceMem(psMemInfo);
+ /*
+ FreeDeviceMem will free the meminfo so set
+ it to NULL to avoid double free below
+ */
+ psMemInfo = IMG_NULL;
+ }
+
+ErrorExitPhase3:
+ if(psMemInfo)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
+ /*not nulling pointer, out of scope*/
+ }
+
+ErrorExitPhase2:
+ if(psIntSysPAddr)
+ {
+ OSReleasePhysPageAddr(hOSWrapMem);
+ }
+
+ErrorExitPhase1:
+ if(psIntSysPAddr)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, uPageCount * sizeof(IMG_SYS_PHYADDR), psIntSysPAddr, IMG_NULL);
+ /*not nulling shared pointer, uninitialized to this point*/
+ }
+
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVUnmapDeviceMemoryKM
+
+ @Description
+ Unmaps an existing allocation previously mapped by PVRSRVMapDeviceMemory
+
+ @Input psMemInfo
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemoryKM (PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+ if (!psMemInfo)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL);
+}
+
+
+/*!
+******************************************************************************
+ @Function UnmapDeviceMemoryCallBack
+
+ @Description Resman callback to unmap memory memory previously mapped
+ from one allocation to another
+
+ @Input pvParam - opaque void ptr param
+ @Input ui32Param - opaque unsigned long param
+ @Return PVRSRV_ERROR
+******************************************************************************/
+static PVRSRV_ERROR UnmapDeviceMemoryCallBack(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ PVRSRV_ERROR eError;
+ RESMAN_MAP_DEVICE_MEM_DATA *psMapData = pvParam;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ if(psMapData->psMemInfo->sMemBlk.psIntSysPAddr)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psMapData->psMemInfo->sMemBlk.psIntSysPAddr, IMG_NULL);
+ psMapData->psMemInfo->sMemBlk.psIntSysPAddr = IMG_NULL;
+ }
+
+ if( psMapData->psMemInfo->psKernelSyncInfo )
+ {
+ PVRSRVKernelSyncInfoDecRef(psMapData->psMemInfo->psKernelSyncInfo, psMapData->psMemInfo);
+ }
+
+ eError = FreeDeviceMem(psMapData->psMemInfo);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceMemoryCallBack: Failed to free DST meminfo"));
+ return eError;
+ }
+
+ /* This will only free the src psMemInfo if we hold the last reference */
+ eError = FreeMemCallBackCommon(psMapData->psSrcMemInfo, 0,
+ PVRSRV_FREE_CALLBACK_ORIGIN_IMPORTER);
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_MAP_DEVICE_MEM_DATA), psMapData, IMG_NULL);
+ /*not nulling pointer, copy on stack*/
+
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVMapDeviceMemoryKM
+
+ @Description
+ Maps an existing allocation to a specific device address space and heap
+ Note: it's valid to map from one physical device to another
+
+ @Input psPerProc : Per-process data
+ @Input psSrcMemInfo
+ @Input hDstDevMemHeap
+ @Input ppsDstMemInfo
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+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_SIZE_T uPageCount, uPageOffset;
+ IMG_SIZE_T 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;
+
+ /* check params */
+ if(!psSrcMemInfo || !hDstDevMemHeap || !ppsDstMemInfo)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ /* initialise the Dst Meminfo to NULL*/
+ *ppsDstMemInfo = IMG_NULL;
+
+ uPageOffset = psSrcMemInfo->sDevVAddr.uiAddr & (ui32HostPageSize - 1);
+ uPageCount = HOST_PAGEALIGN(psSrcMemInfo->uAllocSize + uPageOffset) / ui32HostPageSize;
+ pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)psSrcMemInfo->pvLinAddrKM - uPageOffset);
+
+ /*
+ allocate array of SysPAddr to hold SRC allocation page addresses
+ */
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ uPageCount*sizeof(IMG_SYS_PHYADDR),
+ (IMG_VOID **)&psSysPAddr, IMG_NULL,
+ "Array of Page Addresses") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc memory for block"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ psBuf = psSrcMemInfo->sMemBlk.hBuffer;
+
+ /* get the device node */
+ psDeviceNode = psBuf->pMapping->pBMHeap->pBMContext->psDeviceNode;
+
+ /* build a list of physical page addresses */
+ sDevVAddr.uiAddr = psSrcMemInfo->sDevVAddr.uiAddr - IMG_CAST_TO_DEVVADDR_UINT(uPageOffset);
+ for(i=0; i<uPageCount; i++)
+ {
+ BM_GetPhysPageAddr(psSrcMemInfo, sDevVAddr, &sDevPAddr);
+
+ /* save the address */
+ psSysPAddr[i] = SysDevPAddrToSysPAddr (psDeviceNode->sDevId.eDeviceType, sDevPAddr);
+
+ /* advance the DevVaddr one page */
+ sDevVAddr.uiAddr += IMG_CAST_TO_DEVVADDR_UINT(ui32HostPageSize);
+ }
+
+ /* allocate the resman map data */
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(RESMAN_MAP_DEVICE_MEM_DATA),
+ (IMG_VOID **)&psMapData, IMG_NULL,
+ "Resource Manager Map Data") != 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,
+ "Kernel Memory Info") != 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));
+ psMemInfo->ui32Flags = psSrcMemInfo->ui32Flags;
+
+ psMemBlock = &(psMemInfo->sMemBlk);
+
+ bBMError = BM_Wrap(hDstDevMemHeap,
+ psSrcMemInfo->uAllocSize,
+ uPageOffset,
+ 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;
+ }
+
+ /* Fill in "Implementation dependant" section of mem info */
+ psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
+ psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
+
+ /* Convert from BM_HANDLE to external IMG_HANDLE */
+ psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
+
+ /* Store page list */
+ psMemBlock->psIntSysPAddr = psSysPAddr;
+
+ /* patch up the CPU VAddr into the meminfo */
+ psMemInfo->pvLinAddrKM = psSrcMemInfo->pvLinAddrKM;
+
+ /* Fill in the public fields of the MEM_INFO structure */
+ psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
+ psMemInfo->uAllocSize = psSrcMemInfo->uAllocSize;
+ psMemInfo->psKernelSyncInfo = psSrcMemInfo->psKernelSyncInfo;
+
+ /* reference the same ksi that the original meminfo referenced */
+ if(psMemInfo->psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoIncRef(psMemInfo->psKernelSyncInfo, psMemInfo);
+ }
+
+ /* Clear the Backup buffer pointer as we do not have one at this point.
+ We only allocate this as we are going up/down
+ */
+ psMemInfo->pvSysBackupBuffer = IMG_NULL;
+
+ /* increment our refcount */
+ PVRSRVKernelMemInfoIncRef(psMemInfo);
+
+ /* increment the src refcount */
+ PVRSRVKernelMemInfoIncRef(psSrcMemInfo);
+
+ /* Tell the buffer manager about the export */
+ BM_Export(psSrcMemInfo->sMemBlk.hBuffer);
+
+ psMemInfo->memType = PVRSRV_MEMTYPE_MAPPED;
+
+ /* setup the resman map data */
+ psMapData->psMemInfo = psMemInfo;
+ psMapData->psSrcMemInfo = psSrcMemInfo;
+
+ /* Register Resource */
+ psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_DEVICEMEM_MAPPING,
+ psMapData,
+ 0,
+ &UnmapDeviceMemoryCallBack);
+
+ *ppsDstMemInfo = psMemInfo;
+
+ return PVRSRV_OK;
+
+ /* error handling: */
+
+ErrorExit:
+
+ if(psSysPAddr)
+ {
+ /* Free the page address list */
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psSysPAddr, IMG_NULL);
+ /*not nulling shared pointer, holding structure could be not initialized*/
+ }
+
+ if(psMemInfo)
+ {
+ /* Free the page address list */
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
+ /*not nulling shared pointer, holding structure could be not initialized*/
+ }
+
+ if(psMapData)
+ {
+ /* Free the resman map data */
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(RESMAN_MAP_DEVICE_MEM_DATA), psMapData, IMG_NULL);
+ /*not nulling pointer, out of scope*/
+ }
+
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+ @Function PVRSRVUnmapDeviceClassMemoryKM
+
+ @Description unmaps physical pages from devices address space at a specified
+ Device Virtual Address.
+ Note: this can only unmap memory mapped by
+ PVRSRVMapDeviceClassMemoryKM
+
+ @Input psMemInfo - mem info describing the device virtual address
+ to unmap RAM from
+ @Return None
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+ if (!psMemInfo)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL);
+}
+
+
+/*!
+******************************************************************************
+ @Function UnmapDeviceClassMemoryCallBack
+
+ @Description Resman callback to unmap device class memory
+
+ @Input pvParam - opaque void ptr param
+ @Input ui32Param - opaque unsigned long param
+ @Return PVRSRV_ERROR
+******************************************************************************/
+static PVRSRV_ERROR UnmapDeviceClassMemoryCallBack(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ PVRSRV_DC_MAPINFO *psDCMapInfo = pvParam;
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ psMemInfo = psDCMapInfo->psMemInfo;
+
+#if defined(SUPPORT_MEMORY_TILING)
+ if(psDCMapInfo->ui32TilingStride > 0)
+ {
+ PVRSRV_DEVICE_NODE *psDeviceNode = psDCMapInfo->psDeviceNode;
+
+ if (psDeviceNode->pfnFreeMemTilingRange(psDeviceNode,
+ psDCMapInfo->ui32RangeIndex) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceClassMemoryCallBack: FreeMemTilingRange failed"));
+ }
+ }
+#endif
+
+ (psDCMapInfo->psDeviceClassBuffer->ui32MemMapRefCount)--;
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_MAPINFO), psDCMapInfo, IMG_NULL);
+
+ return FreeMemCallBackCommon(psMemInfo, ui32Param,
+ PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR);
+}
+
+
+/*!
+******************************************************************************
+ @Function PVRSRVMapDeviceClassMemoryKM
+
+ @Description maps physical pages for DeviceClass buffers into a devices
+ address space at a specified and pre-allocated Device
+ Virtual Address
+
+ @Input psPerProc - Per-process data
+ @Input hDevMemContext - Device memory context
+ @Input hDeviceClassBuffer - Device Class Buffer (Surface) handle
+ @Input hDevMemContext - device memory context to which mapping
+ is made
+ @Output ppsMemInfo - mem info describing the mapped memory
+ @Output phOSMapInfo - OS specific mapping information
+ @Return None
+******************************************************************************/
+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_DEVICE_NODE* psDeviceNode;
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL;
+ 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_SIZE_T uByteSize;
+ IMG_SIZE_T ui32Offset;
+ IMG_SIZE_T ui32PageSize = HOST_PAGESIZE();
+ BM_HANDLE hBuffer;
+ PVRSRV_MEMBLK *psMemBlock;
+ IMG_BOOL bBMError;
+ IMG_UINT32 i;
+ PVRSRV_DC_MAPINFO *psDCMapInfo = IMG_NULL;
+
+ if(!hDeviceClassBuffer || !ppsMemInfo || !phOSMapInfo || !hDevMemContext)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ /* allocate resman storage structure */
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_DC_MAPINFO),
+ (IMG_VOID **)&psDCMapInfo, IMG_NULL,
+ "PVRSRV_DC_MAPINFO") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: Failed to alloc memory for psDCMapInfo"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ OSMemSet(psDCMapInfo, 0, sizeof(PVRSRV_DC_MAPINFO));
+
+ psDeviceClassBuffer = (PVRSRV_DEVICECLASS_BUFFER*)hDeviceClassBuffer;
+
+ /*
+ call into external driver to get info so we can map a meminfo
+ Notes:
+ It's expected that third party displays will only support
+ physically contiguous display surfaces. However, it's possible
+ a given display may have an MMU and therefore support non-contig'
+ display surfaces.
+
+ If surfaces are contiguous, ext driver should return:
+ - a CPU virtual address, or IMG_NULL where the surface is not mapped to CPU
+ - (optional) an OS Mapping handle for KM->UM surface mapping
+ - the size in bytes
+ - a single system physical address
+
+ If surfaces are non-contiguous, ext driver should return:
+ - a CPU virtual address
+ - (optional) an OS Mapping handle for KM->UM surface mapping
+ - the size in bytes (must be multiple of 4kB)
+ - a list of system physical addresses (at 4kB intervals)
+ */
+ eError = psDeviceClassBuffer->pfnGetBufferAddr(psDeviceClassBuffer->hExtDevice,
+ psDeviceClassBuffer->hExtBuffer,
+ &psSysPAddr,
+ &uByteSize,
+ &pvCPUVAddr,
+ phOSMapInfo,
+ &bPhysContig,
+ &psDCMapInfo->ui32TilingStride);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to get buffer address"));
+ goto ErrorExitPhase1;
+ }
+
+ /* Choose the heap to map to */
+ psBMContext = (BM_CONTEXT*)psDeviceClassBuffer->hDevMemContext;
+ psDeviceNode = psBMContext->psDeviceNode;
+ psDevMemoryInfo = &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)
+ {
+ if (psDeviceMemoryHeap[i].ui32HeapSize > 0)
+ {
+ hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]);
+ }
+ else
+ {
+ hDevMemHeap = IMG_NULL;
+ }
+ }
+ else
+ {
+ hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap;
+ }
+ break;
+ }
+ }
+
+ if(hDevMemHeap == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to find mapping heap"));
+ eError = PVRSRV_ERROR_UNABLE_TO_FIND_RESOURCE;
+ goto ErrorExitPhase1;
+ }
+
+ /* Only need lower 12 bits of the cpu addr - don't care what size a void* is */
+ ui32Offset = ((IMG_UINTPTR_T)pvCPUVAddr) & (ui32PageSize - 1);
+ pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)pvCPUVAddr - ui32Offset);
+
+ eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+ sizeof(PVRSRV_KERNEL_MEM_INFO),
+ (IMG_VOID **)&psMemInfo, IMG_NULL,
+ "Kernel Memory Info");
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: Failed to alloc memory for block"));
+ goto ErrorExitPhase1;
+ }
+
+ OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
+
+ psMemBlock = &(psMemInfo->sMemBlk);
+
+ bBMError = BM_Wrap(hDevMemHeap,
+ uByteSize,
+ ui32Offset,
+ bPhysContig,
+ psSysPAddr,
+ pvPageAlignedCPUVAddr,
+ &psMemInfo->ui32Flags,
+ &hBuffer);
+
+ if (!bBMError)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: BM_Wrap Failed"));
+ /*not nulling pointer, out of scope*/
+ eError = PVRSRV_ERROR_BAD_MAPPING;
+ goto ErrorExitPhase2;
+ }
+
+ /* Fill in "Implementation dependant" section of mem info */
+ psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
+ psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
+
+ /* Convert from BM_HANDLE to external IMG_HANDLE */
+ psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
+
+ /* patch up the CPU VAddr into the meminfo - use the address from the BM, not the one from the deviceclass
+ api, to ensure user mode mapping is possible
+ */
+ psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
+
+ /* Fill in the public fields of the MEM_INFO structure */
+ psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
+ psMemInfo->uAllocSize = uByteSize;
+ psMemInfo->psKernelSyncInfo = psDeviceClassBuffer->psKernelSyncInfo;
+
+ PVR_ASSERT(psMemInfo->psKernelSyncInfo != IMG_NULL);
+ if (psMemInfo->psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoIncRef(psMemInfo->psKernelSyncInfo, psMemInfo);
+ }
+
+ /* Clear the Backup buffer pointer as we do not have one at this point.
+ We only allocate this as we are going up/down
+ */
+ psMemInfo->pvSysBackupBuffer = IMG_NULL;
+
+ /* setup DCMapInfo */
+ psDCMapInfo->psMemInfo = psMemInfo;
+ psDCMapInfo->psDeviceClassBuffer = psDeviceClassBuffer;
+
+#if defined(SUPPORT_MEMORY_TILING)
+ psDCMapInfo->psDeviceNode = psDeviceNode;
+
+ if(psDCMapInfo->ui32TilingStride > 0)
+ {
+ /* try to acquire a tiling range on this device */
+ eError = psDeviceNode->pfnAllocMemTilingRange(psDeviceNode,
+ psMemInfo,
+ psDCMapInfo->ui32TilingStride,
+ &psDCMapInfo->ui32RangeIndex);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: AllocMemTilingRange failed"));
+ goto ErrorExitPhase3;
+ }
+ }
+#endif
+
+ /* Register Resource */
+ psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_DEVICECLASSMEM_MAPPING,
+ psDCMapInfo,
+ 0,
+ &UnmapDeviceClassMemoryCallBack);
+
+ (psDeviceClassBuffer->ui32MemMapRefCount)++;
+ PVRSRVKernelMemInfoIncRef(psMemInfo);
+
+ psMemInfo->memType = PVRSRV_MEMTYPE_DEVICECLASS;
+
+ /* return the meminfo */
+ *ppsMemInfo = psMemInfo;
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ /* If the 3PDD supplies a kernel virtual address, we can PDUMP it */
+ if(psMemInfo->pvLinAddrKM)
+ {
+ /* FIXME:
+ * Initialise the display surface here when it is mapped into Services.
+ * Otherwise there is a risk that pdump toolchain will assign previously
+ * used physical pages, leading to visual artefacts on the unrendered surface
+ * (e.g. during LLS rendering).
+ *
+ * A better method is to pdump the allocation from the DC driver, so the
+ * BM_Wrap pdumps only the virtual memory which better represents the driver
+ * behaviour.
+ */
+ PDUMPCOMMENT("Dump display surface");
+ PDUMPMEM(IMG_NULL, psMemInfo, ui32Offset, psMemInfo->uAllocSize, PDUMP_FLAGS_CONTINUOUS, ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping);
+ }
+#endif
+ return PVRSRV_OK;
+
+#if defined(SUPPORT_MEMORY_TILING)
+ErrorExitPhase3:
+ if(psMemInfo)
+ {
+ if (psMemInfo->psKernelSyncInfo)
+ {
+ PVRSRVKernelSyncInfoDecRef(psMemInfo->psKernelSyncInfo, psMemInfo);
+ }
+
+ FreeDeviceMem(psMemInfo);
+ /*
+ FreeDeviceMem will free the meminfo so set
+ it to NULL to avoid double free below
+ */
+ psMemInfo = IMG_NULL;
+ }
+#endif
+
+ErrorExitPhase2:
+ if(psMemInfo)
+ {
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
+ }
+
+ErrorExitPhase1:
+ if(psDCMapInfo)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psDCMapInfo, IMG_NULL);
+ }
+
+ return eError;
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVChangeDeviceMemoryAttributesKM(IMG_HANDLE hKernelMemInfo, IMG_UINT32 ui32Attribs)
+{
+ PVRSRV_KERNEL_MEM_INFO *psKMMemInfo;
+
+ if (hKernelMemInfo == IMG_NULL)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psKMMemInfo = (PVRSRV_KERNEL_MEM_INFO *)hKernelMemInfo;
+
+ if (ui32Attribs & PVRSRV_CHANGEDEVMEM_ATTRIBS_CACHECOHERENT)
+ {
+ psKMMemInfo->ui32Flags |= PVRSRV_MEM_CACHE_CONSISTENT;
+ }
+ else
+ {
+ psKMMemInfo->ui32Flags &= ~PVRSRV_MEM_CACHE_CONSISTENT;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+/******************************************************************************
+ End of file (devicemem.c)
+******************************************************************************/
+
diff --git a/pvr-source/services4/srvkm/common/handle.c b/pvr-source/services4/srvkm/common/handle.c
new file mode 100644
index 0000000..1e26047
--- /dev/null
+++ b/pvr-source/services4/srvkm/common/handle.c
@@ -0,0 +1,2689 @@
+/*************************************************************************/ /*!
+@Title Resource Handle Manager
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Provide resource handle management
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+/* See handle.h for a description of the handle API. */
+
+/*
+ * There is no locking here. It is assumed the code is used in a single
+ * threaded environment. In particular, it is assumed that the code will
+ * never be called from an interrupt handler.
+ *
+ * The implmentation supports movable handle structures, allowing the address
+ * of a handle structure to change without having to fix up pointers in
+ * any of the handle structures. For example, the linked list mechanism
+ * used to link subhandles together uses handle array indices rather than
+ * pointers to the structures themselves.
+ */
+
+#include <stddef.h>
+
+#include "services_headers.h"
+#include "handle.h"
+
+#ifdef DEBUG
+#define HANDLE_BLOCK_SHIFT 2
+#else
+#define HANDLE_BLOCK_SHIFT 8
+#endif
+
+#define DIVIDE_BY_BLOCK_SIZE(i) (((IMG_UINT32)(i)) >> HANDLE_BLOCK_SHIFT)
+#define MULTIPLY_BY_BLOCK_SIZE(i) (((IMG_UINT32)(i)) << HANDLE_BLOCK_SHIFT)
+
+#define HANDLE_BLOCK_SIZE MULTIPLY_BY_BLOCK_SIZE(1)
+#define HANDLE_SUB_BLOCK_MASK (HANDLE_BLOCK_SIZE - 1)
+#define HANDLE_BLOCK_MASK (~(HANDLE_SUB_BLOCK_MASK))
+
+#define HANDLE_HASH_TAB_INIT_SIZE 32
+
+#define INDEX_IS_VALID(psBase, i) ((i) < (psBase)->ui32TotalHandCount)
+
+/* Valid handles are never NULL, but handle array indices are based from 0 */
+#if defined (SUPPORT_SID_INTERFACE)
+#define INDEX_TO_HANDLE(i) ((IMG_SID)((i) + 1))
+#define HANDLE_TO_INDEX(h) ((IMG_UINT32)(h) - 1)
+#else
+#define INDEX_TO_HANDLE(i) ((IMG_HANDLE)((IMG_UINTPTR_T)(i) + 1))
+#define HANDLE_TO_INDEX(h) ((IMG_UINT32)(IMG_UINTPTR_T)(h) - 1)
+
+#endif
+
+#define INDEX_TO_BLOCK_INDEX(i) DIVIDE_BY_BLOCK_SIZE(i)
+#define BLOCK_INDEX_TO_INDEX(i) MULTIPLY_BY_BLOCK_SIZE(i)
+#define INDEX_TO_SUB_BLOCK_INDEX(i) ((i) & HANDLE_SUB_BLOCK_MASK)
+
+#define INDEX_TO_INDEX_STRUCT_PTR(psArray, i) (&((psArray)[INDEX_TO_BLOCK_INDEX(i)]))
+#define BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i) INDEX_TO_INDEX_STRUCT_PTR((psBase)->psHandleArray, i)
+
+#define INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, i) (BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i)->ui32FreeHandBlockCount)
+
+#define INDEX_TO_HANDLE_STRUCT_PTR(psBase, i) (BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i)->psHandle + INDEX_TO_SUB_BLOCK_INDEX(i))
+
+#define HANDLE_TO_HANDLE_STRUCT_PTR(psBase, h) (INDEX_TO_HANDLE_STRUCT_PTR(psBase, HANDLE_TO_INDEX(h)))
+
+#define HANDLE_PTR_TO_INDEX(psHandle) ((psHandle)->ui32Index)
+#define HANDLE_PTR_TO_HANDLE(psHandle) INDEX_TO_HANDLE(HANDLE_PTR_TO_INDEX(psHandle))
+
+#define ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(a) (HANDLE_BLOCK_MASK & (a))
+#define ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(a) ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE((a) + HANDLE_BLOCK_SIZE - 1)
+
+#define DEFAULT_MAX_HANDLE 0x7fffffffu
+#define DEFAULT_MAX_INDEX_PLUS_ONE ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(DEFAULT_MAX_HANDLE)
+
+#define HANDLES_BATCHED(psBase) ((psBase)->ui32HandBatchSize != 0)
+
+#define HANDLE_ARRAY_SIZE(handleCount) DIVIDE_BY_BLOCK_SIZE(ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(handleCount))
+
+#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))
+
+/*
+ * Linked list structure. Used for both the list head and list items.
+ * Array indices, rather than pointers, are used to point to the next and
+ * previous items on the list.
+ */
+struct sHandleList
+{
+ IMG_UINT32 ui32Prev;
+ IMG_UINT32 ui32Next;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hParent;
+#else
+ IMG_HANDLE hParent;
+#endif
+};
+
+enum ePVRSRVInternalHandleFlag
+{
+ INTERNAL_HANDLE_FLAG_NONE = 0x00,
+ INTERNAL_HANDLE_FLAG_BATCHED = 0x01,
+ INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE = 0x02,
+};
+
+/* Handle structure */
+struct sHandle
+{
+ /* Handle type */
+ PVRSRV_HANDLE_TYPE eType;
+
+ /* Pointer to the data that the handle represents */
+ IMG_VOID *pvData;
+
+ /*
+ * When handles are on the free list, the value of the "next index
+ * plus one field" has the following meaning:
+ * zero - next handle is the one that follows this one,
+ * nonzero - the index of the next handle is the value minus one.
+ * This scheme means handle space can be initialised to all zeros.
+ *
+ * When this field is used to link together handles on a list
+ * other than the free list, zero indicates the end of the
+ * list, with nonzero the same as above.
+ */
+ IMG_UINT32 ui32NextIndexPlusOne;
+
+ /* Internal flags */
+ enum ePVRSRVInternalHandleFlag eInternalFlag;
+
+ /* Flags specified when the handle was allocated */
+ PVRSRV_HANDLE_ALLOC_FLAG eFlag;
+
+ /* Index of this handle in the handle array */
+ IMG_UINT32 ui32Index;
+
+ /* List head for subhandles of this handle */
+ struct sHandleList sChildren;
+
+ /* List entry for sibling subhandles */
+ struct sHandleList sSiblings;
+};
+
+/* Handle array index structure.
+ * The handle array is an array of index structures, reallocated as the number of
+ * handles increases.
+ * NOTE: There is one index structure per block of handles.
+ */
+struct sHandleIndex
+{
+ /* Pointer to first handle structure in the block */
+ struct sHandle *psHandle;
+
+ /* Block allocation cookie returned from OSAllocMem for the block of handles */
+ IMG_HANDLE hBlockAlloc;
+
+ /* Number of free handles in block */
+ IMG_UINT32 ui32FreeHandBlockCount;
+};
+
+struct _PVRSRV_HANDLE_BASE_
+{
+ /* Handle returned from OSAllocMem for handle base allocation */
+ IMG_HANDLE hBaseBlockAlloc;
+
+ /* Handle returned from OSAllocMem for handle array allocation */
+ IMG_HANDLE hArrayBlockAlloc;
+
+ /* Pointer to array of pointers to handle structures */
+ struct sHandleIndex *psHandleArray;
+
+ /*
+ * Pointer to handle hash table.
+ * The hash table is used to do reverse lookups, converting data
+ * pointers to handles.
+ */
+ HASH_TABLE *psHashTab;
+
+ /* Number of free handles */
+ IMG_UINT32 ui32FreeHandCount;
+
+ /*
+ * If purging is not enabled, this is the array index of first free
+ * handle.
+ * If purging is enabled, this is the index to start searching for
+ * a free handle from. In this case it is usually zero, unless
+ * the handle array size has been increased due to lack of
+ * handles.
+ */
+ IMG_UINT32 ui32FirstFreeIndex;
+
+ /* Maximum handle index, plus one */
+ IMG_UINT32 ui32MaxIndexPlusOne;
+
+ /* Total number of handles, free and allocated */
+ IMG_UINT32 ui32TotalHandCount;
+
+ /*
+ * Index of the last free index, plus one. Not used if purging
+ * is enabled.
+ */
+ IMG_UINT32 ui32LastFreeIndexPlusOne;
+
+ /* Size of current handle batch, or zero if batching not enabled */
+ IMG_UINT32 ui32HandBatchSize;
+
+ /* Number of handles prior to start of current batch */
+ IMG_UINT32 ui32TotalHandCountPreBatch;
+
+ /* Index of first handle in batch, plus one */
+ IMG_UINT32 ui32FirstBatchIndexPlusOne;
+
+ /* Number of handle allocation failures in batch */
+ IMG_UINT32 ui32BatchHandAllocFailures;
+
+ /* Purging enabled.
+ * If purging is enabled, the size of the table can be reduced
+ * by removing free space at the end of the table. To make
+ * purging more likely to succeed, handles are allocated as
+ * far to the front of the table as possible. The first free
+ * handle is found by a linear search from the start of the table,
+ * and so no free handle list management is done.
+ */
+ IMG_BOOL bPurgingEnabled;
+};
+
+/*
+ * The key for the handle hash table is an array of three elements, the
+ * pointer to the resource, the resource type, and the process ID. The
+ * eHandKey enumeration gives the array indices of the elements making
+ * up the key.
+ */
+enum eHandKey {
+ HAND_KEY_DATA = 0,
+ HAND_KEY_TYPE,
+ HAND_KEY_PARENT,
+ HAND_KEY_LEN /* Must be last item in list */
+};
+
+/*
+ * Kernel handle base structure. For handles that are not allocated on
+ * behalf of a particular process
+ */
+PVRSRV_HANDLE_BASE *gpsKernelHandleBase = IMG_NULL;
+
+/* HAND_KEY is the type of the hash table key */
+typedef IMG_UINTPTR_T HAND_KEY[HAND_KEY_LEN];
+
+/*!
+******************************************************************************
+
+ @Function HandleListInit
+
+ @Description Initialise a linked list structure embedded in a handle
+ structure.
+
+ @Input ui32Index - index of handle in the handle array
+ psList - pointer to linked list structure
+ hParent - parent handle, or IMG_NULL
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListInit)
+#endif
+static INLINE
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_VOID HandleListInit(IMG_UINT32 ui32Index, struct sHandleList *psList, IMG_SID hParent)
+#else
+IMG_VOID HandleListInit(IMG_UINT32 ui32Index, struct sHandleList *psList, IMG_HANDLE hParent)
+#endif
+{
+ psList->ui32Next = ui32Index;
+ psList->ui32Prev = ui32Index;
+ psList->hParent = hParent;
+}
+
+/*!
+******************************************************************************
+
+ @Function InitParentList
+
+ @Description Initialise the children list head in a handle structure.
+ The children are the subhandles of this handle.
+
+ @Input psHandle - pointer to handle structure
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(InitParentList)
+#endif
+static INLINE
+IMG_VOID InitParentList(struct sHandle *psHandle)
+{
+ IMG_UINT32 ui32Parent = HANDLE_PTR_TO_INDEX(psHandle);
+
+ HandleListInit(ui32Parent, &psHandle->sChildren, INDEX_TO_HANDLE(ui32Parent));
+}
+
+/*!
+******************************************************************************
+
+ @Function InitChildEntry
+
+ @Description Initialise the child list entry in a handle structure.
+ The list entry is used to link together subhandles of
+ a given handle.
+
+ @Input psHandle - pointer to handle structure
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(InitChildEntry)
+#endif
+static INLINE
+IMG_VOID InitChildEntry(struct sHandle *psHandle)
+{
+ HandleListInit(HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sSiblings, IMG_NULL);
+}
+
+/*!
+******************************************************************************
+
+ @Function HandleListIsEmpty
+
+ @Description Determine whether a given linked list is empty.
+
+ @Input ui32Index - index of the handle containing the list head
+ psList - pointer to the list head
+
+ @Return IMG_TRUE if the list is empty, IMG_FALSE if it isn't.
+
+******************************************************************************/
+#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
+/*!
+******************************************************************************
+
+ @Function NoChildren
+
+ @Description Determine whether a handle has any subhandles
+
+ @Input psHandle - pointer to handle structure
+
+ @Return IMG_TRUE if the handle has no subhandles, IMG_FALSE if it does.
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(NoChildren)
+#endif
+static INLINE
+IMG_BOOL NoChildren(struct sHandle *psHandle)
+{
+ PVR_ASSERT(psHandle->sChildren.hParent == HANDLE_PTR_TO_HANDLE(psHandle));
+
+ return HandleListIsEmpty(HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sChildren);
+}
+
+/*!
+******************************************************************************
+
+ @Function NoParent
+
+ @Description Determine whether a handle is a subhandle
+
+ @Input psHandle - pointer to handle structure
+
+ @Return IMG_TRUE if the handle is not a subhandle, IMG_FALSE if it is.
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(NoParent)
+#endif
+static INLINE
+IMG_BOOL NoParent(struct sHandle *psHandle)
+{
+ if (HandleListIsEmpty(HANDLE_PTR_TO_INDEX(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 /*DEBUG*/
+/*!
+******************************************************************************
+
+ @Function ParentHandle
+
+ @Description Determine the parent of a handle
+
+ @Input psHandle - pointer to handle structure
+
+ @Return Parent handle, or IMG_NULL if the handle is not a subhandle.
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(ParentHandle)
+#endif
+static INLINE
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_SID ParentHandle(struct sHandle *psHandle)
+#else
+IMG_HANDLE ParentHandle(struct sHandle *psHandle)
+#endif
+{
+ return psHandle->sSiblings.hParent;
+}
+
+/*
+ * The LIST_PTR_FROM_INDEX_AND_OFFSET macro is used to generate either a
+ * pointer to the subhandle list head, or a pointer to the linked list
+ * structure of an item on a subhandle list.
+ * The list head is itself on the list, but is at a different offset
+ * in the handle structure to the linked list structure for items on
+ * the list. The two linked list structures are differentiated by
+ * the third parameter, containing the parent index. The parent field
+ * in the list head structure references the handle structure that contains
+ * it. For items on the list, the parent field in the linked list structure
+ * references the parent handle, which will be different from the handle
+ * containing the linked list structure.
+ */
+#define LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, i, p, po, eo) \
+ ((struct sHandleList *)((IMG_CHAR *)(INDEX_TO_HANDLE_STRUCT_PTR(psBase, i)) + (((i) == (p)) ? (po) : (eo))))
+
+/*!
+******************************************************************************
+
+ @Function HandleListInsertBefore
+
+ @Description Insert a handle before a handle currently on the list.
+
+ @Input ui32InsIndex - index of handle to be inserted after
+ psIns - pointer to handle structure to be inserted after
+ uiParentOffset - offset to list head struct in handle structure
+ ui32EntryIndex - index of handle to be inserted
+ psEntry - pointer to handle structure of item to be inserted
+ uiEntryOffset - offset of list item struct in handle structure
+
+******************************************************************************/
+#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)
+{
+ /* PRQA S 3305 7 */ /*override stricter alignment warning */
+ 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(ui32ParentIndex));
+
+ psEntry->ui32Prev = psIns->ui32Prev;
+ psIns->ui32Prev = ui32EntryIndex;
+ psEntry->ui32Next = ui32InsIndex;
+ psPrevIns->ui32Next = ui32EntryIndex;
+
+ psEntry->hParent = INDEX_TO_HANDLE(ui32ParentIndex);
+}
+
+/*!
+******************************************************************************
+
+ @Function AdoptChild
+
+ @Description Assign a subhandle to a handle
+
+ @Input psParent - pointer to handle structure of parent handle
+ psChild - pointer to handle structure of child subhandle
+
+******************************************************************************/
+#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(psParent->sChildren.hParent);
+
+ PVR_ASSERT(ui32Parent == HANDLE_PTR_TO_INDEX(psParent));
+
+ HandleListInsertBefore(psBase, ui32Parent, &psParent->sChildren, offsetof(struct sHandle, sChildren), HANDLE_PTR_TO_INDEX(psChild), &psChild->sSiblings, offsetof(struct sHandle, sSiblings), ui32Parent);
+
+}
+
+/*!
+******************************************************************************
+
+ @Function HandleListRemove
+
+ @Description Remove a handle from a list
+
+ @Input ui32EntryIndex - index of handle to be removed
+ psEntry - pointer to handle structure of item to be removed
+ uiEntryOffset - offset of list item struct in handle structure
+ uiParentOffset - offset to list head struct in handle structure
+
+******************************************************************************/
+#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))
+ {
+ /* PRQA S 3305 3 */ /*override stricter alignment warning */
+ struct sHandleList *psPrev = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psEntry->ui32Prev, HANDLE_TO_INDEX(psEntry->hParent), uiParentOffset, uiEntryOffset);
+ struct sHandleList *psNext = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psEntry->ui32Next, HANDLE_TO_INDEX(psEntry->hParent), uiParentOffset, uiEntryOffset);
+
+ /*
+ * The list head is on the list, and we don't want to
+ * remove it.
+ */
+ PVR_ASSERT(psEntry->hParent != IMG_NULL);
+
+ psPrev->ui32Next = psEntry->ui32Next;
+ psNext->ui32Prev = psEntry->ui32Prev;
+
+ HandleListInit(ui32EntryIndex, psEntry, IMG_NULL);
+ }
+}
+
+/*!
+******************************************************************************
+
+ @Function UnlinkFromParent
+
+ @Description Remove a subhandle from its parents list
+
+ @Input psHandle - pointer to handle structure of child subhandle
+
+******************************************************************************/
+#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(psHandle), &psHandle->sSiblings, offsetof(struct sHandle, sSiblings), offsetof(struct sHandle, sChildren));
+}
+
+/*!
+******************************************************************************
+
+ @Function HandleListIterate
+
+ @Description Iterate over the items in a list
+
+ @Input psHead - pointer to list head
+ uiParentOffset - offset to list head struct in handle structure
+ uiEntryOffset - offset of list item struct in handle structure
+ pfnIterFunc - function to be called for each handle in the list
+
+******************************************************************************/
+#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(psHead->hParent);
+
+ PVR_ASSERT(psHead->hParent != IMG_NULL);
+
+ /*
+ * Follow the next chain from the list head until we reach
+ * the list head again, which signifies the end of the list.
+ */
+ for(ui32Index = psHead->ui32Next; ui32Index != ui32Parent; )
+ {
+ struct sHandle *psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32Index);
+ /* PRQA S 3305 2 */ /*override stricter alignment warning */
+ struct sHandleList *psEntry = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, ui32Index, ui32Parent, uiParentOffset, uiEntryOffset);
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(psEntry->hParent == psHead->hParent);
+ /*
+ * Get the next index now, in case the list item is
+ * modified by the iteration function.
+ */
+ ui32Index = psEntry->ui32Next;
+
+ eError = (*pfnIterFunc)(psBase, psHandle);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function IterateOverChildren
+
+ @Description Iterate over the subhandles of a parent handle
+
+ @Input psParent - pointer to parent handle structure
+ pfnIterFunc - function to be called for each subhandle
+
+******************************************************************************/
+#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);
+}
+
+/*!
+******************************************************************************
+
+ @Function GetHandleStructure
+
+ @Description Get the handle structure for a given handle
+
+ @Input psBase - pointer to handle base structure
+ ppsHandle - location to return pointer to handle structure
+ hHandle - handle from client
+ eType - handle type or PVRSRV_HANDLE_TYPE_NONE if the
+ handle type is not to be checked.
+
+ @Output ppsHandle - points to a pointer to the handle structure
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(GetHandleStructure)
+#endif
+static INLINE
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR GetHandleStructure(PVRSRV_HANDLE_BASE *psBase, struct sHandle **ppsHandle, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType)
+#else
+PVRSRV_ERROR GetHandleStructure(PVRSRV_HANDLE_BASE *psBase, struct sHandle **ppsHandle, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+#endif
+{
+ IMG_UINT32 ui32Index = HANDLE_TO_INDEX(hHandle);
+ struct sHandle *psHandle;
+
+ /* Check handle index is in range */
+ if (!INDEX_IS_VALID(psBase, ui32Index))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle index out of range (%u >= %u)", ui32Index, psBase->ui32TotalHandCount));
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DBG_BREAK
+#endif
+ return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
+ }
+
+ psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32Index);
+ if (psHandle->eType == PVRSRV_HANDLE_TYPE_NONE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle not allocated (index: %u)", ui32Index));
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DBG_BREAK
+#endif
+ return PVRSRV_ERROR_HANDLE_NOT_ALLOCATED;
+ }
+
+ /*
+ * Unless PVRSRV_HANDLE_TYPE_NONE was passed in to this function,
+ * check handle is of the correct type.
+ */
+ if (eType != PVRSRV_HANDLE_TYPE_NONE && eType != psHandle->eType)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle type mismatch (%d != %d)", eType, psHandle->eType));
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DBG_BREAK
+#endif
+ return PVRSRV_ERROR_HANDLE_TYPE_MISMATCH;
+ }
+
+ /* Return the handle structure */
+ *ppsHandle = psHandle;
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function ParentIfPrivate
+
+ @Description Return the parent handle if the handle was allocated
+ with PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE, else return
+ IMG_NULL
+
+ @Input psHandle - pointer to handle
+
+ @Return Parent handle, or IMG_NULL
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(ParentIfPrivate)
+#endif
+static INLINE
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_SID ParentIfPrivate(struct sHandle *psHandle)
+#else
+IMG_HANDLE ParentIfPrivate(struct sHandle *psHandle)
+#endif
+{
+ return TEST_ALLOC_FLAG(psHandle, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ?
+ ParentHandle(psHandle) : IMG_NULL;
+}
+
+/*!
+******************************************************************************
+
+ @Function InitKey
+
+ @Description Initialise a hash table key for the current process
+
+ @Input psBase - pointer to handle base structure
+ aKey - pointer to key
+ pvData - pointer to the resource the handle represents
+ eType - type of resource
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(InitKey)
+#endif
+static INLINE
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_VOID InitKey(HAND_KEY aKey, PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_SID hParent)
+#else
+IMG_VOID InitKey(HAND_KEY aKey, PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hParent)
+#endif
+{
+ 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;
+}
+
+/*!
+******************************************************************************
+
+ @Function ReallocHandleArray
+
+ @Description Reallocate the handle array
+
+ @Input psBase - handle base.
+ phBlockAlloc - pointer to block allocation handle.
+ ui32NewCount - new handle count
+ ui32OldCount - old handle count
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+static
+PVRSRV_ERROR ReallocHandleArray(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32NewCount)
+{
+ struct sHandleIndex *psOldArray = psBase->psHandleArray;
+ IMG_HANDLE hOldArrayBlockAlloc = psBase->hArrayBlockAlloc;
+ IMG_UINT32 ui32OldCount = psBase->ui32TotalHandCount;
+ struct sHandleIndex *psNewArray = IMG_NULL;
+ IMG_HANDLE hNewArrayBlockAlloc = IMG_NULL;
+ PVRSRV_ERROR eError;
+ PVRSRV_ERROR eReturn = PVRSRV_OK;
+ IMG_UINT32 ui32Index;
+
+ if (ui32NewCount == ui32OldCount)
+ {
+ return PVRSRV_OK;
+ }
+
+ if (ui32NewCount != 0 && !psBase->bPurgingEnabled &&
+ ui32NewCount < ui32OldCount)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if (((ui32OldCount % HANDLE_BLOCK_SIZE) != 0) ||
+ ((ui32NewCount % HANDLE_BLOCK_SIZE) != 0))
+ {
+ PVR_ASSERT((ui32OldCount % HANDLE_BLOCK_SIZE) == 0);
+ PVR_ASSERT((ui32NewCount % HANDLE_BLOCK_SIZE) == 0);
+
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if (ui32NewCount != 0)
+ {
+ /* Allocate new handle array */
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ HANDLE_ARRAY_SIZE(ui32NewCount) * sizeof(struct sHandleIndex),
+ (IMG_VOID **)&psNewArray,
+ &hNewArrayBlockAlloc,
+ "Memory Area");
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't allocate new handle array (%d)", eError));
+ eReturn = eError;
+ goto error;
+ }
+
+ if (ui32OldCount != 0)
+ {
+ OSMemCopy(psNewArray, psOldArray, HANDLE_ARRAY_SIZE(MIN(ui32NewCount, ui32OldCount)) * sizeof(struct sHandleIndex));
+ }
+ }
+
+ /*
+ * If the new handle array is smaller than the old one, free
+ * unused handle structures
+ */
+ for(ui32Index = ui32NewCount; ui32Index < ui32OldCount; ui32Index += HANDLE_BLOCK_SIZE)
+ {
+ struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psOldArray, ui32Index);
+
+ eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(struct sHandle) * HANDLE_BLOCK_SIZE,
+ psIndex->psHandle,
+ psIndex->hBlockAlloc);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free handle structures (%d)", eError));
+ }
+ }
+
+ /*
+ * If the new handle array is bigger than the old one, allocate
+ * new handle structures
+ */
+ for(ui32Index = ui32OldCount; ui32Index < ui32NewCount; ui32Index += HANDLE_BLOCK_SIZE)
+ {
+ /* PRQA S 0505 1 */ /* psNewArray is never NULL, see assert earlier */
+ struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psNewArray, ui32Index);
+
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(struct sHandle) * HANDLE_BLOCK_SIZE,
+ (IMG_VOID **)&psIndex->psHandle,
+ &psIndex->hBlockAlloc,
+ "Memory Area");
+ if (eError != PVRSRV_OK)
+ {
+ psIndex->psHandle = IMG_NULL;
+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't allocate handle structures (%d)", eError));
+ eReturn = eError;
+ }
+ else
+ {
+ IMG_UINT32 ui32SubIndex;
+
+ psIndex->ui32FreeHandBlockCount = HANDLE_BLOCK_SIZE;
+
+ for(ui32SubIndex = 0; ui32SubIndex < HANDLE_BLOCK_SIZE; ui32SubIndex++)
+ {
+ struct sHandle *psHandle = psIndex->psHandle + ui32SubIndex;
+
+
+ psHandle->ui32Index = ui32SubIndex + ui32Index;
+ psHandle->eType = PVRSRV_HANDLE_TYPE_NONE;
+ psHandle->eInternalFlag = INTERNAL_HANDLE_FLAG_NONE;
+ psHandle->ui32NextIndexPlusOne = 0;
+ }
+ }
+ }
+ if (eReturn != PVRSRV_OK)
+ {
+ goto error;
+ }
+
+#ifdef DEBUG_MAX_HANDLE_COUNT
+ /* Force handle failure to test error exit code */
+ if (ui32NewCount > DEBUG_MAX_HANDLE_COUNT)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Max handle count (%u) reached", DEBUG_MAX_HANDLE_COUNT));
+ eReturn = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto error;
+ }
+#endif
+
+ if (psOldArray != IMG_NULL)
+ {
+ /* Free old handle array */
+ eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ HANDLE_ARRAY_SIZE(ui32OldCount) * sizeof(struct sHandleIndex),
+ psOldArray,
+ hOldArrayBlockAlloc);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free old handle array (%d)", eError));
+ }
+ }
+
+ psBase->psHandleArray = psNewArray;
+ psBase->hArrayBlockAlloc = hNewArrayBlockAlloc;
+ psBase->ui32TotalHandCount = ui32NewCount;
+
+ if (ui32NewCount > ui32OldCount)
+ {
+ /* Check for wraparound */
+ PVR_ASSERT(psBase->ui32FreeHandCount + (ui32NewCount - ui32OldCount) > psBase->ui32FreeHandCount);
+
+ /* PRQA S 3382 1 */ /* ui32NewCount always > ui32OldCount */
+ psBase->ui32FreeHandCount += (ui32NewCount - ui32OldCount);
+
+ /*
+ * If purging is enabled, there is no free handle list
+ * management, but as an optimization, when allocating
+ * new handles, we use ui32FirstFreeIndex to point to
+ * the first handle in a newly allocated block.
+ */
+ if (psBase->ui32FirstFreeIndex == 0)
+ {
+ PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0);
+
+ psBase->ui32FirstFreeIndex = ui32OldCount;
+ }
+ else
+ {
+ if (!psBase->bPurgingEnabled)
+ {
+ PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0);
+ PVR_ASSERT(INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne == 0);
+
+ INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne = ui32OldCount + 1;
+ }
+ }
+
+ if (!psBase->bPurgingEnabled)
+ {
+ psBase->ui32LastFreeIndexPlusOne = ui32NewCount;
+ }
+ }
+ else
+ {
+ PVR_ASSERT(ui32NewCount == 0 || psBase->bPurgingEnabled);
+ PVR_ASSERT(ui32NewCount == 0 || psBase->ui32FirstFreeIndex <= ui32NewCount);
+ PVR_ASSERT(psBase->ui32FreeHandCount - (ui32OldCount - ui32NewCount) < psBase->ui32FreeHandCount);
+
+ /* PRQA S 3382 1 */ /* ui32OldCount always >= ui32NewCount */
+ psBase->ui32FreeHandCount -= (ui32OldCount - ui32NewCount);
+
+ if (ui32NewCount == 0)
+ {
+ psBase->ui32FirstFreeIndex = 0;
+ psBase->ui32LastFreeIndexPlusOne = 0;
+ }
+ }
+
+ PVR_ASSERT(psBase->ui32FirstFreeIndex <= psBase->ui32TotalHandCount);
+
+ return PVRSRV_OK;
+
+error:
+ PVR_ASSERT(eReturn != PVRSRV_OK);
+
+ if (psNewArray != IMG_NULL)
+ {
+ /* Free any new handle structures that were allocated */
+ for(ui32Index = ui32OldCount; ui32Index < ui32NewCount; ui32Index += HANDLE_BLOCK_SIZE)
+ {
+ struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psNewArray, ui32Index);
+ if (psIndex->psHandle != IMG_NULL)
+ {
+ eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(struct sHandle) * HANDLE_BLOCK_SIZE,
+ psIndex->psHandle,
+ psIndex->hBlockAlloc);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free handle structures (%d)", eError));
+ }
+ }
+ }
+
+ /* Free new handle array */
+ eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ HANDLE_ARRAY_SIZE(ui32NewCount) * sizeof(struct sHandleIndex),
+ psNewArray,
+ hNewArrayBlockAlloc);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free new handle array (%d)", eError));
+ }
+ }
+
+ return eReturn;
+}
+
+/*!
+******************************************************************************
+
+ @Function FreeHandleArray
+
+ @Description Frees the handle array.
+ The memory containing the array of handle structure
+ pointers is deallocated.
+
+ @Input psBase - pointer to handle base structure
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+static PVRSRV_ERROR FreeHandleArray(PVRSRV_HANDLE_BASE *psBase)
+{
+ return ReallocHandleArray(psBase, 0);
+}
+
+/*!
+******************************************************************************
+
+ @Function FreeHandle
+
+ @Description Free a handle structure.
+
+ @Input psBase - pointer to handle base structure
+ psHandle - pointer to handle structure
+
+ @Return PVRSRV_OK or PVRSRV_ERROR
+
+******************************************************************************/
+static PVRSRV_ERROR FreeHandle(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle)
+{
+ HAND_KEY aKey;
+ IMG_UINT32 ui32Index = HANDLE_PTR_TO_INDEX(psHandle);
+ PVRSRV_ERROR eError;
+
+ /*
+ * If a handle allocated in batch mode is freed whilst still
+ * in batch mode, the type is set to PVRSRV_HANDLE_TYPE_NONE further
+ * down, to indicate the handle will not be used, but not actually
+ * freed. The Free is completed when this function is called a
+ * second time as part of the batch commit or release.
+ */
+
+ InitKey(aKey, psBase, psHandle->pvData, psHandle->eType, ParentIfPrivate(psHandle));
+
+ if (!TEST_ALLOC_FLAG(psHandle, PVRSRV_HANDLE_ALLOC_FLAG_MULTI) && !BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hHandle;
+ hHandle = (IMG_SID) HASH_Remove_Extended(psBase->psHashTab, aKey);
+#else
+ IMG_HANDLE hHandle;
+ hHandle = (IMG_HANDLE) HASH_Remove_Extended(psBase->psHashTab, aKey);
+
+#endif
+
+ PVR_ASSERT(hHandle != IMG_NULL);
+ PVR_ASSERT(hHandle == INDEX_TO_HANDLE(ui32Index));
+ PVR_UNREFERENCED_PARAMETER(hHandle);
+ }
+
+ /* Unlink handle from parent */
+ UnlinkFromParent(psBase, psHandle);
+
+ /* Free children */
+ eError = IterateOverChildren(psBase, psHandle, FreeHandle);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreeHandle: Error whilst freeing subhandles (%d)", eError));
+ return eError;
+ }
+
+ /*
+ * Clear the type here, so that a handle can no longer be looked
+ * up if it is only partially freed.
+ */
+ psHandle->eType = PVRSRV_HANDLE_TYPE_NONE;
+
+ if (BATCHED_HANDLE(psHandle) && !BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
+ {
+ /* PRQA S 1474,4130 1 */ /* ignore warnings about enum types being modified */
+ SET_BATCHED_HANDLE_PARTIALLY_FREE(psHandle);
+ /*
+ * If the handle was allocated in batch mode, delay the free
+ * until the batch commit or release.
+ */
+ return PVRSRV_OK;
+ }
+
+ /* No free list management if purging is enabled */
+ if (!psBase->bPurgingEnabled)
+ {
+ if (psBase->ui32FreeHandCount == 0)
+ {
+ PVR_ASSERT(psBase->ui32FirstFreeIndex == 0);
+ PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0);
+
+ psBase->ui32FirstFreeIndex = ui32Index;
+ }
+ else
+ {
+ /*
+ * Put the handle pointer on the end of the the free
+ * handle pointer linked list.
+ */
+ PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0);
+ PVR_ASSERT(INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne == 0);
+ INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne = ui32Index + 1;
+ }
+
+ PVR_ASSERT(psHandle->ui32NextIndexPlusOne == 0);
+
+ /* Update the end of the free handle linked list */
+ psBase->ui32LastFreeIndexPlusOne = ui32Index + 1;
+ }
+
+ psBase->ui32FreeHandCount++;
+ INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32Index)++;
+
+ PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32Index)<= HANDLE_BLOCK_SIZE);
+
+#ifdef DEBUG
+ {
+ IMG_UINT32 ui32BlockedIndex;
+ IMG_UINT32 ui32FreeHandCount = 0;
+
+ for (ui32BlockedIndex = 0; ui32BlockedIndex < psBase->ui32TotalHandCount; ui32BlockedIndex += HANDLE_BLOCK_SIZE)
+ {
+ ui32FreeHandCount += INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32BlockedIndex);
+ }
+
+ PVR_ASSERT(ui32FreeHandCount == psBase->ui32FreeHandCount);
+ }
+#endif
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function FreeAllHandles
+
+ @Description Free all handles for a given handle base
+
+ @Input psBase - pointer to handle base structure
+
+ @Return PVRSRV_OK or PVRSRV_ERROR
+
+******************************************************************************/
+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_STRUCT_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;
+ }
+
+ /* Break out of loop if all the handles free */
+ if (psBase->ui32FreeHandCount == psBase->ui32TotalHandCount)
+ {
+ break;
+ }
+ }
+ }
+
+ return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function FreeHandleBase
+
+ @Description Free a handle base.
+
+ @Input psHandleBase - pointer to handle base
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+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);
+ }
+
+ /* Free the handle array */
+ eError = FreeAllHandles(psBase);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handles (%d)", eError));
+ return eError;
+ }
+
+ /* Free the handle array */
+ 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)
+ {
+ /* Free the hash table */
+ 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;
+}
+
+/*!
+******************************************************************************
+
+ @Function FindHandle
+
+ @Description Find handle corresponding to a resource pointer
+
+ @Input psBase - pointer to handle base structure
+ pvData - pointer to resource to be associated with the handle
+ eType - the type of resource
+
+ @Return the handle, or IMG_NULL if not found
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(FindHandle)
+#endif
+static INLINE
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_SID FindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_SID hParent)
+#else
+IMG_HANDLE FindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hParent)
+#endif
+{
+ HAND_KEY aKey;
+
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+
+ InitKey(aKey, psBase, pvData, eType, hParent);
+
+#if defined (SUPPORT_SID_INTERFACE)
+ return (IMG_SID) HASH_Retrieve_Extended(psBase->psHashTab, aKey);
+#else
+ return (IMG_HANDLE) HASH_Retrieve_Extended(psBase->psHashTab, aKey);
+#endif
+}
+
+/*!
+******************************************************************************
+
+ @Function IncreaseHandleArraySize
+
+ @Description Allocate some more free handles
+
+ @Input psBase - pointer to handle base structure
+ ui32Delta - number of new handles required
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+static PVRSRV_ERROR IncreaseHandleArraySize(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32Delta)
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32DeltaAdjusted = ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(ui32Delta);
+ IMG_UINT32 ui32NewTotalHandCount = psBase->ui32TotalHandCount + ui32DeltaAdjusted;
+
+ PVR_ASSERT(ui32Delta != 0);
+
+ /*
+ * Check new count against max handle index, and check for wrap around.
+ */
+ 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);
+
+ /* Realloc handle pointer array */
+ eError = ReallocHandleArray(psBase, ui32NewTotalHandCount);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "IncreaseHandleArraySize: ReallocHandleArray failed (%d)", eError));
+ return eError;
+ }
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function EnsureFreeHandles
+
+ @Description Ensure there are enough free handles
+
+ @Input psBase - pointer to handle base structure
+ ui32Free - number of free handles required
+
+ @Return Error code or 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;
+}
+
+/*!
+******************************************************************************
+
+ @Function AllocHandle
+
+ @Description Allocate a new handle
+
+ @Input phHandle - location for new handle
+ pvData - pointer to resource to be associated with the handle
+ eType - the type of resource
+ hParent - parent handle or IMG_NULL
+
+ @Output phHandle - points to new handle
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+#if defined (SUPPORT_SID_INTERFACE)
+static PVRSRV_ERROR AllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_SID hParent)
+#else
+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)
+#endif
+{
+ IMG_UINT32 ui32NewIndex = DEFAULT_MAX_INDEX_PLUS_ONE;
+ struct sHandle *psNewHandle = IMG_NULL;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hHandle;
+#else
+ IMG_HANDLE hHandle;
+#endif
+ HAND_KEY aKey;
+ PVRSRV_ERROR eError;
+
+ /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+ PVR_ASSERT(psBase != IMG_NULL);
+ PVR_ASSERT(psBase->psHashTab != IMG_NULL);
+
+ if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+ {
+ /* Handle must not already exist */
+ 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));
+ }
+
+ /* Ensure there is a free handle */
+ 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)
+ {
+ /* Array index of first free handle */
+ ui32NewIndex = psBase->ui32FirstFreeIndex;
+
+ /* Get handle array entry */
+ psNewHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32NewIndex);
+ }
+ else
+ {
+ IMG_UINT32 ui32BlockedIndex;
+
+ /*
+ * If purging is enabled, we always try to allocate handles
+ * at the front of the array, to increase the chances that
+ * the size of the handle array can be reduced by a purge.
+ * No linked list of free handles is kept; we search for
+ * free handles as required.
+ */
+
+ /*
+ * ui32FirstFreeIndex should only be set when a new batch of
+ * handle structures is allocated, and should always be a
+ * multiple of the block size.
+ */
+ PVR_ASSERT((psBase->ui32FirstFreeIndex % HANDLE_BLOCK_SIZE) == 0);
+
+ for (ui32BlockedIndex = ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(psBase->ui32FirstFreeIndex); ui32BlockedIndex < psBase->ui32TotalHandCount; ui32BlockedIndex += HANDLE_BLOCK_SIZE)
+ {
+ struct sHandleIndex *psIndex = BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, ui32BlockedIndex);
+
+ if (psIndex->ui32FreeHandBlockCount == 0)
+ {
+ continue;
+ }
+
+ for (ui32NewIndex = ui32BlockedIndex; ui32NewIndex < ui32BlockedIndex + HANDLE_BLOCK_SIZE; ui32NewIndex++)
+ {
+ psNewHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32NewIndex);
+ if (HANDLE_STRUCT_IS_FREE(psNewHandle))
+ {
+ break;
+ }
+ }
+ }
+ psBase->ui32FirstFreeIndex = 0;
+ PVR_ASSERT(ui32NewIndex < psBase->ui32TotalHandCount);
+ }
+ PVR_ASSERT(psNewHandle != IMG_NULL);
+
+ /* Handle to be returned to client */
+ hHandle = INDEX_TO_HANDLE(ui32NewIndex);
+
+ /*
+ * If a data pointer can be associated with multiple handles, we
+ * don't put the handle in the hash table, as the data pointer
+ * may not map to a unique handle
+ */
+ if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+ {
+ /* Initialise hash key */
+ InitKey(aKey, psBase, pvData, eType, hParent);
+
+ /* Put the new handle in the hash table */
+ 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_UNABLE_TO_ADD_HANDLE;
+ }
+ }
+
+ psBase->ui32FreeHandCount--;
+
+ PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex) <= HANDLE_BLOCK_SIZE);
+ PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex) > 0);
+
+ INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex)--;
+
+ /* No free list management if purging is enabled */
+ if (!psBase->bPurgingEnabled)
+ {
+ /* Check whether the last free handle has been allocated */
+ if (psBase->ui32FreeHandCount == 0)
+ {
+ PVR_ASSERT(psBase->ui32FirstFreeIndex == ui32NewIndex);
+ PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == (ui32NewIndex + 1));
+
+ psBase->ui32LastFreeIndexPlusOne = 0;
+ psBase->ui32FirstFreeIndex = 0;
+ }
+ else
+ {
+ /*
+ * Update the first free handle index.
+ * If the "next free index plus one" field in the new
+ * handle structure is zero, the next free index is
+ * the index of the new handle plus one. This
+ * convention has been adopted to simplify the
+ * initialisation of freshly allocated handle
+ * space.
+ */
+ psBase->ui32FirstFreeIndex = (psNewHandle->ui32NextIndexPlusOne == 0) ?
+ ui32NewIndex + 1 :
+ psNewHandle->ui32NextIndexPlusOne - 1;
+ }
+ }
+
+ /* Initialise the newly allocated handle */
+ PVR_ASSERT(psNewHandle->ui32Index == ui32NewIndex);
+
+ /* PRQA S 0505 1 */ /* psNewHandle is never NULL, see assert earlier */
+ psNewHandle->eType = eType;
+ psNewHandle->pvData = pvData;
+ psNewHandle->eInternalFlag = INTERNAL_HANDLE_FLAG_NONE;
+ psNewHandle->eFlag = eFlag;
+
+ InitParentList(psNewHandle);
+#if defined(DEBUG)
+ PVR_ASSERT(NoChildren(psNewHandle));
+#endif
+
+ InitChildEntry(psNewHandle);
+#if defined(DEBUG)
+ PVR_ASSERT(NoParent(psNewHandle));
+#endif
+
+ if (HANDLES_BATCHED(psBase))
+ {
+ /* Add handle to batch list */
+ psNewHandle->ui32NextIndexPlusOne = psBase->ui32FirstBatchIndexPlusOne;
+
+ psBase->ui32FirstBatchIndexPlusOne = ui32NewIndex + 1;
+
+ /* PRQA S 1474 1 */ /* ignore warnings about enum types being modified */
+ SET_BATCHED_HANDLE(psNewHandle);
+ }
+ else
+ {
+ psNewHandle->ui32NextIndexPlusOne = 0;
+ }
+
+ /* Return the new handle to the client */
+ *phHandle = hHandle;
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVAllocHandle
+
+ @Description Allocate a handle
+
+ @Input phHandle - location for new handle
+ pvData - pointer to resource to be associated with the handle
+ eType - the type of resource
+
+ @Output phHandle - points to new handle
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag)
+#else
+PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag)
+#endif
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hHandle;
+#else
+ IMG_HANDLE hHandle;
+#endif
+ PVRSRV_ERROR eError;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ *phHandle = 0;
+#else
+ *phHandle = IMG_NULL;
+#endif
+
+ if (HANDLES_BATCHED(psBase))
+ {
+ /*
+ * Increment the counter in case of failure. It will be
+ * decremented on success.
+ */
+ psBase->ui32BatchHandAllocFailures++;
+ }
+
+ /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+
+ if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+ {
+ /* See if there is already a handle for this data pointer */
+ hHandle = FindHandle(psBase, pvData, eType, IMG_NULL);
+#if defined (SUPPORT_SID_INTERFACE)
+ if (hHandle != 0)
+#else
+ if (hHandle != IMG_NULL)
+#endif
+ {
+ 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 the client is willing to share a handle, and the
+ * existing handle is marked as shareable, return the
+ * existing handle.
+ */
+ if (TEST_FLAG(psHandle->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED))
+ {
+ *phHandle = hHandle;
+ eError = PVRSRV_OK;
+ goto exit_ok;
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DBG_BREAK
+#endif
+ return PVRSRV_ERROR_HANDLE_NOT_SHAREABLE;
+ }
+ }
+
+ eError = AllocHandle(psBase, phHandle, pvData, eType, eFlag, IMG_NULL);
+
+exit_ok:
+ if (HANDLES_BATCHED(psBase) && (eError == PVRSRV_OK))
+ {
+ psBase->ui32BatchHandAllocFailures--;
+ }
+
+ return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVAllocSubHandle
+
+ @Description Allocate a subhandle
+
+ @Input phHandle - location for new subhandle
+ pvData - pointer to resource to be associated with the subhandle
+ eType - the type of resource
+ hParent - parent handle
+
+ @Output phHandle - points to new subhandle
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_SID hParent)
+#else
+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)
+#endif
+{
+ struct sHandle *psPHand;
+ struct sHandle *psCHand;
+ PVRSRV_ERROR eError;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hParentKey;
+ IMG_SID hHandle;
+
+ *phHandle = 0;
+#else
+ IMG_HANDLE hParentKey;
+ IMG_HANDLE hHandle;
+
+ *phHandle = IMG_NULL;
+#endif
+
+ if (HANDLES_BATCHED(psBase))
+ {
+ /*
+ * Increment the counter in case of failure. It will be
+ * decremented on success.
+ */
+ psBase->ui32BatchHandAllocFailures++;
+ }
+
+ /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+
+ hParentKey = TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ?
+ hParent : IMG_NULL;
+
+ /* Lookup the parent handle */
+ eError = GetHandleStructure(psBase, &psPHand, hParent, PVRSRV_HANDLE_TYPE_NONE);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+ {
+ /* See if there is already a handle for this data pointer */
+ hHandle = FindHandle(psBase, pvData, eType, hParentKey);
+#if defined (SUPPORT_SID_INTERFACE)
+ if (hHandle != 0)
+#else
+ if (hHandle != IMG_NULL)
+#endif
+ {
+ 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_STRUCT_PTR(psBase, hHandle)) == hParent);
+
+ /*
+ * If the client is willing to share a handle, the
+ * existing handle is marked as shareable, and the
+ * existing handle has the same parent, return the
+ * existing handle.
+ */
+ if (TEST_FLAG(psCHandle->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED) && ParentHandle(HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hHandle)) == hParent)
+ {
+ *phHandle = hHandle;
+ goto exit_ok;
+ }
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DBG_BREAK
+#endif
+ return PVRSRV_ERROR_HANDLE_NOT_SHAREABLE;
+ }
+ }
+
+ eError = AllocHandle(psBase, &hHandle, pvData, eType, eFlag, hParentKey);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ /*
+ * Get the parent handle structure again, in case the handle
+ * structure has moved (depending on the implementation
+ * of AllocHandle).
+ */
+ psPHand = HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hParent);
+
+ psCHand = HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hHandle);
+
+ AdoptChild(psBase, psPHand, psCHand);
+
+ *phHandle = hHandle;
+
+exit_ok:
+ if (HANDLES_BATCHED(psBase))
+ {
+ psBase->ui32BatchHandAllocFailures--;
+ }
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVFindHandle
+
+ @Description Find handle corresponding to a resource pointer
+
+ @Input phHandle - location for returned handle
+ pvData - pointer to resource to be associated with the handle
+ eType - the type of resource
+
+ @Output phHandle - points to handle
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType)
+#else
+PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType)
+#endif
+{
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hHandle;
+#else
+ IMG_HANDLE hHandle;
+#endif
+
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+
+ /* See if there is a handle for this data pointer */
+#if defined (SUPPORT_SID_INTERFACE)
+ hHandle = (IMG_SID) FindHandle(psBase, pvData, eType, IMG_NULL);
+#else
+ hHandle = (IMG_HANDLE) FindHandle(psBase, pvData, eType, IMG_NULL);
+#endif
+ if (hHandle == IMG_NULL)
+ {
+ return PVRSRV_ERROR_HANDLE_NOT_FOUND;
+ }
+
+ *phHandle = hHandle;
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVLookupHandleAnyType
+
+ @Description Lookup the data pointer and type corresponding to a handle
+
+ @Input ppvData - location to return data pointer
+ peType - location to return handle type
+ hHandle - handle from client
+
+ @Output ppvData - points to the data pointer
+ peType - points to handle type
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_SID hHandle)
+#else
+PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle)
+#endif
+{
+ 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));
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DBG_BREAK
+#endif
+ return eError;
+ }
+
+ *ppvData = psHandle->pvData;
+ *peType = psHandle->eType;
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVLookupHandle
+
+ @Description Lookup the data pointer corresponding to a handle
+
+ @Input ppvData - location to return data pointer
+ hHandle - handle from client
+ eType - handle type
+
+ @Output ppvData - points to the data pointer
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType)
+#else
+PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+#endif
+{
+ struct sHandle *psHandle;
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_ASSERT(hHandle != 0);
+#endif
+
+ eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupHandle: Error looking up handle (%d)", eError));
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DBG_BREAK
+#endif
+ return eError;
+ }
+
+ *ppvData = psHandle->pvData;
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVLookupSubHandle
+
+ @Description Lookup the data pointer corresponding to a subhandle
+
+ @Input ppvData - location to return data pointer
+ hHandle - handle from client
+ eType - handle type
+ hAncestor - ancestor handle
+
+ @Output ppvData - points to the data pointer
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType, IMG_SID hAncestor)
+#else
+PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor)
+#endif
+{
+ struct sHandle *psPHand;
+ struct sHandle *psCHand;
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_ASSERT(hHandle != 0);
+#endif
+
+ eError = GetHandleStructure(psBase, &psCHand, hHandle, eType);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupSubHandle: Error looking up subhandle (%d)", eError));
+ return eError;
+ }
+
+ /* Look for hAncestor among the handle's ancestors */
+ 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_INVALID_SUBHANDLE;
+ }
+ }
+
+ *ppvData = psCHand->pvData;
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVGetParentHandle
+
+ @Description Lookup the parent of a handle
+
+ @Input phParent - location for returning parent handle
+ hHandle - handle for which the parent handle is required
+ eType - handle type
+ hParent - parent handle
+
+ @Output *phParent - parent handle, or IMG_NULL if there is no parent
+
+ @Return Error code or PVRSRV_OK. Note that not having a parent is
+ not regarded as an error.
+
+******************************************************************************/
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phParent, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType)
+#else
+PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+#endif
+{
+ 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;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVLookupAndReleaseHandle
+
+ @Description Lookup the data pointer corresponding to a handle
+
+ @Input ppvData - location to return data pointer
+ hHandle - handle from client
+ eType - handle type
+ eFlag - lookup flags
+
+ @Output ppvData - points to the data pointer
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType)
+#else
+PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+#endif
+{
+ 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));
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DBG_BREAK
+#endif
+ return eError;
+ }
+
+ *ppvData = psHandle->pvData;
+
+ eError = FreeHandle(psBase, psHandle);
+
+ return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVReleaseHandle
+
+ @Description Release a handle that is no longer needed
+
+ @Input hHandle - handle from client
+ eType - handle type
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType)
+#else
+PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
+#endif
+{
+ 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;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVNewHandleBatch
+
+ @Description Start a new handle batch
+
+ @Input psBase - handle base
+ @Input ui32BatchSize - handle batch size
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+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_HANDLE_BATCH_IN_USE;
+ }
+
+ 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;
+
+ /* Record current number of handles */
+ psBase->ui32TotalHandCountPreBatch = psBase->ui32TotalHandCount;
+
+ PVR_ASSERT(psBase->ui32BatchHandAllocFailures == 0);
+
+ PVR_ASSERT(psBase->ui32FirstBatchIndexPlusOne == 0);
+
+ PVR_ASSERT(HANDLES_BATCHED(psBase));
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVHandleBatchCommitOrRelease
+
+ @Description Release a handle batch
+
+ @Input psBase - handle base
+ bCommit - commit handles
+
+ @Return none
+
+******************************************************************************/
+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;
+ }
+ /*
+ * The whole point of batched handles is to avoid handle allocation
+ * failures.
+ */
+ PVR_ASSERT(psBase->ui32BatchHandAllocFailures == 0 || !bCommit);
+
+ ui32IndexPlusOne = psBase->ui32FirstBatchIndexPlusOne;
+ while(ui32IndexPlusOne != 0)
+ {
+ struct sHandle *psHandle = INDEX_TO_HANDLE_STRUCT_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;
+
+ /*
+ * We need a complete free here. If the handle
+ * is not partially free, set the handle as
+ * unbatched to avoid a partial free.
+ */
+ if (!BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
+ {
+ /* PRQA S 1474,4130 1 */ /* ignore warnings about enum types being modified */
+ SET_UNBATCHED_HANDLE(psHandle); /* PRQA S 4130 */ /* mis-use of enums FIXME*/
+ }
+
+ 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
+ {
+ /* PRQA S 1474,4130 1 */ /* ignore warnings about enum types being modified */
+ 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_HANDLE_BATCH_COMMIT_FAILURE;
+ }
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVCommitHandleBatch
+
+ @Description Commit a handle batch
+
+ @Input psBase - handle base
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase)
+{
+ return PVRSRVHandleBatchCommitOrRelease(psBase, IMG_TRUE);
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRReleaseHandleBatch
+
+ @Description Release a handle batch
+
+ @Input psBase - handle base
+
+ @Return none
+
+******************************************************************************/
+IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase)
+{
+ (IMG_VOID) PVRSRVHandleBatchCommitOrRelease(psBase, IMG_FALSE);
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVSetMaxHandle
+
+ @Description Set maximum handle number for given handle base
+
+ @Input psBase - pointer to handle base structure
+ ui32MaxHandle - Maximum handle number
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle)
+{
+ IMG_UINT32 ui32MaxHandleRounded;
+
+ if (HANDLES_BATCHED(psBase))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit cannot be set whilst in batch mode"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ /* Validate the limit */
+ 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;
+ }
+
+ /* The limit can only be set if no handles have been allocated */
+ if (psBase->ui32TotalHandCount != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit cannot be set because handles have already been allocated"));
+
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ ui32MaxHandleRounded = ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(ui32MaxHandle);
+
+ /*
+ * Allow the maximum number of handles to be reduced, but never to
+ * zero.
+ */
+ if (ui32MaxHandleRounded != 0 && ui32MaxHandleRounded < psBase->ui32MaxIndexPlusOne)
+ {
+ psBase->ui32MaxIndexPlusOne = ui32MaxHandleRounded;
+ }
+
+ PVR_ASSERT(psBase->ui32MaxIndexPlusOne != 0);
+ PVR_ASSERT(psBase->ui32MaxIndexPlusOne <= DEFAULT_MAX_INDEX_PLUS_ONE);
+ PVR_ASSERT((psBase->ui32MaxIndexPlusOne % HANDLE_BLOCK_SIZE) == 0);
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVGetMaxHandle
+
+ @Description Get maximum handle number for given handle base
+
+ @Input psBase - pointer to handle base structure
+
+ @Output Maximum handle number, or 0 if handle limits not
+ supported.
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase)
+{
+ return psBase->ui32MaxIndexPlusOne;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVEnableHandlePurging
+
+ @Description Enable purging for a given handle base
+
+ @Input psBase - pointer to handle base structure
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase)
+{
+ if (psBase->bPurgingEnabled)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "PVRSRVEnableHandlePurging: Purging already enabled"));
+ return PVRSRV_OK;
+ }
+
+ /* Purging can only be enabled if no handles have been allocated */
+ 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;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVPurgeHandles
+
+ @Description Purge handles for a given handle base
+
+ @Input psBase - pointer to handle base structure
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase)
+{
+ IMG_UINT32 ui32BlockIndex;
+ 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;
+ }
+
+ PVR_ASSERT((psBase->ui32TotalHandCount % HANDLE_BLOCK_SIZE) == 0);
+
+ for (ui32BlockIndex = INDEX_TO_BLOCK_INDEX(psBase->ui32TotalHandCount); ui32BlockIndex != 0; ui32BlockIndex--)
+ {
+ if (psBase->psHandleArray[ui32BlockIndex - 1].ui32FreeHandBlockCount != HANDLE_BLOCK_SIZE)
+ {
+ break;
+ }
+ }
+ ui32NewHandCount = BLOCK_INDEX_TO_INDEX(ui32BlockIndex);
+
+ /*
+ * Check for a suitable decrease in the handle count.
+ */
+ if (ui32NewHandCount <= (psBase->ui32TotalHandCount/2))
+ {
+ PVRSRV_ERROR eError;
+
+ // PVR_TRACE((" PVRSRVPurgeHandles: reducing number of handles from %u to %u", psBase->ui32TotalHandCount, ui32NewHandCount));
+
+ eError = ReallocHandleArray(psBase, ui32NewHandCount);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVAllocHandleBase
+
+ @Description Allocate a handle base structure for a process
+
+ @Input ppsBase - pointer to handle base structure pointer
+
+ @Output ppsBase - points to handle base structure pointer
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase)
+{
+ PVRSRV_HANDLE_BASE *psBase;
+ IMG_HANDLE hBlockAlloc;
+ PVRSRV_ERROR eError;
+
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(*psBase),
+ (IMG_PVOID *)&psBase,
+ &hBlockAlloc,
+ "Handle Base");
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandleBase: Couldn't allocate handle base (%d)", eError));
+ return eError;
+ }
+ OSMemSet(psBase, 0, sizeof(*psBase));
+
+ /* Create hash table */
+ 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"));
+ (IMG_VOID)PVRSRVFreeHandleBase(psBase);
+ return PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE;
+ }
+
+ psBase->hBaseBlockAlloc = hBlockAlloc;
+
+ psBase->ui32MaxIndexPlusOne = DEFAULT_MAX_INDEX_PLUS_ONE;
+
+ *ppsBase = psBase;
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVFreeHandleBase
+
+ @Description Free a handle base structure
+
+ @Input psBase - pointer to handle base structure
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+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;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVHandleInit
+
+ @Description Initialise handle management
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+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;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVHandleDeInit
+
+ @Description De-initialise handle management
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+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
+/* disable warning about empty module */
+#endif /* #if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE) */
+/******************************************************************************
+ End of file (handle.c)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/common/hash.c b/pvr-source/services4/srvkm/common/hash.c
new file mode 100644
index 0000000..1569425
--- /dev/null
+++ b/pvr-source/services4/srvkm/common/hash.c
@@ -0,0 +1,738 @@
+/*************************************************************************/ /*!
+@Title Self scaling hash tables.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description
+ Implements simple self scaling hash tables. Hash collisions are
+ handled by chaining entries together. Hash tables are increased in
+ size when they become more than (50%?) full and decreased in size
+ when less than (25%?) full. Hash tables are never decreased below
+ their initial size.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#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)))
+
+/* Each entry in a hash table is placed into a bucket */
+struct _BUCKET_
+{
+ /* the next bucket on the same chain */
+ struct _BUCKET_ *pNext;
+
+ /* entry value */
+ IMG_UINTPTR_T v;
+
+ /* entry key */
+ IMG_UINTPTR_T k[]; /* PRQA S 0642 */ /* override dynamic array declaration warning */
+};
+typedef struct _BUCKET_ BUCKET;
+
+struct _HASH_TABLE_
+{
+ /* the hash table array */
+ BUCKET **ppBucketTable;
+
+ /* current size of the hash table */
+ IMG_UINT32 uSize;
+
+ /* number of entries currently in the hash table */
+ IMG_UINT32 uCount;
+
+ /* the minimum size that the hash table should be re-sized to */
+ IMG_UINT32 uMinimumSize;
+
+ /* size of key in bytes */
+ IMG_UINT32 uKeySize;
+
+ /* hash function */
+ HASH_FUNC *pfnHashFunc;
+
+ /* key comparison function */
+ HASH_KEY_COMP *pfnKeyComp;
+};
+
+/*!
+******************************************************************************
+ @Function HASH_Func_Default
+
+ @Description Hash function intended for hashing keys composed of
+ IMG_UINTPTR_T arrays.
+
+ @Input uKeySize - the size of the hash key, in bytes.
+ @Input pKey - a pointer to the key to hash.
+ @Input uHashTabLen - the length of the hash table.
+
+ @Return the hash value.
+******************************************************************************/
+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 = (IMG_UINT32)(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;
+}
+
+/*!
+******************************************************************************
+ @Function HASH_Key_Comp_Default
+
+ @Description Compares keys composed of IMG_UINTPTR_T arrays.
+
+ @Input uKeySize - the size of the hash key, in bytes.
+ @Input pKey1 - pointer to first hash key to compare.
+ @Input pKey2 - pointer to second hash key to compare.
+ @Return IMG_TRUE - the keys match.
+ IMG_FALSE - the keys don't match.
+******************************************************************************/
+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 = (IMG_UINT32)(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;
+}
+
+/*!
+******************************************************************************
+ @Function _ChainInsert
+
+ @Description Insert a bucket into the appropriate hash table chain.
+
+ @Input pBucket - the bucket
+ @Input ppBucketTable - the hash table
+ @Input uSize - the size of the hash table
+
+ @Return PVRSRV_ERROR
+******************************************************************************/
+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); /* PRQA S 0432,0541 */ /* ignore dynamic array warning */
+ pBucket->pNext = ppBucketTable[uIndex];
+ ppBucketTable[uIndex] = pBucket;
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+ @Function _Rehash
+
+ @Description Iterate over every entry in an old hash table and
+ rehash into the new table.
+
+ @Input ppOldTable - the old hash table
+ @Input uOldSize - the size of the old hash table
+ @Input ppNewTable - the new hash table
+ @Input uNewSize - the size of the new hash table
+
+ @Return None
+******************************************************************************/
+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)
+ {
+ PVRSRV_ERROR eError;
+ BUCKET *pNextBucket = pBucket->pNext;
+ eError = _ChainInsert (pHash, pBucket, ppNewTable, uNewSize);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "_Rehash: call to _ChainInsert failed"));
+ return eError;
+ }
+ pBucket = pNextBucket;
+ }
+ }
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+ @Function _Resize
+
+ @Description Attempt to resize a hash table, failure to allocate a
+ new larger hash table is not considered a hard failure.
+ We simply continue and allow the table to fill up, the
+ effect is to allow hash chains to become longer.
+
+ @Input pHash - Hash table to resize.
+ @Input uNewSize - Required table size.
+ @Return IMG_TRUE Success
+ IMG_FALSE Failed
+******************************************************************************/
+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,
+ "Hash Table Buckets");
+ 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, sizeof(BUCKET *)*pHash->uSize, pHash->ppBucketTable, IMG_NULL);
+ /*not nulling pointer, being reassigned just below*/
+ pHash->ppBucketTable = ppNewTable;
+ pHash->uSize = uNewSize;
+ }
+ return IMG_TRUE;
+}
+
+
+/*!
+******************************************************************************
+ @Function HASH_Create_Extended
+
+ @Description Create a self scaling hash table, using the supplied
+ key size, and the supplied hash and key comparsion
+ functions.
+
+ @Input uInitialLen - initial and minimum length of the
+ hash table, where the length refers to the number
+ of entries in the hash table, not its size in
+ bytes.
+ @Input uKeySize - the size of the key, in bytes.
+ @Input pfnHashFunc - pointer to hash function.
+ @Input pfnKeyComp - pointer to key comparsion function.
+ @Return IMG_NULL or hash table handle.
+******************************************************************************/
+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,
+ "Hash Table") != PVRSRV_OK)
+ {
+ return IMG_NULL;
+ }
+
+ pHash->uCount = 0;
+ pHash->uSize = uInitialLen;
+ pHash->uMinimumSize = uInitialLen;
+ pHash->uKeySize = (IMG_UINT32)uKeySize;
+ pHash->pfnHashFunc = pfnHashFunc;
+ pHash->pfnKeyComp = pfnKeyComp;
+
+ OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+ sizeof (BUCKET *) * pHash->uSize,
+ (IMG_PVOID*)&pHash->ppBucketTable, IMG_NULL,
+ "Hash Table Buckets");
+
+ if (pHash->ppBucketTable == IMG_NULL)
+ {
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(HASH_TABLE), pHash, IMG_NULL);
+ /*not nulling pointer, out of scope*/
+ return IMG_NULL;
+ }
+
+ for (uIndex=0; uIndex<pHash->uSize; uIndex++)
+ pHash->ppBucketTable[uIndex] = IMG_NULL;
+ return pHash;
+}
+
+/*!
+******************************************************************************
+ @Function HASH_Create
+
+ @Description Create a self scaling hash table with a key
+ consisting of a single IMG_UINTPTR_T, and using
+ the default hash and key comparison functions.
+
+ @Input uInitialLen - initial and minimum length of the
+ hash table, where the length refers to the
+ number of entries in the hash table, not its size
+ in bytes.
+ @Return IMG_NULL or hash table handle.
+******************************************************************************/
+HASH_TABLE * HASH_Create (IMG_UINT32 uInitialLen)
+{
+ return HASH_Create_Extended(uInitialLen, sizeof(IMG_UINTPTR_T),
+ &HASH_Func_Default, &HASH_Key_Comp_Default);
+}
+
+/*!
+******************************************************************************
+ @Function HASH_Delete
+
+ @Description Delete a hash table created by HASH_Create_Extended or
+ HASH_Create. All entries in the table must have been
+ removed before calling this function.
+
+ @Input pHash - hash table
+
+ @Return None
+******************************************************************************/
+IMG_VOID
+HASH_Delete (HASH_TABLE *pHash)
+{
+ if (pHash != IMG_NULL)
+ {
+ PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Delete"));
+
+ PVR_ASSERT (pHash->uCount==0);
+ if(pHash->uCount != 0)
+ {
+ PVR_DPF ((PVR_DBG_ERROR, "HASH_Delete: leak detected in hash table!"));
+ PVR_DPF ((PVR_DBG_ERROR, "Likely Cause: client drivers not freeing alocations before destroying devmemcontext"));
+ }
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET *)*pHash->uSize, pHash->ppBucketTable, IMG_NULL);
+ pHash->ppBucketTable = IMG_NULL;
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(HASH_TABLE), pHash, IMG_NULL);
+ /*not nulling pointer, copy on stack*/
+ }
+}
+
+/*!
+******************************************************************************
+ @Function HASH_Insert_Extended
+
+ @Description Insert a key value pair into a hash table created
+ with HASH_Create_Extended.
+
+ @Input pHash - the hash table.
+ @Input pKey - pointer to the key.
+ @Input v - the value associated with the key.
+
+ @Return IMG_TRUE - success
+ IMG_FALSE - failure
+******************************************************************************/
+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=0x%08x, pKey=0x%08x, v=0x%x",
+ (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)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,
+ "Hash Table entry") != PVRSRV_OK)
+ {
+ return IMG_FALSE;
+ }
+
+ pBucket->v = v;
+ /* PRQA S 0432,0541 1 */ /* ignore warning about dynamic array k (linux)*/
+ OSMemCopy(pBucket->k, pKey, pHash->uKeySize);
+ if (_ChainInsert (pHash, pBucket, pHash->ppBucketTable, pHash->uSize) != PVRSRV_OK)
+ {
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT,
+ sizeof(BUCKET) + pHash->uKeySize,
+ pBucket, IMG_NULL);
+ return IMG_FALSE;
+ }
+
+ pHash->uCount++;
+
+ /* check if we need to think about re-balencing */
+ if (pHash->uCount << 1 > pHash->uSize)
+ {
+ /* Ignore the return code from _Resize because the hash table is
+ still in a valid state and although not ideally sized, it is still
+ functional */
+ _Resize (pHash, pHash->uSize << 1);
+ }
+
+
+ return IMG_TRUE;
+}
+
+/*!
+******************************************************************************
+ @Function HASH_Insert
+
+ @Description Insert a key value pair into a hash table created with
+ HASH_Create.
+
+ @Input pHash - the hash table.
+ @Input k - the key value.
+ @Input v - the value associated with the key.
+
+ @Return IMG_TRUE - success.
+ IMG_FALSE - failure.
+******************************************************************************/
+IMG_BOOL
+HASH_Insert (HASH_TABLE *pHash, IMG_UINTPTR_T k, IMG_UINTPTR_T v)
+{
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "HASH_Insert: Hash=0x%x, k=0x%x, v=0x%x",
+ (IMG_UINTPTR_T)pHash, k, v));
+
+ return HASH_Insert_Extended(pHash, &k, v);
+}
+
+/*!
+******************************************************************************
+ @Function HASH_Remove_Extended
+
+ @Description Remove a key from a hash table created with
+ HASH_Create_Extended.
+
+ @Input pHash - the hash table.
+ @Input pKey - pointer to key.
+
+ @Return 0 if the key is missing, or the value associated
+ with the key.
+******************************************************************************/
+IMG_UINTPTR_T
+HASH_Remove_Extended(HASH_TABLE *pHash, IMG_VOID *pKey)
+{
+ BUCKET **ppBucket;
+ IMG_UINT32 uIndex;
+
+ PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Remove_Extended: Hash=0x%x, pKey=0x%x",
+ (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey));
+
+ PVR_ASSERT (pHash != IMG_NULL);
+
+ if (pHash == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "HASH_Remove_Extended: Null hash table"));
+ return 0;
+ }
+
+ uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize);
+
+ for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != IMG_NULL; ppBucket = &((*ppBucket)->pNext))
+ {
+ /* PRQA S 0432,0541 1 */ /* ignore warning about dynamic array k */
+ 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);
+ /*not nulling original pointer, already overwritten*/
+
+ pHash->uCount--;
+
+ /* check if we need to think about re-balencing */
+ if (pHash->uSize > (pHash->uCount << 2) &&
+ pHash->uSize > pHash->uMinimumSize)
+ {
+ /* Ignore the return code from _Resize because the
+ hash table is still in a valid state and although
+ not ideally sized, it is still functional */
+ _Resize (pHash,
+ PRIVATE_MAX (pHash->uSize >> 1,
+ pHash->uMinimumSize));
+ }
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "HASH_Remove_Extended: Hash=0x%x, pKey=0x%x = 0x%x",
+ (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey, v));
+ return v;
+ }
+ }
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "HASH_Remove_Extended: Hash=0x%x, pKey=0x%x = 0x0 !!!!",
+ (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey));
+ return 0;
+}
+
+/*!
+******************************************************************************
+ @Function HASH_Remove
+
+ @Description Remove a key value pair from a hash table created
+ with HASH_Create.
+
+ @Input pHash - the hash table
+ @Input k - the key
+
+ @Return 0 if the key is missing, or the value associated
+ with the key.
+******************************************************************************/
+IMG_UINTPTR_T
+HASH_Remove (HASH_TABLE *pHash, IMG_UINTPTR_T k)
+{
+ PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Remove: Hash=0x%x, k=0x%x",
+ (IMG_UINTPTR_T)pHash, k));
+
+ return HASH_Remove_Extended(pHash, &k);
+}
+
+/*!
+******************************************************************************
+ @Function HASH_Retrieve_Extended
+
+ @Description Retrieve a value from a hash table created with
+ HASH_Create_Extended.
+
+ @Input pHash - the hash table.
+ @Input pKey - pointer to the key.
+
+ @Return 0 if the key is missing, or the value associated with
+ the key.
+******************************************************************************/
+IMG_UINTPTR_T
+HASH_Retrieve_Extended (HASH_TABLE *pHash, IMG_VOID *pKey)
+{
+ BUCKET **ppBucket;
+ IMG_UINT32 uIndex;
+
+ PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Retrieve_Extended: Hash=0x%x, pKey=0x%x",
+ (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey));
+
+ PVR_ASSERT (pHash != IMG_NULL);
+
+ if (pHash == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "HASH_Retrieve_Extended: Null hash table"));
+ return 0;
+ }
+
+ uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize);
+
+ for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != IMG_NULL; ppBucket = &((*ppBucket)->pNext))
+ {
+ /* PRQA S 0432,0541 1 */ /* ignore warning about dynamic array k */
+ if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey))
+ {
+ BUCKET *pBucket = *ppBucket;
+ IMG_UINTPTR_T v = pBucket->v;
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "HASH_Retrieve: Hash=0x%x, pKey=0x%x = 0x%x",
+ (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey, v));
+ return v;
+ }
+ }
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "HASH_Retrieve: Hash=0x%x, pKey=0x%x = 0x0 !!!!",
+ (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey));
+ return 0;
+}
+
+/*!
+******************************************************************************
+ @Function HASH_Retrieve
+
+ @Description Retrieve a value from a hash table created with
+ HASH_Create.
+
+ @Input pHash - the hash table
+ @Input k - the key
+ @Return 0 if the key is missing, or the value associated with
+ the key.
+******************************************************************************/
+IMG_UINTPTR_T
+HASH_Retrieve (HASH_TABLE *pHash, IMG_UINTPTR_T k)
+{
+ PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Retrieve: Hash=0x%x, k=0x%x",
+ (IMG_UINTPTR_T)pHash, k));
+ return HASH_Retrieve_Extended(pHash, &k);
+}
+
+/*!
+******************************************************************************
+ @Function HASH_Iterate
+
+ @Description Iterate over every entry in the hash table
+
+ @Input pHash - the old hash table
+ @Input pfnCallback - the size of the old hash table
+
+ @Return Callback error if any, otherwise PVRSRV_OK
+******************************************************************************/
+PVRSRV_ERROR
+HASH_Iterate(HASH_TABLE *pHash, HASH_pfnCallback pfnCallback)
+{
+ IMG_UINT32 uIndex;
+ for (uIndex=0; uIndex < pHash->uSize; uIndex++)
+ {
+ BUCKET *pBucket;
+ pBucket = pHash->ppBucketTable[uIndex];
+ while (pBucket != IMG_NULL)
+ {
+ PVRSRV_ERROR eError;
+ BUCKET *pNextBucket = pBucket->pNext;
+
+ eError = pfnCallback((IMG_UINTPTR_T) ((IMG_VOID *) *(pBucket->k)), (IMG_UINTPTR_T) pBucket->v);
+
+ /* The callback might want us to break out early */
+ if (eError != PVRSRV_OK)
+ return eError;
+
+ pBucket = pNextBucket;
+ }
+ }
+ return PVRSRV_OK;
+}
+
+#ifdef HASH_TRACE
+/*!
+******************************************************************************
+ @Function HASH_Dump
+
+ @Description To dump the contents of a hash table in human readable
+ form.
+
+ @Input pHash - the hash table
+
+ @Return None
+******************************************************************************/
+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/pvr-source/services4/srvkm/common/lists.c b/pvr-source/services4/srvkm/common/lists.c
new file mode 100644
index 0000000..c6e1ee8
--- /dev/null
+++ b/pvr-source/services4/srvkm/common/lists.c
@@ -0,0 +1,156 @@
+/*************************************************************************/ /*!
+@Title Linked list shared functions implementation
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Implementation of the list iterators for types shared among
+ more than one file in the services code.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#include "lists.h"
+#include "services_headers.h"
+
+/*===================================================================
+ LIST ITERATOR FUNCTIONS USED IN MORE THAN ONE FILE (those used just
+ once are implemented locally).
+ ===================================================================*/
+
+IMPLEMENT_LIST_ANY_VA(BM_HEAP)
+IMPLEMENT_LIST_ANY_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK)
+IMPLEMENT_LIST_ANY_VA_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK)
+IMPLEMENT_LIST_FOR_EACH_VA(BM_HEAP)
+IMPLEMENT_LIST_REMOVE(BM_HEAP)
+IMPLEMENT_LIST_INSERT(BM_HEAP)
+
+IMPLEMENT_LIST_ANY_VA(BM_CONTEXT)
+IMPLEMENT_LIST_ANY_VA_2(BM_CONTEXT, IMG_HANDLE, IMG_NULL)
+IMPLEMENT_LIST_ANY_VA_2(BM_CONTEXT, PVRSRV_ERROR, PVRSRV_OK)
+IMPLEMENT_LIST_FOR_EACH(BM_CONTEXT)
+IMPLEMENT_LIST_REMOVE(BM_CONTEXT)
+IMPLEMENT_LIST_INSERT(BM_CONTEXT)
+
+IMPLEMENT_LIST_ANY_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK)
+IMPLEMENT_LIST_ANY_VA(PVRSRV_DEVICE_NODE)
+IMPLEMENT_LIST_ANY_VA_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK)
+IMPLEMENT_LIST_FOR_EACH(PVRSRV_DEVICE_NODE)
+IMPLEMENT_LIST_FOR_EACH_VA(PVRSRV_DEVICE_NODE)
+IMPLEMENT_LIST_INSERT(PVRSRV_DEVICE_NODE)
+IMPLEMENT_LIST_REMOVE(PVRSRV_DEVICE_NODE)
+
+IMPLEMENT_LIST_ANY_VA(PVRSRV_POWER_DEV)
+IMPLEMENT_LIST_ANY_VA_2(PVRSRV_POWER_DEV, PVRSRV_ERROR, PVRSRV_OK)
+IMPLEMENT_LIST_INSERT(PVRSRV_POWER_DEV)
+IMPLEMENT_LIST_REMOVE(PVRSRV_POWER_DEV)
+
+
+/*===================================================================
+ BELOW ARE IMPLEMENTED SOME COMMON CALLBACKS USED IN DIFFERENT FILES
+ ===================================================================*/
+
+
+/*!
+******************************************************************************
+ @Function MatchDeviceKM_AnyVaCb
+ @Description Matchs a device node with an id and optionally a class.
+
+ @Input psDeviceNode - Pointer to the device node.
+ @Input va - Variable argument list, with te following values:
+ # ui32DevIndex - Index of de device to match.
+ # bIgnoreClass - Flag indicating if there's
+ no need to check the device class.
+ # eDevClass - Device class, ONLY present if
+ bIgnoreClass was IMG_FALSE.
+
+ @Return The pointer to the device node if it matchs, IMG_NULL
+ otherwise.
+******************************************************************************/
+IMG_VOID* MatchDeviceKM_AnyVaCb(PVRSRV_DEVICE_NODE* psDeviceNode, va_list va)
+{
+ IMG_UINT32 ui32DevIndex;
+ IMG_BOOL bIgnoreClass;
+ PVRSRV_DEVICE_CLASS eDevClass;
+
+ ui32DevIndex = va_arg(va, IMG_UINT32);
+ bIgnoreClass = va_arg(va, IMG_BOOL);
+ if (!bIgnoreClass)
+ {
+ eDevClass = va_arg(va, PVRSRV_DEVICE_CLASS);
+ }
+ else
+ {
+ /*this value will never be used, since the short circuit evaluation
+ of the first clause will stop because bIgnoreClass is true, but the
+ compiler complains if it's not initialized.*/
+ eDevClass = PVRSRV_DEVICE_CLASS_FORCE_I32;
+ }
+
+ if ((bIgnoreClass || psDeviceNode->sDevId.eDeviceClass == eDevClass) &&
+ psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex)
+ {
+ return psDeviceNode;
+ }
+ return IMG_NULL;
+}
+
+/*!
+******************************************************************************
+
+ @Function MatchPowerDeviceIndex_AnyVaCb
+
+ @Description
+ Matches a power device with its device index.
+
+ @Input va : variable argument list with:
+ ui32DeviceIndex : device index
+
+ @Return the pointer to the device it matched, IMG_NULL otherwise.
+
+******************************************************************************/
+IMG_VOID* MatchPowerDeviceIndex_AnyVaCb(PVRSRV_POWER_DEV *psPowerDev, va_list va)
+{
+ IMG_UINT32 ui32DeviceIndex;
+
+ ui32DeviceIndex = va_arg(va, IMG_UINT32);
+
+ if (psPowerDev->ui32DeviceIndex == ui32DeviceIndex)
+ {
+ return psPowerDev;
+ }
+ else
+ {
+ return IMG_NULL;
+ }
+}
diff --git a/pvr-source/services4/srvkm/common/mem.c b/pvr-source/services4/srvkm/common/mem.c
new file mode 100644
index 0000000..cccdd24
--- /dev/null
+++ b/pvr-source/services4/srvkm/common/mem.c
@@ -0,0 +1,175 @@
+/*************************************************************************/ /*!
+@Title System memory functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description System memory allocation APIs
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "services_headers.h"
+#include "pvr_bridge_km.h"
+
+
+static PVRSRV_ERROR
+FreeSharedSysMemCallBack(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bDummy)
+{
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = pvParam;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ OSFreePages(psKernelMemInfo->ui32Flags,
+ psKernelMemInfo->uAllocSize,
+ psKernelMemInfo->pvLinAddrKM,
+ psKernelMemInfo->sMemBlk.hOSMemHandle);
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(PVRSRV_KERNEL_MEM_INFO),
+ psKernelMemInfo,
+ IMG_NULL);
+ /*not nulling pointer, copy on stack*/
+
+ return PVRSRV_OK;
+}
+
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVAllocSharedSysMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_UINT32 ui32Flags,
+ IMG_SIZE_T uSize,
+ 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,
+ "Kernel Memory Info") != 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->uAllocSize = uSize;
+
+ if(OSAllocPages(psKernelMemInfo->ui32Flags,
+ psKernelMemInfo->uAllocSize,
+ (IMG_UINT32)HOST_PAGESIZE(),
+ IMG_NULL,
+ 0,
+ IMG_NULL,
+ &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;
+ }
+
+ /* register with the resman */
+ 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, CLEANUP_WITH_POLL);
+ }
+ else
+ {
+ eError = FreeSharedSysMemCallBack(psKernelMemInfo, 0, CLEANUP_WITH_POLL);
+ }
+
+ 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;
+}
+
+/******************************************************************************
+ End of file (mem.c)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/common/mem_debug.c b/pvr-source/services4/srvkm/common/mem_debug.c
new file mode 100644
index 0000000..04432b1
--- /dev/null
+++ b/pvr-source/services4/srvkm/common/mem_debug.c
@@ -0,0 +1,272 @@
+/*************************************************************************/ /*!
+@Title Memory debugging routines.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Adds extra memory to the allocations to trace the memory bounds
+ and other runtime information.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef MEM_DEBUG_C
+#define MEM_DEBUG_C
+
+#if defined(PVRSRV_DEBUG_OS_MEMORY)
+
+#include "img_types.h"
+#include "services_headers.h"
+
+#if defined (__cplusplus)
+extern "C"
+{
+#endif
+
+#define STOP_ON_ERROR 0
+
+ /*
+ Allocated Memory Layout:
+
+ --------- \
+ Status [OSMEM_DEBUG_INFO] |- TEST_BUFFER_PADDING_STATUS
+ --------- <
+ [0xBB]* [raw bytes] |- ui32Size
+ --------- <
+ [0xB2]* [raw bytes] |- TEST_BUFFER_PADDING_AFTER
+ --------- /
+ */
+
+ IMG_BOOL MemCheck(const IMG_PVOID pvAddr, const IMG_UINT8 ui8Pattern, IMG_SIZE_T uSize)
+ {
+ IMG_UINT8 *pui8Addr;
+ for (pui8Addr = (IMG_UINT8*)pvAddr; uSize > 0; uSize--, pui8Addr++)
+ {
+ if (*pui8Addr != ui8Pattern)
+ {
+ return IMG_FALSE;
+ }
+ }
+ return IMG_TRUE;
+ }
+
+ /*
+ This function expects the pointer to the user data, not the debug data.
+ */
+ IMG_VOID OSCheckMemDebug(IMG_PVOID pvCpuVAddr, IMG_SIZE_T uSize, const IMG_CHAR *pszFileName, const IMG_UINT32 uLine)
+ {
+ OSMEM_DEBUG_INFO const *psInfo = (OSMEM_DEBUG_INFO *)((IMG_UINT32)pvCpuVAddr - TEST_BUFFER_PADDING_STATUS);
+
+ /* invalid pointer */
+ if (pvCpuVAddr == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : null pointer"
+ " - referenced %s:%d - allocated %s:%d",
+ pvCpuVAddr,
+ pszFileName, uLine,
+ psInfo->sFileName, psInfo->uLineNo));
+ while (STOP_ON_ERROR);
+ }
+
+ /* align */
+ if (((IMG_UINT32)pvCpuVAddr&3) != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : invalid alignment"
+ " - referenced %s:%d - allocated %s:%d",
+ pvCpuVAddr,
+ pszFileName, uLine,
+ psInfo->sFileName, psInfo->uLineNo));
+ while (STOP_ON_ERROR);
+ }
+
+ /*check guard region before*/
+ if (!MemCheck((IMG_PVOID)psInfo->sGuardRegionBefore, 0xB1, sizeof(psInfo->sGuardRegionBefore)))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : guard region before overwritten"
+ " - referenced %s:%d - allocated %s:%d",
+ pvCpuVAddr,
+ pszFileName, uLine,
+ psInfo->sFileName, psInfo->uLineNo));
+ while (STOP_ON_ERROR);
+ }
+
+ /*check size*/
+ if (uSize != psInfo->uSize)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "Pointer 0x%X : supplied size was different to stored size (0x%X != 0x%X)"
+ " - referenced %s:%d - allocated %s:%d",
+ pvCpuVAddr, uSize, psInfo->uSize,
+ pszFileName, uLine,
+ psInfo->sFileName, psInfo->uLineNo));
+ while (STOP_ON_ERROR);
+ }
+
+ /*check size parity*/
+ if ((0x01234567 ^ psInfo->uSizeParityCheck) != psInfo->uSize)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "Pointer 0x%X : stored size parity error (0x%X != 0x%X)"
+ " - referenced %s:%d - allocated %s:%d",
+ pvCpuVAddr, psInfo->uSize, 0x01234567 ^ psInfo->uSizeParityCheck,
+ pszFileName, uLine,
+ psInfo->sFileName, psInfo->uLineNo));
+ while (STOP_ON_ERROR);
+ }
+ else
+ {
+ /*the stored size is ok, so we use it instead the supplied uSize*/
+ uSize = psInfo->uSize;
+ }
+
+ /*check padding after*/
+ if (uSize)
+ {
+ if (!MemCheck((IMG_VOID*)((IMG_UINT32)pvCpuVAddr + uSize), 0xB2, TEST_BUFFER_PADDING_AFTER))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : guard region after overwritten"
+ " - referenced from %s:%d - allocated from %s:%d",
+ pvCpuVAddr,
+ pszFileName, uLine,
+ psInfo->sFileName, psInfo->uLineNo));
+ }
+ }
+
+ /* allocated... */
+ if (psInfo->eValid != isAllocated)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : not allocated (freed? %d)"
+ " - referenced %s:%d - freed %s:%d",
+ pvCpuVAddr, psInfo->eValid == isFree,
+ pszFileName, uLine,
+ psInfo->sFileName, psInfo->uLineNo));
+ while (STOP_ON_ERROR);
+ }
+ }
+
+ IMG_VOID debug_strcpy(IMG_CHAR *pDest, const IMG_CHAR *pSrc)
+ {
+ IMG_SIZE_T i = 0;
+
+ for (; i < 128; i++) /*changed to 128 to match the filename array size*/
+ {
+ *pDest = *pSrc;
+ if (*pSrc == '\0') break;
+ pDest++;
+ pSrc++;
+ }
+ }
+
+ PVRSRV_ERROR OSAllocMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
+ IMG_UINT32 ui32Size,
+ IMG_PVOID *ppvCpuVAddr,
+ IMG_HANDLE *phBlockAlloc,
+ IMG_CHAR *pszFilename,
+ IMG_UINT32 ui32Line)
+ {
+ OSMEM_DEBUG_INFO *psInfo;
+
+ PVRSRV_ERROR eError;
+
+ eError = OSAllocMem_Debug_Linux_Memory_Allocations(ui32Flags,
+ ui32Size + TEST_BUFFER_PADDING,
+ ppvCpuVAddr,
+ phBlockAlloc,
+ pszFilename,
+ ui32Line);
+
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ OSMemSet((IMG_CHAR *)(*ppvCpuVAddr) + TEST_BUFFER_PADDING_STATUS, 0xBB, ui32Size);
+ OSMemSet((IMG_CHAR *)(*ppvCpuVAddr) + ui32Size + TEST_BUFFER_PADDING_STATUS, 0xB2, TEST_BUFFER_PADDING_AFTER);
+
+ /*fill the dbg info struct*/
+ psInfo = (OSMEM_DEBUG_INFO *)(*ppvCpuVAddr);
+
+ OSMemSet(psInfo->sGuardRegionBefore, 0xB1, sizeof(psInfo->sGuardRegionBefore));
+ debug_strcpy(psInfo->sFileName, pszFilename);
+ psInfo->uLineNo = ui32Line;
+ psInfo->eValid = isAllocated;
+ psInfo->uSize = ui32Size;
+ psInfo->uSizeParityCheck = 0x01234567 ^ ui32Size;
+
+ /*point to the user data section*/
+ *ppvCpuVAddr = (IMG_PVOID) ((IMG_UINT32)*ppvCpuVAddr)+TEST_BUFFER_PADDING_STATUS;
+
+#ifdef PVRSRV_LOG_MEMORY_ALLOCS
+ /*this is here to simplify the surounding logging macro, that is a expression
+ maybe the macro should be an expression */
+ PVR_TRACE(("Allocated pointer (after debug info): 0x%X from %s:%d", *ppvCpuVAddr, pszFilename, ui32Line));
+#endif
+
+ return PVRSRV_OK;
+ }
+
+ PVRSRV_ERROR OSFreeMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
+ IMG_UINT32 ui32Size,
+ IMG_PVOID pvCpuVAddr,
+ IMG_HANDLE hBlockAlloc,
+ IMG_CHAR *pszFilename,
+ IMG_UINT32 ui32Line)
+ {
+ OSMEM_DEBUG_INFO *psInfo;
+
+ /*check dbginfo (arg pointing to user memory)*/
+ OSCheckMemDebug(pvCpuVAddr, ui32Size, pszFilename, ui32Line);
+
+ /*mark memory as freed*/
+ OSMemSet(pvCpuVAddr, 0xBF, ui32Size + TEST_BUFFER_PADDING_AFTER);
+
+ /*point to the starting address of the total allocated memory*/
+ psInfo = (OSMEM_DEBUG_INFO *)((IMG_UINT32) pvCpuVAddr - TEST_BUFFER_PADDING_STATUS);
+
+ /*update dbg info struct*/
+ psInfo->uSize = 0;
+ psInfo->uSizeParityCheck = 0;
+ psInfo->eValid = isFree;
+ psInfo->uLineNo = ui32Line;
+ debug_strcpy(psInfo->sFileName, pszFilename);
+
+ return OSFreeMem_Debug_Linux_Memory_Allocations(ui32Flags, ui32Size + TEST_BUFFER_PADDING, psInfo, hBlockAlloc, pszFilename, ui32Line);
+ }
+
+#if defined (__cplusplus)
+
+}
+#endif
+
+#endif /* PVRSRV_DEBUG_OS_MEMORY */
+
+#endif /* MEM_DEBUG_C */
diff --git a/pvr-source/services4/srvkm/common/metrics.c b/pvr-source/services4/srvkm/common/metrics.c
new file mode 100644
index 0000000..7370ec1
--- /dev/null
+++ b/pvr-source/services4/srvkm/common/metrics.c
@@ -0,0 +1,209 @@
+/*************************************************************************/ /*!
+@Title Time measuring functions.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "services_headers.h"
+#include "metrics.h"
+
+/* VGX: */
+#if defined(SUPPORT_VGX)
+#include "vgxapi_km.h"
+#endif
+
+/* SGX: */
+#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];
+
+
+/***********************************************************************************
+ Function Name : PVRSRVTimeNow
+ Inputs : None
+ Outputs : None
+ Returns : Current timer register value
+ Description : Returns the current timer register value
+************************************************************************************/
+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 /* defined(__sh__) */
+
+ return 0;
+
+#endif /* defined(__sh__) */
+}
+
+
+/***********************************************************************************
+ Function Name : PVRSRVGetCPUFreq
+ Inputs : None
+ Outputs : None
+ Returns : CPU timer frequency
+ Description : Returns the CPU timer frequency
+************************************************************************************/
+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);
+}
+
+
+/***********************************************************************************
+ Function Name : PVRSRVSetupMetricTimers
+ Inputs : pvDevInfo
+ Outputs : None
+ Returns : None
+ Description : Resets metric timers and sets up the timer register
+************************************************************************************/
+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__)
+
+ /* timer control register */
+ // clock / 1024 when TIMER_DIVISOR = 4
+ // underflow int disabled
+ // we get approx 38 uS per timer tick
+ *TCR_2 = TIMER_DIVISOR;
+
+ /* reset the timer counter to 0 */
+ *TCOR_2 = *TCNT_2 = (IMG_UINT)0xffffffff;
+
+ /* start timer 2 */
+ *TST_REG |= (IMG_UINT8)0x04;
+
+ pui32TimerRegister = (IMG_UINT32 *)TCNT_2;
+
+ #else /* defined(__sh__) */
+
+ pui32TimerRegister = 0;
+
+ #endif /* defined(__sh__) */
+}
+
+
+/***********************************************************************************
+ Function Name : PVRSRVOutputMetricTotals
+ Inputs : None
+ Outputs : None
+ Returns : None
+ Description : Displays final metric data
+************************************************************************************/
+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
+ /*
+ ** EXAMPLE TIMER OUTPUT
+ */
+ 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 /* defined(DEBUG) || defined(TIMING) */
+
+/******************************************************************************
+ End of file (metrics.c)
+******************************************************************************/
+
diff --git a/pvr-source/services4/srvkm/common/osfunc_common.c b/pvr-source/services4/srvkm/common/osfunc_common.c
new file mode 100644
index 0000000..19ba9ea
--- /dev/null
+++ b/pvr-source/services4/srvkm/common/osfunc_common.c
@@ -0,0 +1,48 @@
+/*************************************************************************/ /*!
+@Title Wrapper layer for osfunc routines that have common code.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Adds extra memory to the allocations to trace the memory bounds
+ and other runtime information.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "img_types.h"
+#include "services_headers.h"
+#include "osfunc.h"
+
+
diff --git a/pvr-source/services4/srvkm/common/pdump_common.c b/pvr-source/services4/srvkm/common/pdump_common.c
new file mode 100644
index 0000000..2d96dc3
--- /dev/null
+++ b/pvr-source/services4/srvkm/common/pdump_common.c
@@ -0,0 +1,2967 @@
+/*************************************************************************/ /*!
+@Title Common PDump functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if defined(PDUMP)
+#include <stdarg.h>
+
+#include "services_headers.h"
+#include "perproc.h"
+
+/* pdump headers */
+#include "pdump_km.h"
+#include "pdump_int.h"
+
+/* Allow temporary buffer size override */
+#if !defined(PDUMP_TEMP_BUFFER_SIZE)
+#define PDUMP_TEMP_BUFFER_SIZE (64 * 1024U)
+#endif
+
+/* DEBUG */
+#if 1
+#define PDUMP_DBG(a) PDumpOSDebugPrintf (a)
+#else
+#define PDUMP_DBG(a)
+#endif
+
+
+#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 (32)
+static IMG_VOID *gpvTempBuffer = IMG_NULL;
+static IMG_HANDLE ghTempBufferBlockAlloc;
+static IMG_UINT16 gui16MMUContextUsage = 0;
+
+#if defined(PDUMP_DEBUG_OUTFILES)
+/* counter increments each time debug write is called */
+IMG_UINT32 g_ui32EveryLineCounter = 1U;
+#endif
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(_PDumpIsPersistent)
+#endif
+static INLINE
+IMG_BOOL _PDumpIsPersistent(IMG_VOID)
+{
+ PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+
+ if(psPerProc == IMG_NULL)
+ {
+ /* only occurs early in driver init, and init phase is already persistent */
+ return IMG_FALSE;
+ }
+ return psPerProc->bPDumpPersistent;
+}
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+
+
+static INLINE
+IMG_BOOL _PDumpIsProcessActive(IMG_VOID)
+{
+ PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+ if(psPerProc == IMG_NULL)
+ {
+ /* FIXME: kernel process logs some comments when kernel module is
+ * loaded, want to keep those.
+ */
+ return IMG_TRUE;
+ }
+ return psPerProc->bPDumpActive;
+}
+
+#endif /* SUPPORT_PDUMP_MULTI_PROCESS */
+
+#if defined(PDUMP_DEBUG_OUTFILES)
+static INLINE
+IMG_UINT32 _PDumpGetPID(IMG_VOID)
+{
+ PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+ if(psPerProc == IMG_NULL)
+ {
+ /* Kernel PID */
+ return 0;
+ }
+ return psPerProc->ui32PID;
+}
+#endif /* PDUMP_DEBUG_OUTFILES */
+
+/**************************************************************************
+ * Function Name : GetTempBuffer
+ * Inputs : None
+ * Outputs : None
+ * Returns : Temporary buffer address, or IMG_NULL
+ * Description : Get temporary buffer address.
+**************************************************************************/
+static IMG_VOID *GetTempBuffer(IMG_VOID)
+{
+ /*
+ * Allocate the temporary buffer, it it hasn't been allocated already.
+ * Return the address of the temporary buffer, or IMG_NULL if it
+ * couldn't be allocated.
+ * It is expected that the buffer will be allocated once, at driver
+ * load time, and left in place until the driver unloads.
+ */
+
+ if (gpvTempBuffer == IMG_NULL)
+ {
+ PVRSRV_ERROR eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ PDUMP_TEMP_BUFFER_SIZE,
+ &gpvTempBuffer,
+ &ghTempBufferBlockAlloc,
+ "PDUMP Temporary Buffer");
+ 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)
+{
+ /* Allocate temporary buffer for copying from user space */
+ (IMG_VOID) GetTempBuffer();
+
+ /* Call environment specific PDump initialisation */
+ PDumpInit();
+}
+
+IMG_VOID PDumpDeInitCommon(IMG_VOID)
+{
+ /* Free temporary buffer */
+ FreeTempBuffer();
+
+ /* Call environment specific PDump Deinitialisation */
+ PDumpDeInit();
+}
+
+IMG_BOOL PDumpIsSuspended(IMG_VOID)
+{
+ return PDumpOSIsSuspended();
+}
+
+IMG_BOOL PDumpIsCaptureFrameKM(IMG_VOID)
+{
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ if( _PDumpIsProcessActive() )
+ {
+ return PDumpOSIsCaptureFrameKM();
+ }
+ return IMG_FALSE;
+#else
+ return PDumpOSIsCaptureFrameKM();
+#endif
+}
+
+PVRSRV_ERROR PDumpSetFrameKM(IMG_UINT32 ui32Frame)
+{
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ if( _PDumpIsProcessActive() )
+ {
+ return PDumpOSSetFrameKM(ui32Frame);
+ }
+ return PVRSRV_OK;
+#else
+ return PDumpOSSetFrameKM(ui32Frame);
+#endif
+}
+
+/**************************************************************************
+ * Function Name : PDumpRegWithFlagsKM
+ * Inputs : pszPDumpDevName, Register offset, and value to write
+ * Outputs : None
+ * Returns : PVRSRV_ERROR
+ * Description : Create a PDUMP string, which represents a register write
+**************************************************************************/
+PVRSRV_ERROR PDumpRegWithFlagsKM(IMG_CHAR *pszPDumpRegName,
+ IMG_UINT32 ui32Reg,
+ IMG_UINT32 ui32Data,
+ IMG_UINT32 ui32Flags)
+{
+ PVRSRV_ERROR eErr;
+ PDUMP_GET_SCRIPT_STRING()
+ PDUMP_DBG(("PDumpRegWithFlagsKM"));
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :%s:0x%08X 0x%08X\r\n",
+ pszPDumpRegName, ui32Reg, ui32Data);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ return PVRSRV_OK;
+}
+
+/**************************************************************************
+ * Function Name : PDumpRegKM
+ * Inputs : Register offset, and value to write
+ * Outputs : None
+ * Returns : PVRSRV_ERROR
+ * Description : Create a PDUMP string, which represents a register write
+**************************************************************************/
+PVRSRV_ERROR PDumpRegKM(IMG_CHAR *pszPDumpRegName,
+ IMG_UINT32 ui32Reg,
+ IMG_UINT32 ui32Data)
+{
+ return PDumpRegWithFlagsKM(pszPDumpRegName, ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS);
+}
+
+/**************************************************************************
+ * Function Name : PDumpRegPolWithFlagsKM
+ * Inputs : Description of what this register read is trying to do
+ * pszPDumpDevName
+ * Register offset
+ * expected value
+ * mask for that value
+ * Outputs : None
+ * Returns : None
+ * Description : Create a PDUMP string which represents a register read
+ * with the expected value
+**************************************************************************/
+PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_CHAR *pszPDumpRegName,
+ IMG_UINT32 ui32RegAddr,
+ IMG_UINT32 ui32RegValue,
+ IMG_UINT32 ui32Mask,
+ IMG_UINT32 ui32Flags,
+ PDUMP_POLL_OPERATOR eOperator)
+{
+ /* Timings correct for linux and XP */
+ #define POLL_DELAY 1000U
+ #define POLL_COUNT_LONG (2000000000U / POLL_DELAY)
+ #define POLL_COUNT_SHORT (1000000U / POLL_DELAY)
+
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32PollCount;
+
+ PDUMP_GET_SCRIPT_STRING();
+ PDUMP_DBG(("PDumpRegPolWithFlagsKM"));
+ if ( _PDumpIsPersistent() )
+ {
+ /* Don't pdump-poll if the process is persistent */
+ return PVRSRV_OK;
+ }
+
+ ui32PollCount = POLL_COUNT_LONG;
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "POL :%s:0x%08X 0x%08X 0x%08X %d %u %d\r\n",
+ pszPDumpRegName, ui32RegAddr, ui32RegValue,
+ ui32Mask, eOperator, ui32PollCount, POLL_DELAY);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ return PVRSRV_OK;
+}
+
+
+/**************************************************************************
+ * Function Name : PDumpRegPol
+ * Inputs : Description of what this register read is trying to do
+ * pszPDumpDevName
+ Register offset
+ * expected value
+ * mask for that value
+ * Outputs : None
+ * Returns : None
+ * Description : Create a PDUMP string which represents a register read
+ * with the expected value
+**************************************************************************/
+PVRSRV_ERROR PDumpRegPolKM(IMG_CHAR *pszPDumpRegName, IMG_UINT32 ui32RegAddr, IMG_UINT32 ui32RegValue, IMG_UINT32 ui32Mask, PDUMP_POLL_OPERATOR eOperator)
+{
+ return PDumpRegPolWithFlagsKM(pszPDumpRegName, ui32RegAddr, ui32RegValue, ui32Mask, PDUMP_FLAGS_CONTINUOUS, eOperator);
+}
+
+/**************************************************************************
+ * Function Name : PDumpMallocPages
+ * Inputs : psDevID, ui32DevVAddr, pvLinAddr, ui32NumBytes, hOSMemHandle
+ * : hUniqueTag
+ * Outputs : None
+ * Returns : None
+ * Description : Malloc memory pages
+
+FIXME: This function assumes pvLinAddr is the address of the start of the
+block for this hOSMemHandle.
+If this isn't true, the call to PDumpOSCPUVAddrToDevPAddr below will be
+incorrect. (Consider using OSMemHandleToCPUPAddr() instead?)
+The only caller at the moment is in buffer_manager.c, which does the right
+thing.
+**************************************************************************/
+PVRSRV_ERROR PDumpMallocPages (PVRSRV_DEVICE_IDENTIFIER *psDevID,
+ IMG_UINT32 ui32DevVAddr,
+ IMG_CPU_VIRTADDR pvLinAddr,
+ IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32NumBytes,
+ IMG_UINT32 ui32PageSize,
+ IMG_BOOL bShared,
+ IMG_HANDLE hUniqueTag)
+{
+ PVRSRV_ERROR eErr;
+ IMG_PUINT8 pui8LinAddr;
+ IMG_UINT32 ui32Offset;
+ IMG_UINT32 ui32NumPages;
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_UINT32 ui32Page;
+ IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
+
+ PDUMP_GET_SCRIPT_STRING();
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ /* Always dump physical pages backing a shared allocation */
+ ui32Flags |= ( _PDumpIsPersistent() || bShared ) ? PDUMP_FLAGS_PERSISTENT : 0;
+#else
+ PVR_UNREFERENCED_PARAMETER(bShared);
+ ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+#endif
+
+ /* However, lin addr is only required in non-linux OSes */
+#if !defined(LINUX)
+ PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & HOST_PAGEMASK) == 0);
+#endif
+
+ PVR_ASSERT(((IMG_UINT32) ui32DevVAddr & HOST_PAGEMASK) == 0);
+ PVR_ASSERT(((IMG_UINT32) ui32NumBytes & HOST_PAGEMASK) == 0);
+
+ /*
+ Write a comment to the PDump2 script streams indicating the memory allocation
+ */
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- MALLOC :%s:VA_%08X 0x%08X %u\r\n",
+ psDevID->pszPDumpDevName, ui32DevVAddr, ui32NumBytes, ui32PageSize);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ /*
+ Write to the MMU script stream indicating the memory allocation
+ */
+ pui8LinAddr = (IMG_PUINT8) pvLinAddr;
+ ui32Offset = 0;
+ ui32NumPages = ui32NumBytes / ui32PageSize;
+ while (ui32NumPages)
+ {
+ ui32NumPages--;
+
+ /* See FIXME in function header.
+ * Currently: linux pdump uses OSMemHandle and Offset
+ * other OSes use the LinAddr.
+ */
+ /* Calculate the device physical address for this page */
+ PDumpOSCPUVAddrToDevPAddr(psDevID->eDeviceType,
+ hOSMemHandle,
+ ui32Offset,
+ pui8LinAddr,
+ ui32PageSize,
+ &sDevPAddr);
+ ui32Page = (IMG_UINT32)(sDevPAddr.uiAddr / ui32PageSize);
+ /* increment kernel virtual address */
+ pui8LinAddr += ui32PageSize;
+ ui32Offset += ui32PageSize;
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC :%s:PA_%08X%08X %u %u 0x%08X\r\n",
+ psDevID->pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+ ui32Page * ui32PageSize,
+ ui32PageSize,
+ ui32PageSize,
+ ui32Page * ui32PageSize);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+ }
+ return PVRSRV_OK;
+}
+
+
+/**************************************************************************
+ * Function Name : PDumpMallocPageTable
+ * Inputs : psDevId, pvLinAddr, ui32NumBytes, hUniqueTag
+ * Outputs : None
+ * Returns : None
+ * Description : Malloc memory page table
+**************************************************************************/
+PVRSRV_ERROR PDumpMallocPageTable (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32Offset,
+ IMG_CPU_VIRTADDR pvLinAddr,
+ IMG_UINT32 ui32PTSize,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag)
+{
+ PVRSRV_ERROR eErr;
+ IMG_DEV_PHYADDR sDevPAddr;
+
+ PDUMP_GET_SCRIPT_STRING();
+
+ PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PTSize - 1)) == 0);
+ ui32Flags |= PDUMP_FLAGS_CONTINUOUS;
+ ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+ /*
+ Write a comment to the PDump2 script streams indicating the memory allocation
+ */
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "-- MALLOC :%s:PAGE_TABLE 0x%08X %u\r\n",
+ psDevId->pszPDumpDevName,
+ ui32PTSize,
+ ui32PTSize);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ /*
+ Write to the MMU script stream indicating the memory allocation
+ */
+ // FIXME: we'll never need more than a 4k page for a pagetable
+ // fixing to 1 page for now.
+ // note: when the mmu code supports packed pagetables the PTs
+ // will be as small as 16bytes
+
+ PDumpOSCPUVAddrToDevPAddr(psDevId->eDeviceType,
+ hOSMemHandle, /* um - does this mean the pvLinAddr would be ignored? Is that safe? */
+ ui32Offset,
+ (IMG_PUINT8) pvLinAddr,
+ ui32PTSize,
+ &sDevPAddr);
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC :%s:PA_%08X%08X 0x%X %u 0x%08X\r\n",
+ psDevId->pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+ sDevPAddr.uiAddr,
+ ui32PTSize,//size
+ ui32PTSize,//alignment
+ sDevPAddr.uiAddr);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ return PVRSRV_OK;
+}
+
+/**************************************************************************
+ * Function Name : PDumpFreePages
+ * Inputs : psBMHeap, sDevVAddr, ui32NumBytes, hUniqueTag,
+ bInterLeaved
+ * Outputs : None
+ * Returns : None
+ * Description : Free memory pages
+**************************************************************************/
+PVRSRV_ERROR PDumpFreePages (BM_HEAP *psBMHeap,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_UINT32 ui32NumBytes,
+ IMG_UINT32 ui32PageSize,
+ IMG_HANDLE hUniqueTag,
+ IMG_BOOL bInterleaved,
+ IMG_BOOL bSparse)
+{
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32NumPages, ui32PageCounter;
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+
+ PDUMP_GET_SCRIPT_STRING();
+
+ PVR_ASSERT(((IMG_UINT32) sDevVAddr.uiAddr & (ui32PageSize - 1)) == 0);
+ PVR_ASSERT(((IMG_UINT32) ui32NumBytes & (ui32PageSize - 1)) == 0);
+
+ psDeviceNode = psBMHeap->pBMContext->psDeviceNode;
+ ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+ /*
+ Write a comment to the PDUMP2 script streams indicating the memory free
+ */
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :%s:VA_%08X\r\n",
+ psDeviceNode->sDevId.pszPDumpDevName, sDevVAddr.uiAddr);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ /* if we're dumping a shared heap, need to ensure phys allocation
+ * is freed even if this app isn't the one marked for pdumping
+ */
+ {
+ PVRSRV_DEVICE_NODE *psDeviceNode = psBMHeap->pBMContext->psDeviceNode;
+
+ if( psDeviceNode->pfnMMUIsHeapShared(psBMHeap->pMMUHeap) )
+ {
+ ui32Flags |= PDUMP_FLAGS_PERSISTENT;
+ }
+ }
+#endif
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ /*
+ Write to the MMU script stream indicating the memory free
+ */
+ ui32NumPages = ui32NumBytes / ui32PageSize;
+ for (ui32PageCounter = 0; ui32PageCounter < ui32NumPages; ui32PageCounter++)
+ {
+ if (!bInterleaved || (ui32PageCounter % 2) == 0)
+ {
+ sDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(psBMHeap->pMMUHeap, sDevVAddr);
+
+ /* With sparse mappings we expect spaces */
+ if (bSparse && (sDevPAddr.uiAddr == 0))
+ {
+ continue;
+ }
+
+ PVR_ASSERT(sDevPAddr.uiAddr != 0);
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:PA_%08X%08X\r\n",
+ psDeviceNode->sDevId.pszPDumpDevName, (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag, sDevPAddr.uiAddr);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+ }
+ else
+ {
+ /* Gap pages in an interleaved allocation should be ignored. */
+ }
+
+ sDevVAddr.uiAddr += ui32PageSize;
+ }
+ return PVRSRV_OK;
+}
+
+/**************************************************************************
+ * Function Name : PDumpFreePageTable
+ * Inputs : psDevID, pvLinAddr, ui32NumBytes, hUniqueTag
+ * Outputs : None
+ * Returns : None
+ * Description : Free memory page table
+**************************************************************************/
+PVRSRV_ERROR PDumpFreePageTable (PVRSRV_DEVICE_IDENTIFIER *psDevID,
+ IMG_HANDLE hOSMemHandle,
+ IMG_CPU_VIRTADDR pvLinAddr,
+ IMG_UINT32 ui32PTSize,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag)
+{
+ PVRSRV_ERROR eErr;
+ IMG_DEV_PHYADDR sDevPAddr;
+
+ PDUMP_GET_SCRIPT_STRING();
+
+ PVR_UNREFERENCED_PARAMETER(ui32PTSize);
+ ui32Flags |= PDUMP_FLAGS_CONTINUOUS;
+ ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+ /* override QAC warning about wrap around */
+ PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PTSize-1UL)) == 0); /* PRQA S 3382 */
+
+ /*
+ Write a comment to the PDUMP2 script streams indicating the memory free
+ */
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :%s:PAGE_TABLE\r\n", psDevID->pszPDumpDevName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ /*
+ Write to the MMU script stream indicating the memory free
+ */
+ // FIXME: we'll never need more than a 4k page for a pagetable
+ // fixing to 1 page for now.
+ // note: when the mmu code supports packed pagetables the PTs
+ // will be as small as 16bytes
+
+ PDumpOSCPUVAddrToDevPAddr(psDevID->eDeviceType,
+ hOSMemHandle, /* um - does this mean the pvLinAddr would be ignored? Is that safe? */
+ 0,
+ (IMG_PUINT8) pvLinAddr,
+ ui32PTSize,
+ &sDevPAddr);
+
+ {
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:PA_%08X%08X\r\n",
+ psDevID->pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+ sDevPAddr.uiAddr);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+ }
+
+ return PVRSRV_OK;
+}
+
+/**************************************************************************
+ * Function Name : PDumpPDRegWithFlags
+ * Inputs : psMMUAttrib
+ * : ui32Reg
+ * : ui32Data
+ * : hUniqueTag
+ * Outputs : None
+ * Returns : None
+ * Description : Kernel Services internal pdump memory API
+ * Used for registers specifying physical addresses
+ e.g. MMU page directory register
+**************************************************************************/
+PVRSRV_ERROR PDumpPDRegWithFlags(PDUMP_MMU_ATTRIB *psMMUAttrib,
+ IMG_UINT32 ui32Reg,
+ IMG_UINT32 ui32Data,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag)
+{
+ PVRSRV_ERROR eErr;
+ IMG_CHAR *pszRegString;
+ PDUMP_GET_SCRIPT_STRING()
+
+ if(psMMUAttrib->pszPDRegRegion != IMG_NULL)
+ {
+ pszRegString = psMMUAttrib->pszPDRegRegion;
+ }
+ else
+ {
+ pszRegString = psMMUAttrib->sDevId.pszPDumpRegName;
+ }
+
+ /*
+ Write to the MMU script stream indicating the physical page directory
+ */
+#if defined(SGX_FEATURE_36BIT_MMU)
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen,
+ "WRW :%s:$1 :%s:PA_%08X%08X:0x0\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)hUniqueTag,
+ (ui32Data & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PDEAlignShift);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "SHR :%s:$1 :%s:$1 0x4\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ psMMUAttrib->sDevId.pszPDumpDevName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen,
+ "WRW :%s:0x%08X: %s:$1\r\n",
+ pszRegString,
+ ui32Reg,
+ psMMUAttrib->sDevId.pszPDumpDevName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+#else
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "WRW :%s:0x%08X :%s:PA_%08X%08X:0x%08X\r\n",
+ pszRegString,
+ ui32Reg,
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+ (ui32Data & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PDEAlignShift,
+ ui32Data & ~psMMUAttrib->ui32PDEMask);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+#endif
+ return PVRSRV_OK;
+}
+
+/**************************************************************************
+ * Function Name : PDumpPDReg
+ * Inputs : psMMUAttrib
+ : ui32Reg
+ * : ui32Data
+ * : hUniqueTag
+ * Outputs : None
+ * Returns : PVRSRV_ERROR
+ * Description : Kernel Services internal pdump memory API
+ * Used for registers specifying physical addresses
+ e.g. MMU page directory register
+**************************************************************************/
+PVRSRV_ERROR PDumpPDReg (PDUMP_MMU_ATTRIB *psMMUAttrib,
+ IMG_UINT32 ui32Reg,
+ IMG_UINT32 ui32Data,
+ IMG_HANDLE hUniqueTag)
+{
+ return PDumpPDRegWithFlags(psMMUAttrib, ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS, hUniqueTag);
+}
+
+/**************************************************************************
+ * Function Name : PDumpMemPolKM
+ * Inputs : psMemInfo
+ * : ui32Offset
+ * : ui32Value
+ * : ui32Mask
+ * : eOperator
+ * : ui32Flags
+ * : hUniqueTag
+ * Outputs : None
+ * Returns : PVRSRV_ERROR
+ * Description : Implements Client pdump memory poll API
+**************************************************************************/
+PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32Offset,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ PDUMP_POLL_OPERATOR eOperator,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag)
+{
+ #define MEMPOLL_DELAY (1000)
+ #define MEMPOLL_COUNT (2000000000 / MEMPOLL_DELAY)
+
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32PageOffset;
+ IMG_UINT8 *pui8LinAddr;
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_DEV_VIRTADDR sDevVPageAddr;
+ PDUMP_MMU_ATTRIB *psMMUAttrib;
+
+ PDUMP_GET_SCRIPT_STRING();
+
+ if (PDumpOSIsSuspended())
+ {
+ return PVRSRV_OK;
+ }
+
+ if ( _PDumpIsPersistent() )
+ {
+ /* Don't pdump-poll if the process is persistent */
+ return PVRSRV_OK;
+ }
+
+ /* Check the offset and size don't exceed the bounds of the allocation */
+ PVR_ASSERT((ui32Offset + sizeof(IMG_UINT32)) <= psMemInfo->uAllocSize);
+
+ psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
+
+ /*
+ Write a comment to the PDump2 script streams indicating the virtual memory pol
+ */
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "-- POL :%s:VA_%08X 0x%08X 0x%08X %d %d %d\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ psMemInfo->sDevVAddr.uiAddr + ui32Offset,
+ ui32Value,
+ ui32Mask,
+ eOperator,
+ MEMPOLL_COUNT,
+ MEMPOLL_DELAY);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+
+ pui8LinAddr = psMemInfo->pvLinAddrKM;
+
+ /* Advance address by offset */
+ pui8LinAddr += ui32Offset;
+
+ /*
+ query the buffer manager for the physical pages that back the
+ virtual address
+ */
+ PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle,
+ ui32Offset,
+ pui8LinAddr,
+ psMMUAttrib->ui32DataPageMask,
+ &ui32PageOffset);
+
+ /* calculate the DevV page address */
+ sDevVPageAddr.uiAddr = psMemInfo->sDevVAddr.uiAddr + ui32Offset - ui32PageOffset;
+
+ PVR_ASSERT((sDevVPageAddr.uiAddr & psMMUAttrib->ui32DataPageMask) == 0);
+
+ /* get the physical page address based on the device virtual address */
+ BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
+
+ /* convert DevP page address to byte address */
+ sDevPAddr.uiAddr += ui32PageOffset;
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "POL :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %d %d %d\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+ sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask),
+ sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask),
+ ui32Value,
+ ui32Mask,
+ eOperator,
+ MEMPOLL_COUNT,
+ MEMPOLL_DELAY);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ return PVRSRV_OK;
+}
+
+/**************************************************************************
+ * Function Name : _PDumpMemIntKM
+ * Inputs : psMemInfo
+ * : ui32Offset
+ * : ui32Bytes
+ * : ui32Flags
+ * : hUniqueTag
+ * Outputs : None
+ * Returns : PVRSRV_ERROR
+ * Description : Implements Client pdump mem API
+**************************************************************************/
+static PVRSRV_ERROR _PDumpMemIntKM(IMG_PVOID pvAltLinAddr,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32Offset,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag)
+{
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32NumPages;
+ IMG_UINT32 ui32PageByteOffset;
+ IMG_UINT32 ui32BlockBytes;
+ IMG_UINT8* pui8LinAddr;
+ IMG_UINT8* pui8DataLinAddr = IMG_NULL;
+ IMG_DEV_VIRTADDR sDevVPageAddr;
+ IMG_DEV_VIRTADDR sDevVAddr;
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_UINT32 ui32ParamOutPos;
+ PDUMP_MMU_ATTRIB *psMMUAttrib;
+ IMG_UINT32 ui32DataPageSize;
+
+ PDUMP_GET_SCRIPT_AND_FILE_STRING();
+
+ /* PRQA S 3415 1 */ /* side effects desired */
+ if (ui32Bytes == 0 || PDumpOSIsSuspended())
+ {
+ return PVRSRV_OK;
+ }
+
+ psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
+
+ /*
+ check the offset and size don't exceed the bounds of the allocation
+ */
+ PVR_ASSERT((ui32Offset + ui32Bytes) <= psMemInfo->uAllocSize);
+
+ if (!PDumpOSJTInitialised())
+ {
+ return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
+ }
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ /* if we're dumping a shared heap, need to ensure phys allocation
+ * is initialised even if this app isn't the one marked for pdumping
+ */
+ {
+ BM_HEAP *pHeap = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap;
+ PVRSRV_DEVICE_NODE *psDeviceNode = pHeap->pBMContext->psDeviceNode;
+
+ if( psDeviceNode->pfnMMUIsHeapShared(pHeap->pMMUHeap) )
+ {
+ ui32Flags |= PDUMP_FLAGS_PERSISTENT;
+ }
+ }
+#endif
+
+ /* setup memory addresses */
+ if(pvAltLinAddr)
+ {
+ pui8DataLinAddr = pvAltLinAddr;
+ }
+ else if(psMemInfo->pvLinAddrKM)
+ {
+ pui8DataLinAddr = (IMG_UINT8 *)psMemInfo->pvLinAddrKM + ui32Offset;
+ }
+ pui8LinAddr = (IMG_UINT8 *)psMemInfo->pvLinAddrKM;
+ sDevVAddr = psMemInfo->sDevVAddr;
+
+ /* advance address by offset */
+ sDevVAddr.uiAddr += ui32Offset;
+ pui8LinAddr += ui32Offset;
+
+ PVR_ASSERT(pui8DataLinAddr);
+
+ PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags);
+
+ ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);
+
+ /*
+ write the binary data up-front.
+ */
+ if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
+ pui8DataLinAddr,
+ ui32Bytes,
+ ui32Flags))
+ {
+ return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
+ }
+
+ if (PDumpOSGetParamFileNum() == 0)
+ {
+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm");
+ }
+ else
+ {
+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum());
+ }
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+ /*
+ Write a comment to the PDump2 script streams indicating the virtual memory load
+ */
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "-- LDB :%s:VA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+ psMemInfo->sDevVAddr.uiAddr,
+ ui32Offset,
+ ui32Bytes,
+ ui32ParamOutPos,
+ pszFileName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ /*
+ query the buffer manager for the physical pages that back the
+ virtual address
+ */
+ PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle,
+ ui32Offset,
+ pui8LinAddr,
+ psMMUAttrib->ui32DataPageMask,
+ &ui32PageByteOffset);
+ ui32DataPageSize = psMMUAttrib->ui32DataPageMask + 1;
+ ui32NumPages = (ui32PageByteOffset + ui32Bytes + psMMUAttrib->ui32DataPageMask) / ui32DataPageSize;
+
+ while(ui32NumPages)
+ {
+ ui32NumPages--;
+
+ /* calculate the DevV page address */
+ sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset;
+
+ if (ui32DataPageSize <= PDUMP_TEMP_BUFFER_SIZE)
+ {
+ /* if a page fits within temp buffer, we should dump in page-aligned chunks. */
+ PVR_ASSERT((sDevVPageAddr.uiAddr & psMMUAttrib->ui32DataPageMask) == 0);
+ }
+
+ /* get the physical page address based on the device virtual address */
+ BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
+
+ /* convert DevP page address to byte address */
+ sDevPAddr.uiAddr += ui32PageByteOffset;
+
+ /* how many bytes to dump from this page */
+ if (ui32PageByteOffset + ui32Bytes > ui32DataPageSize)
+ {
+ /* dump up to the page boundary */
+ ui32BlockBytes = ui32DataPageSize - ui32PageByteOffset;
+ }
+ else
+ {
+ /* dump what's left */
+ ui32BlockBytes = ui32Bytes;
+ }
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "LDB :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+ sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask),
+ sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask),
+ ui32BlockBytes,
+ ui32ParamOutPos,
+ pszFileName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ /* update details for next page */
+
+#if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
+ /* page may be larger than pdump temporary buffer */
+ ui32PageByteOffset = (ui32PageByteOffset + ui32BlockBytes) % ui32DataPageSize;
+#else
+ /* page offset 0 after first page dump */
+ ui32PageByteOffset = 0;
+#endif
+ /* bytes left over */
+ ui32Bytes -= ui32BlockBytes; /* PRQA S 3382 */ /* QAC missed MIN test */
+ /* advance devVaddr */
+ sDevVAddr.uiAddr += ui32BlockBytes;
+ /* advance the cpuVaddr */
+ pui8LinAddr += ui32BlockBytes;
+ /* update the file write offset */
+ ui32ParamOutPos += ui32BlockBytes;
+ }
+
+ return PVRSRV_OK;
+}
+
+/**************************************************************************
+ * Function Name : PDumpMemKM
+ * Inputs : psMemInfo
+ * : ui32Offset
+ * : ui32Bytes
+ * : ui32Flags
+ * : hUniqueTag
+ * Outputs : None
+ * Returns : PVRSRV_ERROR
+ * Description : Implements Client pdump mem API
+**************************************************************************/
+PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32Offset,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag)
+{
+ /*
+ For now we don't support dumping sparse allocations that
+ are from within the kernel, or are from UM but without a
+ alternative linear address
+ */
+ PVR_ASSERT((psMemInfo->ui32Flags & PVRSRV_MEM_SPARSE) == 0);
+
+ if (psMemInfo->ui32Flags & PVRSRV_MEM_SPARSE)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ else
+ {
+ return _PDumpMemIntKM(pvAltLinAddr,
+ psMemInfo,
+ ui32Offset,
+ ui32Bytes,
+ ui32Flags,
+ hUniqueTag);
+ }
+}
+
+PVRSRV_ERROR PDumpMemPDEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib,
+ IMG_HANDLE hOSMemHandle,
+ IMG_CPU_VIRTADDR pvLinAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_BOOL bInitialisePages,
+ IMG_HANDLE hUniqueTag1,
+ IMG_HANDLE hUniqueTag2)
+{
+ PDUMP_MMU_ATTRIB sMMUAttrib;
+
+ /* Override the (variable) PT size since PDs are always 4K in size */
+ sMMUAttrib = *psMMUAttrib;
+ sMMUAttrib.ui32PTSize = (IMG_UINT32)HOST_PAGESIZE();
+ return PDumpMemPTEntriesKM( &sMMUAttrib,
+ hOSMemHandle,
+ pvLinAddr,
+ ui32Bytes,
+ ui32Flags,
+ bInitialisePages,
+ hUniqueTag1,
+ hUniqueTag2);
+}
+
+/**************************************************************************
+ * Function Name : PDumpMemPTEntriesKM
+ * Inputs : psMMUAttrib - MMU attributes for pdump
+ * : pvLinAddr - CPU address of PT base
+ * : ui32Bytes - size
+ * : ui32Flags - pdump flags
+ * : bInitialisePages - whether to initialise pages from file
+ * : hUniqueTag1 - ID for PT physical page
+ * : hUniqueTag2 - ID for target physical page (if !bInitialisePages)
+ * Outputs : None
+ * Returns : PVRSRV_ERROR
+ * Description : Kernel Services internal pdump memory API
+ * Used for memory without DevVAddress mappings
+ e.g. MMU page tables
+ FIXME: This function doesn't support non-4k data pages,
+ e.g. dummy data page
+**************************************************************************/
+PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib,
+ IMG_HANDLE hOSMemHandle,
+ IMG_CPU_VIRTADDR pvLinAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_BOOL bInitialisePages,
+ IMG_HANDLE hUniqueTag1,
+ IMG_HANDLE hUniqueTag2)
+{
+ PVRSRV_ERROR eErr;
+ 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;
+ IMG_UINT32 ui32PageMask; /* mask for the physical page backing the PT */
+
+ PDUMP_GET_SCRIPT_AND_FILE_STRING();
+ ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+
+ if (PDumpOSIsSuspended())
+ {
+ return PVRSRV_OK;
+ }
+
+ if (!PDumpOSJTInitialised())
+ {
+ return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
+ }
+
+ if (!pvLinAddr)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags);
+
+ ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);
+
+ if (bInitialisePages)
+ {
+ /*
+ write the binary data up-front
+ Use the 'continuous' memory stream
+ */
+ if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
+ pvLinAddr,
+ ui32Bytes,
+ ui32Flags | PDUMP_FLAGS_CONTINUOUS))
+ {
+ return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
+ }
+
+ if (PDumpOSGetParamFileNum() == 0)
+ {
+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm");
+ }
+ else
+ {
+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum());
+ }
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ }
+
+ /*
+ Mask for the physical page address backing the PT
+ The PT size can be less than 4k with variable page size support
+ The PD size is always 4k
+ FIXME: This won't work for dumping the dummy data page
+ */
+ ui32PageMask = psMMUAttrib->ui32PTSize - 1;
+
+ /*
+ Write to the MMU script stream indicating the physical page table entries
+ */
+ /* physical pages that back the virtual address */
+ ui32PageOffset = (IMG_UINT32)((IMG_UINTPTR_T)pvLinAddr & (psMMUAttrib->ui32PTSize - 1));
+ ui32NumPages = (ui32PageOffset + ui32Bytes + psMMUAttrib->ui32PTSize - 1) / psMMUAttrib->ui32PTSize;
+ pui8LinAddr = (IMG_UINT8*) pvLinAddr;
+
+ while (ui32NumPages)
+ {
+ ui32NumPages--;
+ /* FIXME: if we used OSMemHandleToCPUPAddr() here, we might be
+ able to lose the lin addr arg. At least one thing that
+ would need to be done here is to pass in an offset, as the
+ calling function doesn't necessarily give us the lin addr
+ of the start of the mem area. Probably best to keep the
+ lin addr arg for now - but would be nice to remove the
+ redundancy */
+ sCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle, pui8LinAddr);
+ sDevPAddr = SysCpuPAddrToDevPAddr(psMMUAttrib->sDevId.eDeviceType, sCpuPAddr);
+
+ /* how many bytes to dump from this page */
+ if (ui32PageOffset + ui32Bytes > psMMUAttrib->ui32PTSize)
+ {
+ /* dump up to the page boundary */
+ ui32BlockBytes = psMMUAttrib->ui32PTSize - ui32PageOffset;
+ }
+ else
+ {
+ /* dump what's left */
+ ui32BlockBytes = ui32Bytes;
+ }
+
+ /*
+ Write a comment to the MMU script stream indicating the page table load
+ */
+
+ if (bInitialisePages)
+ {
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "LDB :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+ sDevPAddr.uiAddr & ~ui32PageMask,
+ sDevPAddr.uiAddr & ui32PageMask,
+ ui32BlockBytes,
+ ui32ParamOutPos,
+ pszFileName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+ }
+ else
+ {
+ for (ui32Offset = 0; ui32Offset < ui32BlockBytes; ui32Offset += sizeof(IMG_UINT32))
+ {
+ IMG_UINT32 ui32PTE = *((IMG_UINT32 *)(IMG_UINTPTR_T)(pui8LinAddr + ui32Offset)); /* PRQA S 3305 */ /* strict pointer */
+
+ if ((ui32PTE & psMMUAttrib->ui32PDEMask) != 0)
+ {
+ /* PT entry points to non-null page */
+#if defined(SGX_FEATURE_36BIT_MMU)
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "WRW :%s:$1 :%s:PA_%08X%08X:0x0\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)hUniqueTag2,
+ (ui32PTE & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PTEAlignShift);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "SHR :%s:$1 :%s:$1 0x4\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ psMMUAttrib->sDevId.pszPDumpDevName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "OR :%s:$1 :%s:$1 0x%08X\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ ui32PTE & ~psMMUAttrib->ui32PDEMask);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "WRW :%s:PA_%08X%08X:0x%08X :%s:$1\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)hUniqueTag1,
+ (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask,
+ (sDevPAddr.uiAddr + ui32Offset) & ui32PageMask,
+ psMMUAttrib->sDevId.pszPDumpDevName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+#else
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "WRW :%s:PA_%08X%08X:0x%08X :%s:PA_%08X%08X:0x%08X\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+ (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask,
+ (sDevPAddr.uiAddr + ui32Offset) & ui32PageMask,
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag2,
+ (ui32PTE & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PTEAlignShift,
+ ui32PTE & ~psMMUAttrib->ui32PDEMask);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+#endif
+ }
+ else
+ {
+#if !defined(FIX_HW_BRN_31620)
+ PVR_ASSERT((ui32PTE & psMMUAttrib->ui32PTEValid) == 0UL);
+#endif
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "WRW :%s:PA_%08X%08X:0x%08X 0x%08X%08X\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+ (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask,
+ (sDevPAddr.uiAddr + ui32Offset) & ui32PageMask,
+ (ui32PTE << psMMUAttrib->ui32PTEAlignShift),
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag2);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
+ }
+ }
+ }
+
+ /* update details for next page */
+
+ /* page offset 0 after first page dump */
+ ui32PageOffset = 0;
+ /* bytes left over */
+ ui32Bytes -= ui32BlockBytes;
+ /* advance the cpuVaddr */
+ pui8LinAddr += ui32BlockBytes;
+ /* update the file write offset */
+ 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)
+{
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32PageByteOffset;
+ IMG_DEV_VIRTADDR sDevVAddr;
+ IMG_DEV_VIRTADDR sDevVPageAddr;
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
+ IMG_UINT32 ui32ParamOutPos;
+ PDUMP_MMU_ATTRIB *psMMUAttrib;
+ IMG_UINT32 ui32PageMask; /* mask for the physical page backing the PT */
+
+ PDUMP_GET_SCRIPT_AND_FILE_STRING();
+
+ if (!PDumpOSJTInitialised())
+ {
+ return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
+ }
+
+ psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
+ ui32PageMask = psMMUAttrib->ui32PTSize - 1;
+
+ ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);
+
+ /* Write the PD phys addr to the param stream up front */
+ if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
+ (IMG_UINT8 *)&sPDDevPAddr,
+ sizeof(IMG_DEV_PHYADDR),
+ ui32Flags))
+ {
+ return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
+ }
+
+ if (PDumpOSGetParamFileNum() == 0)
+ {
+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm");
+ }
+ else
+ {
+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum());
+ }
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+ /* Write a comment indicating the PD phys addr write, so that the offsets
+ * into the param stream increase in correspondence with the number of bytes
+ * written. */
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "-- LDB :%s:PA_0x%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+ sPDDevPAddr.uiAddr & ~ui32PageMask,
+ sPDDevPAddr.uiAddr & ui32PageMask,
+ sizeof(IMG_DEV_PHYADDR),
+ ui32ParamOutPos,
+ pszFileName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ sDevVAddr = psMemInfo->sDevVAddr;
+ ui32PageByteOffset = sDevVAddr.uiAddr & ui32PageMask;
+
+ sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset;
+ PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
+
+ BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
+ sDevPAddr.uiAddr += ui32PageByteOffset + ui32Offset;
+
+ if ((sPDDevPAddr.uiAddr & psMMUAttrib->ui32PDEMask) != 0UL)
+ {
+#if defined(SGX_FEATURE_36BIT_MMU)
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "WRW :%s:$1 :%s:PA_%08X%08X:0x0\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)hUniqueTag2,
+ sPDDevPAddr.uiAddr);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "AND :%s:$2 :%s:$1 0xFFFFFFFF\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ psMMUAttrib->sDevId.pszPDumpDevName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "WRW :%s:PA_%08X%08X:0x%08X :%s:$2\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)hUniqueTag1,
+ (sDevPAddr.uiAddr) & ~(psMMUAttrib->ui32DataPageMask),
+ (sDevPAddr.uiAddr) & (psMMUAttrib->ui32DataPageMask),
+ psMMUAttrib->sDevId.pszPDumpDevName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "SHR :%s:$2 :%s:$1 0x20\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ psMMUAttrib->sDevId.pszPDumpDevName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "WRW :%s:PA_%08X%08X:0x%08X :%s:$2\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)hUniqueTag1,
+ (sDevPAddr.uiAddr + 4) & ~(psMMUAttrib->ui32DataPageMask),
+ (sDevPAddr.uiAddr + 4) & (psMMUAttrib->ui32DataPageMask),
+ psMMUAttrib->sDevId.pszPDumpDevName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+#else
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "WRW :%s:PA_%08X%08X:0x%08X :%s:PA_%08X%08X:0x%08X\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+ sDevPAddr.uiAddr & ~ui32PageMask,
+ sDevPAddr.uiAddr & ui32PageMask,
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag2,
+ sPDDevPAddr.uiAddr & psMMUAttrib->ui32PDEMask,
+ sPDDevPAddr.uiAddr & ~psMMUAttrib->ui32PDEMask);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+#endif
+ }
+ else
+ {
+ PVR_ASSERT(!(sDevPAddr.uiAddr & psMMUAttrib->ui32PTEValid));
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "WRW :%s:PA_%08X%08X:0x%08X 0x%08X\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+ sDevPAddr.uiAddr & ~ui32PageMask,
+ sDevPAddr.uiAddr & ui32PageMask,
+ sPDDevPAddr.uiAddr);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ return PVRSRV_OK;
+}
+
+/**************************************************************************
+ * Function Name : PDumpCommentKM
+ * Inputs : pszComment, ui32Flags
+ * Outputs : None
+ * Returns : None
+ * Description : Dumps a comment
+**************************************************************************/
+PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags)
+{
+ PVRSRV_ERROR eErr;
+ IMG_CHAR pszCommentPrefix[] = "-- "; /* prefix for comments */
+#if defined(PDUMP_DEBUG_OUTFILES)
+ IMG_CHAR pszTemp[256];
+#endif
+ IMG_UINT32 ui32LenCommentPrefix;
+ PDUMP_GET_SCRIPT_STRING();
+ PDUMP_DBG(("PDumpCommentKM"));
+#if defined(PDUMP_DEBUG_OUTFILES)
+ /* include comments in the "extended" init phase.
+ * default is to ignore them.
+ */
+ ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+#endif
+ /* Put \r \n sequence at the end if it isn't already there */
+ PDumpOSVerifyLineEnding(pszComment, ui32MaxLen);
+
+ /* Length of string excluding terminating NULL character */
+ ui32LenCommentPrefix = PDumpOSBuflen(pszCommentPrefix, sizeof(pszCommentPrefix));
+
+ /* Ensure output file is available for writing */
+ /* FIXME: is this necessary? */
+ if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_SCRIPT2),
+ (IMG_UINT8*)pszCommentPrefix,
+ ui32LenCommentPrefix,
+ ui32Flags))
+ {
+#if defined(PDUMP_DEBUG_OUTFILES)
+ if(ui32Flags & PDUMP_FLAGS_CONTINUOUS)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s (continuous set)",
+ g_ui32EveryLineCounter, pszComment));
+ return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
+ }
+ else if(ui32Flags & PDUMP_FLAGS_PERSISTENT)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s (persistent set)",
+ g_ui32EveryLineCounter, pszComment));
+ return PVRSRV_ERROR_CMD_NOT_PROCESSED;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s",
+ g_ui32EveryLineCounter, pszComment));
+ return PVRSRV_ERROR_CMD_NOT_PROCESSED;
+ }
+#else
+ PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %s",
+ pszComment));
+ return PVRSRV_ERROR_CMD_NOT_PROCESSED;
+#endif
+ }
+
+#if defined(PDUMP_DEBUG_OUTFILES)
+ /* Prefix comment with PID and line number */
+ eErr = PDumpOSSprintf(pszTemp, 256, "%d-%d %s",
+ _PDumpGetPID(),
+ g_ui32EveryLineCounter,
+ pszComment);
+
+ /* Append the comment to the script stream */
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "%s",
+ pszTemp);
+#else
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "%s",
+ pszComment);
+#endif
+ if( (eErr != PVRSRV_OK) &&
+ (eErr != PVRSRV_ERROR_PDUMP_BUF_OVERFLOW))
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+ return PVRSRV_OK;
+}
+
+/**************************************************************************
+ * Function Name : PDumpCommentWithFlags
+ * Inputs : psPDev - PDev for PDump device
+ * : pszFormat - format string for comment
+ * : ... - args for format string
+ * Outputs : None
+ * Returns : None
+ * Description : PDumps a comments
+**************************************************************************/
+PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32 ui32Flags, IMG_CHAR * pszFormat, ...)
+{
+ PVRSRV_ERROR eErr;
+ PDUMP_va_list ap;
+ PDUMP_GET_MSG_STRING();
+
+ /* Construct the string */
+ PDUMP_va_start(ap, pszFormat);
+ eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, ap);
+ PDUMP_va_end(ap);
+
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ return PDumpCommentKM(pszMsg, ui32Flags);
+}
+
+/**************************************************************************
+ * Function Name : PDumpComment
+ * Inputs : psPDev - PDev for PDump device
+ * : pszFormat - format string for comment
+ * : ... - args for format string
+ * Outputs : None
+ * Returns : None
+ * Description : PDumps a comments
+**************************************************************************/
+PVRSRV_ERROR PDumpComment(IMG_CHAR *pszFormat, ...)
+{
+ PVRSRV_ERROR eErr;
+ PDUMP_va_list ap;
+ PDUMP_GET_MSG_STRING();
+
+ /* Construct the string */
+ PDUMP_va_start(ap, pszFormat);
+ eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, ap);
+ PDUMP_va_end(ap);
+
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ return PDumpCommentKM(pszMsg, PDUMP_FLAGS_CONTINUOUS);
+}
+
+/**************************************************************************
+ * Function Name : PDumpDriverInfoKM
+ * Inputs : pszString, ui32Flags
+ * Outputs : None
+ * Returns : None
+ * Description : Dumps a comment
+**************************************************************************/
+PVRSRV_ERROR PDumpDriverInfoKM(IMG_CHAR *pszString, IMG_UINT32 ui32Flags)
+{
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32MsgLen;
+ PDUMP_GET_MSG_STRING();
+
+ /* Construct the string */
+ eErr = PDumpOSSprintf(pszMsg, ui32MaxLen, "%s", pszString);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+ /* Put \r \n sequence at the end if it isn't already there */
+ PDumpOSVerifyLineEnding(pszMsg, ui32MaxLen);
+ ui32MsgLen = PDumpOSBuflen(pszMsg, ui32MaxLen);
+
+ if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_DRIVERINFO),
+ (IMG_UINT8*)pszMsg,
+ ui32MsgLen,
+ ui32Flags))
+ {
+ if (ui32Flags & PDUMP_FLAGS_CONTINUOUS)
+ {
+ return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
+ }
+ else
+ {
+ return PVRSRV_ERROR_CMD_NOT_PROCESSED;
+ }
+ }
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PDumpBitmapKM
+
+ @Description
+
+ Dumps a bitmap from device memory to a file
+
+ @Input psDevId
+ @Input pszFileName
+ @Input ui32FileOffset
+ @Input ui32Width
+ @Input ui32Height
+ @Input ui32StrideInBytes
+ @Input sDevBaseAddr
+ @Input ui32Size
+ @Input ePixelFormat
+ @Input eMemFormat
+ @Input ui32PDumpFlags
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR PDumpBitmapKM( PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_UINT32 ui32Width,
+ IMG_UINT32 ui32Height,
+ IMG_UINT32 ui32StrideInBytes,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_UINT32 ui32Size,
+ PDUMP_PIXEL_FORMAT ePixelFormat,
+ PDUMP_MEM_FORMAT eMemFormat,
+ IMG_UINT32 ui32PDumpFlags)
+{
+ PVRSRV_DEVICE_IDENTIFIER *psDevId = &psDeviceNode->sDevId;
+ IMG_UINT32 ui32MMUContextID;
+ PVRSRV_ERROR eErr;
+ PDUMP_GET_SCRIPT_STRING();
+
+ if ( _PDumpIsPersistent() )
+ {
+ return PVRSRV_OK;
+ }
+
+ PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump bitmap of render\r\n");
+
+ /* find MMU context ID */
+ ui32MMUContextID = psDeviceNode->pfnMMUGetContextID( hDevMemContext );
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "SII %s %s.bin :%s:v%x:0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\r\n",
+ pszFileName,
+ pszFileName,
+ psDevId->pszPDumpDevName,
+ ui32MMUContextID,
+ sDevBaseAddr.uiAddr,
+ ui32Size,
+ ui32FileOffset,
+ ePixelFormat,
+ ui32Width,
+ ui32Height,
+ ui32StrideInBytes,
+ eMemFormat);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+ PDumpOSWriteString2( hScript, ui32PDumpFlags);
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PDumpReadRegKM
+
+ @Description
+
+ Dumps a read from a device register to a file
+
+ @Input psConnection : connection info
+ @Input pszFileName
+ @Input ui32FileOffset
+ @Input ui32Address
+ @Input ui32Size
+ @Input ui32PDumpFlags
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR PDumpReadRegKM ( IMG_CHAR *pszPDumpRegName,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_UINT32 ui32Address,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32PDumpFlags)
+{
+ PVRSRV_ERROR eErr;
+ PDUMP_GET_SCRIPT_STRING();
+
+ PVR_UNREFERENCED_PARAMETER(ui32Size);
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "SAB :%s:0x%08X 0x%08X %s\r\n",
+ pszPDumpRegName,
+ ui32Address,
+ ui32FileOffset,
+ pszFileName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+ PDumpOSWriteString2( hScript, ui32PDumpFlags);
+
+ return PVRSRV_OK;
+}
+
+/*****************************************************************************
+ @name PDumpTestNextFrame
+ @brief Tests whether the next frame will be pdumped
+ @param ui32CurrentFrame
+ @return bFrameDumped
+*****************************************************************************/
+IMG_BOOL PDumpTestNextFrame(IMG_UINT32 ui32CurrentFrame)
+{
+ IMG_BOOL bFrameDumped;
+
+ /*
+ Try dumping a string
+ */
+ (IMG_VOID) PDumpSetFrameKM(ui32CurrentFrame + 1);
+ bFrameDumped = PDumpIsCaptureFrameKM();
+ (IMG_VOID) PDumpSetFrameKM(ui32CurrentFrame);
+
+ return bFrameDumped;
+}
+
+/*****************************************************************************
+ @name PDumpSignatureRegister
+ @brief Dumps a single signature register
+ @param psDevId - device ID
+ @param ui32Address - The register address
+ @param ui32Size - The amount of data to be dumped in bytes
+ @param pui32FileOffset - Offset of dump in output file
+ @param ui32Flags - Flags
+ @return none
+*****************************************************************************/
+static PVRSRV_ERROR PDumpSignatureRegister (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32Address,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 *pui32FileOffset,
+ IMG_UINT32 ui32Flags)
+{
+ PVRSRV_ERROR eErr;
+ PDUMP_GET_SCRIPT_STRING();
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "SAB :%s:0x%08X 0x%08X %s\r\n",
+ psDevId->pszPDumpRegName,
+ ui32Address,
+ *pui32FileOffset,
+ pszFileName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+ PDumpOSWriteString2(hScript, ui32Flags);
+ *pui32FileOffset += ui32Size;
+ return PVRSRV_OK;
+}
+
+/*****************************************************************************
+ @name PDumpRegisterRange
+ @brief Dumps a list of signature registers to a file
+ @param psDevId - device ID
+ @param pszFileName - target filename for dump
+ @param pui32Registers - register list
+ @param ui32NumRegisters - number of regs to dump
+ @param pui32FileOffset - file offset
+ @param ui32Size - size of write in bytes
+ @param ui32Flags - pdump flags
+ @return none
+ *****************************************************************************/
+static IMG_VOID PDumpRegisterRange(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 *pui32Registers,
+ IMG_UINT32 ui32NumRegisters,
+ IMG_UINT32 *pui32FileOffset,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32Flags)
+{
+ IMG_UINT32 i;
+ for (i = 0; i < ui32NumRegisters; i++)
+ {
+ PDumpSignatureRegister(psDevId, pszFileName, pui32Registers[i], ui32Size, pui32FileOffset, ui32Flags);
+ }
+}
+
+/*****************************************************************************
+ @name PDump3DSignatureRegisters
+ @brief Dumps the signature registers for 3D modules...
+ @param psDevId - device ID info
+ @param pui32Registers - register list
+ @param ui32NumRegisters - number of regs to dump
+ @return Error
+*****************************************************************************/
+PVRSRV_ERROR PDump3DSignatureRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_UINT32 ui32DumpFrameNum,
+ IMG_BOOL bLastFrame,
+ IMG_UINT32 *pui32Registers,
+ IMG_UINT32 ui32NumRegisters)
+{
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32FileOffset, ui32Flags;
+
+ PDUMP_GET_FILE_STRING();
+
+ ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0;
+ ui32FileOffset = 0;
+
+ PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump 3D signature registers\r\n");
+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u_3d.sig", ui32DumpFrameNum);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+ PDumpRegisterRange(psDevId,
+ pszFileName,
+ pui32Registers,
+ ui32NumRegisters,
+ &ui32FileOffset,
+ sizeof(IMG_UINT32),
+ ui32Flags);
+
+ return PVRSRV_OK;
+}
+
+/*****************************************************************************
+ @name PDumpTASignatureRegisters
+ @brief Dumps the TA signature registers
+ @param psDevId - device id info
+ @param ui32DumpFrameNum - frame number
+ @param ui32TAKickCount - TA kick counter
+ @param bLastFrame
+ @param pui32Registers - register list
+ @param ui32NumRegisters - number of regs to dump
+ @return Error
+*****************************************************************************/
+PVRSRV_ERROR PDumpTASignatureRegisters (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_UINT32 ui32DumpFrameNum,
+ IMG_UINT32 ui32TAKickCount,
+ IMG_BOOL bLastFrame,
+ IMG_UINT32 *pui32Registers,
+ IMG_UINT32 ui32NumRegisters)
+{
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32FileOffset, ui32Flags;
+
+ PDUMP_GET_FILE_STRING();
+
+ ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0;
+ ui32FileOffset = ui32TAKickCount * ui32NumRegisters * sizeof(IMG_UINT32);
+
+ PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump TA signature registers\r\n");
+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u_ta.sig", ui32DumpFrameNum);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+ PDumpRegisterRange(psDevId,
+ pszFileName,
+ pui32Registers,
+ ui32NumRegisters,
+ &ui32FileOffset,
+ sizeof(IMG_UINT32),
+ ui32Flags);
+ return PVRSRV_OK;
+}
+
+/*****************************************************************************
+ @name PDumpCounterRegisters
+ @brief Dumps the performance counters
+ @param psDevId - device id info
+ @param ui32DumpFrameNum - frame number
+ @param bLastFrame
+ @param pui32Registers - register list
+ @param ui32NumRegisters - number of regs to dump
+ @return Error
+*****************************************************************************/
+PVRSRV_ERROR PDumpCounterRegisters (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_UINT32 ui32DumpFrameNum,
+ IMG_BOOL bLastFrame,
+ IMG_UINT32 *pui32Registers,
+ IMG_UINT32 ui32NumRegisters)
+{
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32FileOffset, ui32Flags;
+
+ PDUMP_GET_FILE_STRING();
+
+ ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0UL;
+ ui32FileOffset = 0UL;
+
+ PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump counter registers\r\n");
+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u.perf", ui32DumpFrameNum);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+ PDumpRegisterRange(psDevId,
+ pszFileName,
+ pui32Registers,
+ ui32NumRegisters,
+ &ui32FileOffset,
+ sizeof(IMG_UINT32),
+ ui32Flags);
+
+ return PVRSRV_OK;
+}
+
+/*****************************************************************************
+ @name PDumpRegRead
+ @brief Dump signature register read to script
+ @param pszPDumpDevName - pdump device name
+ @param ui32RegOffset - register offset
+ @param ui32Flags - pdump flags
+ @return Error
+*****************************************************************************/
+PVRSRV_ERROR PDumpRegRead(IMG_CHAR *pszPDumpRegName,
+ const IMG_UINT32 ui32RegOffset,
+ IMG_UINT32 ui32Flags)
+{
+ PVRSRV_ERROR eErr;
+ PDUMP_GET_SCRIPT_STRING();
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW :%s:0x%X\r\n",
+ pszPDumpRegName,
+ ui32RegOffset);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+ return PVRSRV_OK;
+}
+
+/*****************************************************************************
+ @name PDumpSaveMemKM
+ @brief Save device memory to a file
+ @param psDevId
+ @param pszFileName
+ @param ui32FileOffset
+ @param sDevBaseAddr
+ @param ui32Size
+ @param ui32PDumpFlags
+ @return Error
+*****************************************************************************/
+PVRSRV_ERROR PDumpSaveMemKM (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32MMUContextID,
+ IMG_UINT32 ui32PDumpFlags)
+{
+ PVRSRV_ERROR eErr;
+ PDUMP_GET_SCRIPT_STRING();
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "SAB :%s:v%x:0x%08X 0x%08X 0x%08X %s.bin\r\n",
+ psDevId->pszPDumpDevName,
+ ui32MMUContextID,
+ sDevBaseAddr.uiAddr,
+ ui32Size,
+ ui32FileOffset,
+ pszFileName);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+
+ PDumpOSWriteString2(hScript, ui32PDumpFlags);
+ return PVRSRV_OK;
+}
+
+/*****************************************************************************
+ @name PDumpCycleCountRegRead
+ @brief Dump counter register read to script
+ @param ui32RegOffset - register offset
+ @param bLastFrame
+ @return Error
+*****************************************************************************/
+PVRSRV_ERROR PDumpCycleCountRegRead(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ const IMG_UINT32 ui32RegOffset,
+ IMG_BOOL bLastFrame)
+{
+ PVRSRV_ERROR eErr;
+ PDUMP_GET_SCRIPT_STRING();
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW :%s:0x%X\r\n",
+ psDevId->pszPDumpRegName,
+ ui32RegOffset);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PDumpSignatureBuffer
+
+ @Description
+
+ Dumps a signature registers buffer
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR PDumpSignatureBuffer (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_CHAR *pszFileName,
+ IMG_CHAR *pszBufferType,
+ IMG_UINT32 ui32FileOffset,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32MMUContextID,
+ IMG_UINT32 ui32PDumpFlags)
+{
+ PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump microkernel %s signature Buffer\r\n",
+ pszBufferType);
+ PDumpCommentWithFlags(ui32PDumpFlags, "Buffer format (sizes in 32-bit words):\r\n");
+ PDumpCommentWithFlags(ui32PDumpFlags, "\tNumber of signatures per sample (1)\r\n");
+ PDumpCommentWithFlags(ui32PDumpFlags, "\tNumber of samples (1)\r\n");
+ PDumpCommentWithFlags(ui32PDumpFlags, "\tSignature register offsets (1 * number of signatures)\r\n");
+ PDumpCommentWithFlags(ui32PDumpFlags, "\tSignature sample values (number of samples * number of signatures)\r\n");
+ PDumpCommentWithFlags(ui32PDumpFlags, "Note: If buffer is full, last sample is final state after test completed\r\n");
+ return PDumpSaveMemKM(psDevId, pszFileName, ui32FileOffset, sDevBaseAddr, ui32Size,
+ ui32MMUContextID, ui32PDumpFlags);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PDumpHWPerfCBKM
+
+ @Description
+
+ Dumps the HW Perf Circular Buffer
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR PDumpHWPerfCBKM (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32MMUContextID,
+ IMG_UINT32 ui32PDumpFlags)
+{
+ PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump Hardware Performance Circular Buffer\r\n");
+ return PDumpSaveMemKM(psDevId, pszFileName, ui32FileOffset, sDevBaseAddr, ui32Size,
+ ui32MMUContextID, ui32PDumpFlags);
+}
+
+
+/*****************************************************************************
+ FUNCTION : PDumpCBP
+
+ PURPOSE : Dump CBP command to script
+
+ PARAMETERS :
+
+ RETURNS : None
+*****************************************************************************/
+PVRSRV_ERROR PDumpCBP(PPVRSRV_KERNEL_MEM_INFO psROffMemInfo,
+ IMG_UINT32 ui32ROffOffset,
+ IMG_UINT32 ui32WPosVal,
+ IMG_UINT32 ui32PacketSize,
+ IMG_UINT32 ui32BufferSize,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag)
+{
+ PVRSRV_ERROR eErr;
+ IMG_UINT32 ui32PageOffset;
+ IMG_UINT8 *pui8LinAddr;
+ IMG_DEV_VIRTADDR sDevVAddr;
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_DEV_VIRTADDR sDevVPageAddr;
+ //IMG_CPU_PHYADDR CpuPAddr;
+ PDUMP_MMU_ATTRIB *psMMUAttrib;
+
+ PDUMP_GET_SCRIPT_STRING();
+
+ psMMUAttrib = ((BM_BUF*)psROffMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
+
+ /* Check the offset and size don't exceed the bounds of the allocation */
+ PVR_ASSERT((ui32ROffOffset + sizeof(IMG_UINT32)) <= psROffMemInfo->uAllocSize);
+
+ pui8LinAddr = psROffMemInfo->pvLinAddrKM;
+ sDevVAddr = psROffMemInfo->sDevVAddr;
+
+ /* Advance addresses by offset */
+ pui8LinAddr += ui32ROffOffset;
+ sDevVAddr.uiAddr += ui32ROffOffset;
+
+ /*
+ query the buffer manager for the physical pages that back the
+ virtual address
+ */
+ PDumpOSCPUVAddrToPhysPages(psROffMemInfo->sMemBlk.hOSMemHandle,
+ ui32ROffOffset,
+ pui8LinAddr,
+ psMMUAttrib->ui32DataPageMask,
+ &ui32PageOffset);
+
+ /* calculate the DevV page address */
+ sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageOffset;
+
+ PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
+
+ /* get the physical page address based on the device virtual address */
+ BM_GetPhysPageAddr(psROffMemInfo, sDevVPageAddr, &sDevPAddr);
+
+ /* convert DevP page address to byte address */
+ sDevPAddr.uiAddr += ui32PageOffset;
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "CBP :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X 0x%08X\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+ sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask),
+ sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask),
+ ui32WPosVal,
+ ui32PacketSize,
+ ui32BufferSize);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+ return PVRSRV_OK;
+}
+
+
+/**************************************************************************
+ * Function Name : PDumpIDLWithFlags
+ * Inputs : Idle time in clocks
+ * Outputs : None
+ * Returns : Error
+ * Description : Dump IDL command to script
+**************************************************************************/
+PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags)
+{
+ PVRSRV_ERROR eErr;
+ PDUMP_GET_SCRIPT_STRING();
+ PDUMP_DBG(("PDumpIDLWithFlags"));
+
+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "IDL %u\r\n", ui32Clocks);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, ui32Flags);
+ return PVRSRV_OK;
+}
+
+
+/**************************************************************************
+ * Function Name : PDumpIDL
+ * Inputs : Idle time in clocks
+ * Outputs : None
+ * Returns : Error
+ * Description : Dump IDL command to script
+**************************************************************************/
+PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks)
+{
+ return PDumpIDLWithFlags(ui32Clocks, PDUMP_FLAGS_CONTINUOUS);
+}
+
+/**************************************************************************
+ * Function Name : PDumpMemUM
+ * Inputs : pvAltLinAddrUM
+ * : pvLinAddrUM
+ * : psMemInfo
+ * : ui32Offset
+ * : ui32Bytes
+ * : ui32Flags
+ * : hUniqueTag
+ * Outputs : None
+ * Returns : PVRSRV_ERROR
+ * Description : Dump user mode memory
+**************************************************************************/
+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;
+ PVRSRV_ERROR eError;
+
+ if (psMemInfo->pvLinAddrKM != IMG_NULL && pvAltLinAddrUM == IMG_NULL)
+ {
+ /*
+ * There is a kernel virtual address for the memory that is
+ * being dumped, and no alternate user mode linear address.
+ */
+ 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();
+
+ /*
+ * The memory to be dumped needs to be copied in from
+ * the client. Dump the memory, a buffer at a time.
+ */
+ 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_INVALID_PARAMS;
+ }
+
+ if (ui32Bytes > PDUMP_TEMP_BUFFER_SIZE)
+ {
+ PDumpCommentWithFlags(ui32Flags, "Dumping 0x%08x bytes of memory, in blocks of 0x%08x bytes", ui32Bytes, (IMG_UINT32)PDUMP_TEMP_BUFFER_SIZE);
+ }
+
+ if (psMemInfo->ui32Flags & PVRSRV_MEM_SPARSE)
+ {
+ /*
+ In case of sparse mappings we can't just copy the full range as not
+ all pages are valid, instead we walk a page at a time only dumping
+ if the a page exists at that address
+ */
+ IMG_UINT32 ui32BytesRemain = ui32Bytes;
+ IMG_UINT32 ui32InPageStart = ui32Offset & (~HOST_PAGEMASK);
+ IMG_UINT32 ui32PageOffset = ui32Offset & (HOST_PAGEMASK);
+ IMG_UINT32 ui32BytesToCopy = MIN(HOST_PAGESIZE() - ui32InPageStart, ui32BytesRemain);
+
+ do
+ {
+ if (BM_MapPageAtOffset(BM_MappingHandleFromBuffer(psMemInfo->sMemBlk.hBuffer), ui32PageOffset))
+ {
+ eError = OSCopyFromUser(psPerProc,
+ pvAddrKM,
+ pvAddrUM,
+ ui32BytesToCopy);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: OSCopyFromUser failed (%d)", eError));
+ return eError;
+ }
+
+ /*
+ At this point we know we're dumping a valid page so call
+ the internal function
+ */
+ eError = _PDumpMemIntKM(pvAddrKM,
+ psMemInfo,
+ ui32PageOffset + ui32InPageStart,
+ ui32BytesToCopy,
+ ui32Flags,
+ hUniqueTag);
+
+ if (eError != PVRSRV_OK)
+ {
+ /*
+ * If writing fails part way through, then some
+ * investigation is needed.
+ */
+ if (ui32BytesToCopy != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: PDumpMemKM failed (%d)", eError));
+ }
+ PVR_ASSERT(ui32BytesToCopy == 0);
+ return eError;
+ }
+ }
+
+ VPTR_INC(pvAddrUM, ui32BytesToCopy);
+ ui32BytesRemain -= ui32BytesToCopy;
+ ui32InPageStart = 0;
+ ui32PageOffset += HOST_PAGESIZE();
+ } while(ui32BytesRemain);
+ }
+ else
+ {
+ IMG_UINT32 ui32CurrentOffset = ui32Offset;
+ IMG_UINT32 ui32BytesDumped;
+
+ for (ui32BytesDumped = 0; ui32BytesDumped < ui32Bytes;)
+ {
+ 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 eError;
+ }
+
+ eError = PDumpMemKM(pvAddrKM,
+ psMemInfo,
+ ui32CurrentOffset,
+ ui32BytesToDump,
+ ui32Flags,
+ hUniqueTag);
+
+ if (eError != PVRSRV_OK)
+ {
+ /*
+ * If writing fails part way through, then some
+ * investigation is needed.
+ */
+ 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;
+}
+
+
+/**************************************************************************
+ * Function Name : _PdumpAllocMMUContext
+ * Inputs : pui32MMUContextID
+ * Outputs : None
+ * Returns : PVRSRV_ERROR
+ * Description : pdump util to allocate MMU contexts
+**************************************************************************/
+static PVRSRV_ERROR _PdumpAllocMMUContext(IMG_UINT32 *pui32MMUContextID)
+{
+ IMG_UINT32 i;
+
+ /* there are MAX_PDUMP_MMU_CONTEXTS contexts available, find one */
+ for(i=0; i<MAX_PDUMP_MMU_CONTEXTS; i++)
+ {
+ if((gui16MMUContextUsage & (1U << i)) == 0)
+ {
+ /* mark in use */
+ gui16MMUContextUsage |= 1U << i;
+ *pui32MMUContextID = i;
+ return PVRSRV_OK;
+ }
+ }
+
+ PVR_DPF((PVR_DBG_ERROR, "_PdumpAllocMMUContext: no free MMU context ids"));
+
+ return PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND;
+}
+
+
+/**************************************************************************
+ * Function Name : _PdumpFreeMMUContext
+ * Inputs : ui32MMUContextID
+ * Outputs : None
+ * Returns : PVRSRV_ERROR
+ * Description : pdump util to free MMU contexts
+**************************************************************************/
+static PVRSRV_ERROR _PdumpFreeMMUContext(IMG_UINT32 ui32MMUContextID)
+{
+ if(ui32MMUContextID < MAX_PDUMP_MMU_CONTEXTS)
+ {
+ /* free the id */
+ gui16MMUContextUsage &= ~(1U << ui32MMUContextID);
+ return PVRSRV_OK;
+ }
+
+ PVR_DPF((PVR_DBG_ERROR, "_PdumpFreeMMUContext: MMU context ids invalid"));
+
+ return PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND;
+}
+
+
+/**************************************************************************
+ * Function Name : PDumpSetMMUContext
+ * Inputs :
+ * Outputs : None
+ * Returns : PVRSRV_ERROR
+ * Description : Set MMU Context
+**************************************************************************/
+PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
+ IMG_CHAR *pszMemSpace,
+ IMG_UINT32 *pui32MMUContextID,
+ IMG_UINT32 ui32MMUType,
+ IMG_HANDLE hUniqueTag1,
+ IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvPDCPUAddr)
+{
+ IMG_UINT8 *pui8LinAddr = (IMG_UINT8 *)pvPDCPUAddr;
+ IMG_CPU_PHYADDR sCpuPAddr;
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_UINT32 ui32MMUContextID;
+ PVRSRV_ERROR eErr;
+ PDUMP_GET_SCRIPT_STRING();
+
+ eErr = _PdumpAllocMMUContext(&ui32MMUContextID);
+ if(eErr != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PDumpSetMMUContext: _PdumpAllocMMUContext failed: %d", eErr));
+ return eErr;
+ }
+
+ /* derive the DevPAddr */
+ /* FIXME: if we used OSMemHandleToCPUPAddr() here, we could lose the lin addr arg */
+ sCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle, pui8LinAddr);
+ sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
+ /* and round to 4k page */
+ sDevPAddr.uiAddr &= ~((PVRSRV_4K_PAGE_SIZE) -1);
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "MMU :%s:v%d %d :%s:PA_%08X%08X\r\n",
+ pszMemSpace,
+ ui32MMUContextID,
+ ui32MMUType,
+ pszMemSpace,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
+ sDevPAddr.uiAddr);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
+
+ /* return the MMU Context ID */
+ *pui32MMUContextID = ui32MMUContextID;
+
+ return PVRSRV_OK;
+}
+
+
+/**************************************************************************
+ * Function Name : PDumpClearMMUContext
+ * Inputs :
+ * Outputs : None
+ * Returns : PVRSRV_ERROR
+ * Description : Clear MMU Context
+**************************************************************************/
+PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
+ IMG_CHAR *pszMemSpace,
+ IMG_UINT32 ui32MMUContextID,
+ IMG_UINT32 ui32MMUType)
+{
+ PVRSRV_ERROR eErr;
+ PDUMP_GET_SCRIPT_STRING();
+ PVR_UNREFERENCED_PARAMETER(eDeviceType);
+ PVR_UNREFERENCED_PARAMETER(ui32MMUType);
+
+ /* FIXME: Propagate error from PDumpComment once it's supported on
+ * all OSes and platforms
+ */
+ PDumpComment("Clear MMU Context for memory space %s\r\n", pszMemSpace);
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "MMU :%s:v%d\r\n",
+ pszMemSpace,
+ ui32MMUContextID);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
+
+ eErr = _PdumpFreeMMUContext(ui32MMUContextID);
+ if(eErr != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PDumpClearMMUContext: _PdumpFreeMMUContext failed: %d", eErr));
+ return eErr;
+ }
+
+ return PVRSRV_OK;
+}
+
+/*****************************************************************************
+ FUNCTION : PDumpStoreMemToFile
+
+ PURPOSE : Dumps a given addr:size to a file
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+PVRSRV_ERROR PDumpStoreMemToFile(PDUMP_MMU_ATTRIB *psMMUAttrib,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 uiAddr,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32PDumpFlags,
+ IMG_HANDLE hUniqueTag)
+{
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_DEV_VIRTADDR sDevVPageAddr;
+ IMG_UINT32 ui32PageOffset;
+
+ PDUMP_GET_SCRIPT_STRING();
+
+ /*
+ query the buffer manager for the physical pages that back the
+ virtual address
+ */
+ ui32PageOffset = (IMG_UINT32)((IMG_UINTPTR_T)psMemInfo->pvLinAddrKM & psMMUAttrib->ui32DataPageMask);
+
+ /* calculate the DevV page address */
+ sDevVPageAddr.uiAddr = uiAddr - ui32PageOffset;
+
+ /* get the physical page address based on the device virtual address */
+ BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
+
+ /* convert DevP page address to byte address */
+ sDevPAddr.uiAddr += ui32PageOffset;
+
+ PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "SAB :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
+ psMMUAttrib->sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
+ sDevPAddr.uiAddr & ~psMMUAttrib->ui32DataPageMask,
+ sDevPAddr.uiAddr & psMMUAttrib->ui32DataPageMask,
+ ui32Size,
+ ui32FileOffset,
+ pszFileName);
+
+ PDumpOSWriteString2(hScript, ui32PDumpFlags);
+
+ return PVRSRV_OK;
+}
+
+/*****************************************************************************
+ FUNCTION : PDumpRegBasedCBP
+
+ PURPOSE : Dump CBP command to script
+
+ PARAMETERS :
+
+ RETURNS : None
+*****************************************************************************/
+PVRSRV_ERROR PDumpRegBasedCBP(IMG_CHAR *pszPDumpRegName,
+ IMG_UINT32 ui32RegOffset,
+ IMG_UINT32 ui32WPosVal,
+ IMG_UINT32 ui32PacketSize,
+ IMG_UINT32 ui32BufferSize,
+ IMG_UINT32 ui32Flags)
+{
+ PDUMP_GET_SCRIPT_STRING();
+
+ PDumpOSBufprintf(hScript,
+ ui32MaxLen,
+ "CBP :%s:0x%08X 0x%08X 0x%08X 0x%08X\r\n",
+ pszPDumpRegName,
+ ui32RegOffset,
+ ui32WPosVal,
+ ui32PacketSize,
+ ui32BufferSize);
+ PDumpOSWriteString2(hScript, ui32Flags);
+
+ return PVRSRV_OK;
+}
+
+
+/****************************************************
+ * Non-uitron code here.
+ * For example, code communicating with dbg driver.
+ ***************************************************/
+/* PRQA S 5087 1 */ /* include file needed here */
+#include "syscommon.h"
+
+/**************************************************************************
+ * Function Name : PDumpConnectionNotify
+ * Description : Called by the debugdrv to tell Services that pdump has
+ * connected
+ * NOTE: No debugdrv on uitron.
+ **************************************************************************/
+IMG_EXPORT IMG_VOID PDumpConnectionNotify(IMG_VOID)
+{
+ SYS_DATA *psSysData;
+ PVRSRV_DEVICE_NODE *psThis;
+ PVR_DPF((PVR_DBG_WARNING, "PDump has connected."));
+
+ /* Loop over all known devices */
+ SysAcquireData(&psSysData);
+
+ psThis = psSysData->psDeviceNodeList;
+ while (psThis)
+ {
+ if (psThis->pfnPDumpInitDevice)
+ {
+ /* Reset pdump according to connected device */
+ psThis->pfnPDumpInitDevice(psThis);
+ }
+ psThis = psThis->psNext;
+ }
+}
+
+/*****************************************************************************
+ * Function Name : DbgWrite
+ * Inputs : psStream - debug stream to write to
+ pui8Data - buffer
+ ui32BCount - buffer length
+ ui32Flags - flags, e.g. continuous, LF
+ * Outputs : None
+ * Returns : Bytes written
+ * Description : Write a block of data to a debug stream
+ * NOTE: No debugdrv on uitron.
+ *****************************************************************************/
+IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags)
+{
+ IMG_UINT32 ui32BytesWritten = 0;
+ IMG_UINT32 ui32Off = 0;
+ PDBG_STREAM_CONTROL psCtrl = psStream->psCtrl;
+
+ /* Return immediately if marked as "never" */
+ if ((ui32Flags & PDUMP_FLAGS_NEVER) != 0)
+ {
+ return ui32BCount;
+ }
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ /* Return if process is not marked for pdumping, unless it's persistent.
+ */
+ if ( (_PDumpIsProcessActive() == IMG_FALSE ) &&
+ ((ui32Flags & PDUMP_FLAGS_PERSISTENT) == 0) )
+ {
+ return ui32BCount;
+ }
+#endif
+
+ /* Send persistent data first ...
+ * If we're still initialising the params will be captured to the
+ * init stream in the call to pfnDBGDrivWrite2 below.
+ */
+ if ( ((ui32Flags & PDUMP_FLAGS_PERSISTENT) != 0) && (psCtrl->bInitPhaseComplete) )
+ {
+ while (ui32BCount > 0)
+ {
+ /*
+ Params marked as persistent should be appended to the init phase.
+ For example window system mem mapping of the primary surface.
+ */
+ ui32BytesWritten = PDumpOSDebugDriverWrite( psStream,
+ PDUMP_WRITE_MODE_PERSISTENT,
+ &pui8Data[ui32Off], ui32BCount, 1, 0);
+
+ if (ui32BytesWritten == 0)
+ {
+ PDumpOSReleaseExecution();
+ }
+
+ if (ui32BytesWritten != 0xFFFFFFFFU)
+ {
+ ui32Off += ui32BytesWritten;
+ ui32BCount -= ui32BytesWritten;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DbgWrite: Failed to send persistent data"));
+ if( (psCtrl->ui32Flags & DEBUG_FLAGS_READONLY) != 0)
+ {
+ /* suspend pdump to prevent flooding kernel log buffer */
+ PDumpSuspendKM();
+ }
+ return 0xFFFFFFFFU;
+ }
+ }
+
+ /* reset buffer counters */
+ ui32BCount = ui32Off; ui32Off = 0; ui32BytesWritten = 0;
+ }
+
+ while (((IMG_UINT32) ui32BCount > 0) && (ui32BytesWritten != 0xFFFFFFFFU))
+ {
+ if ((ui32Flags & PDUMP_FLAGS_CONTINUOUS) != 0)
+ {
+ /*
+ If pdump client (or its equivalent) isn't running then throw continuous data away.
+ */
+ if (((psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED) != 0) &&
+ (psCtrl->ui32Start == 0xFFFFFFFFU) &&
+ (psCtrl->ui32End == 0xFFFFFFFFU) &&
+ psCtrl->bInitPhaseComplete)
+ {
+ ui32BytesWritten = ui32BCount;
+ }
+ else
+ {
+ ui32BytesWritten = PDumpOSDebugDriverWrite( psStream,
+ PDUMP_WRITE_MODE_CONTINUOUS,
+ &pui8Data[ui32Off], ui32BCount, 1, 0);
+ }
+ }
+ else
+ {
+ if (ui32Flags & PDUMP_FLAGS_LASTFRAME)
+ {
+ IMG_UINT32 ui32DbgFlags;
+
+ ui32DbgFlags = 0;
+ if (ui32Flags & PDUMP_FLAGS_RESETLFBUFFER)
+ {
+ ui32DbgFlags |= WRITELF_FLAGS_RESETBUF;
+ }
+
+ ui32BytesWritten = PDumpOSDebugDriverWrite( psStream,
+ PDUMP_WRITE_MODE_LASTFRAME,
+ &pui8Data[ui32Off], ui32BCount, 1, ui32DbgFlags);
+ }
+ else
+ {
+ ui32BytesWritten = PDumpOSDebugDriverWrite( psStream,
+ PDUMP_WRITE_MODE_BINCM,
+ &pui8Data[ui32Off], ui32BCount, 1, 0);
+ }
+ }
+
+ /*
+ If the debug driver's buffers are full so no data could be written then yield
+ execution so pdump can run and empty them.
+ */
+ if (ui32BytesWritten == 0)
+ {
+ PDumpOSReleaseExecution();
+ }
+
+ if (ui32BytesWritten != 0xFFFFFFFFU)
+ {
+ ui32Off += ui32BytesWritten;
+ ui32BCount -= ui32BytesWritten;
+ }
+
+ /* loop exits when i) all data is written, or ii) an unrecoverable error occurs */
+ }
+
+ return ui32BytesWritten;
+}
+
+
+
+#else /* defined(PDUMP) */
+/* disable warning about empty module */
+#endif /* defined(PDUMP) */
+/*****************************************************************************
+ End of file (pdump_common.c)
+*****************************************************************************/
diff --git a/pvr-source/services4/srvkm/common/perproc.c b/pvr-source/services4/srvkm/common/perproc.c
new file mode 100644
index 0000000..3918bb2
--- /dev/null
+++ b/pvr-source/services4/srvkm/common/perproc.c
@@ -0,0 +1,398 @@
+/*************************************************************************/ /*!
+@Title Per-process storage
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Manage per-process storage
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "services_headers.h"
+#include "resman.h"
+#include "handle.h"
+#include "perproc.h"
+#include "osperproc.h"
+#if defined(TTRACE)
+#include "ttrace.h"
+#endif
+
+#define HASH_TAB_INIT_SIZE 32
+
+static HASH_TABLE *psHashTab = IMG_NULL;
+
+/*!
+******************************************************************************
+
+ @Function FreePerProcData
+
+ @Description Free a per-process data area
+
+ @Input psPerProc - pointer to per-process data area
+
+ @Return Error code, or PVRSRV_OK
+
+******************************************************************************/
+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"));
+ /*
+ * We must have failed early in the per-process data area
+ * creation, before the process ID was set.
+ */
+ PVR_ASSERT(psPerProc->ui32PID == 0);
+ }
+ else
+ {
+ PVR_ASSERT((PVRSRV_PER_PROCESS_DATA *)uiPerProc == psPerProc);
+ PVR_ASSERT(((PVRSRV_PER_PROCESS_DATA *)uiPerProc)->ui32PID == psPerProc->ui32PID);
+ }
+
+ /* Free handle base for this process */
+ 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;
+ }
+ }
+
+ /* Release handle for per-process data area */
+ 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;
+ }
+ }
+
+ /* Call environment specific per process deinit function */
+ 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);
+ /*not nulling pointer, copy on stack*/
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't free per-process data (%d)", eError));
+ return eError;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVPerProcessData
+
+ @Description Return per-process data area
+
+ @Input ui32PID - process ID
+
+ @Return Pointer to per-process data area, or IMG_NULL on error.
+
+******************************************************************************/
+PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(IMG_UINT32 ui32PID)
+{
+ PVRSRV_PER_PROCESS_DATA *psPerProc;
+
+ PVR_ASSERT(psHashTab != IMG_NULL);
+
+ /* Look for existing per-process data area */
+ psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
+ return psPerProc;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVPerProcessDataConnect
+
+ @Description Allocate per-process data area, or increment refcount if one
+ already exists for this PID.
+
+ @Input ui32PID - process ID
+ ppsPerProc - Pointer to per-process data area
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32 ui32PID, IMG_UINT32 ui32Flags)
+{
+ PVRSRV_PER_PROCESS_DATA *psPerProc;
+ IMG_HANDLE hBlockAlloc;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ if (psHashTab == IMG_NULL)
+ {
+ return PVRSRV_ERROR_INIT_FAILURE;
+ }
+
+ /* Look for existing per-process data area */
+ psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
+
+ if (psPerProc == IMG_NULL)
+ {
+ /* Allocate per-process data area */
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(*psPerProc),
+ (IMG_PVOID *)&psPerProc,
+ &hBlockAlloc,
+ "Per Process Data");
+ 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_INSERT_HASH_TABLE_DATA_FAILED;
+ goto failure;
+ }
+
+ psPerProc->ui32PID = ui32PID;
+ psPerProc->ui32RefCount = 0;
+
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ if (ui32Flags == SRV_FLAGS_PDUMP_ACTIVE)
+ {
+ psPerProc->bPDumpActive = IMG_TRUE;
+ }
+#else
+ PVR_UNREFERENCED_PARAMETER(ui32Flags);
+#endif
+
+ /* Call environment specific per process init function */
+ eError = OSPerProcessPrivateDataInit(&psPerProc->hOsPrivateData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: OSPerProcessPrivateDataInit failed (%d)", eError));
+ goto failure;
+ }
+
+ /* Allocate a handle for the per-process data area */
+ 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;
+ }
+
+ /* Allocate handle base for this process */
+ 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;
+ }
+
+ /* Set per-process handle options */
+ eError = OSPerProcessSetHandleOptions(psPerProc->psHandleBase);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't set handle options (%d)", eError));
+ goto failure;
+ }
+
+ /* Create a resource manager context for the process */
+ eError = PVRSRVResManConnect(psPerProc, &psPerProc->hResManContext);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't register with the resource manager"));
+ goto failure;
+ }
+#if defined (TTRACE)
+ PVRSRVTimeTraceBufferCreate(ui32PID);
+#endif
+ }
+
+ 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;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVPerProcessDataDisconnect
+
+ @Description Decrement refcount for per-process data area,
+ and free the resources if necessary.
+
+ @Input ui32PID - process ID
+
+ @Return IMG_VOID
+
+******************************************************************************/
+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));
+
+ /* Close the Resource Manager connection */
+ PVRSRVResManDisconnect(psPerProc->hResManContext, IMG_FALSE);
+
+#if defined (TTRACE)
+ PVRSRVTimeTraceBufferDestroy(ui32PID);
+#endif
+
+ /* Free the per-process data */
+ 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));
+ }
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVPerProcessDataInit
+
+ @Description Initialise per-process data management
+
+ @Return Error code, or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVPerProcessDataInit(IMG_VOID)
+{
+ PVR_ASSERT(psHashTab == IMG_NULL);
+
+ /* Create hash table */
+ 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_UNABLE_TO_CREATE_HASH_TABLE;
+ }
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVPerProcessDataDeInit
+
+ @Description De-initialise per-process data management
+
+ @Return Error code, or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVPerProcessDataDeInit(IMG_VOID)
+{
+ /* Destroy per-process data area hash table */
+ if (psHashTab != IMG_NULL)
+ {
+ /* Free the hash table */
+ HASH_Delete(psHashTab);
+ psHashTab = IMG_NULL;
+ }
+
+ return PVRSRV_OK;
+}
+
+/******************************************************************************
+ End of file (perproc.c)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/common/power.c b/pvr-source/services4/srvkm/common/power.c
new file mode 100644
index 0000000..511a690
--- /dev/null
+++ b/pvr-source/services4/srvkm/common/power.c
@@ -0,0 +1,996 @@
+/*************************************************************************/ /*!
+@Title Power management functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Main APIs for power management functions
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "services_headers.h"
+#include "pdump_km.h"
+
+#include "lists.h"
+
+static IMG_BOOL gbInitServerRunning = IMG_FALSE;
+static IMG_BOOL gbInitServerRan = IMG_FALSE;
+static IMG_BOOL gbInitSuccessful = IMG_FALSE;
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVSetInitServerState
+
+ @Description Sets given services init state.
+
+ @Input eInitServerState : a services init state
+ @Input bState : a state to set
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+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 %x", eInitServerState));
+ return PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE;
+ }
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVGetInitServerState
+
+ @Description Tests whether a given services init state was run.
+
+ @Input eInitServerState : a services init state
+
+ @Return IMG_BOOL
+
+******************************************************************************/
+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 %x", eInitServerState));
+ bReturnVal = IMG_FALSE;
+ }
+
+ return bReturnVal;
+}
+
+/*!
+******************************************************************************
+
+ @Function _IsSystemStatePowered
+
+ @Description Tests whether a given system state represents powered-up.
+
+ @Input eSystemPowerState : a system power state
+
+ @Return IMG_BOOL
+
+******************************************************************************/
+static IMG_BOOL _IsSystemStatePowered(PVRSRV_SYS_POWER_STATE eSystemPowerState)
+{
+ return (IMG_BOOL)(eSystemPowerState < PVRSRV_SYS_POWER_STATE_D2);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVPowerLock
+
+ @Description Obtain the mutex for power transitions
+
+ @Input ui32CallerID : KERNEL_ID or ISR_ID
+ @Input bSystemPowerEvent : Only pass IMG_TRUE if the lock is for a
+ system power state change
+
+ @Return PVRSRV_ERROR IMG_CALLCONV
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVPowerLock(IMG_UINT32 ui32CallerID,
+ IMG_BOOL bSystemPowerEvent)
+{
+ PVRSRV_ERROR eError;
+ SYS_DATA *psSysData;
+ IMG_UINT32 ui32Timeout = 1000000;
+ IMG_BOOL bTryLock = (ui32CallerID == ISR_ID);
+
+ SysAcquireData(&psSysData);
+
+ eError = OSPowerLockWrap(bTryLock);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ do
+ {
+ eError = OSLockResource(&psSysData->sPowerStateChangeResource,
+ ui32CallerID);
+ if (eError == PVRSRV_OK)
+ {
+ break;
+ }
+ else if (bTryLock)
+ {
+ /*
+ ISR failed to acquire lock so it must be held by a kernel thread.
+ */
+ eError = PVRSRV_ERROR_RETRY;
+ break;
+ }
+
+ OSWaitus(1);
+ ui32Timeout--;
+ } while (ui32Timeout > 0);
+
+ if (eError != PVRSRV_OK)
+ {
+ OSPowerLockUnwrap();
+ }
+
+ /* PRQA S 3415 3 */ /* side effects desired */
+ if ((eError == PVRSRV_OK) &&
+ !bSystemPowerEvent &&
+ !_IsSystemStatePowered(psSysData->eCurrentPowerState))
+ {
+ /* Reject device power state change due to system power state. */
+ PVRSRVPowerUnlock(ui32CallerID);
+ eError = PVRSRV_ERROR_RETRY;
+ }
+
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVPowerUnlock
+
+ @Description Release the mutex for power transitions
+
+ @Input ui32CallerID : KERNEL_ID or ISR_ID
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+IMG_VOID PVRSRVPowerUnlock(IMG_UINT32 ui32CallerID)
+{
+ OSUnlockResource(&gpsSysData->sPowerStateChangeResource, ui32CallerID);
+ OSPowerLockUnwrap();
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVDevicePrePowerStateKM_AnyVaCb
+
+ @Description
+
+ Perform device-specific processing required before a power transition
+
+ @Input psPowerDevice : the device
+ @Input va : variable argument list with:
+ bAllDevices : IMG_TRUE - All devices
+ IMG_FALSE - Use ui32DeviceIndex
+ ui32DeviceIndex : device index
+ eNewPowerState : New power state
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+static PVRSRV_ERROR PVRSRVDevicePrePowerStateKM_AnyVaCb(PVRSRV_POWER_DEV *psPowerDevice, va_list va)
+{
+ PVRSRV_DEV_POWER_STATE eNewDevicePowerState;
+ PVRSRV_ERROR eError;
+
+ /*Variable Argument variables*/
+ IMG_BOOL bAllDevices;
+ IMG_UINT32 ui32DeviceIndex;
+ PVRSRV_DEV_POWER_STATE eNewPowerState;
+
+ /* WARNING: if types were not aligned to 4 bytes, this could be dangerous. */
+ bAllDevices = va_arg(va, IMG_BOOL);
+ ui32DeviceIndex = va_arg(va, IMG_UINT32);
+ eNewPowerState = va_arg(va, PVRSRV_DEV_POWER_STATE);
+
+ if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex))
+ {
+ eNewDevicePowerState = (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) ?
+ psPowerDevice->eDefaultPowerState : eNewPowerState;
+
+ if (psPowerDevice->eCurrentPowerState != eNewDevicePowerState)
+ {
+ if (psPowerDevice->pfnPrePower != IMG_NULL)
+ {
+ /* Call the device's power callback. */
+ eError = psPowerDevice->pfnPrePower(psPowerDevice->hDevCookie,
+ eNewDevicePowerState,
+ psPowerDevice->eCurrentPowerState);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+
+ /* Do any required system-layer processing. */
+ eError = SysDevicePrePowerState(psPowerDevice->ui32DeviceIndex,
+ eNewDevicePowerState,
+ psPowerDevice->eCurrentPowerState);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+ }
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVDevicePrePowerStateKM
+
+ @Description
+
+ Perform device-specific processing required before a power transition
+
+ @Input bAllDevices : IMG_TRUE - All devices
+ IMG_FALSE - Use ui32DeviceIndex
+ @Input ui32DeviceIndex : device index
+ @Input eNewPowerState : New power state
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+static
+PVRSRV_ERROR PVRSRVDevicePrePowerStateKM(IMG_BOOL bAllDevices,
+ IMG_UINT32 ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE eNewPowerState)
+{
+ PVRSRV_ERROR eError;
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+
+ /* Loop through the power devices. */
+ eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psSysData->psPowerDeviceList,
+ &PVRSRVDevicePrePowerStateKM_AnyVaCb,
+ bAllDevices,
+ ui32DeviceIndex,
+ eNewPowerState);
+
+ return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVDevicePostPowerStateKM_AnyVaCb
+
+ @Description
+
+ Perform device-specific processing required after a power transition
+
+ @Input psPowerDevice : the device
+ @Input va : variable argument list with:
+ bAllDevices : IMG_TRUE - All devices
+ IMG_FALSE - Use ui32DeviceIndex
+ ui32DeviceIndex : device index
+ eNewPowerState : New power state
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+static PVRSRV_ERROR PVRSRVDevicePostPowerStateKM_AnyVaCb(PVRSRV_POWER_DEV *psPowerDevice, va_list va)
+{
+ PVRSRV_DEV_POWER_STATE eNewDevicePowerState;
+ PVRSRV_ERROR eError;
+
+ /*Variable Argument variables*/
+ IMG_BOOL bAllDevices;
+ IMG_UINT32 ui32DeviceIndex;
+ PVRSRV_DEV_POWER_STATE eNewPowerState;
+
+ /* WARNING: if types were not aligned to 4 bytes, this could be dangerous. */
+ bAllDevices = va_arg(va, IMG_BOOL);
+ ui32DeviceIndex = va_arg(va, IMG_UINT32);
+ eNewPowerState = va_arg(va, PVRSRV_DEV_POWER_STATE);
+
+ if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex))
+ {
+ eNewDevicePowerState = (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) ?
+ psPowerDevice->eDefaultPowerState : eNewPowerState;
+
+ if (psPowerDevice->eCurrentPowerState != eNewDevicePowerState)
+ {
+ /* Do any required system-layer processing. */
+ eError = SysDevicePostPowerState(psPowerDevice->ui32DeviceIndex,
+ eNewDevicePowerState,
+ psPowerDevice->eCurrentPowerState);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ if (psPowerDevice->pfnPostPower != IMG_NULL)
+ {
+ /* Call the device's power callback. */
+ eError = psPowerDevice->pfnPostPower(psPowerDevice->hDevCookie,
+ eNewDevicePowerState,
+ psPowerDevice->eCurrentPowerState);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+
+ psPowerDevice->eCurrentPowerState = eNewDevicePowerState;
+ }
+ }
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVDevicePostPowerStateKM
+
+ @Description
+
+ Perform device-specific processing required after a power transition
+
+ @Input bAllDevices : IMG_TRUE - All devices
+ IMG_FALSE - Use ui32DeviceIndex
+ @Input ui32DeviceIndex : device index
+ @Input eNewPowerState : New power state
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+static
+PVRSRV_ERROR PVRSRVDevicePostPowerStateKM(IMG_BOOL bAllDevices,
+ IMG_UINT32 ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE eNewPowerState)
+{
+ PVRSRV_ERROR eError;
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+
+ /* Loop through the power devices. */
+ eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psSysData->psPowerDeviceList,
+ &PVRSRVDevicePostPowerStateKM_AnyVaCb,
+ bAllDevices,
+ ui32DeviceIndex,
+ eNewPowerState);
+
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVSetDevicePowerStateKM
+
+ @Description Set the Device into a new state
+
+ @Input ui32DeviceIndex : device index
+ @Input eNewPowerState : New power state
+ @Input ui32CallerID : KERNEL_ID or ISR_ID
+ @Input bRetainMutex : If true, the power mutex is retained on exit
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32 ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE eNewPowerState)
+{
+ PVRSRV_ERROR eError;
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+
+ #if defined(PDUMP)
+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
+ {
+ /*
+ Pdump a power-up regardless of the default state.
+ Then disable pdump and transition to the default power state.
+ This ensures that a power-up is always present in the pdump when necessary.
+ */
+ eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON);
+ if(eError != PVRSRV_OK)
+ {
+ goto Exit;
+ }
+
+ eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON);
+
+ if (eError != PVRSRV_OK)
+ {
+ goto Exit;
+ }
+
+ PDUMPSUSPEND();
+ }
+ #endif /* PDUMP */
+
+ eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState);
+ if(eError != PVRSRV_OK)
+ {
+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
+ {
+ PDUMPRESUME();
+ }
+ goto Exit;
+ }
+
+ eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState);
+
+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
+ {
+ PDUMPRESUME();
+ }
+
+Exit:
+
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "PVRSRVSetDevicePowerStateKM : Transition to %d FAILED 0x%x", eNewPowerState, eError));
+ }
+
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVSystemPrePowerStateKM
+
+ @Description Perform processing required before a system power transition
+
+ @Input eNewSysPowerState :
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSystemPrePowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState)
+{
+ PVRSRV_ERROR eError;
+ SYS_DATA *psSysData;
+ PVRSRV_DEV_POWER_STATE eNewDevicePowerState;
+
+ SysAcquireData(&psSysData);
+
+ /* This mutex is unlocked in PVRSRVSystemPostPowerStateKM() */
+ eError = PVRSRVPowerLock(KERNEL_ID, IMG_TRUE);
+ if(eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ if (_IsSystemStatePowered(eNewSysPowerState) !=
+ _IsSystemStatePowered(psSysData->eCurrentPowerState))
+ {
+ if (_IsSystemStatePowered(eNewSysPowerState))
+ {
+ /* Return device back to its default state. */
+ eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_DEFAULT;
+ }
+ else
+ {
+ eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_OFF;
+ }
+
+ /* Perform device-specific transitions. */
+ eError = PVRSRVDevicePrePowerStateKM(IMG_TRUE, 0, eNewDevicePowerState);
+ if (eError != PVRSRV_OK)
+ {
+ goto ErrorExit;
+ }
+ }
+
+ if (eNewSysPowerState != psSysData->eCurrentPowerState)
+ {
+ /* Perform system-specific power transitions. */
+ eError = SysSystemPrePowerState(eNewSysPowerState);
+ 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, eNewSysPowerState, eError));
+
+ /* save the power state for the re-attempt */
+ psSysData->eFailedPowerState = eNewSysPowerState;
+
+ PVRSRVPowerUnlock(KERNEL_ID);
+
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVSystemPostPowerStateKM
+
+ @Description Perform processing required after a system power transition
+
+ @Input eNewSysPowerState :
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSystemPostPowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ SYS_DATA *psSysData;
+ PVRSRV_DEV_POWER_STATE eNewDevicePowerState;
+
+ SysAcquireData(&psSysData);
+
+ if (eNewSysPowerState != psSysData->eCurrentPowerState)
+ {
+ /* Perform system-specific power transitions. */
+ eError = SysSystemPostPowerState(eNewSysPowerState);
+ if (eError != PVRSRV_OK)
+ {
+ goto Exit;
+ }
+ }
+
+ if (_IsSystemStatePowered(eNewSysPowerState) !=
+ _IsSystemStatePowered(psSysData->eCurrentPowerState))
+ {
+ if (_IsSystemStatePowered(eNewSysPowerState))
+ {
+ /* Return device back to its default state. */
+ eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_DEFAULT;
+ }
+ else
+ {
+ eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_OFF;
+ }
+
+ /* Perform device-specific power transitions. */
+ eError = PVRSRVDevicePostPowerStateKM(IMG_TRUE, 0, eNewDevicePowerState);
+ if (eError != PVRSRV_OK)
+ {
+ goto Exit;
+ }
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "PVRSRVSystemPostPowerStateKM: System Power Transition from %d to %d OK",
+ psSysData->eCurrentPowerState, eNewSysPowerState));
+
+ psSysData->eCurrentPowerState = eNewSysPowerState;
+
+Exit:
+
+ PVRSRVPowerUnlock(KERNEL_ID);
+
+ /* PRQA S 3415 2 */ /* side effects desired */
+ if (_IsSystemStatePowered(eNewSysPowerState) &&
+ PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL))
+ {
+ /*
+ Reprocess the devices' queues in case commands were blocked during
+ the power transition.
+ */
+ PVRSRVScheduleDeviceCallbacks();
+ }
+
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVSetPowerStateKM
+
+ @Description Set the system into a new state
+
+ @Input eNewPowerState :
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState)
+{
+ PVRSRV_ERROR eError;
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+
+ eError = PVRSRVSystemPrePowerStateKM(eNewSysPowerState);
+ if(eError != PVRSRV_OK)
+ {
+ goto ErrorExit;
+ }
+
+ eError = PVRSRVSystemPostPowerStateKM(eNewSysPowerState);
+ if(eError != PVRSRV_OK)
+ {
+ goto ErrorExit;
+ }
+
+ /* save new power state */
+ psSysData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified;
+
+ return PVRSRV_OK;
+
+ErrorExit:
+
+ PVR_DPF((PVR_DBG_ERROR,
+ "PVRSRVSetPowerStateKM: Transition from %d to %d FAILED 0x%x",
+ psSysData->eCurrentPowerState, eNewSysPowerState, eError));
+
+ /* save the power state for the re-attempt */
+ psSysData->eFailedPowerState = eNewSysPowerState;
+
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVRegisterPowerDevice
+
+ @Description
+
+ Registers a device with the power manager. Passes Pre/Post Power handlers
+ and private device handle to be passed to power handlers
+
+ @Input ui32DeviceIndex : device index
+ @Input pfnPrePower : Pre power transition handler
+ @Input pfnPostPower : Post power transition handler
+ @Input pfnPreClockSpeedChange : Pre clock speed transition handler (if required)
+ @Input pfnPostClockSpeedChange : Post clock speed transition handler (if required)
+ @Input hDevCookie : Dev cookie for dev power handlers
+ @Input eCurrentPowerState : Current power state of the device
+ @Input eDefaultPowerState : Default power state of the device
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+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,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState,
+ PVRSRV_DEV_POWER_STATE eDefaultPowerState)
+{
+ PVRSRV_ERROR eError;
+ SYS_DATA *psSysData;
+ PVRSRV_POWER_DEV *psPowerDevice;
+
+ if (pfnPrePower == IMG_NULL &&
+ pfnPostPower == IMG_NULL)
+ {
+ return PVRSRVRemovePowerDevice(ui32DeviceIndex);
+ }
+
+ SysAcquireData(&psSysData);
+
+ eError = OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_POWER_DEV),
+ (IMG_VOID **)&psPowerDevice, IMG_NULL,
+ "Power Device");
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterPowerDevice: Failed to alloc PVRSRV_POWER_DEV"));
+ return eError;
+ }
+
+ /* setup device for power manager */
+ psPowerDevice->pfnPrePower = pfnPrePower;
+ psPowerDevice->pfnPostPower = pfnPostPower;
+ psPowerDevice->pfnPreClockSpeedChange = pfnPreClockSpeedChange;
+ psPowerDevice->pfnPostClockSpeedChange = pfnPostClockSpeedChange;
+ psPowerDevice->hDevCookie = hDevCookie;
+ psPowerDevice->ui32DeviceIndex = ui32DeviceIndex;
+ psPowerDevice->eCurrentPowerState = eCurrentPowerState;
+ psPowerDevice->eDefaultPowerState = eDefaultPowerState;
+
+ /* insert into power device list */
+ List_PVRSRV_POWER_DEV_Insert(&(psSysData->psPowerDeviceList), psPowerDevice);
+
+ return (PVRSRV_OK);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVRemovePowerDevice
+
+ @Description
+
+ Removes device from power management register. Device is located by Device Index
+
+ @Input ui32DeviceIndex : device index
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVRemovePowerDevice (IMG_UINT32 ui32DeviceIndex)
+{
+ SYS_DATA *psSysData;
+ PVRSRV_POWER_DEV *psPowerDev;
+
+ SysAcquireData(&psSysData);
+
+ /* find device in list and remove it */
+ psPowerDev = (PVRSRV_POWER_DEV*)
+ List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
+ &MatchPowerDeviceIndex_AnyVaCb,
+ ui32DeviceIndex);
+
+ if (psPowerDev)
+ {
+ List_PVRSRV_POWER_DEV_Remove(psPowerDev);
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_POWER_DEV), psPowerDev, IMG_NULL);
+ /*not nulling pointer, copy on stack*/
+ }
+
+ return (PVRSRV_OK);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVIsDevicePowered
+
+ @Description
+
+ Whether the device is powered, for the purposes of lockup detection.
+
+ @Input ui32DeviceIndex : device index
+
+ @Return IMG_BOOL
+
+******************************************************************************/
+IMG_EXPORT
+IMG_BOOL PVRSRVIsDevicePowered(IMG_UINT32 ui32DeviceIndex)
+{
+ SYS_DATA *psSysData;
+ PVRSRV_POWER_DEV *psPowerDevice;
+
+ SysAcquireData(&psSysData);
+
+ /* PRQA S 3415 2 */ /* order not important */
+ if (OSIsResourceLocked(&psSysData->sPowerStateChangeResource, KERNEL_ID) ||
+ OSIsResourceLocked(&psSysData->sPowerStateChangeResource, ISR_ID))
+ {
+ return IMG_FALSE;
+ }
+
+ psPowerDevice = (PVRSRV_POWER_DEV*)
+ List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
+ &MatchPowerDeviceIndex_AnyVaCb,
+ ui32DeviceIndex);
+ return (psPowerDevice && (psPowerDevice->eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON))
+ ? IMG_TRUE : IMG_FALSE;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVDevicePreClockSpeedChange
+
+ @Description
+
+ Notification from system layer that a device clock speed change is about to happen.
+
+ @Input ui32DeviceIndex : device index
+ @Input bIdleDevice : whether the device should be idled
+ @Input pvInfo
+
+ @Return IMG_VOID
+
+******************************************************************************/
+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);
+
+ SysAcquireData(&psSysData);
+
+ if (bIdleDevice)
+ {
+ /* This mutex is released in PVRSRVDevicePostClockSpeedChange. */
+ eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVDevicePreClockSpeedChange : failed to acquire lock, error:0x%x", eError));
+ return eError;
+ }
+ }
+
+ /*search the device and then do the pre clock speed change*/
+ psPowerDevice = (PVRSRV_POWER_DEV*)
+ List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
+ &MatchPowerDeviceIndex_AnyVaCb,
+ ui32DeviceIndex);
+
+ if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange)
+ {
+ eError = psPowerDevice->pfnPreClockSpeedChange(psPowerDevice->hDevCookie,
+ bIdleDevice,
+ psPowerDevice->eCurrentPowerState);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "PVRSRVDevicePreClockSpeedChange : Device %u failed, error:0x%x",
+ ui32DeviceIndex, eError));
+ }
+ }
+
+ if (bIdleDevice && eError != PVRSRV_OK)
+ {
+ PVRSRVPowerUnlock(KERNEL_ID);
+ }
+
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVDevicePostClockSpeedChange
+
+ @Description
+
+ Notification from system layer that a device clock speed change has just happened.
+
+ @Input ui32DeviceIndex : device index
+ @Input bIdleDevice : whether the device had been idled
+ @Input pvInfo
+
+ @Return IMG_VOID
+
+******************************************************************************/
+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);
+
+ SysAcquireData(&psSysData);
+
+ /*search the device and then do the post clock speed change*/
+ psPowerDevice = (PVRSRV_POWER_DEV*)
+ List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList,
+ &MatchPowerDeviceIndex_AnyVaCb,
+ ui32DeviceIndex);
+
+ if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange)
+ {
+ eError = psPowerDevice->pfnPostClockSpeedChange(psPowerDevice->hDevCookie,
+ bIdleDevice,
+ psPowerDevice->eCurrentPowerState);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "PVRSRVDevicePostClockSpeedChange : Device %u failed, error:0x%x",
+ ui32DeviceIndex, eError));
+ }
+ }
+
+
+ if (bIdleDevice)
+ {
+ /* This mutex was acquired in PVRSRVDevicePreClockSpeedChange. */
+ PVRSRVPowerUnlock(KERNEL_ID);
+ }
+}
+
+/******************************************************************************
+ End of file (power.c)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/common/pvrsrv.c b/pvr-source/services4/srvkm/common/pvrsrv.c
new file mode 100644
index 0000000..1b5312c
--- /dev/null
+++ b/pvr-source/services4/srvkm/common/pvrsrv.c
@@ -0,0 +1,1846 @@
+/*************************************************************************/ /*!
+@Title core services functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Main APIs for core services functions
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "services_headers.h"
+#include "buffer_manager.h"
+#include "pvr_bridge_km.h"
+#include "handle.h"
+#include "perproc.h"
+#include "pdump_km.h"
+#include "deviceid.h"
+#include "ra.h"
+#if defined(__linux__)
+#include "sysfs.h"
+#endif
+#if defined(TTRACE)
+#include "ttrace.h"
+#endif
+#include "perfkm.h"
+
+#include "pvrversion.h"
+
+#include "lists.h"
+
+IMG_UINT32 g_ui32InitFlags;
+extern int powering_down;
+
+/* mark which parts of Services were initialised */
+#define INIT_DATA_ENABLE_PDUMPINIT 0x1U
+#define INIT_DATA_ENABLE_TTARCE 0x2U
+
+/*!
+******************************************************************************
+
+ @Function AllocateDeviceID
+
+ @Description
+
+ allocates a device id from the pool of valid ids
+
+ @input psSysData : system data
+
+ @input pui32DevID : device id to return
+
+ @Return device id
+
+******************************************************************************/
+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;
+
+ /* find a free ID */
+ 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!"));
+
+ /* Should never get here: sDeviceID[] may have been setup too small */
+ PVR_ASSERT(psDeviceWalker < psDeviceEnd);
+
+ return PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function FreeDeviceID
+
+ @Description
+
+ frees a device id from the pool of valid ids
+
+ @input psSysData : system data
+
+ @input ui32DevID : device id to free
+
+ @Return device id
+
+******************************************************************************/
+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;
+
+ /* find the ID to free */
+ while (psDeviceWalker < psDeviceEnd)
+ {
+ /* if matching id and in use, free */
+ 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!"));
+
+ /* should never get here */
+ PVR_ASSERT(psDeviceWalker < psDeviceEnd);
+
+ return PVRSRV_ERROR_INVALID_DEVICEID;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function ReadHWReg
+
+ @Description
+
+ register access function
+
+ @input pvLinRegBaseAddr : lin addr of register block base
+
+ @input ui32Offset : byte offset from register base
+
+ @Return register value
+
+******************************************************************************/
+#ifndef ReadHWReg
+IMG_EXPORT
+IMG_UINT32 ReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
+{
+ return *(volatile IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset);
+}
+#endif
+
+
+/*!
+******************************************************************************
+
+ @Function WriteHWReg
+
+ @Description
+
+ register access function
+
+ @input pvLinRegBaseAddr : lin addr of register block base
+
+ @input ui32Offset : byte offset from register base
+
+ @input ui32Value : value to write to register
+
+ @Return register value : original reg. value
+
+******************************************************************************/
+#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",
+ (IMG_UINTPTR_T)pvLinRegBaseAddr,ui32Offset,ui32Value));
+
+ *(IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset) = ui32Value;
+}
+#endif
+
+
+/*!
+******************************************************************************
+
+ @Function WriteHWRegs
+
+ @Description
+
+ register access function
+
+ @input pvLinRegBaseAddr : lin addr of register block base
+
+ @input ui32Count : register count
+
+ @input psHWRegs : address/value register list
+
+ @Return none
+
+******************************************************************************/
+#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
+
+/*!
+******************************************************************************
+ @Function PVRSRVEnumerateDCKM_ForEachVaCb
+
+ @Description
+
+ Enumerates the device node (if is of the same class as given).
+
+ @Input psDeviceNode - The device node to be enumerated
+ va - variable arguments list, with:
+ pui32DevCount - The device count pointer (to be increased)
+ ppui32DevID - The pointer to the device IDs pointer (to be updated and increased)
+******************************************************************************/
+static IMG_VOID PVRSRVEnumerateDevicesKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+ IMG_UINT *pui32DevCount;
+ PVRSRV_DEVICE_IDENTIFIER **ppsDevIdList;
+
+ pui32DevCount = va_arg(va, IMG_UINT*);
+ ppsDevIdList = va_arg(va, PVRSRV_DEVICE_IDENTIFIER**);
+
+ if (psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_EXT)
+ {
+ *(*ppsDevIdList) = psDeviceNode->sDevId;
+ (*ppsDevIdList)++;
+ (*pui32DevCount)++;
+ }
+}
+
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVEnumerateDevicesKM
+
+ @Description
+ This function will enumerate all the devices supported by the
+ PowerVR services within the target system.
+ The function returns a list of the device ID strcutres stored either in
+ the services or constructed in the user mode glue component in certain
+ environments. The number of devices in the list is also returned.
+
+ In a binary layered component which does not support dynamic runtime selection,
+ the glue code should compile to return the supported devices statically,
+ e.g. multiple instances of the same device if multiple devices are supported,
+ or the target combination of MBX and display device.
+
+ In the case of an environment (for instance) where one MBX1 may connect to two
+ display devices this code would enumerate all three devices and even
+ non-dynamic MBX1 selection code should retain the facility to parse the list
+ to find the index of the MBX device
+
+ @output pui32NumDevices : On success, contains the number of devices present
+ in the system
+
+ @output psDevIdList : Pointer to called supplied buffer to receive the
+ list of PVRSRV_DEVICE_IDENTIFIER
+
+ @return PVRSRV_ERROR : PVRSRV_NO_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices,
+ PVRSRV_DEVICE_IDENTIFIER *psDevIdList)
+{
+ 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;
+ }
+
+ SysAcquireData(&psSysData);
+
+ /*
+ setup input buffer to be `empty'
+ */
+ for (i=0; i<PVRSRV_MAX_DEVICES; i++)
+ {
+ psDevIdList[i].eDeviceType = PVRSRV_DEVICE_TYPE_UNKNOWN;
+ }
+
+ /* and zero device count */
+ *pui32NumDevices = 0;
+
+ /*
+ Search through the device list for services managed devices
+ return id info for each device and the number of devices
+ available
+ */
+ List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
+ &PVRSRVEnumerateDevicesKM_ForEachVaCb,
+ pui32NumDevices,
+ &psDevIdList);
+
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVInit
+
+ @Description Initialise services
+
+ @Input psSysData : sysdata structure
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(PSYS_DATA psSysData)
+{
+ PVRSRV_ERROR eError;
+
+#if defined(__linux__)
+ eError = PVRSRVCreateSysfsEntry();
+ if (eError != PVRSRV_OK)
+ {
+ goto Error;
+ }
+#endif
+
+ /* Initialise Resource Manager */
+ eError = ResManInit();
+ if (eError != PVRSRV_OK)
+ {
+ goto Error;
+ }
+
+ eError = PVRSRVPerProcessDataInit();
+ if(eError != PVRSRV_OK)
+ {
+ goto Error;
+ }
+
+ /* Initialise handles */
+ eError = PVRSRVHandleInit();
+ if(eError != PVRSRV_OK)
+ {
+ goto Error;
+ }
+
+ /* Initialise Power Manager Lock */
+ eError = OSCreateResource(&psSysData->sPowerStateChangeResource);
+ if (eError != PVRSRV_OK)
+ {
+ goto Error;
+ }
+
+ /* Initialise system power state */
+ psSysData->eCurrentPowerState = PVRSRV_SYS_POWER_STATE_D0;
+ psSysData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified;
+
+ /* Create an event object */
+ if(OSAllocMem( PVRSRV_PAGEABLE_SELECT,
+ sizeof(PVRSRV_EVENTOBJECT) ,
+ (IMG_VOID **)&psSysData->psGlobalEventObject, 0,
+ "Event Object") != PVRSRV_OK)
+ {
+
+ goto Error;
+ }
+
+ if(OSEventObjectCreateKM("PVRSRV_GLOBAL_EVENTOBJECT", psSysData->psGlobalEventObject) != PVRSRV_OK)
+ {
+ goto Error;
+ }
+
+ /* Store OS high res timer fallbacks, the system is free to overide these */
+ psSysData->pfnHighResTimerCreate = OSFuncHighResTimerCreate;
+ psSysData->pfnHighResTimerGetus = OSFuncHighResTimerGetus;
+ psSysData->pfnHighResTimerDestroy = OSFuncHighResTimerDestroy;
+
+#if defined(TTRACE)
+ eError = PVRSRVTimeTraceInit();
+ if (eError != PVRSRV_OK)
+ goto Error;
+ g_ui32InitFlags |= INIT_DATA_ENABLE_TTARCE;
+#endif
+
+ /* Initialise pdump */
+ PDUMPINIT();
+ g_ui32InitFlags |= INIT_DATA_ENABLE_PDUMPINIT;
+
+ PERFINIT();
+ return eError;
+
+Error:
+ PVRSRVDeInit(psSysData);
+ return eError;
+}
+
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVDeInit
+
+ @Description De-Initialise services
+
+ @Input psSysData : sysdata structure
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+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;
+ }
+
+ PERFDEINIT();
+
+#if defined(TTRACE)
+ /* deinitialise ttrace */
+ if ((g_ui32InitFlags & INIT_DATA_ENABLE_TTARCE) > 0)
+ {
+ PVRSRVTimeTraceDeinit();
+ }
+#endif
+ /* deinitialise pdump */
+ if( (g_ui32InitFlags & INIT_DATA_ENABLE_PDUMPINIT) > 0)
+ {
+ PDUMPDEINIT();
+ }
+
+ /* destroy event object */
+ if(psSysData->psGlobalEventObject)
+ {
+ OSEventObjectDestroyKM(psSysData->psGlobalEventObject);
+ OSFreeMem( PVRSRV_PAGEABLE_SELECT,
+ sizeof(PVRSRV_EVENTOBJECT),
+ psSysData->psGlobalEventObject,
+ 0);
+ psSysData->psGlobalEventObject = IMG_NULL;
+ }
+
+ 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();
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVRegisterDevice
+
+ @Description
+
+ registers a device with the system
+
+ @Input psSysData : sysdata structure
+
+ @Input pfnRegisterDevice : device registration function
+
+ @Input ui32SOCInterruptBit : SoC interrupt bit for this device
+
+ @Output pui32DeviceIndex : unique device key (for case of multiple identical devices)
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+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;
+
+ /* Allocate device node */
+ if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_DEVICE_NODE),
+ (IMG_VOID **)&psDeviceNode, IMG_NULL,
+ "Device Node") != 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);
+ /*not nulling pointer, out of scope*/
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to register device"));
+ return (PVRSRV_ERROR_DEVICE_REGISTER_FAILED);
+ }
+
+ /*
+ make the refcount 1 and test on this to initialise device
+ at acquiredevinfo. On release if refcount is 1, deinitialise
+ and when refcount is 0 (sysdata de-alloc) deallocate the device
+ structures
+ */
+ psDeviceNode->ui32RefCount = 1;
+ psDeviceNode->psSysData = psSysData;
+ psDeviceNode->ui32SOCInterruptBit = ui32SOCInterruptBit;
+
+ /* all devices need a unique identifier */
+ AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex);
+
+ /* and finally insert the device into the dev-list */
+ List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode);
+
+ /* and copy back index */
+ *pui32DeviceIndex = psDeviceNode->sDevId.ui32DeviceIndex;
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVInitialiseDevice
+
+ @Description
+
+ initialises device by index
+
+ @Input ui32DevIndex : Index to the required device
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice (IMG_UINT32 ui32DevIndex)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ SYS_DATA *psSysData;
+ PVRSRV_ERROR eError;
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInitialiseDevice"));
+
+ SysAcquireData(&psSysData);
+
+ /* Find device in the list */
+ psDeviceNode = (PVRSRV_DEVICE_NODE*)
+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+ &MatchDeviceKM_AnyVaCb,
+ ui32DevIndex,
+ IMG_TRUE);
+ if(!psDeviceNode)
+ {
+ /* Devinfo not in the list */
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: requested device is not present"));
+ return PVRSRV_ERROR_INIT_FAILURE;
+ }
+/*
+FoundDevice:
+*/
+
+ PVR_ASSERT (psDeviceNode->ui32RefCount > 0);
+
+ /*
+ Create the device's resource manager context.
+ */
+ eError = PVRSRVResManConnect(IMG_NULL, &psDeviceNode->hResManContext);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed PVRSRVResManConnect call"));
+ return eError;
+ }
+
+ /* Initialise the device */
+ 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;
+}
+
+
+static PVRSRV_ERROR PVRSRVFinaliseSystem_SetPowerState_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVRSRV_ERROR eError;
+
+ eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVPowerLock call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
+ return eError;
+ }
+
+ eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE_DEFAULT);
+ PVRSRVPowerUnlock(KERNEL_ID);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVSetDevicePowerStateKM call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
+ }
+ return eError;
+}
+
+/*wraps the PVRSRVDevInitCompatCheck call and prints a debugging message if failed*/
+static PVRSRV_ERROR PVRSRVFinaliseSystem_CompatCheck_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVRSRV_ERROR eError;
+ eError = PVRSRVDevInitCompatCheck(psDeviceNode);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVDevInitCompatCheck call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex));
+ }
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVFinaliseSystem
+
+ @Description
+
+ Final part of system initialisation.
+
+ @Input ui32DevIndex : Index to the required device
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccessful)
+{
+/* PVRSRV_DEVICE_NODE *psDeviceNode;*/
+ SYS_DATA *psSysData;
+ PVRSRV_ERROR eError;
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVFinaliseSystem"));
+
+ SysAcquireData(&psSysData);
+
+ if (bInitSuccessful)
+ {
+ eError = SysFinalise();
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: SysFinalise failed (%d)", eError));
+ return eError;
+ }
+
+ /* Place all devices into their default power state. */
+ eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList,
+ &PVRSRVFinaliseSystem_SetPowerState_AnyCb);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ /* Verify microkernel compatibility for devices */
+ eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList,
+ &PVRSRVFinaliseSystem_CompatCheck_AnyCb);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+
+ /* Some platforms call this too early in the boot phase. */
+ PDUMPENDINITPHASE();
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ /* Only check devices which specify a compatibility check callback */
+ if (psDeviceNode->pfnInitDeviceCompatCheck)
+ return psDeviceNode->pfnInitDeviceCompatCheck(psDeviceNode);
+ else
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVAcquireDeviceDataKM
+
+ @Description
+
+ Matchs a device given a device type and a device index.
+
+ @input psDeviceNode :The device node to be matched.
+
+ @Input va : Variable argument list with:
+ eDeviceType : Required device type. If type is unknown use ui32DevIndex
+ to locate device data
+
+ ui32DevIndex : Index to the required device obtained from the
+ PVRSRVEnumerateDevice function
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+static IMG_VOID * PVRSRVAcquireDeviceDataKM_Match_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+ PVRSRV_DEVICE_TYPE eDeviceType;
+ IMG_UINT32 ui32DevIndex;
+
+ eDeviceType = va_arg(va, PVRSRV_DEVICE_TYPE);
+ ui32DevIndex = va_arg(va, IMG_UINT32);
+
+ if ((eDeviceType != PVRSRV_DEVICE_TYPE_UNKNOWN &&
+ psDeviceNode->sDevId.eDeviceType == eDeviceType) ||
+ (eDeviceType == PVRSRV_DEVICE_TYPE_UNKNOWN &&
+ psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex))
+ {
+ return psDeviceNode;
+ }
+ else
+ {
+ return IMG_NULL;
+ }
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVAcquireDeviceDataKM
+
+ @Description
+
+ Returns device information
+
+ @Input ui32DevIndex : Index to the required device obtained from the
+ PVRSRVEnumerateDevice function
+
+ @Input eDeviceType : Required device type. If type is unknown use ui32DevIndex
+ to locate device data
+
+ @Output *phDevCookie : Dev Cookie
+
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM (IMG_UINT32 ui32DevIndex,
+ PVRSRV_DEVICE_TYPE eDeviceType,
+ IMG_HANDLE *phDevCookie)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ SYS_DATA *psSysData;
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVAcquireDeviceDataKM"));
+
+ SysAcquireData(&psSysData);
+
+ /* Find device in the list */
+ psDeviceNode = List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+ &PVRSRVAcquireDeviceDataKM_Match_AnyVaCb,
+ eDeviceType,
+ ui32DevIndex);
+
+
+ if (!psDeviceNode)
+ {
+ /* device can't be found in the list so it isn't in the system */
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquireDeviceDataKM: requested device is not present"));
+ return PVRSRV_ERROR_INIT_FAILURE;
+ }
+
+/*FoundDevice:*/
+
+ PVR_ASSERT (psDeviceNode->ui32RefCount > 0);
+
+ /* return the dev cookie? */
+ if (phDevCookie)
+ {
+ *phDevCookie = (IMG_HANDLE)psDeviceNode;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVDeinitialiseDevice
+
+ @Description
+
+ This De-inits device
+
+ @Input ui32DevIndex : Index to the required device
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ SYS_DATA *psSysData;
+ PVRSRV_ERROR eError;
+
+ SysAcquireData(&psSysData);
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE*)
+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+ &MatchDeviceKM_AnyVaCb,
+ ui32DevIndex,
+ IMG_TRUE);
+
+ if (!psDeviceNode)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: requested device %d is not present", ui32DevIndex));
+ return PVRSRV_ERROR_DEVICEID_NOT_FOUND;
+ }
+
+ eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVPowerLock call"));
+ return eError;
+ }
+
+ /*
+ Power down the device if necessary.
+ */
+ eError = PVRSRVSetDevicePowerStateKM(ui32DevIndex,
+ PVRSRV_DEV_POWER_STATE_OFF);
+ PVRSRVPowerUnlock(KERNEL_ID);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVSetDevicePowerStateKM call"));
+ return eError;
+ }
+
+ /*
+ Free the dissociated device memory.
+ */
+ 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;
+ }
+
+ /*
+ De-init the device.
+ */
+ if(psDeviceNode->pfnDeInitDevice != IMG_NULL)
+ {
+ eError = psDeviceNode->pfnDeInitDevice(psDeviceNode);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed DeInitDevice call"));
+ return eError;
+ }
+ }
+
+ /*
+ Close the device's resource manager context.
+ */
+ PVRSRVResManDisconnect(psDeviceNode->hResManContext, IMG_TRUE);
+ psDeviceNode->hResManContext = IMG_NULL;
+
+ /* remove node from list */
+ List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode);
+
+ /* deallocate id and memory */
+ (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex);
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL);
+ /*not nulling pointer, out of scope*/
+
+ return (PVRSRV_OK);
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PollForValueKM (volatile IMG_UINT32* pui32LinMemAddr,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ IMG_UINT32 ui32Timeoutus,
+ IMG_UINT32 ui32PollPeriodus,
+ IMG_BOOL bAllowPreemption)
+{
+#if defined (EMULATOR)
+ {
+ PVR_UNREFERENCED_PARAMETER(bAllowPreemption);
+ #if !defined(__linux__)
+ PVR_UNREFERENCED_PARAMETER(ui32PollPeriodus);
+ #endif
+
+ /* For the Emulator we want the system to stop when a lock-up is detected so the state can be analysed.
+ * Also the Emulator is much slower than real silicon so timeouts are not valid.
+ */
+ do
+ {
+ if((*pui32LinMemAddr & ui32Mask) == ui32Value)
+ {
+ return PVRSRV_OK;
+ }
+
+ #if defined(__linux__)
+ OSWaitus(ui32PollPeriodus);
+ #else
+ OSReleaseThreadQuanta();
+ #endif
+
+ } while (ui32Timeoutus); /* Endless loop only for the Emulator */
+ }
+#else
+ {
+ IMG_UINT32 ui32ActualValue = 0xFFFFFFFFU; /* Initialiser only required to prevent incorrect warning */
+
+ if (bAllowPreemption)
+ {
+ PVR_ASSERT(ui32PollPeriodus >= 1000);
+ }
+
+ /* PRQA S 3415,4109 1 */ /* macro format critical - leave alone */
+ LOOP_UNTIL_TIMEOUT(ui32Timeoutus)
+ {
+ ui32ActualValue = (*pui32LinMemAddr & ui32Mask);
+ if(ui32ActualValue == ui32Value)
+ {
+ return PVRSRV_OK;
+ }
+
+ if (bAllowPreemption)
+ {
+ OSSleepms(ui32PollPeriodus / 1000);
+ }
+ else
+ {
+ OSWaitus(ui32PollPeriodus);
+ }
+ } END_LOOP_UNTIL_TIMEOUT();
+
+ PVR_DPF((PVR_DBG_ERROR,"PollForValueKM: Timeout. Expected 0x%x but found 0x%x (mask 0x%x).",
+ ui32Value, ui32ActualValue, ui32Mask));
+ }
+#endif /* #if defined (EMULATOR) */
+
+ return PVRSRV_ERROR_TIMEOUT;
+}
+
+
+/*Level 3 of the loop nesting*/
+static IMG_VOID PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb(BM_HEAP *psBMHeap, va_list va)
+{
+ IMG_CHAR **ppszStr;
+ IMG_UINT32 *pui32StrLen;
+ IMG_UINT32 ui32Mode;
+ PVRSRV_ERROR (*pfnGetStats)(RA_ARENA *, IMG_CHAR **, IMG_UINT32 *);
+
+ ppszStr = va_arg(va, IMG_CHAR**);
+ pui32StrLen = va_arg(va, IMG_UINT32*);
+ ui32Mode = va_arg(va, IMG_UINT32);
+
+ /* Would be better to pass fn pointer in the variable args list
+ * but MS C compiler complains with error C2066: In ANSI C,
+ * it is not legal to cast between a function pointer and a data pointer.
+ */
+ switch(ui32Mode)
+ {
+ case PVRSRV_MISC_INFO_MEMSTATS_PRESENT:
+ pfnGetStats = &RA_GetStats;
+ break;
+ case PVRSRV_MISC_INFO_FREEMEM_PRESENT:
+ pfnGetStats = &RA_GetStatsFreeMem;
+ break;
+ default:
+ return;
+ }
+
+ if(psBMHeap->pImportArena)
+ {
+ pfnGetStats(psBMHeap->pImportArena,
+ ppszStr,
+ pui32StrLen);
+ }
+
+ if(psBMHeap->pVMArena)
+ {
+ pfnGetStats(psBMHeap->pVMArena,
+ ppszStr,
+ pui32StrLen);
+ }
+}
+
+/*Level 2 of the loop nesting*/
+static PVRSRV_ERROR PVRSRVGetMiscInfoKM_BMContext_AnyVaCb(BM_CONTEXT *psBMContext, va_list va)
+{
+
+ IMG_UINT32 *pui32StrLen;
+ IMG_INT32 *pi32Count;
+ IMG_CHAR **ppszStr;
+ IMG_UINT32 ui32Mode;
+
+ pui32StrLen = va_arg(va, IMG_UINT32*);
+ pi32Count = va_arg(va, IMG_INT32*);
+ ppszStr = va_arg(va, IMG_CHAR**);
+ ui32Mode = va_arg(va, IMG_UINT32);
+
+ CHECK_SPACE(*pui32StrLen);
+ *pi32Count = OSSNPrintf(*ppszStr, 100, "\nApplication Context (hDevMemContext) %p:\n",
+ (IMG_HANDLE)psBMContext);
+ UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
+
+ List_BM_HEAP_ForEach_va(psBMContext->psBMHeap,
+ &PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb,
+ ppszStr,
+ pui32StrLen,
+ ui32Mode);
+ return PVRSRV_OK;
+}
+
+
+/*level 1 of the loop nesting*/
+static PVRSRV_ERROR PVRSRVGetMiscInfoKM_Device_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+ IMG_UINT32 *pui32StrLen;
+ IMG_INT32 *pi32Count;
+ IMG_CHAR **ppszStr;
+ IMG_UINT32 ui32Mode;
+
+ pui32StrLen = va_arg(va, IMG_UINT32*);
+ pi32Count = va_arg(va, IMG_INT32*);
+ ppszStr = va_arg(va, IMG_CHAR**);
+ ui32Mode = va_arg(va, IMG_UINT32);
+
+ CHECK_SPACE(*pui32StrLen);
+ *pi32Count = OSSNPrintf(*ppszStr, 100, "\n\nDevice Type %d:\n", psDeviceNode->sDevId.eDeviceType);
+ UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
+
+ /* kernel context: */
+ if(psDeviceNode->sDevMemoryInfo.pBMKernelContext)
+ {
+ CHECK_SPACE(*pui32StrLen);
+ *pi32Count = OSSNPrintf(*ppszStr, 100, "\nKernel Context:\n");
+ UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen);
+
+ List_BM_HEAP_ForEach_va(psDeviceNode->sDevMemoryInfo.pBMKernelContext->psBMHeap,
+ &PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb,
+ ppszStr,
+ pui32StrLen,
+ ui32Mode);
+ }
+
+ /* double loop app contexts:heaps */
+ return List_BM_CONTEXT_PVRSRV_ERROR_Any_va(psDeviceNode->sDevMemoryInfo.pBMContext,
+ &PVRSRVGetMiscInfoKM_BMContext_AnyVaCb,
+ pui32StrLen,
+ pi32Count,
+ ppszStr,
+ ui32Mode);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVGetMiscInfoKM
+
+ @Description
+ Retrieves misc. info.
+
+ @Output PVRSRV_MISC_INFO
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+IMG_EXPORT
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO_KM *psMiscInfo)
+#else
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo)
+#endif
+{
+ SYS_DATA *psSysData;
+
+ if(!psMiscInfo)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid parameters"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psMiscInfo->ui32StatePresent = 0;
+
+ /* do a basic check for uninitialised request flag */
+ 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
+ |PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT
+ |PVRSRV_MISC_INFO_RESET_PRESENT
+ |PVRSRV_MISC_INFO_FREEMEM_PRESENT
+ |PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT
+ |PVRSRV_MISC_INFO_GET_PAGE_SIZE_PRESENT
+ |PVRSRV_MISC_INFO_FORCE_SWAP_TO_SYSTEM_PRESENT))
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid state request flags"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ SysAcquireData(&psSysData);
+
+ /* return SOC Timer registers */
+ 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;
+ }
+
+ /* return SOC Clock Gating registers */
+ 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;
+ }
+
+ /* memory stats */
+ 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;
+
+ /* Local backing stores */
+ 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);
+ /* advance through the array */
+ ppArena++;
+ }
+
+ /* per device */
+/* psDeviceNode = psSysData->psDeviceNodeList;*/
+
+ /*triple loop; devices:contexts:heaps*/
+ List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList,
+ &PVRSRVGetMiscInfoKM_Device_AnyVaCb,
+ &ui32StrLen,
+ &i32Count,
+ &pszStr,
+ PVRSRV_MISC_INFO_MEMSTATS_PRESENT);
+
+ /* attach a new line and string terminate */
+ i32Count = OSSNPrintf(pszStr, 100, "\n");
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+ }
+
+ /* Lean version of mem stats: only show free mem on each RA */
+ if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0)
+ && psMiscInfo->pszMemoryStr)
+ {
+ IMG_CHAR *pszStr;
+ IMG_UINT32 ui32StrLen;
+ IMG_INT32 i32Count;
+
+ pszStr = psMiscInfo->pszMemoryStr;
+ ui32StrLen = psMiscInfo->ui32MemoryStrLen;
+
+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_FREEMEM_PRESENT;
+
+ /* triple loop over devices:contexts:heaps */
+ List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList,
+ &PVRSRVGetMiscInfoKM_Device_AnyVaCb,
+ &ui32StrLen,
+ &i32Count,
+ &pszStr,
+ PVRSRV_MISC_INFO_FREEMEM_PRESENT);
+
+ i32Count = OSSNPrintf(pszStr, 100, "\n");
+ 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;
+ }
+
+ /* DDK version and memstats not supported in same call to GetMiscInfo */
+
+ 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; /* string length per UI32: 10 digits + '.' + '\0' = 12 bytes */
+ IMG_INT32 i32Count;
+ IMG_INT i;
+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_DDKVERSION_PRESENT;
+
+ /* construct DDK string */
+ psMiscInfo->aui32DDKVersion[0] = PVRVERSION_MAJ;
+ psMiscInfo->aui32DDKVersion[1] = PVRVERSION_MIN;
+ psMiscInfo->aui32DDKVersion[2] = PVRVERSION_BUILD_HI;
+ psMiscInfo->aui32DDKVersion[3] = PVRVERSION_BUILD_LO;
+
+ pszStr = psMiscInfo->pszMemoryStr;
+ ui32StrLen = psMiscInfo->ui32MemoryStrLen;
+
+ for (i=0; i<4; i++)
+ {
+ if (ui32StrLen < ui32LenStrPerNum)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ i32Count = OSSNPrintf(pszStr, ui32LenStrPerNum, "%u", psMiscInfo->aui32DDKVersion[i]);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+ if (i != 3)
+ {
+ i32Count = OSSNPrintf(pszStr, 2, ".");
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+ }
+ }
+ }
+
+ if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT) != 0UL)
+ {
+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT;
+
+ if(psMiscInfo->sCacheOpCtl.bDeferOp)
+ {
+ /* For now, assume deferred ops are "full" cache ops,
+ * and we don't need (or expect) a meminfo.
+ */
+ psSysData->ePendingCacheOpType = psMiscInfo->sCacheOpCtl.eCacheOpType;
+ }
+ else
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = psMiscInfo->sCacheOpCtl.psKernelMemInfo;
+
+ if(!psMiscInfo->sCacheOpCtl.psKernelMemInfo)
+#else
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+ PVRSRV_PER_PROCESS_DATA *psPerProc;
+
+ if(!psMiscInfo->sCacheOpCtl.u.psKernelMemInfo)
+#endif
+ {
+ PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: "
+ "Ignoring non-deferred cache op with no meminfo"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if(psSysData->ePendingCacheOpType != PVRSRV_MISC_INFO_CPUCACHEOP_NONE)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: "
+ "Deferred cache op is pending. It is unlikely you want "
+ "to combine deferred cache ops with immediate ones"));
+ }
+
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DBG_BREAK
+#else
+ psPerProc = PVRSRVFindPerProcessData();
+
+ if(PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_PVOID *)&psKernelMemInfo,
+ psMiscInfo->sCacheOpCtl.u.psKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: "
+ "Can't find kernel meminfo"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+#endif
+
+ if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH)
+ {
+ if(!OSFlushCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle,
+ 0,
+ psMiscInfo->sCacheOpCtl.pvBaseVAddr,
+ psMiscInfo->sCacheOpCtl.ui32Length))
+ {
+ return PVRSRV_ERROR_CACHEOP_FAILED;
+ }
+ }
+ else if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN)
+ {
+ if(!OSCleanCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle,
+ 0,
+ psMiscInfo->sCacheOpCtl.pvBaseVAddr,
+ psMiscInfo->sCacheOpCtl.ui32Length))
+ {
+ return PVRSRV_ERROR_CACHEOP_FAILED;
+ }
+ }
+ }
+ }
+
+ if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT) != 0UL)
+ {
+#if !defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+ PVRSRV_PER_PROCESS_DATA *psPerProc;
+#endif
+
+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DBG_BREAK
+#else
+ psPerProc = PVRSRVFindPerProcessData();
+
+ if(PVRSRVLookupHandle(psPerProc->psHandleBase,
+ (IMG_PVOID *)&psKernelMemInfo,
+ psMiscInfo->sGetRefCountCtl.u.psKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: "
+ "Can't find kernel meminfo"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ psMiscInfo->sGetRefCountCtl.ui32RefCount = psKernelMemInfo->ui32RefCount;
+#endif
+ }
+
+ if ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GET_PAGE_SIZE_PRESENT) != 0UL)
+ {
+ psMiscInfo->ui32PageSize = HOST_PAGESIZE();
+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GET_PAGE_SIZE_PRESENT;
+ }
+
+#if defined(PVRSRV_RESET_ON_HWTIMEOUT)
+ if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_RESET_PRESENT) != 0UL)
+ {
+ PVR_LOG(("User requested OS reset"));
+ OSPanic();
+ }
+#endif /* #if defined(PVRSRV_RESET_ON_HWTIMEOUT) */
+
+ if ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_FORCE_SWAP_TO_SYSTEM_PRESENT) != 0UL)
+ {
+ PVRSRVSetDCState(DC_STATE_FORCE_SWAP_TO_SYSTEM);
+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_FORCE_SWAP_TO_SYSTEM_PRESENT;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVDeviceLISR
+
+ @Description
+ OS-independent Device Low-level Interrupt Service Routine
+
+ @Input psDeviceNode
+
+ @Return IMG_BOOL : Whether any interrupts were serviced
+
+******************************************************************************/
+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;
+
+ /* query the SOC/system to see whether this device was the source of the interrupt */
+ ui32InterruptSource = SysGetInterruptSource(psSysData, psDeviceNode);
+ if(ui32InterruptSource & psDeviceNode->ui32SOCInterruptBit)
+ {
+ if(psDeviceNode->pfnDeviceISR != IMG_NULL)
+ {
+ bStatus = (*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData);
+ }
+ if(!powering_down) {
+ SysClearInterrupts(psSysData, psDeviceNode->ui32SOCInterruptBit);
+ }
+ }
+
+out:
+ return bStatus;
+}
+
+static IMG_VOID PVRSRVSystemLISR_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va)
+{
+
+ IMG_BOOL *pbStatus;
+ IMG_UINT32 *pui32InterruptSource;
+ IMG_UINT32 *pui32ClearInterrupts;
+
+ pbStatus = va_arg(va, IMG_BOOL*);
+ pui32InterruptSource = va_arg(va, IMG_UINT32*);
+ pui32ClearInterrupts = va_arg(va, IMG_UINT32*);
+
+
+ if(psDeviceNode->pfnDeviceISR != IMG_NULL)
+ {
+ if(*pui32InterruptSource & psDeviceNode->ui32SOCInterruptBit)
+ {
+ if((*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData))
+ {
+ /* Record if serviced any interrupts. */
+ *pbStatus = IMG_TRUE;
+ }
+ /* Combine the SOC clear bits. */
+ *pui32ClearInterrupts |= psDeviceNode->ui32SOCInterruptBit;
+ }
+ }
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVSystemLISR
+
+ @Description
+ OS-independent System Low-level Interrupt Service Routine
+
+ @Input pvSysData
+
+ @Return IMG_BOOL : Whether any interrupts were serviced
+
+******************************************************************************/
+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; */
+ }
+ else
+ {
+ /* query SOC for source of interrupts */
+ ui32InterruptSource = SysGetInterruptSource(psSysData, IMG_NULL);
+
+ /* only proceed if PVR interrupts */
+ if(ui32InterruptSource)
+ {
+ /* traverse the devices' ISR handlers */
+ List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList,
+ &PVRSRVSystemLISR_ForEachVaCb,
+ &bStatus,
+ &ui32InterruptSource,
+ &ui32ClearInterrupts);
+
+ SysClearInterrupts(psSysData, ui32ClearInterrupts);
+ }
+/*out:*/
+ }
+ return bStatus;
+}
+
+
+static IMG_VOID PVRSRVMISR_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ if(psDeviceNode->pfnDeviceMISR != IMG_NULL)
+ {
+ (*psDeviceNode->pfnDeviceMISR)(psDeviceNode->pvISRData);
+ }
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVMISR
+
+ @Input pvSysData
+
+ @Description
+ OS-independent Medium-level Interrupt Service Routine
+
+******************************************************************************/
+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;
+ }
+
+ /* Traverse the devices' MISR handlers. */
+ List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
+ &PVRSRVMISR_ForEachCb);
+
+ /* Process the queues. */
+ if (PVRSRVProcessQueues(IMG_FALSE) == PVRSRV_ERROR_PROCESSING_BLOCKED)
+ {
+ PVRSRVProcessQueues(IMG_FALSE);
+ }
+
+ /* signal global event object */
+ if (psSysData->psGlobalEventObject)
+ {
+ IMG_HANDLE hOSEventKM = psSysData->psGlobalEventObject->hOSEventKM;
+ if(hOSEventKM)
+ {
+ OSEventObjectSignalKM(hOSEventKM);
+ }
+ }
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVProcessConnect
+
+ @Description Inform services that a process has connected.
+
+ @Input ui32PID - process ID
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVProcessConnect(IMG_UINT32 ui32PID, IMG_UINT32 ui32Flags)
+{
+ return PVRSRVPerProcessDataConnect(ui32PID, ui32Flags);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVProcessDisconnect
+
+ @Description Inform services that a process has disconnected.
+
+ @Input ui32PID - process ID
+
+ @Return IMG_VOID
+
+******************************************************************************/
+IMG_EXPORT
+IMG_VOID IMG_CALLCONV PVRSRVProcessDisconnect(IMG_UINT32 ui32PID)
+{
+ PVRSRVPerProcessDataDisconnect(ui32PID);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVSaveRestoreLiveSegments
+
+ @Input pArena - the arena the segment was originally allocated from.
+ pbyBuffer - the system memory buffer set to null to get the size needed.
+ puiBufSize - size of system memory buffer.
+ bSave - IMG_TRUE if a save is required
+
+ @Description
+ Function to save or restore Resources Live segments
+
+******************************************************************************/
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer,
+ IMG_SIZE_T *puiBufSize, IMG_BOOL bSave)
+{
+ IMG_SIZE_T 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;
+
+ /* walk the arena segments and write live one to the buffer */
+ while (RA_GetNextLiveSegment(hArena, &sSegDetails))
+ {
+ if (pbyBuffer == IMG_NULL)
+ {
+ /* calc buffer required */
+ 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));
+
+ /* Map the device's local memory area onto the host. */
+ 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)
+ {
+ /* write segment size then segment data */
+ OSMemCopy(pbyBuffer, &sSegDetails.uiSize, sizeof(sSegDetails.uiSize));
+ pbyBuffer += sizeof(sSegDetails.uiSize);
+
+ OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr, sSegDetails.uiSize);
+ pbyBuffer += sSegDetails.uiSize;
+ }
+ else
+ {
+ IMG_UINT32 uiSize;
+ /* reag segment size and validate */
+ 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);
+}
+
+
+/*!
+ ******************************************************************************
+
+ @Function PVRSRVGetErrorStringKM
+
+ @Description Returns a text string relating to the PVRSRV_ERROR enum.
+
+ @Note case statement used rather than an indexed arrary to ensure text is
+ synchronised with the correct enum
+
+ @Input eError : PVRSRV_ERROR enum
+
+ @Return const IMG_CHAR * : Text string
+
+ @Note Must be kept in sync with servicesext.h
+
+******************************************************************************/
+
+IMG_EXPORT
+const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError)
+{
+/* PRQA S 5087 1 */ /* include file required here */
+#include "pvrsrv_errors.h"
+}
+
+static IMG_VOID PVRSRVCommandCompleteCallbacks_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ if(psDeviceNode->pfnDeviceCommandComplete != IMG_NULL)
+ {
+ /* Call the device's callback function. */
+ (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode);
+ }
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVScheduleDeviceCallbacks
+
+ @Description Schedule all device callbacks
+
+ @Return IMG_VOID
+
+******************************************************************************/
+IMG_VOID PVRSRVScheduleDeviceCallbacks(IMG_VOID)
+{
+ SYS_DATA *psSysData;
+/* PVRSRV_DEVICE_NODE *psDeviceNode;*/
+
+ SysAcquireData(&psSysData);
+
+ /*for all the device, invoke the callback function*/
+ List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
+ &PVRSRVCommandCompleteCallbacks_ForEachCb);
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVScheduleDevices
+
+ @Description Schedules all Services-Managed Devices to check their pending
+ command queues. The intention is that ScheduleDevices be called by the
+ 3rd party BC driver after it has finished writing new data to its output
+ texture.
+
+ @Return IMG_VOID
+
+******************************************************************************/
+IMG_EXPORT
+IMG_VOID PVRSRVScheduleDevicesKM(IMG_VOID)
+{
+ PVRSRVScheduleDeviceCallbacks();
+}
+
+/*****************************************************************************
+ End of file (pvrsrv.c)
+*****************************************************************************/
diff --git a/pvr-source/services4/srvkm/common/queue.c b/pvr-source/services4/srvkm/common/queue.c
new file mode 100644
index 0000000..88b05a4
--- /dev/null
+++ b/pvr-source/services4/srvkm/common/queue.c
@@ -0,0 +1,1500 @@
+/*************************************************************************/ /*!
+@Title Kernel side command queue functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "services_headers.h"
+#include "pvr_bridge_km.h"
+
+#include "lists.h"
+#include "ttrace.h"
+
+/*
+ * The number of commands of each type which can be in flight at once.
+ */
+#if defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED)
+#define DC_NUM_COMMANDS_PER_TYPE 2
+#else
+#define DC_NUM_COMMANDS_PER_TYPE 1
+#endif
+
+/*
+ * List of private command processing function pointer tables and command
+ * complete tables for a device in the system.
+ * Each table is allocated when the device registers its private command
+ * processing functions.
+ */
+typedef struct _DEVICE_COMMAND_DATA_
+{
+ PFN_CMD_PROC pfnCmdProc;
+ PCOMMAND_COMPLETE_DATA apsCmdCompleteData[DC_NUM_COMMANDS_PER_TYPE];
+ IMG_UINT32 ui32CCBOffset;
+ IMG_UINT32 ui32MaxDstSyncCount; /*!< Maximum number of dest syncs */
+ IMG_UINT32 ui32MaxSrcSyncCount; /*!< Maximum number of source syncs */
+} DEVICE_COMMAND_DATA;
+
+
+#if defined(__linux__) && defined(__KERNEL__)
+
+#include "proc.h"
+
+/*****************************************************************************
+ FUNCTION : ProcSeqShowQueue
+
+ PURPOSE : Print the content of queue element to /proc file
+ (See env/linux/proc.c:CreateProcReadEntrySeq)
+
+ PARAMETERS : sfile - /proc seq_file
+ el - Element to print
+*****************************************************************************/
+void ProcSeqShowQueue(struct seq_file *sfile,void* el)
+{
+ PVRSRV_QUEUE_INFO *psQueue = (PVRSRV_QUEUE_INFO*)el;
+ IMG_INT cmds = 0;
+ IMG_SIZE_T ui32ReadOffset;
+ IMG_SIZE_T ui32WriteOffset;
+ PVRSRV_COMMAND *psCmd;
+
+ if(el == PVR_PROC_SEQ_START_TOKEN)
+ {
+ seq_printf( sfile,
+ "Command Queues\n"
+ "Queue CmdPtr Pid Command Size DevInd DSC SSC #Data ...\n");
+ return;
+ }
+
+ ui32ReadOffset = psQueue->ui32ReadOffset;
+ ui32WriteOffset = psQueue->ui32WriteOffset;
+
+ while (ui32ReadOffset != ui32WriteOffset)
+ {
+ psCmd= (PVRSRV_COMMAND *)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + ui32ReadOffset);
+
+ seq_printf(sfile, "%x %x %5u %6u %3u %5u %2u %2u %3u \n",
+ (IMG_UINTPTR_T)psQueue,
+ (IMG_UINTPTR_T)psCmd,
+ psCmd->ui32ProcessID,
+ psCmd->CommandType,
+ psCmd->uCmdSize,
+ psCmd->ui32DevIndex,
+ psCmd->ui32DstSyncCount,
+ psCmd->ui32SrcSyncCount,
+ psCmd->uDataSize);
+ {
+ IMG_UINT32 i;
+ for (i = 0; i < psCmd->ui32SrcSyncCount; i++)
+ {
+ PVRSRV_SYNC_DATA *psSyncData = psCmd->psSrcSync[i].psKernelSyncInfoKM->psSyncData;
+ seq_printf(sfile, " Sync %u: ROP/ROC: 0x%x/0x%x WOP/WOC: 0x%x/0x%x ROC-VA: 0x%x WOC-VA: 0x%x\n",
+ i,
+ psCmd->psSrcSync[i].ui32ReadOps2Pending,
+ psSyncData->ui32ReadOps2Complete,
+ psCmd->psSrcSync[i].ui32WriteOpsPending,
+ psSyncData->ui32WriteOpsComplete,
+ psCmd->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr,
+ psCmd->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr);
+ }
+ }
+
+ /* taken from UPDATE_QUEUE_ROFF in queue.h */
+ ui32ReadOffset += psCmd->uCmdSize;
+ ui32ReadOffset &= psQueue->ui32QueueSize - 1;
+ cmds++;
+ }
+
+ if (cmds == 0)
+ {
+ seq_printf(sfile, "%x <empty>\n", (IMG_UINTPTR_T)psQueue);
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : ProcSeqOff2ElementQueue
+
+ PURPOSE : Transale offset to element (/proc stuff)
+
+ PARAMETERS : sfile - /proc seq_file
+ off - the offset into the buffer
+
+ RETURNS : element to print
+*****************************************************************************/
+void* ProcSeqOff2ElementQueue(struct seq_file * sfile, loff_t off)
+{
+ PVRSRV_QUEUE_INFO *psQueue = IMG_NULL;
+ SYS_DATA *psSysData;
+
+ PVR_UNREFERENCED_PARAMETER(sfile);
+
+ if(!off)
+ {
+ return PVR_PROC_SEQ_START_TOKEN;
+ }
+
+
+ psSysData = SysAcquireDataNoCheck();
+ if (psSysData != IMG_NULL)
+ {
+ for (psQueue = psSysData->psQueueList; (((--off) > 0) && (psQueue != IMG_NULL)); psQueue = psQueue->psNextKM);
+ }
+
+ return psQueue;
+}
+#endif /* __linux__ && __KERNEL__ */
+
+/*!
+ * Macro to return space in given command queue
+ */
+#define GET_SPACE_IN_CMDQ(psQueue) \
+ ((((psQueue)->ui32ReadOffset - (psQueue)->ui32WriteOffset) \
+ + ((psQueue)->ui32QueueSize - 1)) & ((psQueue)->ui32QueueSize - 1))
+
+/*!
+ * Macro to Write Offset in given command queue
+ */
+#define UPDATE_QUEUE_WOFF(psQueue, ui32Size) \
+ (psQueue)->ui32WriteOffset = ((psQueue)->ui32WriteOffset + (ui32Size)) \
+ & ((psQueue)->ui32QueueSize - 1);
+
+/*!
+ * Check if an ops complete value has gone past the pending value.
+ * This can happen when dummy processing multiple operations, e.g. hardware recovery.
+ */
+#define SYNCOPS_STALE(ui32OpsComplete, ui32OpsPending) \
+ ((ui32OpsComplete) >= (ui32OpsPending))
+
+/*!
+****************************************************************************
+ @Function : PVRSRVGetWriteOpsPending
+
+ @Description : Gets the next operation to wait for in a sync object
+
+ @Input : psSyncInfo - pointer to sync information struct
+ @Input : bIsReadOp - Is this a read or write op
+
+ @Return : Next op value
+*****************************************************************************/
+#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
+ {
+ /*
+ Note: This needs to be atomic and is provided the
+ kernel driver is single threaded (non-rentrant)
+ */
+ ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending++;
+ }
+
+ return ui32WriteOpsPending;
+}
+
+/*!
+*****************************************************************************
+ @Function : PVRSRVGetReadOpsPending
+
+ @Description : Gets the number of pending read ops
+
+ @Input : psSyncInfo - pointer to sync information struct
+ @Input : bIsReadOp - Is this a read or write op
+
+ @Return : Next op value
+*****************************************************************************/
+#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->ui32ReadOps2Pending++;
+ }
+ else
+ {
+ ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOps2Pending;
+ }
+
+ return ui32ReadOpsPending;
+}
+
+static IMG_VOID QueueDumpCmdComplete(COMMAND_COMPLETE_DATA *psCmdCompleteData,
+ IMG_UINT32 i,
+ IMG_BOOL bIsSrc)
+{
+ PVRSRV_SYNC_OBJECT *psSyncObject;
+
+ psSyncObject = bIsSrc ? psCmdCompleteData->psSrcSync : psCmdCompleteData->psDstSync;
+
+ if (psCmdCompleteData->bInUse)
+ {
+ PVR_LOG(("\t%s %u: ROC DevVAddr:0x%X ROP:0x%x ROC:0x%x, WOC DevVAddr:0x%X WOP:0x%x WOC:0x%x",
+ bIsSrc ? "SRC" : "DEST", i,
+ psSyncObject[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr,
+ psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32ReadOps2Pending,
+ psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32ReadOps2Complete,
+ psSyncObject[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+ psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsPending,
+ psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete))
+ }
+ else
+ {
+ PVR_LOG(("\t%s %u: (Not in use)", bIsSrc ? "SRC" : "DEST", i))
+ }
+}
+
+
+static IMG_VOID QueueDumpDebugInfo_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ if (psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY)
+ {
+ IMG_UINT32 ui32CmdCounter, ui32SyncCounter;
+ SYS_DATA *psSysData;
+ DEVICE_COMMAND_DATA *psDeviceCommandData;
+ PCOMMAND_COMPLETE_DATA psCmdCompleteData;
+
+ SysAcquireData(&psSysData);
+
+ psDeviceCommandData = psSysData->apsDeviceCommandData[psDeviceNode->sDevId.ui32DeviceIndex];
+
+ if (psDeviceCommandData != IMG_NULL)
+ {
+ for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++)
+ {
+ psCmdCompleteData = psDeviceCommandData[DC_FLIP_COMMAND].apsCmdCompleteData[ui32CmdCounter];
+
+ PVR_LOG(("Flip Command Complete Data %u for display device %u:",
+ ui32CmdCounter, psDeviceNode->sDevId.ui32DeviceIndex))
+
+ for (ui32SyncCounter = 0;
+ ui32SyncCounter < psCmdCompleteData->ui32SrcSyncCount;
+ ui32SyncCounter++)
+ {
+ QueueDumpCmdComplete(psCmdCompleteData, ui32SyncCounter, IMG_TRUE);
+ }
+
+ for (ui32SyncCounter = 0;
+ ui32SyncCounter < psCmdCompleteData->ui32DstSyncCount;
+ ui32SyncCounter++)
+ {
+ QueueDumpCmdComplete(psCmdCompleteData, ui32SyncCounter, IMG_FALSE);
+ }
+ }
+ }
+ else
+ {
+ PVR_LOG(("There is no Command Complete Data for display device %u", psDeviceNode->sDevId.ui32DeviceIndex))
+ }
+ }
+}
+
+
+IMG_VOID QueueDumpDebugInfo(IMG_VOID)
+{
+ SYS_DATA *psSysData;
+ SysAcquireData(&psSysData);
+ List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList, &QueueDumpDebugInfo_ForEachCb);
+}
+
+
+/*****************************************************************************
+ Kernel-side functions of User->Kernel transitions
+******************************************************************************/
+
+static IMG_SIZE_T NearestPower2(IMG_SIZE_T ui32Value)
+{
+ IMG_SIZE_T ui32Temp, ui32Result = 1;
+
+ if(!ui32Value)
+ return 0;
+
+ ui32Temp = ui32Value - 1;
+ while(ui32Temp)
+ {
+ ui32Result <<= 1;
+ ui32Temp >>= 1;
+ }
+
+ return ui32Result;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVCreateCommandQueueKM
+
+ @Description
+ Creates a new command queue into which render/blt commands etc can be
+ inserted.
+
+ @Input ui32QueueSize :
+
+ @Output ppsQueueInfo :
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T ui32QueueSize,
+ PVRSRV_QUEUE_INFO **ppsQueueInfo)
+{
+ PVRSRV_QUEUE_INFO *psQueueInfo;
+ IMG_SIZE_T ui32Power2QueueSize = NearestPower2(ui32QueueSize);
+ SYS_DATA *psSysData;
+ PVRSRV_ERROR eError;
+ IMG_HANDLE hMemBlock;
+
+ SysAcquireData(&psSysData);
+
+ /* allocate an internal queue info structure */
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_QUEUE_INFO),
+ (IMG_VOID **)&psQueueInfo, &hMemBlock,
+ "Queue Info");
+ if (eError != 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();
+
+ /* allocate the command queue buffer - allow for overrun */
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ ui32Power2QueueSize + PVRSRV_MAX_CMD_SIZE,
+ &psQueueInfo->pvLinQueueKM, &hMemBlock,
+ "Command Queue");
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue buffer"));
+ goto ErrorExit;
+ }
+
+ psQueueInfo->hMemBlock[1] = hMemBlock;
+ psQueueInfo->pvLinQueueUM = psQueueInfo->pvLinQueueKM;
+
+ /* Sanity check: Should be zeroed by OSMemSet */
+ PVR_ASSERT(psQueueInfo->ui32ReadOffset == 0);
+ PVR_ASSERT(psQueueInfo->ui32WriteOffset == 0);
+
+ psQueueInfo->ui32QueueSize = ui32Power2QueueSize;
+
+ /* if this is the first q, create a lock resource for the q list */
+ if (psSysData->psQueueList == IMG_NULL)
+ {
+ eError = OSCreateResource(&psSysData->sQProcessResource);
+ if (eError != PVRSRV_OK)
+ {
+ goto ErrorExit;
+ }
+ }
+
+ /* Ensure we don't corrupt queue list, by blocking access */
+ eError = OSLockResource(&psSysData->sQProcessResource,
+ KERNEL_ID);
+ if (eError != PVRSRV_OK)
+ {
+ goto ErrorExit;
+ }
+
+ psQueueInfo->psNextKM = psSysData->psQueueList;
+ psSysData->psQueueList = psQueueInfo;
+
+ eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
+ if (eError != 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]);
+ psQueueInfo->pvLinQueueKM = IMG_NULL;
+ }
+
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_QUEUE_INFO),
+ psQueueInfo,
+ psQueueInfo->hMemBlock[0]);
+ /*not nulling pointer, out of scope*/
+ }
+
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVDestroyCommandQueueKM
+
+ @Description Destroys a command queue
+
+ @Input psQueueInfo :
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+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;
+
+ SysAcquireData(&psSysData);
+
+ psQueue = psSysData->psQueueList;
+
+ /* PRQA S 3415,4109 1 */ /* macro format critical - leave alone */
+ LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+ {
+ if(psQueueInfo->ui32ReadOffset == psQueueInfo->ui32WriteOffset)
+ {
+ bTimeout = IMG_FALSE;
+ break;
+ }
+ OSSleepms(1);
+ } END_LOOP_UNTIL_TIMEOUT();
+
+ if (bTimeout)
+ {
+ /* The command queue could not be flushed within the timeout period.
+ Allow the queue to be destroyed before returning the error code. */
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyCommandQueueKM : Failed to empty queue"));
+ eError = PVRSRV_ERROR_CANNOT_FLUSH_QUEUE;
+ goto ErrorExit;
+ }
+
+ /* Ensure we don't corrupt queue list, by blocking access */
+ 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,
+ NearestPower2(psQueueInfo->ui32QueueSize) + PVRSRV_MAX_CMD_SIZE,
+ psQueueInfo->pvLinQueueKM,
+ psQueueInfo->hMemBlock[1]);
+ psQueueInfo->pvLinQueueKM = IMG_NULL;
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_QUEUE_INFO),
+ psQueueInfo,
+ psQueueInfo->hMemBlock[0]);
+ /* PRQA S 3199 1 */ /* see note */
+ psQueueInfo = IMG_NULL; /*it's a copy on stack, but null it because the function doesn't end right here*/
+ }
+ else
+ {
+ while(psQueue)
+ {
+ if(psQueue->psNextKM == psQueueInfo)
+ {
+ psQueue->psNextKM = psQueueInfo->psNextKM;
+
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ psQueueInfo->ui32QueueSize,
+ psQueueInfo->pvLinQueueKM,
+ psQueueInfo->hMemBlock[1]);
+ psQueueInfo->pvLinQueueKM = IMG_NULL;
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_QUEUE_INFO),
+ psQueueInfo,
+ psQueueInfo->hMemBlock[0]);
+ /* PRQA S 3199 1 */ /* see note */
+ psQueueInfo = IMG_NULL; /*it's a copy on stack, but null it because the function doesn't end right here*/
+ 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;
+ }
+ }
+
+ /* unlock the Q list lock resource */
+ eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
+ if (eError != PVRSRV_OK)
+ {
+ goto ErrorExit;
+ }
+
+ /* if the Q list is now empty, destroy the Q list lock resource */
+ if (psSysData->psQueueList == IMG_NULL)
+ {
+ eError = OSDestroyResource(&psSysData->sQProcessResource);
+ if (eError != PVRSRV_OK)
+ {
+ goto ErrorExit;
+ }
+ }
+
+ErrorExit:
+
+ return eError;
+}
+
+
+/*!
+*****************************************************************************
+
+ @Function : PVRSRVGetQueueSpaceKM
+
+ @Description : Waits for queue access rights and checks for available space in
+ queue for task param structure
+
+ @Input : psQueue - pointer to queue information struct
+ @Input : ui32ParamSize - size of task data structure
+ @Output : ppvSpace
+
+ @Return : PVRSRV_ERROR
+*****************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetQueueSpaceKM(PVRSRV_QUEUE_INFO *psQueue,
+ IMG_SIZE_T ui32ParamSize,
+ IMG_VOID **ppvSpace)
+{
+ IMG_BOOL bTimeout = IMG_TRUE;
+
+ /* round to 4byte units */
+ 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;
+ }
+
+ /* PRQA S 3415,4109 1 */ /* macro format critical - leave alone */
+ LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+ {
+ if (GET_SPACE_IN_CMDQ(psQueue) > ui32ParamSize)
+ {
+ bTimeout = IMG_FALSE;
+ break;
+ }
+ OSSleepms(1);
+ } END_LOOP_UNTIL_TIMEOUT();
+
+ if (bTimeout == IMG_TRUE)
+ {
+ *ppvSpace = IMG_NULL;
+
+ return PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE;
+ }
+ else
+ {
+ *ppvSpace = (IMG_VOID *)((IMG_UINTPTR_T)psQueue->pvLinQueueUM + psQueue->ui32WriteOffset);
+ }
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+*****************************************************************************
+ @Function PVRSRVInsertCommandKM
+
+ @Description :
+ command insertion utility
+ - waits for space in the queue for a new command
+ - fills in generic command information
+ - returns a pointer to the caller who's expected to then fill
+ in the private data.
+ The caller should follow PVRSRVInsertCommand with PVRSRVSubmitCommand
+ which will update the queue's write offset so the command can be
+ executed.
+
+ @Input psQueue : pointer to queue information struct
+
+ @Output ppvCmdData : holds pointer to space in queue for private cmd data
+
+ @Return PVRSRV_ERROR
+*****************************************************************************/
+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_SIZE_T ui32DataByteSize,
+ PFN_QUEUE_COMMAND_COMPLETE pfnCommandComplete,
+ IMG_HANDLE hCallbackData)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_COMMAND *psCommand;
+ IMG_SIZE_T ui32CommandSize;
+ IMG_UINT32 i;
+ SYS_DATA *psSysData;
+ DEVICE_COMMAND_DATA *psDeviceCommandData;
+
+ /* Check that we've got enough space in our command complete data for this command */
+ SysAcquireData(&psSysData);
+ psDeviceCommandData = psSysData->apsDeviceCommandData[ui32DevIndex];
+
+ if ((psDeviceCommandData[CommandType].ui32MaxDstSyncCount < ui32DstSyncCount) ||
+ (psDeviceCommandData[CommandType].ui32MaxSrcSyncCount < ui32SrcSyncCount))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVInsertCommandKM: Too many syncs"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ /* Round up to nearest 32 bit size so pointer arithmetic works */
+ ui32DataByteSize = (ui32DataByteSize + 3UL) & ~3UL;
+
+ /* calc. command size */
+ ui32CommandSize = sizeof(PVRSRV_COMMAND)
+ + ((ui32DstSyncCount + ui32SrcSyncCount) * sizeof(PVRSRV_SYNC_OBJECT))
+ + ui32DataByteSize;
+
+ /* wait for space in queue */
+ eError = PVRSRVGetQueueSpaceKM (psQueue, ui32CommandSize, (IMG_VOID**)&psCommand);
+ if(eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ psCommand->ui32ProcessID = OSGetCurrentProcessIDKM();
+
+ /* setup the command */
+ psCommand->uCmdSize = ui32CommandSize; /* this may change if cmd shrinks */
+ psCommand->ui32DevIndex = ui32DevIndex;
+ psCommand->CommandType = CommandType;
+ psCommand->ui32DstSyncCount = ui32DstSyncCount;
+ psCommand->ui32SrcSyncCount = ui32SrcSyncCount;
+ /* override QAC warning about stricter pointers */
+ /* PRQA S 3305 END_PTR_ASSIGNMENTS */
+ psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand) + sizeof(PVRSRV_COMMAND));
+
+
+ psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psDstSync)
+ + (ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
+
+ psCommand->pvData = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psSrcSync)
+ + (ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
+/* PRQA L:END_PTR_ASSIGNMENTS */
+
+ psCommand->uDataSize = ui32DataByteSize;/* this may change if cmd shrinks */
+
+ psCommand->pfnCommandComplete = pfnCommandComplete;
+ psCommand->hCallbackData = hCallbackData;
+
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_START, QUEUE_TOKEN_INSERTKM);
+ PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_NONE,
+ QUEUE_TOKEN_COMMAND_TYPE, CommandType);
+
+ /* setup dst sync objects and their sync dependencies */
+ for (i=0; i<ui32DstSyncCount; i++)
+ {
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_DST_SYNC,
+ apsDstSync[i], PVRSRV_SYNCOP_SAMPLE);
+
+ psCommand->psDstSync[i].psKernelSyncInfoKM = apsDstSync[i];
+ psCommand->psDstSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsDstSync[i], IMG_FALSE);
+ psCommand->psDstSync[i].ui32ReadOps2Pending = PVRSRVGetReadOpsPending(apsDstSync[i], IMG_FALSE);
+
+ PVRSRVKernelSyncInfoIncRef(apsDstSync[i], IMG_NULL);
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
+ i, psCommand->psDstSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr,
+ psCommand->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+ psCommand->psDstSync[i].ui32ReadOps2Pending,
+ psCommand->psDstSync[i].ui32WriteOpsPending));
+ }
+
+ /* setup src sync objects and their sync dependencies */
+ for (i=0; i<ui32SrcSyncCount; i++)
+ {
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_DST_SYNC,
+ apsSrcSync[i], PVRSRV_SYNCOP_SAMPLE);
+
+ psCommand->psSrcSync[i].psKernelSyncInfoKM = apsSrcSync[i];
+ psCommand->psSrcSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsSrcSync[i], IMG_TRUE);
+ psCommand->psSrcSync[i].ui32ReadOps2Pending = PVRSRVGetReadOpsPending(apsSrcSync[i], IMG_TRUE);
+
+ PVRSRVKernelSyncInfoIncRef(apsSrcSync[i], IMG_NULL);
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
+ i, psCommand->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr,
+ psCommand->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+ psCommand->psSrcSync[i].ui32ReadOps2Pending,
+ psCommand->psSrcSync[i].ui32WriteOpsPending));
+ }
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_END, QUEUE_TOKEN_INSERTKM);
+
+ /* return pointer to caller to fill out private data */
+ *ppsCommand = psCommand;
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+*******************************************************************************
+ @Function : PVRSRVSubmitCommandKM
+
+ @Description :
+ updates the queue's write offset so the command can be executed.
+
+ @Input : psQueue - queue command is in
+ @Input : psCommand
+
+ @Return : PVRSRV_ERROR
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVSubmitCommandKM(PVRSRV_QUEUE_INFO *psQueue,
+ PVRSRV_COMMAND *psCommand)
+{
+ /* override QAC warnings about stricter pointers */
+ /* PRQA S 3305 END_PTR_ASSIGNMENTS2 */
+ /* patch pointers in the command to be kernel pointers */
+ if (psCommand->ui32DstSyncCount > 0)
+ {
+ psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
+ + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND));
+ }
+
+ if (psCommand->ui32SrcSyncCount > 0)
+ {
+ psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
+ + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND)
+ + (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
+ }
+
+ psCommand->pvData = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
+ + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND)
+ + (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT))
+ + (psCommand->ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
+
+/* PRQA L:END_PTR_ASSIGNMENTS2 */
+
+ /* update write offset before releasing access lock */
+ UPDATE_QUEUE_WOFF(psQueue, psCommand->uCmdSize);
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function CheckIfSyncIsQueued
+
+ @Description Check if the specificed sync object is already queued and
+ can safely be given to the display controller.
+ This check is required as a 3rd party displayclass device can
+ have several flips "in flight" and we need to ensure that we
+ keep their pipeline full and don't deadlock waiting for them
+ to complete an operation on a surface.
+
+ @Input psSysData : system data
+ @Input psCmdData : COMMAND_COMPLETE_DATA structure
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+static
+PVRSRV_ERROR CheckIfSyncIsQueued(PVRSRV_SYNC_OBJECT *psSync, COMMAND_COMPLETE_DATA *psCmdData)
+{
+ IMG_UINT32 k;
+
+ if (psCmdData->bInUse)
+ {
+ for (k=0;k<psCmdData->ui32SrcSyncCount;k++)
+ {
+ if (psSync->psKernelSyncInfoKM == psCmdData->psSrcSync[k].psKernelSyncInfoKM)
+ {
+ PVRSRV_SYNC_DATA *psSyncData = psSync->psKernelSyncInfoKM->psSyncData;
+ IMG_UINT32 ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete;
+
+ /*
+ We still need to ensure that we don't we don't give a command
+ to the display controller if writes are outstanding on it
+ */
+ if (ui32WriteOpsComplete == psSync->ui32WriteOpsPending)
+ {
+ return PVRSRV_OK;
+ }
+ else
+ {
+ if (SYNCOPS_STALE(ui32WriteOpsComplete, psSync->ui32WriteOpsPending))
+ {
+ PVR_DPF((PVR_DBG_WARNING,
+ "CheckIfSyncIsQueued: Stale syncops psSyncData:0x%x ui32WriteOpsComplete:0x%x ui32WriteOpsPending:0x%x",
+ (IMG_UINTPTR_T)psSyncData, ui32WriteOpsComplete, psSync->ui32WriteOpsPending));
+ return PVRSRV_OK;
+ }
+ }
+ }
+ }
+ }
+ return PVRSRV_ERROR_FAILED_DEPENDENCIES;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVProcessCommand
+
+ @Description Tries to process a command
+
+ @Input psSysData : system data
+ @Input psCommand : PVRSRV_COMMAND structure
+ @Input bFlush : Check for stale dependencies (only used for HW recovery)
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+static
+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;
+ DEVICE_COMMAND_DATA *psDeviceCommandData;
+ IMG_UINT32 ui32CCBOffset;
+
+ /* satisfy sync dependencies on the DST(s) */
+ psWalkerObj = psCommand->psDstSync;
+ psEndObj = psWalkerObj + psCommand->ui32DstSyncCount;
+ while (psWalkerObj < psEndObj)
+ {
+ PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData;
+
+ ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete;
+ ui32ReadOpsComplete = psSyncData->ui32ReadOps2Complete;
+ /* fail if reads or writes are not up to date */
+ if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending)
+ || (ui32ReadOpsComplete != psWalkerObj->ui32ReadOps2Pending))
+ {
+ if (!bFlush ||
+ !SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) ||
+ !SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOps2Pending))
+ {
+ return PVRSRV_ERROR_FAILED_DEPENDENCIES;
+ }
+ }
+
+ psWalkerObj++;
+ }
+
+ /* satisfy sync dependencies on the SRC(s) */
+ psWalkerObj = psCommand->psSrcSync;
+ psEndObj = psWalkerObj + psCommand->ui32SrcSyncCount;
+ while (psWalkerObj < psEndObj)
+ {
+ PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData;
+
+ ui32ReadOpsComplete = psSyncData->ui32ReadOps2Complete;
+ ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete;
+ /* fail if writes are not up to date */
+ if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending)
+ || (ui32ReadOpsComplete != psWalkerObj->ui32ReadOps2Pending))
+ {
+ if (!bFlush &&
+ SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) &&
+ SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOps2Pending))
+ {
+ PVR_DPF((PVR_DBG_WARNING,
+ "PVRSRVProcessCommand: Stale syncops psSyncData:0x%x ui32WriteOpsComplete:0x%x ui32WriteOpsPending:0x%x",
+ (IMG_UINTPTR_T)psSyncData, ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending));
+ }
+
+ if (!bFlush ||
+ !SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) ||
+ !SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOps2Pending))
+ {
+ IMG_UINT32 j;
+ PVRSRV_ERROR eError;
+ IMG_BOOL bFound = IMG_FALSE;
+
+ psDeviceCommandData = psSysData->apsDeviceCommandData[psCommand->ui32DevIndex];
+ for (j=0;j<DC_NUM_COMMANDS_PER_TYPE;j++)
+ {
+ eError = CheckIfSyncIsQueued(psWalkerObj, psDeviceCommandData[psCommand->CommandType].apsCmdCompleteData[j]);
+
+ if (eError == PVRSRV_OK)
+ {
+ bFound = IMG_TRUE;
+ }
+ }
+ if (!bFound)
+ return PVRSRV_ERROR_FAILED_DEPENDENCIES;
+ }
+ }
+ psWalkerObj++;
+ }
+
+ /* validate device type */
+ if (psCommand->ui32DevIndex >= SYS_DEVICE_COUNT)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "PVRSRVProcessCommand: invalid DeviceType 0x%x",
+ psCommand->ui32DevIndex));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ /* fish out the appropriate storage structure for the duration of the command */
+ psDeviceCommandData = psSysData->apsDeviceCommandData[psCommand->ui32DevIndex];
+ ui32CCBOffset = psDeviceCommandData[psCommand->CommandType].ui32CCBOffset;
+ psCmdCompleteData = psDeviceCommandData[psCommand->CommandType].apsCmdCompleteData[ui32CCBOffset];
+ if (psCmdCompleteData->bInUse)
+ {
+ /* can use this to protect against concurrent execution of same command */
+ return PVRSRV_ERROR_FAILED_DEPENDENCIES;
+ }
+
+ /* mark the structure as in use */
+ psCmdCompleteData->bInUse = IMG_TRUE;
+
+ /* copy src updates over */
+ psCmdCompleteData->ui32DstSyncCount = psCommand->ui32DstSyncCount;
+ for (i=0; i<psCommand->ui32DstSyncCount; i++)
+ {
+ psCmdCompleteData->psDstSync[i] = psCommand->psDstSync[i];
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVProcessCommand: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x (CCB:%u)",
+ i, psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr,
+ psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+ psCmdCompleteData->psDstSync[i].ui32ReadOps2Pending,
+ psCmdCompleteData->psDstSync[i].ui32WriteOpsPending,
+ ui32CCBOffset));
+ }
+
+ psCmdCompleteData->pfnCommandComplete = psCommand->pfnCommandComplete;
+ psCmdCompleteData->hCallbackData = psCommand->hCallbackData;
+
+ /* copy dst updates over */
+ psCmdCompleteData->ui32SrcSyncCount = psCommand->ui32SrcSyncCount;
+ for (i=0; i<psCommand->ui32SrcSyncCount; i++)
+ {
+ psCmdCompleteData->psSrcSync[i] = psCommand->psSrcSync[i];
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVProcessCommand: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x (CCB:%u)",
+ i, psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr,
+ psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+ psCmdCompleteData->psSrcSync[i].ui32ReadOps2Pending,
+ psCmdCompleteData->psSrcSync[i].ui32WriteOpsPending,
+ ui32CCBOffset));
+ }
+
+ /*
+ call the cmd specific handler:
+ it should:
+ - check the cmd specific dependencies
+ - setup private cmd complete structure
+ - execute cmd on HW
+ - store psCmdCompleteData `cookie' and later pass as
+ argument to Generic Command Complete Callback
+
+ n.b. ui32DataSize (packet size) is useful for packet validation
+ */
+ if (psDeviceCommandData[psCommand->CommandType].pfnCmdProc((IMG_HANDLE)psCmdCompleteData,
+ (IMG_UINT32)psCommand->uDataSize,
+ psCommand->pvData) == IMG_FALSE)
+ {
+ /*
+ clean-up:
+ free cmd complete structure
+ */
+ psCmdCompleteData->bInUse = IMG_FALSE;
+ eError = PVRSRV_ERROR_CMD_NOT_PROCESSED;
+ }
+
+ /* Increment the CCB offset */
+ psDeviceCommandData[psCommand->CommandType].ui32CCBOffset = (ui32CCBOffset + 1) % DC_NUM_COMMANDS_PER_TYPE;
+
+ return eError;
+}
+
+
+static IMG_VOID PVRSRVProcessQueues_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ if (psDeviceNode->bReProcessDeviceCommandComplete &&
+ psDeviceNode->pfnDeviceCommandComplete != IMG_NULL)
+ {
+ (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode);
+ }
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVProcessQueues
+
+ @Description Tries to process a command from each Q
+
+ @input ui32CallerID - used to distinguish between async ISR/DPC type calls
+ the synchronous services driver
+ @input bFlush - flush commands with stale dependencies (only used for HW recovery)
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVProcessQueues(IMG_BOOL bFlush)
+{
+ PVRSRV_QUEUE_INFO *psQueue;
+ SYS_DATA *psSysData;
+ PVRSRV_COMMAND *psCommand;
+/* PVRSRV_DEVICE_NODE *psDeviceNode;*/
+
+ SysAcquireData(&psSysData);
+
+ /* Ensure we don't corrupt queue list, by blocking access. This is required for OSs where
+ multiple ISR threads may exist simultaneously (eg WinXP DPC routines)
+ */
+ while (OSLockResource(&psSysData->sQProcessResource, ISR_ID) != PVRSRV_OK)
+ {
+ OSWaitus(1);
+ };
+
+ 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_UINTPTR_T)psQueue->pvLinQueueKM + psQueue->ui32ReadOffset);
+
+ if (PVRSRVProcessCommand(psSysData, psCommand, bFlush) == PVRSRV_OK)
+ {
+ /* processed cmd so update queue */
+ UPDATE_QUEUE_ROFF(psQueue, psCommand->uCmdSize)
+ continue;
+ }
+
+ break;
+ }
+ psQueue = psQueue->psNextKM;
+ }
+
+ if (bFlush)
+ {
+ PVRSRVSetDCState(DC_STATE_NO_FLUSH_COMMANDS);
+ }
+
+ /* Re-process command complete handlers if necessary. */
+ List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
+ &PVRSRVProcessQueues_ForEachCb);
+
+ OSUnlockResource(&psSysData->sQProcessResource, ISR_ID);
+
+ return PVRSRV_OK;
+}
+
+#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
+/*!
+******************************************************************************
+
+ @Function PVRSRVCommandCompleteKM
+
+ @Description Updates non-private command complete sync objects
+
+ @Input hCmdCookie : command cookie
+ @Input bScheduleMISR : obsolete parameter
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+IMG_INTERNAL
+IMG_VOID PVRSRVFreeCommandCompletePacketKM(IMG_HANDLE hCmdCookie,
+ IMG_BOOL bScheduleMISR)
+{
+ COMMAND_COMPLETE_DATA *psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie;
+ SYS_DATA *psSysData;
+
+ PVR_UNREFERENCED_PARAMETER(bScheduleMISR);
+
+ SysAcquireData(&psSysData);
+
+ /* free command complete storage */
+ psCmdCompleteData->bInUse = IMG_FALSE;
+
+ /* FIXME: This may cause unrelated devices to be woken up. */
+ PVRSRVScheduleDeviceCallbacks();
+
+ /* the MISR is always scheduled, regardless of bScheduleMISR */
+ OSScheduleMISR(psSysData);
+}
+
+#endif /* (SUPPORT_CUSTOM_SWAP_OPERATIONS) */
+
+#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK)
+extern void sgxfreq_notif_sgx_frame_done(void);
+#endif /* (SYS_OMAP4_HAS_DVFS_FRAMEWORK) */
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVCommandCompleteKM
+
+ @Description Updates non-private command complete sync objects
+
+ @Input hCmdCookie : command cookie
+ @Input bScheduleMISR : boolean to schedule MISR
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+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 defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK)
+ sgxfreq_notif_sgx_frame_done();
+#endif /* (SYS_OMAP4_HAS_DVFS_FRAMEWORK) */
+
+ SysAcquireData(&psSysData);
+
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_COMP_START,
+ QUEUE_TOKEN_COMMAND_COMPLETE);
+
+ /* update DST(s) syncs */
+ for (i=0; i<psCmdCompleteData->ui32DstSyncCount; i++)
+ {
+ psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete++;
+
+ PVRSRVKernelSyncInfoDecRef(psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM, IMG_NULL);
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_UPDATE_DST,
+ psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM,
+ PVRSRV_SYNCOP_COMPLETE);
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVCommandCompleteKM: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
+ i, psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr,
+ psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+ psCmdCompleteData->psDstSync[i].ui32ReadOps2Pending,
+ psCmdCompleteData->psDstSync[i].ui32WriteOpsPending));
+ }
+
+ /* update SRC(s) syncs */
+ for (i=0; i<psCmdCompleteData->ui32SrcSyncCount; i++)
+ {
+ psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->psSyncData->ui32ReadOps2Complete++;
+
+ PVRSRVKernelSyncInfoDecRef(psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM, IMG_NULL);
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_UPDATE_SRC,
+ psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM,
+ PVRSRV_SYNCOP_COMPLETE);
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVCommandCompleteKM: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
+ i, psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr,
+ psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
+ psCmdCompleteData->psSrcSync[i].ui32ReadOps2Pending,
+ psCmdCompleteData->psSrcSync[i].ui32WriteOpsPending));
+ }
+
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_COMP_END,
+ QUEUE_TOKEN_COMMAND_COMPLETE);
+
+ if (psCmdCompleteData->pfnCommandComplete)
+ {
+ psCmdCompleteData->pfnCommandComplete(psCmdCompleteData->hCallbackData);
+ }
+
+ /* free command complete storage */
+ psCmdCompleteData->bInUse = IMG_FALSE;
+
+ /* FIXME: This may cause unrelated devices to be woken up. */
+ PVRSRVScheduleDeviceCallbacks();
+
+ if(bScheduleMISR)
+ {
+ OSScheduleMISR(psSysData);
+ }
+}
+
+
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVRegisterCmdProcListKM
+
+ @Description
+
+ registers a list of private command processing functions with the Command
+ Queue Manager
+
+ @Input ui32DevIndex : device index
+
+ @Input ppfnCmdProcList : function ptr table of private command processors
+
+ @Input ui32MaxSyncsPerCmd : max number of syncobjects used by command
+
+ @Input ui32CmdCount : number of entries in function ptr table
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+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 ui32CmdCounter, ui32CmdTypeCounter;
+ IMG_SIZE_T ui32AllocSize;
+ DEVICE_COMMAND_DATA *psDeviceCommandData;
+ COMMAND_COMPLETE_DATA *psCmdCompleteData;
+
+ /* validate device type */
+ if(ui32DevIndex >= SYS_DEVICE_COUNT)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "PVRSRVRegisterCmdProcListKM: invalid DeviceType 0x%x",
+ ui32DevIndex));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ /* acquire system data structure */
+ SysAcquireData(&psSysData);
+
+ /* array of pointers for each command store */
+ ui32AllocSize = ui32CmdCount * sizeof(*psDeviceCommandData);
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ ui32AllocSize,
+ (IMG_VOID **)&psDeviceCommandData, IMG_NULL,
+ "Array of Pointers for Command Store");
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc CC data"));
+ goto ErrorExit;
+ }
+
+ psSysData->apsDeviceCommandData[ui32DevIndex] = psDeviceCommandData;
+
+ for (ui32CmdTypeCounter = 0; ui32CmdTypeCounter < ui32CmdCount; ui32CmdTypeCounter++)
+ {
+ psDeviceCommandData[ui32CmdTypeCounter].pfnCmdProc = ppfnCmdProcList[ui32CmdTypeCounter];
+ psDeviceCommandData[ui32CmdTypeCounter].ui32CCBOffset = 0;
+ psDeviceCommandData[ui32CmdTypeCounter].ui32MaxDstSyncCount = ui32MaxSyncsPerCmd[ui32CmdTypeCounter][0];
+ psDeviceCommandData[ui32CmdTypeCounter].ui32MaxSrcSyncCount = ui32MaxSyncsPerCmd[ui32CmdTypeCounter][1];
+ for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++)
+ {
+ /*
+ allocate storage for the sync update on command complete
+ */
+ ui32AllocSize = sizeof(COMMAND_COMPLETE_DATA) /* space for one GENERIC_CMD_COMPLETE */
+ + ((ui32MaxSyncsPerCmd[ui32CmdTypeCounter][0]
+ + ui32MaxSyncsPerCmd[ui32CmdTypeCounter][1])
+ * sizeof(PVRSRV_SYNC_OBJECT)); /* space for max sync objects */
+
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ ui32AllocSize,
+ (IMG_VOID **)&psCmdCompleteData,
+ IMG_NULL,
+ "Command Complete Data");
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc cmd %d", ui32CmdTypeCounter));
+ goto ErrorExit;
+ }
+
+ psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter] = psCmdCompleteData;
+
+ /* clear memory */
+ OSMemSet(psCmdCompleteData, 0x00, ui32AllocSize);
+
+ /* setup sync pointers */
+ psCmdCompleteData->psDstSync = (PVRSRV_SYNC_OBJECT*)
+ (((IMG_UINTPTR_T)psCmdCompleteData)
+ + sizeof(COMMAND_COMPLETE_DATA));
+ psCmdCompleteData->psSrcSync = (PVRSRV_SYNC_OBJECT*)
+ (((IMG_UINTPTR_T)psCmdCompleteData->psDstSync)
+ + (sizeof(PVRSRV_SYNC_OBJECT) * ui32MaxSyncsPerCmd[ui32CmdTypeCounter][0]));
+
+ psCmdCompleteData->ui32AllocSize = (IMG_UINT32)ui32AllocSize;
+ }
+ }
+
+ return PVRSRV_OK;
+
+ErrorExit:
+
+ /* clean-up if things went wrong */
+ if (PVRSRVRemoveCmdProcListKM(ui32DevIndex, ui32CmdCount) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "PVRSRVRegisterCmdProcListKM: Failed to clean up after error, device 0x%x",
+ ui32DevIndex));
+ }
+
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVRemoveCmdProcListKM
+
+ @Description
+
+ removes a list of private command processing functions and data from the
+ Queue Manager
+
+ @Input ui32DevIndex : device index
+
+ @Input ui32CmdCount : number of entries in function ptr table
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(IMG_UINT32 ui32DevIndex,
+ IMG_UINT32 ui32CmdCount)
+{
+ SYS_DATA *psSysData;
+ IMG_UINT32 ui32CmdTypeCounter, ui32CmdCounter;
+ DEVICE_COMMAND_DATA *psDeviceCommandData;
+ COMMAND_COMPLETE_DATA *psCmdCompleteData;
+ IMG_SIZE_T ui32AllocSize;
+
+ /* validate device type */
+ if(ui32DevIndex >= SYS_DEVICE_COUNT)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "PVRSRVRemoveCmdProcListKM: invalid DeviceType 0x%x",
+ ui32DevIndex));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ /* acquire system data structure */
+ SysAcquireData(&psSysData);
+
+ psDeviceCommandData = psSysData->apsDeviceCommandData[ui32DevIndex];
+ if(psDeviceCommandData != IMG_NULL)
+ {
+ for (ui32CmdTypeCounter = 0; ui32CmdTypeCounter < ui32CmdCount; ui32CmdTypeCounter++)
+ {
+ for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++)
+ {
+ psCmdCompleteData = psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter];
+
+ /* free the cmd complete structure array entries */
+ if (psCmdCompleteData != IMG_NULL)
+ {
+ PVR_ASSERT(psCmdCompleteData->bInUse == IMG_FALSE);
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, psCmdCompleteData->ui32AllocSize,
+ psCmdCompleteData, IMG_NULL);
+ psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter] = IMG_NULL;
+ }
+ }
+ }
+
+ /* free the cmd complete structure array for the device */
+ ui32AllocSize = ui32CmdCount * sizeof(*psDeviceCommandData);
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, ui32AllocSize, psDeviceCommandData, IMG_NULL);
+ psSysData->apsDeviceCommandData[ui32DevIndex] = IMG_NULL;
+ }
+
+ return PVRSRV_OK;
+}
+
+/******************************************************************************
+ End of file (queue.c)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/common/ra.c b/pvr-source/services4/srvkm/common/ra.c
new file mode 100644
index 0000000..da48939
--- /dev/null
+++ b/pvr-source/services4/srvkm/common/ra.c
@@ -0,0 +1,2427 @@
+/*************************************************************************/ /*!
+@Title Resource Allocator
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description
+ Implements generic resource allocation. The resource
+ allocator was originally intended to manage address spaces in
+ practice the resource allocator is generic and can manages arbitrary
+ sets of integers.
+
+ Resources are allocated from arenas. Arena's can be created with an
+ initial span of resources. Further resources spans can be added to
+ arenas. A call back mechanism allows an arena to request further
+ resource spans on demand.
+
+ Each arena maintains an ordered list of resource segments each
+ described by a boundary tag. Each boundary tag describes a segment
+ of resources which are either 'free', available for allocation, or
+ 'busy' currently allocated. Adjacent 'free' segments are always
+ coallesced to avoid fragmentation.
+
+ For allocation, all 'free' segments are kept on lists of 'free'
+ segments in a table index by pvr_log2(segment size). ie Each table index
+ n holds 'free' segments in the size range 2**(n-1) -> 2**n.
+
+ Allocation policy is based on an *almost* best fit
+ stratedy. Choosing any segment from the appropriate table entry
+ guarantees that we choose a segment which is with a power of 2 of
+ the size we are allocating.
+
+ Allocated segments are inserted into a self scaling hash table which
+ maps the base resource of the span to the relevant boundary
+ tag. This allows the code to get back to the bounary tag without
+ exporting explicit boundary tag references through the API.
+
+ Each arena has an associated quantum size, all allocations from the
+ arena are made in multiples of the basic quantum.
+
+ On resource exhaustion in an arena, a callback if provided will be
+ used to request further resources. Resouces spans allocated by the
+ callback mechanism are delimited by special boundary tag markers of
+ zero span, 'span' markers. Span markers are never coallesced. Span
+ markers are used to detect when an imported span is completely free
+ and can be deallocated by the callback mechanism.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/* Issues:
+ * - flags, flags are passed into the resource allocator but are not currently used.
+ * - determination, of import size, is currently braindead.
+ * - debug code should be moved out to own module and #ifdef'd
+ */
+
+#include "services_headers.h"
+#include "hash.h"
+#include "ra.h"
+#include "buffer_manager.h"
+#include "osfunc.h"
+
+#if defined(__linux__) && defined(__KERNEL__)
+#include <linux/kernel.h>
+#include "pvr_uaccess.h"
+#include "proc.h"
+#include <linux/sched.h>
+#endif
+
+#ifdef USE_BM_FREESPACE_CHECK
+#include <stdio.h>
+#endif
+
+/* The initial, and minimum size of the live address -> boundary tag
+ structure hash table. The value 64 is a fairly arbitrary
+ choice. The hash table resizes on demand so the value choosen is
+ not critical. */
+#define MINIMUM_HASH_SIZE (64)
+
+#if defined(VALIDATE_ARENA_TEST)
+
+/* This test validates the doubly linked ordered list of boundary tags, by
+checking that adjacent members of the list have compatible eResourceSpan
+and eResourceType values. */
+
+typedef enum RESOURCE_DESCRIPTOR_TAG {
+
+ RESOURCE_SPAN_LIVE = 10,
+ RESOURCE_SPAN_FREE,
+ IMPORTED_RESOURCE_SPAN_START,
+ IMPORTED_RESOURCE_SPAN_LIVE,
+ IMPORTED_RESOURCE_SPAN_FREE,
+ IMPORTED_RESOURCE_SPAN_END,
+
+} RESOURCE_DESCRIPTOR;
+
+typedef enum RESOURCE_TYPE_TAG {
+
+ IMPORTED_RESOURCE_TYPE = 20,
+ NON_IMPORTED_RESOURCE_TYPE
+
+} RESOURCE_TYPE;
+
+
+static IMG_UINT32 ui32BoundaryTagID = 0;
+
+IMG_UINT32 ValidateArena(RA_ARENA *pArena);
+#endif
+
+/* boundary tags, used to describe a resource segment */
+struct _BT_
+{
+ enum bt_type
+ {
+ btt_span, /* span markers */
+ btt_free, /* free resource segment */
+ btt_live /* allocated resource segment */
+ } type;
+
+ /* The base resource and extent of this segment */
+ IMG_UINTPTR_T base;
+ IMG_SIZE_T uSize;
+
+ /* doubly linked ordered list of all segments within the arena */
+ struct _BT_ *pNextSegment;
+ struct _BT_ *pPrevSegment;
+ /* doubly linked un-ordered list of free segments. */
+ struct _BT_ *pNextFree;
+ struct _BT_ *pPrevFree;
+ /* a user reference associated with this span, user references are
+ * currently only provided in the callback mechanism */
+ BM_MAPPING *psMapping;
+
+#if defined(VALIDATE_ARENA_TEST)
+ RESOURCE_DESCRIPTOR eResourceSpan;
+ RESOURCE_TYPE eResourceType;
+
+ /* This variable provides a reference (used in debug messages) to incompatible
+ boundary tags within the doubly linked ordered list. */
+ IMG_UINT32 ui32BoundaryTagID;
+#endif
+
+};
+typedef struct _BT_ BT;
+
+
+/* resource allocation arena */
+struct _RA_ARENA_
+{
+ /* arena name for diagnostics output */
+ IMG_CHAR *name;
+
+ /* allocations within this arena are quantum sized */
+ IMG_SIZE_T uQuantum;
+
+ /* import interface, if provided */
+ IMG_BOOL (*pImportAlloc)(IMG_VOID *,
+ IMG_SIZE_T uSize,
+ IMG_SIZE_T *pActualSize,
+ BM_MAPPING **ppsMapping,
+ IMG_UINT32 uFlags,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_UINTPTR_T *pBase);
+ IMG_VOID (*pImportFree) (IMG_VOID *,
+ IMG_UINTPTR_T,
+ BM_MAPPING *psMapping);
+ IMG_VOID (*pBackingStoreFree) (IMG_VOID *, IMG_SIZE_T, IMG_SIZE_T, IMG_HANDLE);
+
+ /* arbitrary handle provided by arena owner to be passed into the
+ * import alloc and free hooks */
+ IMG_VOID *pImportHandle;
+
+ /* head of list of free boundary tags for indexed by pvr_log2 of the
+ boundary tag size */
+#define FREE_TABLE_LIMIT 32
+
+ /* power-of-two table of free lists */
+ BT *aHeadFree [FREE_TABLE_LIMIT];
+
+ /* resource ordered segment list */
+ BT *pHeadSegment;
+ BT *pTailSegment;
+
+ /* segment address to boundary tag hash table */
+ HASH_TABLE *pSegmentHash;
+
+#ifdef RA_STATS
+ RA_STATISTICS sStatistics;
+#endif
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_PVR_PROC_FS)
+#define PROC_NAME_SIZE 64
+
+ struct proc_dir_entry* pProcInfo;
+ struct proc_dir_entry* pProcSegs;
+
+ IMG_BOOL bInitProcEntry;
+
+#if defined(CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG)
+ struct proc_dir_entry* pProcAllocFailThreshold;
+
+ IMG_BOOL bFailAllocationOnce;
+ IMG_BOOL bFailAllocationPersist;
+ IMG_SIZE_T uAllocFailThreshold;
+ IMG_UINT32 uAllocFailMask;
+#endif //defined(CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG)
+
+#endif
+};
+/* #define ENABLE_RA_DUMP 1 */
+#if defined(ENABLE_RA_DUMP)
+IMG_VOID RA_Dump (RA_ARENA *pArena);
+#endif
+
+static INLINE IMG_BOOL RA_TestAllocationFail(RA_ARENA *pArena, IMG_SIZE_T size, IMG_UINT32 buff_type)
+{
+ #if defined (CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG)
+ if(pArena->bFailAllocationOnce == IMG_TRUE)
+ {
+ if((size > pArena->uAllocFailThreshold) && (pArena->uAllocFailMask & buff_type))
+ {
+ if(pArena->bFailAllocationPersist == IMG_FALSE)
+ pArena->bFailAllocationOnce = IMG_FALSE;
+ return IMG_TRUE;
+ }
+ }
+ #endif //CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG
+ return IMG_FALSE;
+}
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_PVR_PROC_FS)
+
+static void RA_ProcSeqShowInfo(struct seq_file *sfile, void* el);
+static void* RA_ProcSeqOff2ElementInfo(struct seq_file * sfile, loff_t off);
+
+static void RA_ProcSeqShowRegs(struct seq_file *sfile, void* el);
+static void* RA_ProcSeqOff2ElementRegs(struct seq_file * sfile, loff_t off);
+
+#if defined(CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG)
+static int RA_ProcSetAllocFailThreshold(struct file *file, const char __user *buffer, unsigned long count, void *data);
+static void* RA_ProcSeqOff2AllocFailThreshold(struct seq_file * sfile, loff_t off);
+static void RA_ProcSeqShowAllocFailThreshold(struct seq_file *sfile,void* el);
+#endif //defined(CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG)
+
+#endif /* defined(CONFIG_PROC_FS) && defined(DEBUG) */
+
+static PVRSRV_ERROR RA_DumpHeapInfo(RA_ARENA *pArena, IMG_UINT32 ui32DebugLevel);
+
+#ifdef USE_BM_FREESPACE_CHECK
+IMG_VOID CheckBMFreespace(IMG_VOID);
+#endif
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_PVR_PROC_FS)
+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
+
+/*!
+******************************************************************************
+ @Function _RequestAllocFail
+
+ @Description Default callback allocator used if no callback is
+ specified, always fails to allocate further resources to the
+ arena.
+
+ @Input _h - callback handle
+ @Input _uSize - requested allocation size
+ @Output _pActualSize - actual allocation size
+ @Input _pRef - user reference
+ @Input _uflags - allocation flags
+ @Input _pvPrivData - private data
+ @Input _ui32PrivDataLength - private data length
+ @Input _pBase - receives allocated base
+
+ @Return IMG_FALSE, this function always fails to allocate.
+******************************************************************************/
+static IMG_BOOL
+_RequestAllocFail (IMG_VOID *_h,
+ IMG_SIZE_T _uSize,
+ IMG_SIZE_T *_pActualSize,
+ BM_MAPPING **_ppsMapping,
+ IMG_UINT32 _uFlags,
+ IMG_PVOID _pvPrivData,
+ IMG_UINT32 _ui32PrivDataLength,
+ 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);
+ PVR_UNREFERENCED_PARAMETER (_pvPrivData);
+ PVR_UNREFERENCED_PARAMETER (_ui32PrivDataLength);
+
+ return IMG_FALSE;
+}
+
+/*!
+******************************************************************************
+ @Function pvr_log2
+
+ @Description Computes the floor of the log base 2 of a unsigned integer
+
+ @Input n - unsigned integer
+
+ @Return Floor(Log2(n))
+******************************************************************************/
+static IMG_UINT32
+pvr_log2 (IMG_SIZE_T n)
+{
+ IMG_UINT32 l = 0;
+ n>>=1;
+ while (n>0)
+ {
+ n>>=1;
+ l++;
+ }
+ return l;
+}
+
+/*!
+******************************************************************************
+ @Function _SegmentListInsertAfter
+
+ @Description Insert a boundary tag into an arena segment list after a
+ specified boundary tag.
+
+ @Input pArena - the arena.
+ @Input pInsertionPoint - the insertion point.
+ @Input pBT - the boundary tag to insert.
+
+ @Return PVRSRV_ERROR
+******************************************************************************/
+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;
+}
+
+/*!
+******************************************************************************
+ @Function _SegmentListInsert
+
+ @Description Insert a boundary tag into an arena segment list at the
+ appropriate point.
+
+ @Input pArena - the arena.
+ @Input pBT - the boundary tag to insert.
+
+ @Return None
+******************************************************************************/
+static PVRSRV_ERROR
+_SegmentListInsert (RA_ARENA *pArena, BT *pBT)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ /* insert into the segment chain */
+ 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)
+ {
+ /* The base address of pBT is less than the base address of the boundary tag
+ at the head of the list - so insert this boundary tag at the head. */
+ pBT->pNextSegment = pArena->pHeadSegment;
+ pArena->pHeadSegment->pPrevSegment = pBT;
+ pArena->pHeadSegment = pBT;
+ pBT->pPrevSegment = IMG_NULL;
+ }
+ else
+ {
+
+ /* The base address of pBT is greater than or equal to that of the boundary tag
+ at the head of the list. Search for the insertion point: pBT must be inserted
+ before the first boundary tag with a greater base value - or at the end of the list.
+ */
+ 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;
+}
+
+/*!
+******************************************************************************
+ @Function _SegmentListRemove
+
+ @Description Remove a boundary tag from an arena segment list.
+
+ @Input pArena - the arena.
+ @Input pBT - the boundary tag to remove.
+
+ @Return None
+******************************************************************************/
+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;
+}
+
+/*!
+******************************************************************************
+ @Function _SegmentSplit
+
+ @Description Split a segment into two, maintain the arena segment list. The
+ boundary tag should not be in the free table. Neither the
+ original or the new neighbour bounary tag will be in the free
+ table.
+
+ @Input pArena - the arena.
+ @Input pBT - the boundary tag to split.
+ @Input uSize - the required segment size of boundary tag after
+ splitting.
+
+ @Return New neighbour boundary tag.
+
+******************************************************************************/
+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,
+ "Boundary Tag") != PVRSRV_OK)
+ {
+ return IMG_NULL;
+ }
+
+ OSMemSet(pNeighbour, 0, sizeof(BT));
+
+#if defined(VALIDATE_ARENA_TEST)
+ pNeighbour->ui32BoundaryTagID = ++ui32BoundaryTagID;
+#endif
+
+ 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;
+
+#if defined(VALIDATE_ARENA_TEST)
+ if (pNeighbour->pPrevSegment->eResourceType == IMPORTED_RESOURCE_TYPE)
+ {
+ pNeighbour->eResourceType = IMPORTED_RESOURCE_TYPE;
+ pNeighbour->eResourceSpan = IMPORTED_RESOURCE_SPAN_FREE;
+ }
+ else if (pNeighbour->pPrevSegment->eResourceType == NON_IMPORTED_RESOURCE_TYPE)
+ {
+ pNeighbour->eResourceType = NON_IMPORTED_RESOURCE_TYPE;
+ pNeighbour->eResourceSpan = RESOURCE_SPAN_FREE;
+ }
+ else
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"_SegmentSplit: pNeighbour->pPrevSegment->eResourceType unrecognized"));
+ PVR_DBG_BREAK;
+ }
+#endif
+
+ return pNeighbour;
+}
+
+/*!
+******************************************************************************
+ @Function _FreeListInsert
+
+ @Description Insert a boundary tag into an arena free table.
+
+ @Input pArena - the arena.
+ @Input pBT - the boundary tag.
+
+ @Return None
+
+******************************************************************************/
+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;
+}
+
+/*!
+******************************************************************************
+ @Function _FreeListRemove
+
+ @Description Remove a boundary tag from an arena free table.
+
+ @Input pArena - the arena.
+ @Input pBT - the boundary tag.
+
+ @Return None
+
+******************************************************************************/
+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;
+}
+
+/*!
+******************************************************************************
+ @Function _BuildSpanMarker
+
+ @Description Construct a span marker boundary tag.
+
+ @Input pArena - arena to contain span marker
+ @Input base - the base of the bounary tag.
+
+ @Return span marker boundary tag
+
+******************************************************************************/
+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,
+ "Boundary Tag") != PVRSRV_OK)
+ {
+ return IMG_NULL;
+ }
+
+ OSMemSet(pBT, 0, sizeof(BT));
+
+#if defined(VALIDATE_ARENA_TEST)
+ pBT->ui32BoundaryTagID = ++ui32BoundaryTagID;
+#endif
+
+ pBT->type = btt_span;
+ pBT->base = base;
+ pBT->uSize = uSize;
+ pBT->psMapping = IMG_NULL;
+
+ return pBT;
+}
+
+/*!
+******************************************************************************
+ @Function _BuildBT
+
+ @Description Construct a boundary tag for a free segment.
+
+ @Input base - the base of the resource segment.
+ @Input uSize - the extent of the resouce segment.
+
+ @Return boundary tag
+
+******************************************************************************/
+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,
+ "Boundary Tag") != PVRSRV_OK)
+ {
+ return IMG_NULL;
+ }
+
+ OSMemSet(pBT, 0, sizeof(BT));
+
+#if defined(VALIDATE_ARENA_TEST)
+ pBT->ui32BoundaryTagID = ++ui32BoundaryTagID;
+#endif
+
+ pBT->type = btt_free;
+ pBT->base = base;
+ pBT->uSize = uSize;
+
+ return pBT;
+}
+
+/*!
+******************************************************************************
+ @Function _InsertResource
+
+ @Description Add a free resource segment to an arena.
+
+ @Input pArena - the arena.
+ @Input base - the base of the resource segment.
+ @Input uSize - the extent of the resource segment.
+
+ @Return New bucket pointer
+ IMG_NULL failure
+
+******************************************************************************/
+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 defined(VALIDATE_ARENA_TEST)
+ pBT->eResourceSpan = RESOURCE_SPAN_FREE;
+ pBT->eResourceType = NON_IMPORTED_RESOURCE_TYPE;
+#endif
+
+ 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;
+}
+
+/*!
+******************************************************************************
+ @Function _InsertResourceSpan
+
+ @Description Add a free resource span to an arena, complete with span markers.
+
+ @Input pArena - the arena.
+ @Input base - the base of the resource segment.
+ @Input uSize - the extent of the resource segment.
+
+ @Return the boundary tag representing the free resource segment,
+ or IMG_NULL on failure.
+******************************************************************************/
+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;
+ }
+
+#if defined(VALIDATE_ARENA_TEST)
+ pSpanStart->eResourceSpan = IMPORTED_RESOURCE_SPAN_START;
+ pSpanStart->eResourceType = IMPORTED_RESOURCE_TYPE;
+#endif
+
+ pSpanEnd = _BuildSpanMarker (base + uSize, 0);
+ if (pSpanEnd == IMG_NULL)
+ {
+ goto fail_end;
+ }
+
+#if defined(VALIDATE_ARENA_TEST)
+ pSpanEnd->eResourceSpan = IMPORTED_RESOURCE_SPAN_END;
+ pSpanEnd->eResourceType = IMPORTED_RESOURCE_TYPE;
+#endif
+
+ pBT = _BuildBT (base, uSize);
+ if (pBT == IMG_NULL)
+ {
+ goto fail_bt;
+ }
+
+#if defined(VALIDATE_ARENA_TEST)
+ pBT->eResourceSpan = IMPORTED_RESOURCE_SPAN_FREE;
+ pBT->eResourceType = IMPORTED_RESOURCE_TYPE;
+#endif
+
+ 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;
+/* pArena->sStatistics.uFreeResourceCount+=uSize;
+ This has got to be wrong as uFreeResourceCount ends
+ up larger than uTotalResourceCount by uTotalResourceCount
+ - allocated memory
+*/
+#endif
+ return pBT;
+
+ fail_SegListInsert:
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL);
+ /*not nulling pointer, out of scope*/
+ fail_bt:
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pSpanEnd, IMG_NULL);
+ /*not nulling pointer, out of scope*/
+ fail_end:
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pSpanStart, IMG_NULL);
+ /*not nulling pointer, out of scope*/
+ fail_start:
+ return IMG_NULL;
+}
+
+/*!
+******************************************************************************
+ @Function _FreeBT
+
+ @Description Free a boundary tag taking care of the segment list and the
+ boundary tag free table.
+
+ @Input pArena - the arena.
+ @Input pBT - the boundary tag to free.
+ @Input bFreeBackingStore - Should backing for the memory be freed
+ as well.
+ @Return None
+******************************************************************************/
+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;
+
+ /* try and coalesce with left neighbour */
+ 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);
+ /*not nulling original pointer, already overwritten*/
+#ifdef RA_STATS
+ pArena->sStatistics.uFreeSegmentCount--;
+#endif
+ }
+
+ /* try to coalesce with right neighbour */
+ 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);
+ /*not nulling original pointer, already overwritten*/
+#ifdef RA_STATS
+ pArena->sStatistics.uFreeSegmentCount--;
+#endif
+ }
+
+ /* try to free backing store memory. */
+ if (pArena->pBackingStoreFree != IMG_NULL && bFreeBackingStore)
+ {
+ IMG_UINTPTR_T uRoundedStart, uRoundedEnd;
+
+ /* Work out the first address we might be able to free. */
+ uRoundedStart = (uOrigBase / pArena->uQuantum) * pArena->uQuantum;
+ /* If a span is still using that address then leave it. */
+ if (uRoundedStart < pBT->base)
+ {
+ uRoundedStart += pArena->uQuantum;
+ }
+
+ /* Work out the last address we might be able to free. */
+ uRoundedEnd = ((uOrigBase + uOrigSize + pArena->uQuantum - 1) / pArena->uQuantum) * pArena->uQuantum;
+ /* If a span is still using that addres then leave it. */
+ if (uRoundedEnd > (pBT->base + pBT->uSize))
+ {
+ uRoundedEnd -= pArena->uQuantum;
+ }
+
+ if (uRoundedStart < uRoundedEnd)
+ {
+ pArena->pBackingStoreFree(pArena->pImportHandle, (IMG_SIZE_T)uRoundedStart, (IMG_SIZE_T)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);
+ /*not nulling original pointer, already overwritten*/
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), prev, IMG_NULL);
+ /*not nulling original pointer, already overwritten*/
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL);
+ /*not nulling pointer, copy on stack*/
+ }
+ else
+ _FreeListInsert (pArena, pBT);
+}
+
+
+/*!
+******************************************************************************
+ @Function _AttemptAllocAligned
+
+ @Description Attempt an allocation from an arena.
+
+ @Input pArena - the arena.
+ @Input uSize - the requested allocation size.
+ @Output ppsMapping - the user references associated with
+ the allocated segment.
+ @Input flags - allocation flags
+ @Input uAlignment - required uAlignment, or 0
+ @Input uAlignmentOffset
+ @Output base - allocated resource base
+
+ @Return IMG_FALSE failure
+ IMG_TRUE success
+******************************************************************************/
+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;
+
+ /* search for a near fit free boundary tag, start looking at the
+ pvr_log2 free table for our required size and work on up the
+ table. */
+ uIndex = pvr_log2 (uSize);
+
+ while (uIndex < FREE_TABLE_LIMIT && pArena->aHeadFree[uIndex]==IMG_NULL)
+ uIndex++;
+
+ while (uIndex < FREE_TABLE_LIMIT)
+ {
+ if (pArena->aHeadFree[uIndex]!=IMG_NULL)
+ {
+ /* we have a cached free boundary tag */
+ 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
+
+ /* with uAlignment we might need to discard the front of this segment */
+ if (aligned_base > pBT->base)
+ {
+ BT *pNeighbour;
+ pNeighbour = _SegmentSplit (pArena, pBT, (IMG_SIZE_T)(aligned_base - pBT->base));
+ /* partition the buffer, create a new boundary tag */
+ if (pNeighbour==IMG_NULL)
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: Front split failed"));
+ /* Put pBT back in the list */
+ _FreeListInsert (pArena, pBT);
+ return IMG_FALSE;
+ }
+
+ _FreeListInsert (pArena, pBT);
+ #ifdef RA_STATS
+ pArena->sStatistics.uFreeSegmentCount++;
+ pArena->sStatistics.uFreeResourceCount+=pBT->uSize;
+ #endif
+ pBT = pNeighbour;
+ }
+
+ /* the segment might be too big, if so, discard the back of the segment */
+ if (pBT->uSize > uSize)
+ {
+ BT *pNeighbour;
+ pNeighbour = _SegmentSplit (pArena, pBT, uSize);
+ /* partition the buffer, create a new boundary tag */
+ if (pNeighbour==IMG_NULL)
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: Back split failed"));
+ /* Put pBT back in the list */
+ _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 defined(VALIDATE_ARENA_TEST)
+ if (pBT->eResourceType == IMPORTED_RESOURCE_TYPE)
+ {
+ pBT->eResourceSpan = IMPORTED_RESOURCE_SPAN_LIVE;
+ }
+ else if (pBT->eResourceType == NON_IMPORTED_RESOURCE_TYPE)
+ {
+ pBT->eResourceSpan = RESOURCE_SPAN_LIVE;
+ }
+ else
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned ERROR: pBT->eResourceType unrecognized"));
+ PVR_DBG_BREAK;
+ }
+#endif
+ 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;
+}
+
+
+
+/*!
+******************************************************************************
+ @Function RA_Create
+
+ @Description To create a resource arena.
+
+ @Input name - the name of the arena for diagnostic purposes.
+ @Input base - the base of an initial resource span or 0.
+ @Input uSize - the size of an initial resource span or 0.
+ @Input uQuantum - the arena allocation quantum.
+ @Input alloc - a resource allocation callback or 0.
+ @Input free - a resource de-allocation callback or 0.
+ @Input backingstore_free - a callback to free resources for spans or 0.
+ @Input pImportHandle - handle passed to alloc and free or 0.
+
+ @Return arena handle, or IMG_NULL.
+******************************************************************************/
+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_PVOID pvPrivData, IMG_UINT32 ui32PrivDataLength,
+ IMG_UINTPTR_T *pBase),
+ IMG_VOID (*imp_free) (IMG_VOID *, IMG_UINTPTR_T, BM_MAPPING *),
+ IMG_VOID (*backingstore_free) (IMG_VOID*, IMG_SIZE_T, IMG_SIZE_T, 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, (IMG_UINTPTR_T)imp_alloc, (IMG_UINTPTR_T)imp_free));
+
+
+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof (*pArena),
+ (IMG_VOID **)&pArena, IMG_NULL,
+ "Resource Arena") != 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
+ OSMemSet(&pArena->sStatistics, 0x00, sizeof(pArena->sStatistics));
+#endif
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_PVR_PROC_FS)
+ if(strcmp(pArena->name,"") != 0)
+ {
+ IMG_INT ret;
+ IMG_CHAR szProcInfoName[PROC_NAME_SIZE];
+ IMG_CHAR szProcSegsName[PROC_NAME_SIZE];
+ struct proc_dir_entry* (*pfnCreateProcEntrySeq)(const IMG_CHAR *,
+ IMG_VOID*,
+ pvr_next_proc_seq_t,
+ pvr_show_proc_seq_t,
+ pvr_off2element_proc_seq_t,
+ pvr_startstop_proc_seq_t,
+ write_proc_t);
+
+ pArena->bInitProcEntry = !PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL);
+
+ /* Don't put shared heap info into a per process /proc subdirectory */
+ pfnCreateProcEntrySeq = pArena->bInitProcEntry ? CreateProcEntrySeq : CreatePerProcessProcEntrySeq;
+
+ ret = snprintf(szProcInfoName, sizeof(szProcInfoName), "ra_info_%s", pArena->name);
+ if (ret > 0 && ret < sizeof(szProcInfoName))
+ {
+ pArena->pProcInfo = pfnCreateProcEntrySeq(ReplaceSpaces(szProcInfoName), pArena, NULL,
+ RA_ProcSeqShowInfo, RA_ProcSeqOff2ElementInfo, NULL, NULL);
+ }
+ else
+ {
+ pArena->pProcInfo = 0;
+ PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_info proc entry for arena %s", pArena->name));
+ }
+
+ ret = snprintf(szProcSegsName, sizeof(szProcSegsName), "ra_segs_%s", pArena->name);
+ if (ret > 0 && ret < sizeof(szProcSegsName))
+ {
+ pArena->pProcSegs = pfnCreateProcEntrySeq(ReplaceSpaces(szProcSegsName), pArena, NULL,
+ RA_ProcSeqShowRegs, RA_ProcSeqOff2ElementRegs, NULL, NULL);
+ }
+ else
+ {
+ pArena->pProcSegs = 0;
+ PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_segs proc entry for arena %s", pArena->name));
+ }
+
+#if defined(CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG)
+ pArena->uAllocFailThreshold = ~0;
+ pArena->uAllocFailMask = ~0;
+ pArena->bFailAllocationOnce = IMG_FALSE;
+ pArena->bFailAllocationPersist = IMG_FALSE;
+
+ ret = snprintf(szProcSegsName, sizeof(szProcSegsName), "ra_fail_alloc_thld_%s", pArena->name);
+ if (ret > 0 && ret < sizeof(szProcSegsName))
+ {
+ pArena->pProcAllocFailThreshold = pfnCreateProcEntrySeq(ReplaceSpaces(szProcSegsName), pArena, NULL,
+ RA_ProcSeqShowAllocFailThreshold, RA_ProcSeqOff2AllocFailThreshold, NULL, RA_ProcSetAllocFailThreshold);
+ }
+ else
+ {
+ pArena->pProcAllocFailThreshold = 0;
+ PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_fail_alloc_thld proc entry for arena %s", pArena->name));
+ }
+#endif //defined(CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG)
+ }
+#endif /* defined(CONFIG_PROC_FS) && defined(CONFIG_PVR_PROC_FS) */
+
+ 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);
+ /*not nulling pointer, out of scope*/
+arena_fail:
+ return IMG_NULL;
+}
+
+/*!
+******************************************************************************
+ @Function RA_Delete
+
+ @Description To delete a resource arena. All resources allocated from
+ the arena must be freed before deleting the arena.
+
+ @Input pArena - the arena to delete.
+
+ @Return None
+******************************************************************************/
+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;
+
+ if (pBT->type != btt_free)
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: allocations still exist in the arena that is being destroyed"));
+ PVR_DPF ((PVR_DBG_ERROR,"Likely Cause: client drivers not freeing allocations before destroying devmemcontext"));
+ PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: base = 0x%x size=0x%x", pBT->base, pBT->uSize));
+ }
+
+ _SegmentListRemove (pArena, pBT);
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL);
+ /*not nulling original pointer, it has changed*/
+#ifdef RA_STATS
+ pArena->sStatistics.uSpanCount--;
+#endif
+ }
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_PVR_PROC_FS)
+ {
+ IMG_VOID (*pfnRemoveProcEntrySeq)(struct proc_dir_entry*);
+
+ pfnRemoveProcEntrySeq = pArena->bInitProcEntry ? RemoveProcEntrySeq : RemovePerProcessProcEntrySeq;
+
+ if (pArena->pProcInfo != 0)
+ {
+ pfnRemoveProcEntrySeq( pArena->pProcInfo );
+ }
+
+ if (pArena->pProcSegs != 0)
+ {
+ pfnRemoveProcEntrySeq( pArena->pProcSegs );
+ }
+
+#if defined(CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG)
+ if(pArena->pProcAllocFailThreshold != 0)
+ {
+ pfnRemoveProcEntrySeq( pArena->pProcAllocFailThreshold );
+ }
+#endif //defined(CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG)
+ }
+#endif
+ HASH_Delete (pArena->pSegmentHash);
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RA_ARENA), pArena, IMG_NULL);
+ /*not nulling pointer, copy on stack*/
+}
+
+/*!
+******************************************************************************
+ @Function RA_TestDelete
+
+ @Description To test whether it is safe to delete a resource arena. If any
+ allocations have not been freed, the RA must not be deleted.
+
+ @Input pArena - the arena to test.
+
+ @Return IMG_BOOL - IMG_TRUE if is safe to go on and call RA_Delete.
+******************************************************************************/
+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)
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"RA_TestDelete: detected resource leak!"));
+ PVR_DPF ((PVR_DBG_ERROR,"RA_TestDelete: base = 0x%x size=0x%x", pBT->base, pBT->uSize));
+ return IMG_FALSE;
+ }
+ }
+ }
+
+ return IMG_TRUE;
+}
+
+/*!
+******************************************************************************
+ @Function RA_Add
+
+ @Description To add a resource span to an arena. The span must not
+ overlapp with any span previously added to the arena.
+
+ @Input pArena - the arena to add a span into.
+ @Input base - the base of the span.
+ @Input uSize - the extent of the span.
+
+ @Return IMG_TRUE - Success
+ IMG_FALSE - failure
+******************************************************************************/
+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));
+}
+
+/*!
+******************************************************************************
+ @Function RA_Alloc
+
+ @Description To allocate resource from an arena.
+
+ @Input pArena - the arena
+ @Input uRequestSize - the size of resource segment requested.
+ @Output pActualSize - the actual size of resource segment
+ allocated, typcially rounded up by quantum.
+ @Output ppsMapping - the user reference associated with allocated resource span.
+ @Input uFlags - flags influencing allocation policy.
+ @Input uAlignment - the uAlignment constraint required for the
+ allocated segment, use 0 if uAlignment not required.
+ @Input uAlignmentOffset
+ @Input pvPrivData - opaque private data passed through to allocator
+ @Input ui32PrivDataLength - length of opaque private data
+
+ @Output base - allocated base resource
+
+ @Return IMG_TRUE - success
+ IMG_FALSE - failure
+******************************************************************************/
+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_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_UINTPTR_T *base)
+{
+ IMG_BOOL bResult = IMG_FALSE;
+ IMG_BOOL bTestAllocFail = IMG_FALSE;
+ 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;
+ }
+
+#if defined(VALIDATE_ARENA_TEST)
+ ValidateArena(pArena);
+#endif
+
+#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));
+
+ bTestAllocFail = RA_TestAllocationFail(pArena, uSize, ~0);
+ if(!bTestAllocFail)
+ {
+ /* if allocation failed then we might have an import source which
+ can provide more resource, else we will have to fail the
+ allocation to the caller. */
+ bResult = _AttemptAllocAligned (pArena, uSize, ppsMapping, uFlags,
+ uAlignment, uAlignmentOffset, base);
+ if (!bResult)
+ {
+ BM_MAPPING *psImportMapping;
+ IMG_UINTPTR_T import_base;
+ IMG_SIZE_T uImportSize = uSize;
+
+ /*
+ Ensure that we allocate sufficient space to meet the uAlignment
+ constraint
+ */
+ if (uAlignment > pArena->uQuantum)
+ {
+ uImportSize += (uAlignment - 1);
+ }
+
+ /* ensure that we import according to the quanta of this arena */
+ uImportSize = ((uImportSize + pArena->uQuantum - 1)/pArena->uQuantum)*pArena->uQuantum;
+
+ bResult =
+ pArena->pImportAlloc (pArena->pImportHandle, uImportSize, &uImportSize,
+ &psImportMapping, uFlags,
+ pvPrivData, ui32PrivDataLength, &import_base);
+ if (bResult)
+ {
+ BT *pBT;
+ pBT = _InsertResourceSpan (pArena, import_base, uImportSize);
+ /* successfully import more resource, create a span to
+ represent it and retry the allocation attempt */
+ if (pBT == IMG_NULL)
+ {
+ /* insufficient resources to insert the newly acquired span,
+ so free it back again */
+ pArena->pImportFree(pArena->pImportHandle, import_base,
+ psImportMapping);
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "RA_Alloc: name='%s', size=0x%x failed!",
+ pArena->name, uSize));
+ /* RA_Dump (arena); */
+ 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_ERROR,
+ "RA_Alloc: name='%s' uAlignment failed!",
+ pArena->name));
+ }
+ }
+ }
+ #ifdef RA_STATS
+ if (bResult)
+ pArena->sStatistics.uCumulativeAllocs++;
+ #endif
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "RA_Alloc: arena=%s, size=0x%x(0x%x), alignment=0x%x, "\
+ "offset=0x%x, result=%d",
+ pArena->name,
+ uSize, uRequestSize, uAlignment, uAlignmentOffset,
+ bResult));
+
+ /* RA_Dump (pArena);
+ ra_stats (pArena);
+ */
+
+ if (!bResult) {
+ PVR_LOG(("RA_Alloc %s %s: arena=%s, size=0x%x(0x%x), "\
+ "alignment=0x%x, offset=0x%x",
+ (bResult ? "SUCCESS" : "FAILED"),
+ (bTestAllocFail ? "in TEST_MODE!" : " "),
+ pArena->name,
+ uSize, uRequestSize, uAlignment, uAlignmentOffset));
+ RA_DumpHeapInfo(pArena, ~0);
+ }
+#if defined(VALIDATE_ARENA_TEST)
+ ValidateArena(pArena);
+#endif
+
+ return bResult;
+}
+
+
+#if defined(VALIDATE_ARENA_TEST)
+
+/*!
+******************************************************************************
+ @Function ValidateArena
+
+ @Description Validate an arena by checking that adjacent members of the
+ double linked ordered list are compatible. PVR_DBG_BREAK and
+ PVR_DPF messages are used when an error is detected.
+ NOTE: A DEBUG build is required for PVR_DBG_BREAK and PVR_DPF
+ to operate.
+
+ @Input pArena - the arena
+
+ @Return 0
+******************************************************************************/
+IMG_UINT32 ValidateArena(RA_ARENA *pArena)
+{
+ BT* pSegment;
+ RESOURCE_DESCRIPTOR eNextSpan;
+
+ pSegment = pArena->pHeadSegment;
+
+ if (pSegment == IMG_NULL)
+ {
+ return 0;
+ }
+
+ if (pSegment->eResourceType == IMPORTED_RESOURCE_TYPE)
+ {
+ PVR_ASSERT(pSegment->eResourceSpan == IMPORTED_RESOURCE_SPAN_START);
+
+ while (pSegment->pNextSegment)
+ {
+ eNextSpan = pSegment->pNextSegment->eResourceSpan;
+
+ switch (pSegment->eResourceSpan)
+ {
+ case IMPORTED_RESOURCE_SPAN_LIVE:
+
+ if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) ||
+ (eNextSpan == IMPORTED_RESOURCE_SPAN_FREE) ||
+ (eNextSpan == IMPORTED_RESOURCE_SPAN_END)))
+ {
+ /* error - next span must be live, free or end */
+ PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+ pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+ PVR_DBG_BREAK;
+ }
+ break;
+
+ case IMPORTED_RESOURCE_SPAN_FREE:
+
+ if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) ||
+ (eNextSpan == IMPORTED_RESOURCE_SPAN_END)))
+ {
+ /* error - next span must be live or end */
+ PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+ pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+ PVR_DBG_BREAK;
+ }
+ break;
+
+ case IMPORTED_RESOURCE_SPAN_END:
+
+ if ((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) ||
+ (eNextSpan == IMPORTED_RESOURCE_SPAN_FREE) ||
+ (eNextSpan == IMPORTED_RESOURCE_SPAN_END))
+ {
+ /* error - next span cannot be live, free or end */
+ PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+ pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+ PVR_DBG_BREAK;
+ }
+ break;
+
+
+ case IMPORTED_RESOURCE_SPAN_START:
+
+ if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) ||
+ (eNextSpan == IMPORTED_RESOURCE_SPAN_FREE)))
+ {
+ /* error - next span must be live or free */
+ PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+ pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+ PVR_DBG_BREAK;
+ }
+ break;
+
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+ pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+ PVR_DBG_BREAK;
+ break;
+ }
+ pSegment = pSegment->pNextSegment;
+ }
+ }
+ else if (pSegment->eResourceType == NON_IMPORTED_RESOURCE_TYPE)
+ {
+ PVR_ASSERT((pSegment->eResourceSpan == RESOURCE_SPAN_FREE) || (pSegment->eResourceSpan == RESOURCE_SPAN_LIVE));
+
+ while (pSegment->pNextSegment)
+ {
+ eNextSpan = pSegment->pNextSegment->eResourceSpan;
+
+ switch (pSegment->eResourceSpan)
+ {
+ case RESOURCE_SPAN_LIVE:
+
+ if (!((eNextSpan == RESOURCE_SPAN_FREE) ||
+ (eNextSpan == RESOURCE_SPAN_LIVE)))
+ {
+ /* error - next span must be free or live */
+ PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+ pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+ PVR_DBG_BREAK;
+ }
+ break;
+
+ case RESOURCE_SPAN_FREE:
+
+ if (!((eNextSpan == RESOURCE_SPAN_FREE) ||
+ (eNextSpan == RESOURCE_SPAN_LIVE)))
+ {
+ /* error - next span must be free or live */
+ PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+ pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+ PVR_DBG_BREAK;
+ }
+ break;
+
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)",
+ pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name));
+
+ PVR_DBG_BREAK;
+ break;
+ }
+ pSegment = pSegment->pNextSegment;
+ }
+
+ }
+ else
+ {
+ PVR_DPF ((PVR_DBG_ERROR,"ValidateArena ERROR: pSegment->eResourceType unrecognized"));
+
+ PVR_DBG_BREAK;
+ }
+
+ return 0;
+}
+
+#endif
+
+
+/*!
+******************************************************************************
+ @Function RA_Free
+
+ @Description To free a resource segment.
+
+ @Input pArena - the arena the segment was originally allocated from.
+ @Input base - the base of the resource span to free.
+ @Input bFreeBackingStore - Should backing store memory be freed.
+
+ @Return None
+******************************************************************************/
+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);
+ }
+}
+
+
+/*!
+******************************************************************************
+ @Function RA_GetNextLiveSegment
+
+ @Description Returns details of the next live resource segments
+
+ @Input pArena - the arena the segment was originally allocated from.
+ @InOut psSegDetails - rtn details of segments
+
+ @Return IMG_TRUE if operation succeeded
+******************************************************************************/
+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;
+ }
+ /* walk the arena segments and write live one to the buffer */
+ 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)IMG_UNDEF;
+
+ 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(CONFIG_PVR_PROC_FS)) || 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 /*defined(CONFIG_PROC_FS) && defined(DEBUG)*/
+
+#if defined(ENABLE_RA_DUMP)
+/*!
+******************************************************************************
+ @Function RA_Dump
+
+ @Description To dump a readable description of an arena. Diagnostic only.
+
+ @Input pArena - the arena to dump.
+
+ @Return None
+******************************************************************************/
+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",
+ (IMG_UINT32) pBT->base, pBT->uSize, _BTType (pBT->type)));
+ }
+
+#ifdef HASH_TRACE
+ HASH_Dump (pArena->pSegmentHash);
+#endif
+}
+#endif /* #if defined(ENABLE_RA_DUMP) */
+
+static PVRSRV_ERROR RA_DumpHeapInfo(RA_ARENA *pArena, IMG_UINT32 ui32DebugLevel)
+{
+ BT *pBT;
+
+ {
+ IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
+ IMG_CHAR dirname_buffer[256];
+ IMG_CHAR dirname[256];
+ const IMG_CHAR *proc_basename = dirname_buffer;
+ dirname_buffer[255] = dirname[255] = '\0';
+
+ OSGetProcCmdline(ui32PID, dirname_buffer, sizeof(dirname_buffer));
+ PVR_LOG(("\nCommand Line of the current process with ID %u is %s", ui32PID, dirname_buffer));
+
+ proc_basename = OSGetPathBaseName(dirname_buffer, sizeof(dirname_buffer));
+ PVR_LOG(("Base Name of the current process with ID %u is %s", ui32PID, proc_basename));
+
+ }
+
+ PVR_LOG(("Arena '%s':", pArena->name));
+
+ PVR_LOG(( " allocCB=%p freeCB=%p handle=%p quantum=%d",
+ pArena->pImportAlloc,
+ pArena->pImportFree,
+ pArena->pImportHandle,
+ pArena->uQuantum));
+
+ PVR_LOG(( "span count\t\t%u", pArena->sStatistics.uSpanCount));
+
+ PVR_LOG(( "live segment count\t%u", pArena->sStatistics.uLiveSegmentCount));
+
+ PVR_LOG(( "free segment count\t%u", pArena->sStatistics.uFreeSegmentCount));
+
+ PVR_LOG(( "free resource count\t%u (0x%x)",
+ pArena->sStatistics.uFreeResourceCount,
+ (IMG_UINT)pArena->sStatistics.uFreeResourceCount));
+
+ PVR_LOG(( "total allocs\t\t%u", pArena->sStatistics.uCumulativeAllocs));
+
+ PVR_LOG(( "total failed allocs\t%u", pArena->sStatistics.uFailedAllocCount));
+
+ PVR_LOG(( "total frees\t\t%u", pArena->sStatistics.uCumulativeFrees));
+
+ PVR_LOG(( "import count\t\t%u", pArena->sStatistics.uImportCount));
+
+ PVR_LOG(( "export count\t\t%u", pArena->sStatistics.uExportCount));
+
+ PVR_LOG(( " segment Chain:"));
+
+ if (pArena->pHeadSegment != IMG_NULL &&
+ pArena->pHeadSegment->pPrevSegment != IMG_NULL)
+ {
+ PVR_LOG(( " error: head boundary tag has invalid pPrevSegment"));
+ }
+
+ if (pArena->pTailSegment != IMG_NULL &&
+ pArena->pTailSegment->pNextSegment != IMG_NULL)
+ {
+ PVR_LOG(( " error: tail boundary tag has invalid pNextSegment"));
+ }
+
+ for (pBT=pArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment)
+ {
+ PVR_LOG(( "%s base=0x%08x size=%08d(0x%08x) type=%s ref=%p",
+ ((pBT->type == btt_span) ? "\t\t" : "\t"),
+ (IMG_UINT32) pBT->base,
+ pBT->uSize, pBT->uSize,
+ _BTType(pBT->type),
+ pBT->psMapping));
+ if(pBT->psMapping)
+ {
+ BM_MAPPING *psImportMapping = pBT->psMapping;
+ PVR_LOG(( "\t %p: mapping type %s, mapping count=%d, size=%08d(0x%08x), flags=0x%08x, align=0x%04x",
+ psImportMapping,
+ _BMMappingType(psImportMapping->eCpuMemoryOrigin),
+ psImportMapping->ui32MappingCount,
+ psImportMapping->uSize, psImportMapping->uSize,
+ psImportMapping->ui32Flags,
+ psImportMapping->ui32DevVAddrAlignment));
+ }
+ }
+
+ return PVRSRV_OK;
+}
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_PVR_PROC_FS)
+
+#if defined(CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG)
+#define _PROC_SET_ALLOC_TH_BUFFER_SZ 32
+static int RA_ProcSetAllocFailThreshold(struct file *file, const char __user *buffer, unsigned long count, void *data)
+{
+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)data;
+ RA_ARENA *pArena;
+ IMG_CHAR data_buffer[_PROC_SET_ALLOC_TH_BUFFER_SZ];
+ IMG_INT32 value = ~0;
+ IMG_UINT32 mask = ~0;
+ IMG_INT32 format_ret;
+
+ if ((handlers == NULL) || (handlers->data == NULL) || (count > sizeof(data_buffer)))
+ {
+ return -EINVAL;
+ }
+
+ pArena = (RA_ARENA *)handlers->data;
+
+ count = MIN(count, sizeof(data_buffer));
+
+ if (pvr_copy_from_user(data_buffer, buffer, count))
+ return -EINVAL;
+
+ if (data_buffer[count - 1] != '\n')
+ return -EINVAL;
+
+ data_buffer[(sizeof(data_buffer) - 1)] = '\0';
+ if((sizeof(data_buffer) -1) <= count)
+ data_buffer[count] = '\0';
+
+ PVR_LOG(("Buffer from the user is %s\n", data_buffer));
+ format_ret = sscanf(data_buffer, "%i:0x%x", &value, &mask);
+ PVR_LOG(("Value set is %i, type is %x, format %i\n", value, mask, format_ret));
+ if(format_ret <= 0)
+ return -EINVAL;
+
+/*
+ Heap Allocation Buffer Threshold Setting - for testing purposes only
+ Causes allocation of a GFX buffer of type MASK for the respective heap to
+ fail.
+ Format is <threshold value number>:<buffer type mask hex value>
+ for example: 1000:0x01.
+ Value of -1 disables the allocation fail test
+ Value bigger than and eq. to 0 enables the allocation fail test for
+ the first buffer only.
+ Value smaller than -1 enables the buffer allocation failure for this
+ heap until the test disables it.
+*/
+ if(value < 0)
+ {
+ if(value == -1)
+ {
+ pArena->bFailAllocationPersist = pArena->bFailAllocationOnce = IMG_FALSE;
+ }
+ else if(value == -2)
+ {
+ RA_DumpHeapInfo(pArena, ~0);
+ }
+ else
+ {
+ pArena->bFailAllocationPersist = pArena->bFailAllocationOnce = IMG_TRUE;
+ pArena->uAllocFailThreshold = -value;
+ }
+ }
+ else
+ {
+ pArena->bFailAllocationPersist = 0;
+ pArena->bFailAllocationOnce = 1;
+ pArena->uAllocFailThreshold = value;
+ }
+
+ if(format_ret > 1)
+ {
+ if((pArena->bFailAllocationOnce == IMG_TRUE) && (mask == 0))
+ pArena->uAllocFailMask = ~0;
+ else
+ pArena->uAllocFailMask = mask;
+ }
+ PVR_LOG(("*************** User Fail Heap Allocation Settings for %s *******************************\n",
+ pArena->name));
+ PVR_LOG(("Fail Heap Allocation is %s in %s mode\n", (pArena->bFailAllocationOnce ? "Enabled": "Disabled"),
+ (pArena->bFailAllocationPersist ? "Persistent": "One-Shot")));
+ PVR_LOG(("Fail Heap Allocation Buffer Size Threshold is %u with a Mask of 0x%x\n",
+ pArena->uAllocFailThreshold, pArena->uAllocFailMask));
+ PVR_LOG(("*******************************************************************************************\n"));
+ return (count);
+}
+
+static void* RA_ProcSeqOff2AllocFailThreshold(struct seq_file * sfile, loff_t off)
+{
+
+ if(off <= 1)
+ return (void*)(IMG_INT)(off+1);
+
+ return 0;
+}
+
+static void RA_ProcSeqShowAllocFailThreshold(struct seq_file *sfile,void* el)
+{
+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private;
+ RA_ARENA *pArena = (RA_ARENA *)handlers->data;
+ IMG_INT off = (IMG_INT)el;
+
+ switch (off)
+ {
+ case 1:
+ seq_printf(sfile, "Heap Allocation Buffer Threshold Setting - for testing purposes only\n");
+ seq_printf(sfile, "Format is <threshold value number>:<buffer type mask hex value> for example: 1000:0x01\n");
+ seq_printf(sfile, "Value of -1 disables the allocation fail test\n");
+ seq_printf(sfile, "Value of -2 dumps the heap entries to the kernel log\n");
+ seq_printf(sfile, "Value => 0 enables the allocation fail test for the first buffer with the met threshold only\n");
+ seq_printf(sfile, "Value < -2 enables the buffer allocation failure for this heap until the test disables it\n");
+ break;
+ case 2:
+ seq_printf(sfile, "*********** Current Settings: ********************\n");
+ seq_printf(sfile,"Fail Heap Allocation is %s in %s mode\n", (pArena->bFailAllocationOnce ? "Enabled": "Disabled"),
+ (pArena->bFailAllocationPersist ? "Persistent": "One-Shot"));
+ seq_printf(sfile, "Fail Heap Allocation Buffer Size Threshold is %u with a Mask of 0x%x\n",
+ pArena->uAllocFailThreshold, pArena->uAllocFailMask);
+ break;
+ }
+}
+#endif //defined(CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG)
+
+static void RA_ProcSeqShowInfo(struct seq_file *sfile, void* el)
+{
+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private;
+ RA_ARENA *pArena = (RA_ARENA *)handlers->data;
+ IMG_INT off = (IMG_INT)el;
+
+ switch (off)
+ {
+ case 1:
+ seq_printf(sfile, "quantum\t\t\t%u\n", pArena->uQuantum);
+ break;
+ case 2:
+ seq_printf(sfile, "import_handle\t\t%08X\n", (IMG_UINT)pArena->pImportHandle);
+ break;
+#ifdef RA_STATS
+ case 3:
+ seq_printf(sfile,"span count\t\t%u\n", pArena->sStatistics.uSpanCount);
+ break;
+ case 4:
+ seq_printf(sfile, "live segment count\t%u\n", pArena->sStatistics.uLiveSegmentCount);
+ break;
+ case 5:
+ seq_printf(sfile, "free segment count\t%u\n", pArena->sStatistics.uFreeSegmentCount);
+ break;
+ case 6:
+ seq_printf(sfile, "free resource count\t%u (0x%x)\n",
+ pArena->sStatistics.uFreeResourceCount,
+ (IMG_UINT)pArena->sStatistics.uFreeResourceCount);
+ break;
+ case 7:
+ seq_printf(sfile, "total allocs\t\t%u\n", pArena->sStatistics.uCumulativeAllocs);
+ break;
+ case 8:
+ seq_printf(sfile, "total frees\t\t%u\n", pArena->sStatistics.uCumulativeFrees);
+ break;
+ case 9:
+ seq_printf(sfile, "import count\t\t%u\n", pArena->sStatistics.uImportCount);
+ break;
+ case 10:
+ seq_printf(sfile, "export count\t\t%u\n", pArena->sStatistics.uExportCount);
+ break;
+#endif
+ }
+
+}
+
+static void* RA_ProcSeqOff2ElementInfo(struct seq_file * sfile, loff_t off)
+{
+#ifdef RA_STATS
+ if(off <= 9)
+#else
+ if(off <= 1)
+#endif
+ return (void*)(IMG_INT)(off+1);
+ return 0;
+}
+
+static void RA_ProcSeqShowRegs(struct seq_file *sfile, void* el)
+{
+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private;
+ RA_ARENA *pArena = (RA_ARENA *)handlers->data;
+ BT *pBT = (BT*)el;
+
+ if (el == PVR_PROC_SEQ_START_TOKEN)
+ {
+ seq_printf(sfile, "Arena \"%s\"\nBase Size Type Ref\n", pArena->name);
+ return;
+ }
+
+ if (pBT)
+ {
+ seq_printf(sfile, "%08x %8x %4s %08x\n",
+ (IMG_UINT)pBT->base, (IMG_UINT)pBT->uSize, _BTType (pBT->type),
+ (IMG_UINT)pBT->psMapping);
+ }
+}
+
+static void* RA_ProcSeqOff2ElementRegs(struct seq_file * sfile, loff_t off)
+{
+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private;
+ RA_ARENA *pArena = (RA_ARENA *)handlers->data;
+ BT *pBT = 0;
+
+ if(off == 0)
+ return PVR_PROC_SEQ_START_TOKEN;
+
+ for (pBT=pArena->pHeadSegment; --off && pBT; pBT=pBT->pNextSegment);
+
+ return (void*)pBT;
+}
+
+#endif /* defined(CONFIG_PROC_FS) && defined(DEBUG) */
+
+
+#ifdef RA_STATS
+/*!
+******************************************************************************
+ @Function RA_GetStats
+
+ @Description Gets the arena stats and places in client buffer
+
+ @Input pArena - the arena to print statistics for.
+ @Input ppszStr - caller string to fill
+ @Input pui32StrLen - length of caller string
+
+ @Return PVRSRV_ERROR
+******************************************************************************/
+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=%p freeCB=%p handle=%p 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%u\n", pArena->sStatistics.uSpanCount);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, "live segment count\t%u\n", pArena->sStatistics.uLiveSegmentCount);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, "free segment count\t%u\n", pArena->sStatistics.uFreeSegmentCount);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, "free resource count\t%u (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%u\n", pArena->sStatistics.uCumulativeAllocs);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, "total frees\t\t%u\n", pArena->sStatistics.uCumulativeFrees);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, "import count\t\t%u\n", pArena->sStatistics.uImportCount);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, "export count\t\t%u\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=%p\n",
+ (IMG_UINT32) pBT->base,
+ pBT->uSize,
+ _BTType(pBT->type),
+ pBT->psMapping);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+ }
+
+ *ppszStr = pszStr;
+ *pui32StrLen = ui32StrLen;
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR RA_GetStatsFreeMem(RA_ARENA *pArena,
+ IMG_CHAR **ppszStr,
+ IMG_UINT32 *pui32StrLen)
+{
+ IMG_CHAR *pszStr = *ppszStr;
+ IMG_UINT32 ui32StrLen = *pui32StrLen;
+ IMG_INT32 i32Count;
+ CHECK_SPACE(ui32StrLen);
+ i32Count = OSSNPrintf(pszStr, 100, "Bytes free: Arena %-30s: %u (0x%x)\n", pArena->name,
+ pArena->sStatistics.uFreeResourceCount,
+ pArena->sStatistics.uFreeResourceCount);
+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen);
+ *ppszStr = pszStr;
+ *pui32StrLen = ui32StrLen;
+
+ return PVRSRV_OK;
+}
+#endif
+
+/******************************************************************************
+ End of file (ra.c)
+******************************************************************************/
+
+
+
+
diff --git a/pvr-source/services4/srvkm/common/refcount.c b/pvr-source/services4/srvkm/common/refcount.c
new file mode 100644
index 0000000..fa64b23
--- /dev/null
+++ b/pvr-source/services4/srvkm/common/refcount.c
@@ -0,0 +1,588 @@
+/*************************************************************************/ /*!
+@Title Services reference count debugging
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if defined(PVRSRV_REFCOUNT_DEBUG)
+
+#include "services_headers.h"
+
+#ifndef __linux__
+#warning Reference count debugging is not thread-safe on this platform
+#define PVRSRV_LOCK_CCB()
+#define PVRSRV_UNLOCK_CCB()
+#else /* __linux__ */
+#include <linux/spinlock.h>
+static DEFINE_SPINLOCK(gsCCBLock);
+#define PVRSRV_LOCK_CCB() \
+ { \
+ unsigned long flags; \
+ spin_lock_irqsave(&gsCCBLock, flags);
+#define PVRSRV_UNLOCK_CCB() \
+ spin_unlock_irqrestore(&gsCCBLock, flags); \
+ }
+#endif /* __linux__ */
+
+#define PVRSRV_REFCOUNT_CCB_MAX 512
+#define PVRSRV_REFCOUNT_CCB_MESG_MAX 80
+
+#define PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO (1U << 0)
+#define PVRSRV_REFCOUNT_CCB_DEBUG_MEMINFO (1U << 1)
+#define PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF (1U << 2)
+#define PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF2 (1U << 3)
+#define PVRSRV_REFCOUNT_CCB_DEBUG_BM_XPROC (1U << 4)
+
+#if defined(__linux__)
+#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP (1U << 16)
+#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2 (1U << 17)
+#else
+#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP 0
+#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2 0
+#endif
+
+#define PVRSRV_REFCOUNT_CCB_DEBUG_ALL ~0U
+
+/*static const IMG_UINT guiDebugMask = PVRSRV_REFCOUNT_CCB_DEBUG_ALL;*/
+static const IMG_UINT guiDebugMask =
+ PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO |
+ PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2;
+
+typedef struct
+{
+ const IMG_CHAR *pszFile;
+ IMG_INT iLine;
+ IMG_UINT32 ui32PID;
+ IMG_CHAR pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX];
+}
+PVRSRV_REFCOUNT_CCB;
+
+static PVRSRV_REFCOUNT_CCB gsRefCountCCB[PVRSRV_REFCOUNT_CCB_MAX];
+static IMG_UINT giOffset;
+
+static const IMG_CHAR gszHeader[] =
+ /* 10 20 30 40 50 60 70
+ * 345678901234567890123456789012345678901234567890123456789012345678901
+ */
+ "TYPE SYNCINFO MEMINFO MEMHANDLE OTHER REF REF' SIZE PID";
+ /* NCINFO deadbeef deadbeef deadbeef deadbeef 1234 1234 deadbeef */
+
+#define PVRSRV_REFCOUNT_CCB_FMT_STRING "%8.8s %8p %8p %8p %8p %.4d %.4d %.8x"
+
+IMG_INTERNAL
+void PVRSRVDumpRefCountCCB(void)
+{
+ int i;
+
+ PVRSRV_LOCK_CCB();
+
+ PVR_LOG(("%s", gszHeader));
+
+ for(i = 0; i < PVRSRV_REFCOUNT_CCB_MAX; i++)
+ {
+ PVRSRV_REFCOUNT_CCB *psRefCountCCBEntry =
+ &gsRefCountCCB[(giOffset + i) % PVRSRV_REFCOUNT_CCB_MAX];
+
+ /* Early on, we won't have MAX_REFCOUNT_CCB_SIZE messages */
+ if(!psRefCountCCBEntry->pszFile)
+ break;
+
+ PVR_LOG(("%s %d %s:%d", psRefCountCCBEntry->pcMesg,
+ psRefCountCCBEntry->ui32PID,
+ psRefCountCCBEntry->pszFile,
+ psRefCountCCBEntry->iLine));
+ }
+
+ PVRSRV_UNLOCK_CCB();
+}
+
+IMG_INTERNAL
+void PVRSRVKernelSyncInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ IMG_UINT32 ui32RefValue = OSAtomicRead(psKernelSyncInfo->pvRefCount);
+
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "SYNCINFO",
+ psKernelSyncInfo,
+ psKernelMemInfo,
+ NULL,
+ (psKernelMemInfo) ? psKernelMemInfo->sMemBlk.hOSMemHandle : NULL,
+ ui32RefValue,
+ ui32RefValue + 1,
+ (psKernelMemInfo) ? psKernelMemInfo->uAllocSize : 0);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ PVRSRVAcquireSyncInfoKM(psKernelSyncInfo);
+}
+
+IMG_INTERNAL
+void PVRSRVKernelSyncInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ IMG_UINT32 ui32RefValue = OSAtomicRead(psKernelSyncInfo->pvRefCount);
+
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "SYNCINFO",
+ psKernelSyncInfo,
+ psKernelMemInfo,
+ (psKernelMemInfo) ? psKernelMemInfo->sMemBlk.hOSMemHandle : NULL,
+ NULL,
+ ui32RefValue,
+ ui32RefValue - 1,
+ (psKernelMemInfo) ? psKernelMemInfo->uAllocSize : 0);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ PVRSRVReleaseSyncInfoKM(psKernelSyncInfo);
+}
+
+IMG_INTERNAL
+void PVRSRVKernelMemInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MEMINFO))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "MEMINFO",
+ psKernelMemInfo->psKernelSyncInfo,
+ psKernelMemInfo,
+ psKernelMemInfo->sMemBlk.hOSMemHandle,
+ NULL,
+ psKernelMemInfo->ui32RefCount,
+ psKernelMemInfo->ui32RefCount + 1,
+ psKernelMemInfo->uAllocSize);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psKernelMemInfo->ui32RefCount++;
+}
+
+IMG_INTERNAL
+void PVRSRVKernelMemInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MEMINFO))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "MEMINFO",
+ psKernelMemInfo->psKernelSyncInfo,
+ psKernelMemInfo,
+ psKernelMemInfo->sMemBlk.hOSMemHandle,
+ NULL,
+ psKernelMemInfo->ui32RefCount,
+ psKernelMemInfo->ui32RefCount - 1,
+ psKernelMemInfo->uAllocSize);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psKernelMemInfo->ui32RefCount--;
+}
+
+IMG_INTERNAL
+void PVRSRVBMBufIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "BM_BUF",
+ NULL,
+ NULL,
+ BM_HandleToOSMemHandle(pBuf),
+ pBuf,
+ pBuf->ui32RefCount,
+ pBuf->ui32RefCount + 1,
+ (pBuf->pMapping) ? pBuf->pMapping->uSize : 0);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ pBuf->ui32RefCount++;
+}
+
+IMG_INTERNAL
+void PVRSRVBMBufDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "BM_BUF",
+ NULL,
+ NULL,
+ BM_HandleToOSMemHandle(pBuf),
+ pBuf,
+ pBuf->ui32RefCount,
+ pBuf->ui32RefCount - 1,
+ (pBuf->pMapping) ? pBuf->pMapping->uSize : 0);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ pBuf->ui32RefCount--;
+}
+
+IMG_INTERNAL
+void PVRSRVBMBufIncExport2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF2))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "BM_BUF2",
+ NULL,
+ NULL,
+ BM_HandleToOSMemHandle(pBuf),
+ pBuf,
+ pBuf->ui32ExportCount,
+ pBuf->ui32ExportCount + 1,
+ (pBuf->pMapping) ? pBuf->pMapping->uSize : 0);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ pBuf->ui32ExportCount++;
+}
+
+IMG_INTERNAL
+void PVRSRVBMBufDecExport2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF2))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "BM_BUF2",
+ NULL,
+ NULL,
+ BM_HandleToOSMemHandle(pBuf),
+ pBuf,
+ pBuf->ui32ExportCount,
+ pBuf->ui32ExportCount - 1,
+ (pBuf->pMapping) ? pBuf->pMapping->uSize : 0);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ pBuf->ui32ExportCount--;
+}
+
+IMG_INTERNAL
+void PVRSRVBMXProcIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_XPROC))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "BM_XPROC",
+ NULL,
+ NULL,
+ gXProcWorkaroundShareData[ui32Index].hOSMemHandle,
+ (IMG_VOID *) ui32Index,
+ gXProcWorkaroundShareData[ui32Index].ui32RefCount,
+ gXProcWorkaroundShareData[ui32Index].ui32RefCount + 1,
+ gXProcWorkaroundShareData[ui32Index].ui32Size);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ gXProcWorkaroundShareData[ui32Index].ui32RefCount++;
+}
+
+IMG_INTERNAL
+void PVRSRVBMXProcDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_XPROC))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "BM_XPROC",
+ NULL,
+ NULL,
+ gXProcWorkaroundShareData[ui32Index].hOSMemHandle,
+ (IMG_VOID *) ui32Index,
+ gXProcWorkaroundShareData[ui32Index].ui32RefCount,
+ gXProcWorkaroundShareData[ui32Index].ui32RefCount - 1,
+ gXProcWorkaroundShareData[ui32Index].ui32Size);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ gXProcWorkaroundShareData[ui32Index].ui32RefCount--;
+}
+
+#if defined(__linux__)
+
+/* mmap refcounting is Linux specific */
+
+IMG_INTERNAL
+void PVRSRVOffsetStructIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "MMAP",
+ NULL,
+ NULL,
+ psOffsetStruct->psLinuxMemArea,
+ psOffsetStruct,
+ psOffsetStruct->ui32RefCount,
+ psOffsetStruct->ui32RefCount + 1,
+ psOffsetStruct->ui32RealByteSize);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psOffsetStruct->ui32RefCount++;
+}
+
+IMG_INTERNAL
+void PVRSRVOffsetStructDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "MMAP",
+ NULL,
+ NULL,
+ psOffsetStruct->psLinuxMemArea,
+ psOffsetStruct,
+ psOffsetStruct->ui32RefCount,
+ psOffsetStruct->ui32RefCount - 1,
+ psOffsetStruct->ui32RealByteSize);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psOffsetStruct->ui32RefCount--;
+}
+
+IMG_INTERNAL
+void PVRSRVOffsetStructIncMapped2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "MMAP2",
+ NULL,
+ NULL,
+ psOffsetStruct->psLinuxMemArea,
+ psOffsetStruct,
+ psOffsetStruct->ui32Mapped,
+ psOffsetStruct->ui32Mapped + 1,
+ psOffsetStruct->ui32RealByteSize);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psOffsetStruct->ui32Mapped++;
+}
+
+IMG_INTERNAL
+void PVRSRVOffsetStructDecMapped2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "MMAP2",
+ NULL,
+ NULL,
+ psOffsetStruct->psLinuxMemArea,
+ psOffsetStruct,
+ psOffsetStruct->ui32Mapped,
+ psOffsetStruct->ui32Mapped - 1,
+ psOffsetStruct->ui32RealByteSize);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psOffsetStruct->ui32Mapped--;
+}
+
+#endif /* defined(__linux__) */
+
+#endif /* defined(PVRSRV_REFCOUNT_DEBUG) */
diff --git a/pvr-source/services4/srvkm/common/resman.c b/pvr-source/services4/srvkm/common/resman.c
new file mode 100644
index 0000000..aef102f
--- /dev/null
+++ b/pvr-source/services4/srvkm/common/resman.c
@@ -0,0 +1,985 @@
+/*************************************************************************/ /*!
+@Title Resource Manager
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Provide resource management
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#include "services_headers.h"
+#include "resman.h"
+
+#ifdef __linux__
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#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,37))
+#include <linux/mutex.h>
+#else
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+#include <linux/semaphore.h>
+#else
+#include <asm/semaphore.h>
+#endif
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+static DEFINE_MUTEX(lock);
+#define DOWN(m) mutex_lock(m)
+#define UP(m) mutex_unlock(m)
+#else
+static DECLARE_MUTEX(lock);
+#define DOWN(m) down(m)
+#define UP(m) up(m)
+#endif
+
+#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
+
+/******************************************************************************
+ * resman structures
+ *****************************************************************************/
+
+/* resman item structure */
+typedef struct _RESMAN_ITEM_
+{
+#ifdef DEBUG
+ IMG_UINT32 ui32Signature;
+#endif
+ struct _RESMAN_ITEM_ **ppsThis; /*!< list navigation */
+ struct _RESMAN_ITEM_ *psNext; /*!< list navigation */
+
+ IMG_UINT32 ui32Flags; /*!< flags */
+ IMG_UINT32 ui32ResType;/*!< res type */
+
+ IMG_PVOID pvParam; /*!< param1 for callback */
+ IMG_UINT32 ui32Param; /*!< param2 for callback */
+
+ RESMAN_FREE_FN pfnFreeResource;/*!< resman item free callback */
+} RESMAN_ITEM;
+
+
+/* resman context structure */
+typedef struct _RESMAN_CONTEXT_
+{
+#ifdef DEBUG
+ IMG_UINT32 ui32Signature;
+#endif
+ struct _RESMAN_CONTEXT_ **ppsThis;/*!< list navigation */
+ struct _RESMAN_CONTEXT_ *psNext;/*!< list navigation */
+
+ PVRSRV_PER_PROCESS_DATA *psPerProc; /* owner of resources */
+
+ RESMAN_ITEM *psResItemList;/*!< res item list for context */
+
+} RESMAN_CONTEXT;
+
+
+/* resman list structure */
+typedef struct
+{
+ RESMAN_CONTEXT *psContextList; /*!< resman context list */
+
+} RESMAN_LIST, *PRESMAN_LIST; /* PRQA S 3205 */
+
+
+PRESMAN_LIST gpsResList = IMG_NULL;
+
+#include "lists.h" /* PRQA S 5087 */ /* include lists.h required here */
+
+static IMPLEMENT_LIST_ANY_VA(RESMAN_ITEM)
+static IMPLEMENT_LIST_ANY_VA_2(RESMAN_ITEM, IMG_BOOL, IMG_FALSE)
+static IMPLEMENT_LIST_INSERT(RESMAN_ITEM)
+static IMPLEMENT_LIST_REMOVE(RESMAN_ITEM)
+static IMPLEMENT_LIST_REVERSE(RESMAN_ITEM)
+
+static IMPLEMENT_LIST_REMOVE(RESMAN_CONTEXT)
+static IMPLEMENT_LIST_INSERT(RESMAN_CONTEXT)
+
+
+#define PRINT_RESLIST(x, y, z)
+
+/******************************************************** Forword references */
+
+static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem, IMG_BOOL bExecuteCallback, IMG_BOOL bForceCleanup);
+
+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
+
+
+
+
+
+
+/*!
+******************************************************************************
+
+ @Function ResManInit
+
+ @Description initialises the resman
+
+ @Return none
+
+******************************************************************************/
+PVRSRV_ERROR ResManInit(IMG_VOID)
+{
+ if (gpsResList == IMG_NULL)
+ {
+ /* If not already initialised */
+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(*gpsResList),
+ (IMG_VOID **)&gpsResList, IMG_NULL,
+ "Resource Manager List") != PVRSRV_OK)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ /* Init list, the linked list has dummy entries at both ends */
+ gpsResList->psContextList = IMG_NULL;
+
+ /* Check resource list */
+ VALIDATERESLIST();
+ }
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function ResManDeInit
+
+ @Description de-initialises the resman
+
+ @Return none
+
+******************************************************************************/
+IMG_VOID ResManDeInit(IMG_VOID)
+{
+ if (gpsResList != IMG_NULL)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*gpsResList), gpsResList, IMG_NULL);
+ gpsResList = IMG_NULL;
+ }
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVResManConnect
+
+ @Description Opens a connection to the Resource Manager
+
+ @input hPerProc - Per-process data (if applicable)
+ @output phResManContext - Resman context
+
+ @Return error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVResManConnect(IMG_HANDLE hPerProc,
+ PRESMAN_CONTEXT *phResManContext)
+{
+ PVRSRV_ERROR eError;
+ PRESMAN_CONTEXT psResManContext;
+
+ /*Acquire resource list sync object*/
+ ACQUIRE_SYNC_OBJ;
+
+ /*Check resource list*/
+ VALIDATERESLIST();
+
+ /* Allocate memory for the new context. */
+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psResManContext),
+ (IMG_VOID **)&psResManContext, IMG_NULL,
+ "Resource Manager Context");
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVResManConnect: ERROR allocating new RESMAN context struct"));
+
+ /* Check resource list */
+ VALIDATERESLIST();
+
+ /* Release resource list sync object */
+ RELEASE_SYNC_OBJ;
+
+ return eError;
+ }
+
+#ifdef DEBUG
+ psResManContext->ui32Signature = RESMAN_SIGNATURE;
+#endif /* DEBUG */
+ psResManContext->psResItemList = IMG_NULL;
+ psResManContext->psPerProc = hPerProc;
+
+ /* Insert new context struct after the dummy first entry */
+ List_RESMAN_CONTEXT_Insert(&gpsResList->psContextList, psResManContext);
+
+ /* Check resource list */
+ VALIDATERESLIST();
+
+ /* Release resource list sync object */
+ RELEASE_SYNC_OBJ;
+
+ *phResManContext = psResManContext;
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVResManDisconnect
+
+ @Description Closes a Resource Manager connection and frees all resources
+
+ @input hResManContext - Resman context
+ @input bKernelContext - IMG_TRUE for kernel contexts
+
+ @Return IMG_VOID
+
+******************************************************************************/
+IMG_VOID PVRSRVResManDisconnect(PRESMAN_CONTEXT psResManContext,
+ IMG_BOOL bKernelContext)
+{
+ /* Acquire resource list sync object */
+ ACQUIRE_SYNC_OBJ;
+
+ /* Check resource list */
+ VALIDATERESLIST();
+
+ /* Print and validate resource list */
+ PRINT_RESLIST(gpsResList, psResManContext, IMG_TRUE);
+
+ /* Free all auto-freed resources in order */
+
+ if (!bKernelContext)
+ {
+ /* OS specific User-mode Mappings: */
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_OS_USERMODE_MAPPING, 0, 0, IMG_TRUE);
+
+ /* VGX types: */
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DMA_CLIENT_FIFO_DATA, 0, 0, IMG_TRUE);
+
+ /* Event Object */
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_EVENT_OBJECT, 0, 0, IMG_TRUE);
+
+ /* syncobject state (Read/Write Complete values) */
+ /* Must be FIFO, so we reverse the list, twice */
+ List_RESMAN_ITEM_Reverse(&psResManContext->psResItemList);
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_MODIFY_SYNC_OPS, 0, 0, IMG_TRUE);
+ List_RESMAN_ITEM_Reverse(&psResManContext->psResItemList); // (could survive without this - all following items would be cleared up "fifo" too)
+
+ /* SGX types: */
+ 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);
+
+ /* COMMON types: */
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SYNC_INFO, 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);
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_MEM_INFO, 0, 0, IMG_TRUE);
+#if defined(SUPPORT_ION)
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_ION, 0, 0, IMG_TRUE);
+#endif
+ /* DISPLAY CLASS types: */
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF, 0, 0, IMG_TRUE);
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DISPLAYCLASS_DEVICE, 0, 0, IMG_TRUE);
+
+ /* BUFFER CLASS types: */
+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_BUFFERCLASS_DEVICE, 0, 0, IMG_TRUE);
+ }
+
+ /* Ensure that there are no resources left */
+ PVR_ASSERT(psResManContext->psResItemList == IMG_NULL);
+
+ /* Remove the context struct from the list */
+ List_RESMAN_CONTEXT_Remove(psResManContext);
+
+ /* Free the context struct */
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_CONTEXT), psResManContext, IMG_NULL);
+ /*not nulling pointer, copy on stack*/
+
+
+ /* Check resource list */
+ VALIDATERESLIST();
+
+ /* Print and validate resource list */
+ PRINT_RESLIST(gpsResList, psResManContext, IMG_FALSE);
+
+ /* Release resource list sync object */
+ RELEASE_SYNC_OBJ;
+}
+
+
+/*!
+******************************************************************************
+ @Function ResManRegisterRes
+
+ @Description : Inform the resource manager that the given resource has
+ been alloacted and freeing of it will be the responsibility
+ of the resource manager
+
+ @input psResManContext - resman context
+ @input ui32ResType - identify what kind of resource it is
+ @input pvParam - address of resource
+ @input ui32Param - size of resource
+ @input pfnFreeResource - pointer to function that frees this resource
+
+ @Return On success a pointer to an opaque data structure that represents
+ the allocated resource, else NULL
+
+**************************************************************************/
+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 resource list sync object */
+ ACQUIRE_SYNC_OBJ;
+
+ /* Check resource list */
+ VALIDATERESLIST();
+
+ PVR_DPF((PVR_DBG_MESSAGE, "ResManRegisterRes: register resource "
+ "Context 0x%x, ResType 0x%x, pvParam 0x%x, ui32Param 0x%x, "
+ "FreeFunc %08X",
+ (IMG_UINTPTR_T)psResManContext,
+ ui32ResType,
+ (IMG_UINTPTR_T)pvParam,
+ ui32Param,
+ (IMG_UINTPTR_T)pfnFreeResource));
+
+ /* Allocate memory for the new resource structure */
+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(RESMAN_ITEM), (IMG_VOID **)&psNewResItem,
+ IMG_NULL,
+ "Resource Manager Item") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ResManRegisterRes: "
+ "ERROR allocating new resource item"));
+
+ /* Release resource list sync object */
+ RELEASE_SYNC_OBJ;
+
+ return((PRESMAN_ITEM)IMG_NULL);
+ }
+
+ /* Fill in details about this resource */
+#ifdef DEBUG
+ psNewResItem->ui32Signature = RESMAN_SIGNATURE;
+#endif /* DEBUG */
+ psNewResItem->ui32ResType = ui32ResType;
+ psNewResItem->pvParam = pvParam;
+ psNewResItem->ui32Param = ui32Param;
+ psNewResItem->pfnFreeResource = pfnFreeResource;
+ psNewResItem->ui32Flags = 0;
+
+ /* Insert new structure after dummy first entry */
+ List_RESMAN_ITEM_Insert(&psResManContext->psResItemList, psNewResItem);
+
+ /* Check resource list */
+ VALIDATERESLIST();
+
+ /* Release resource list sync object */
+ RELEASE_SYNC_OBJ;
+
+ return(psNewResItem);
+}
+
+/*!
+******************************************************************************
+ @Function ResManFreeResByPtr
+
+ @Description frees a resource by matching on pointer type
+
+ @inputs psResItem - pointer to resource item to free
+ bForceCleanup - ignored uKernel re-sync
+
+ @Return PVRSRV_ERROR
+**************************************************************************/
+PVRSRV_ERROR ResManFreeResByPtr(RESMAN_ITEM *psResItem, IMG_BOOL bForceCleanup)
+{
+ 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",
+ (IMG_UINTPTR_T)psResItem));
+
+ /*Acquire resource list sync object*/
+ ACQUIRE_SYNC_OBJ;
+
+ /*Check resource list*/
+ VALIDATERESLIST();
+
+ /*Free resource*/
+ eError = FreeResourceByPtr(psResItem, IMG_TRUE, bForceCleanup);
+
+ /*Check resource list*/
+ VALIDATERESLIST();
+
+ /*Release resource list sync object*/
+ RELEASE_SYNC_OBJ;
+
+ return(eError);
+}
+
+
+/*!
+******************************************************************************
+ @Function ResManFreeResByCriteria
+
+ @Description frees a resource by matching on criteria
+
+ @inputs hResManContext - handle for resman context
+ @inputs ui32SearchCriteria - indicates which parameters should be
+ used in search for resources to free
+ @inputs ui32ResType - identify what kind of resource to free
+ @inputs pvParam - address of resource to be free
+ @inputs ui32Param - size of resource to be free
+
+ @Return PVRSRV_ERROR
+**************************************************************************/
+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 resource list sync object */
+ ACQUIRE_SYNC_OBJ;
+
+ /* Check resource list */
+ VALIDATERESLIST();
+
+ PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByCriteria: "
+ "Context 0x%x, Criteria 0x%x, Type 0x%x, Addr 0x%x, Param 0x%x",
+ (IMG_UINTPTR_T)psResManContext, ui32SearchCriteria, ui32ResType,
+ (IMG_UINTPTR_T)pvParam, ui32Param));
+
+ /* Free resources by criteria for this context */
+ eError = FreeResourceByCriteria(psResManContext, ui32SearchCriteria,
+ ui32ResType, pvParam, ui32Param,
+ IMG_TRUE);
+
+ /* Check resource list */
+ VALIDATERESLIST();
+
+ /* Release resource list sync object */
+ RELEASE_SYNC_OBJ;
+
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+ @Function ResManDissociateRes
+
+ @Description Moves a resource from one context to another.
+
+ @inputs psResItem - pointer to resource item to dissociate
+ @inputs psNewResManContext - new resman context for the resource
+
+ @Return IMG_VOID
+**************************************************************************/
+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 /* QAC fix */
+ PVR_ASSERT(psResItem->ui32Signature == RESMAN_SIGNATURE);
+#endif
+
+ if (psNewResManContext != IMG_NULL)
+ {
+ /* Remove this item from its old resource list */
+ List_RESMAN_ITEM_Remove(psResItem);
+
+ /* Re-insert into new list */
+ List_RESMAN_ITEM_Insert(&psNewResManContext->psResItemList, psResItem);
+
+ }
+ else
+ {
+ eError = FreeResourceByPtr(psResItem, IMG_FALSE, CLEANUP_WITH_POLL);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ResManDissociateRes: failed to free resource by pointer"));
+ return eError;
+ }
+ }
+
+ return eError;
+}
+
+/*!
+******************************************************************************
+ @Function ResManFindResourceByPtr_AnyVaCb
+
+ @Description
+ Compares the resman item with a given pointer.
+
+ @inputs psCurItem - theThe item to check
+ @inputs va - Variable argument list with:
+ psItem - pointer to resource item to find
+
+ @Return IMG_BOOL
+**************************************************************************/
+static IMG_BOOL ResManFindResourceByPtr_AnyVaCb(RESMAN_ITEM *psCurItem, va_list va)
+{
+ RESMAN_ITEM *psItem;
+
+ psItem = va_arg(va, RESMAN_ITEM*);
+
+ return (IMG_BOOL)(psCurItem == psItem);
+}
+
+
+/*!
+******************************************************************************
+ @Function ResManFindResourceByPtr
+
+ @Description
+ Attempts to find a resource in the list for this context
+
+ @inputs hResManContext - handle for resman context
+ @inputs psItem - pointer to resource item to find
+
+ @Return PVRSRV_ERROR
+**************************************************************************/
+IMG_INTERNAL PVRSRV_ERROR ResManFindResourceByPtr(PRESMAN_CONTEXT psResManContext,
+ RESMAN_ITEM *psItem)
+{
+/* RESMAN_ITEM *psCurItem;*/
+
+ PVRSRV_ERROR eResult;
+
+ 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 /* QAC fix */
+ PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE);
+#endif
+
+ /* Acquire resource list sync object */
+ ACQUIRE_SYNC_OBJ;
+
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "FindResourceByPtr: psItem=%08X, psItem->psNext=%08X",
+ (IMG_UINTPTR_T)psItem, (IMG_UINTPTR_T)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",
+ (IMG_UINTPTR_T)psResManContext,
+ psItem->ui32ResType,
+ (IMG_UINTPTR_T)psItem->pvParam,
+ psItem->ui32Param,
+ (IMG_UINTPTR_T)psItem->pfnFreeResource,
+ psItem->ui32Flags));
+
+ /* Search resource items starting at after the first dummy item */
+ if(List_RESMAN_ITEM_IMG_BOOL_Any_va(psResManContext->psResItemList,
+ &ResManFindResourceByPtr_AnyVaCb,
+ psItem))
+ {
+ eResult = PVRSRV_OK;
+ }
+ else
+ {
+ eResult = PVRSRV_ERROR_NOT_OWNER;
+ }
+
+ /* Release resource list sync object */
+ RELEASE_SYNC_OBJ;
+
+/* return PVRSRV_ERROR_NOT_OWNER;*/
+ return eResult;
+}
+
+/*!
+******************************************************************************
+ @Function FreeResourceByPtr
+
+ @Description
+ Frees a resource and move it from the list
+ NOTE : this function must be called with the resource
+ list sync object held
+
+ @inputs psItem - pointer to resource item to free
+ bExecuteCallback - execute callback?
+ bForceCleanup - skips uKernel re-sync
+
+ @Return PVRSRV_ERROR
+**************************************************************************/
+static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem,
+ IMG_BOOL bExecuteCallback,
+ IMG_BOOL bForceCleanup)
+{
+ 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 /* QAC fix */
+ PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE);
+#endif
+
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "FreeResourceByPtr: psItem=%08X, psItem->psNext=%08X",
+ (IMG_UINTPTR_T)psItem, (IMG_UINTPTR_T)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_UINTPTR_T)psItem->pvParam, psItem->ui32Param,
+ (IMG_UINTPTR_T)psItem->pfnFreeResource, psItem->ui32Flags));
+
+ /* Release resource list sync object just in case the free routine calls the resource manager */
+ RELEASE_SYNC_OBJ;
+
+ /* Call the freeing routine */
+ if (bExecuteCallback)
+ {
+ eError = psItem->pfnFreeResource(psItem->pvParam, psItem->ui32Param, bForceCleanup);
+ if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: ERROR calling FreeResource function"));
+ }
+ }
+
+ /* Acquire resource list sync object */
+ ACQUIRE_SYNC_OBJ;
+
+ if (eError != PVRSRV_ERROR_RETRY)
+ {
+ /* Remove this item from the resource list */
+ List_RESMAN_ITEM_Remove(psItem);
+
+ /* Free memory for the resource item */
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_ITEM), psItem, IMG_NULL);
+ }
+
+ return(eError);
+}
+
+/*!
+******************************************************************************
+ @Function FreeResourceByCriteria_AnyVaCb
+
+ @Description
+ Matches a resource manager item with a given criteria.
+
+ @inputs psCuItem - the item to be matched
+ @inputs va - a variable argument list with:.
+ ui32SearchCriteria - indicates which parameters should be used
+ search for resources to free
+ ui32ResType - identify what kind of resource to free
+ pvParam - address of resource to be free
+ ui32Param - size of resource to be free
+
+
+ @Return psCurItem if matched, IMG_NULL otherwise.
+**************************************************************************/
+static IMG_VOID* FreeResourceByCriteria_AnyVaCb(RESMAN_ITEM *psCurItem, va_list va)
+{
+ IMG_UINT32 ui32SearchCriteria;
+ IMG_UINT32 ui32ResType;
+ IMG_PVOID pvParam;
+ IMG_UINT32 ui32Param;
+
+ ui32SearchCriteria = va_arg(va, IMG_UINT32);
+ ui32ResType = va_arg(va, IMG_UINT32);
+ pvParam = va_arg(va, IMG_PVOID);
+ ui32Param = va_arg(va, IMG_UINT32);
+
+ /*check that for all conditions are either disabled or eval to true*/
+ if(
+ /* Check resource type */
+ (((ui32SearchCriteria & RESMAN_CRITERIA_RESTYPE) == 0UL) ||
+ (psCurItem->ui32ResType == ui32ResType))
+ &&
+ /* Check address */
+ (((ui32SearchCriteria & RESMAN_CRITERIA_PVOID_PARAM) == 0UL) ||
+ (psCurItem->pvParam == pvParam))
+ &&
+ /* Check size */
+ (((ui32SearchCriteria & RESMAN_CRITERIA_UI32_PARAM) == 0UL) ||
+ (psCurItem->ui32Param == ui32Param))
+ )
+ {
+ return psCurItem;
+ }
+ else
+ {
+ return IMG_NULL;
+ }
+}
+
+/*!
+******************************************************************************
+ @Function FreeResourceByCriteria
+
+ @Description
+ Frees all resources that match the given criteria for the
+ context.
+ NOTE : this function must be called with the resource
+ list sync object held
+
+ @inputs psResManContext - pointer to resman context
+ @inputs ui32SearchCriteria - indicates which parameters should be used
+ @inputs search for resources to free
+ @inputs ui32ResType - identify what kind of resource to free
+ @inputs pvParam - address of resource to be free
+ @inputs ui32Param - size of resource to be free
+ @inputs ui32AutoFreeLev - auto free level to free
+ @inputs bExecuteCallback - execute callback?
+
+ @Return PVRSRV_ERROR
+**************************************************************************/
+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;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ /* Search resource items starting at after the first dummy item */
+ /*while we get a match and not an error*/
+ while((psCurItem = (PRESMAN_ITEM)
+ List_RESMAN_ITEM_Any_va(psResManContext->psResItemList,
+ &FreeResourceByCriteria_AnyVaCb,
+ ui32SearchCriteria,
+ ui32ResType,
+ pvParam,
+ ui32Param)) != IMG_NULL
+ && eError == PVRSRV_OK)
+ {
+ do
+ {
+ eError = FreeResourceByPtr(psCurItem, bExecuteCallback, CLEANUP_WITH_POLL);
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ RELEASE_SYNC_OBJ;
+ OSReleaseBridgeLock();
+ /* Give a chance for other threads to come in and SGX to do more work */
+ OSSleepms(MAX_CLEANUP_TIME_WAIT_US/1000);
+ OSReacquireBridgeLock();
+ ACQUIRE_SYNC_OBJ;
+ }
+ } while (eError == PVRSRV_ERROR_RETRY);
+ }
+
+ return eError;
+}
+
+
+#ifdef DEBUG
+/*!
+******************************************************************************
+ @Function ValidateResList
+
+ @Description
+ Walks the resource list check the pointers
+ NOTE : this function must be called with the resource
+ list sync object held
+
+ @Return none
+**************************************************************************/
+static IMG_VOID ValidateResList(PRESMAN_LIST psResList)
+{
+ PRESMAN_ITEM psCurItem, *ppsThisItem;
+ PRESMAN_CONTEXT psCurContext, *ppsThisContext;
+
+ /* check we're initialised */
+ if (psResList == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "ValidateResList: resman not initialised yet"));
+ return;
+ }
+
+ psCurContext = psResList->psContextList;
+ ppsThisContext = &psResList->psContextList;
+
+ /* Walk the context list */
+ while(psCurContext != IMG_NULL)
+ {
+ /* Check current item */
+ 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",
+ (IMG_UINTPTR_T)psCurContext,
+ (IMG_UINTPTR_T)psCurContext->ppsThis,
+ (IMG_UINTPTR_T)psCurContext->psNext,
+ (IMG_UINTPTR_T)ppsThisContext));
+ PVR_ASSERT(psCurContext->ppsThis == ppsThisContext);
+ }
+
+ /* Walk the list for this context */
+ psCurItem = psCurContext->psResItemList;
+ ppsThisItem = &psCurContext->psResItemList;
+ while(psCurItem != IMG_NULL)
+ {
+ /* Check current item */
+ 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",
+ (IMG_UINTPTR_T)psCurItem,
+ (IMG_UINTPTR_T)psCurItem->ppsThis,
+ (IMG_UINTPTR_T)psCurItem->psNext,
+ (IMG_UINTPTR_T)ppsThisItem));
+ PVR_ASSERT(psCurItem->ppsThis == ppsThisItem);
+ }
+
+ /* Move to next item */
+ ppsThisItem = &psCurItem->psNext;
+ psCurItem = psCurItem->psNext;
+ }
+
+ /* Move to next context */
+ ppsThisContext = &psCurContext->psNext;
+ psCurContext = psCurContext->psNext;
+ }
+}
+#endif /* DEBUG */
+
+
+/******************************************************************************
+ End of file (resman.c)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/common/ttrace.c b/pvr-source/services4/srvkm/common/ttrace.c
new file mode 100644
index 0000000..574bf25
--- /dev/null
+++ b/pvr-source/services4/srvkm/common/ttrace.c
@@ -0,0 +1,597 @@
+/*************************************************************************/ /*!
+@Title Timed Trace functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#if defined (TTRACE)
+
+#include "services_headers.h"
+#include "ttrace.h"
+
+#if defined(PVRSRV_NEED_PVR_DPF)
+#define CHECKSIZE(n,m) \
+ if ((n & m) != n) \
+ PVR_DPF((PVR_DBG_ERROR,"Size check failed for " #m))
+#else
+#define CHECKSIZE(n,m)
+#endif
+
+#define TIME_TRACE_HASH_TABLE_SIZE 32
+
+HASH_TABLE *g_psBufferTable;
+IMG_UINT32 g_ui32HostUID;
+IMG_HANDLE g_psTimer;
+
+/* Trace buffer struct */
+typedef struct
+{
+ IMG_UINT32 ui32Woff; /* Offset to where next item will be written */
+ IMG_UINT32 ui32Roff; /* Offset to where to start reading from */
+ IMG_UINT32 ui32ByteCount; /* Number of bytes in buffer */
+ IMG_UINT8 ui8Data[0];
+} sTimeTraceBuffer;
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVTimeTraceItemSize
+
+ @Description
+
+ Calculate the size of a trace item
+
+ @Input psTraceItem : Trace item
+
+ @Return size of trace item
+
+******************************************************************************/
+static IMG_UINT32
+PVRSRVTimeTraceItemSize(IMG_UINT32 *psTraceItem)
+{
+ IMG_UINT32 ui32Size = PVRSRV_TRACE_ITEM_SIZE;
+
+ ui32Size += READ_HEADER(SIZE, psTraceItem[PVRSRV_TRACE_DATA_HEADER]);
+
+ return ui32Size;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVTimeTraceAllocItem
+
+ @Description
+
+ Allocate a trace item from the buffer of the current process
+
+ @Output ppsTraceItem : Pointer to allocated trace item
+
+ @Input ui32Size : Size of data packet to be allocated
+
+ @Return none
+
+******************************************************************************/
+static IMG_VOID
+PVRSRVTimeTraceAllocItem(IMG_UINT32 **pui32Item, IMG_UINT32 ui32Size)
+{
+ IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
+ IMG_UINT32 ui32AllocOffset;
+ sTimeTraceBuffer *psBuffer = (sTimeTraceBuffer *) HASH_Retrieve(g_psBufferTable, (IMG_UINTPTR_T) ui32PID);
+
+ /* The caller only asks for extra data space */
+ ui32Size += PVRSRV_TRACE_ITEM_SIZE;
+
+ /* Always round to 32-bit */
+ ui32Size = ((ui32Size - 1) & (~0x3)) + 0x04;
+
+ if (!psBuffer)
+ {
+ PVRSRV_ERROR eError;
+
+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVTimeTraceAllocItem: Creating buffer for PID %u", (IMG_UINT32) ui32PID));
+ eError = PVRSRVTimeTraceBufferCreate(ui32PID);
+ if (eError != PVRSRV_OK)
+ {
+ *pui32Item = IMG_NULL;
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceAllocItem: Failed to create buffer"));
+ return;
+ }
+
+ psBuffer = (sTimeTraceBuffer *) HASH_Retrieve(g_psBufferTable, (IMG_UINTPTR_T) ui32PID);
+ if (psBuffer == IMG_NULL)
+ {
+ *pui32Item = NULL;
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceAllocItem: Failed to retrieve buffer"));
+ return;
+ }
+ }
+
+ /* Can't allocate more then buffer size */
+ if (ui32Size >= TIME_TRACE_BUFFER_SIZE)
+ {
+ *pui32Item = NULL;
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceAllocItem: Error trace item too large (%d)", ui32Size));
+ return;
+ }
+
+ /* FIXME: Enter critical section? */
+
+ /* Always ensure we have enough space to write a padding message */
+ if ((psBuffer->ui32Woff + ui32Size + PVRSRV_TRACE_ITEM_SIZE) > TIME_TRACE_BUFFER_SIZE)
+ {
+ IMG_UINT32 *ui32WriteEOB = (IMG_UINT32 *) &psBuffer->ui8Data[psBuffer->ui32Woff];
+ IMG_UINT32 ui32Remain = TIME_TRACE_BUFFER_SIZE - psBuffer->ui32Woff;
+
+ /* Not enough space at the end of the buffer, back to the start */
+ *ui32WriteEOB++ = WRITE_HEADER(GROUP, PVRSRV_TRACE_GROUP_PADDING);
+ *ui32WriteEOB++ = 0; /* Don't need timestamp */
+ *ui32WriteEOB++ = 0; /* Don't need UID */
+ *ui32WriteEOB = WRITE_HEADER(SIZE, (ui32Remain - PVRSRV_TRACE_ITEM_SIZE));
+ psBuffer->ui32ByteCount += ui32Remain;
+ psBuffer->ui32Woff = ui32AllocOffset = 0;
+ }
+ else
+ ui32AllocOffset = psBuffer->ui32Woff;
+
+ psBuffer->ui32Woff = psBuffer->ui32Woff + ui32Size;
+ psBuffer->ui32ByteCount += ui32Size;
+
+ /* This allocation will start overwritting past our read pointer, move the read pointer along */
+ while (psBuffer->ui32ByteCount > TIME_TRACE_BUFFER_SIZE)
+ {
+ IMG_UINT32 *psReadItem = (IMG_UINT32 *) &psBuffer->ui8Data[psBuffer->ui32Roff];
+ IMG_UINT32 ui32ReadSize;
+
+ ui32ReadSize = PVRSRVTimeTraceItemSize(psReadItem);
+ psBuffer->ui32Roff = (psBuffer->ui32Roff + ui32ReadSize) & (TIME_TRACE_BUFFER_SIZE - 1);
+ psBuffer->ui32ByteCount -= ui32ReadSize;
+ }
+
+ *pui32Item = (IMG_UINT32 *) &psBuffer->ui8Data[ui32AllocOffset];
+ /* FIXME: Exit critical section? */
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVTimeTraceBufferCreate
+
+ @Description
+
+ Create a trace buffer.
+
+ Note: We assume that this will only be called once per process.
+
+ @Input ui32PID : PID of the process that is creating the buffer
+
+ @Return none
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVTimeTraceBufferCreate(IMG_UINT32 ui32PID)
+{
+ sTimeTraceBuffer *psBuffer;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+ sizeof(sTimeTraceBuffer) + TIME_TRACE_BUFFER_SIZE,
+ (IMG_VOID **)&psBuffer, IMG_NULL,
+ "Time Trace Buffer");
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceBufferCreate: Error allocating trace buffer"));
+ return eError;
+ }
+
+ OSMemSet(psBuffer, 0, TIME_TRACE_BUFFER_SIZE);
+
+ if (!HASH_Insert(g_psBufferTable, (IMG_UINTPTR_T) ui32PID, (IMG_UINTPTR_T) psBuffer))
+ {
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(sTimeTraceBuffer) + TIME_TRACE_BUFFER_SIZE,
+ psBuffer, NULL);
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceBufferCreate: Error adding trace buffer to hash table"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVTimeTraceBufferDestroy
+
+ @Description
+
+ Destroy a trace buffer.
+
+ Note: We assume that this will only be called once per process.
+
+ @Input ui32PID : PID of the process that is creating the buffer
+
+ @Return none
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVTimeTraceBufferDestroy(IMG_UINT32 ui32PID)
+{
+ sTimeTraceBuffer *psBuffer;
+
+#if defined(DUMP_TTRACE_BUFFERS_ON_EXIT)
+ PVRSRVDumpTimeTraceBuffers();
+#endif
+ psBuffer = (sTimeTraceBuffer *) HASH_Retrieve(g_psBufferTable, (IMG_UINTPTR_T) ui32PID);
+ if (psBuffer)
+ {
+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(sTimeTraceBuffer) + TIME_TRACE_BUFFER_SIZE,
+ psBuffer, NULL);
+ HASH_Remove(g_psBufferTable, (IMG_UINTPTR_T) ui32PID);
+ return PVRSRV_OK;
+ }
+
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceBufferDestroy: Can't find trace buffer in hash table"));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVTimeTraceInit
+
+ @Description
+
+ Initialise the timed trace subsystem.
+
+ @Return Error
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVTimeTraceInit(IMG_VOID)
+{
+ g_psBufferTable = HASH_Create(TIME_TRACE_HASH_TABLE_SIZE);
+
+ /* Create hash table to store the per process buffers in */
+ if (!g_psBufferTable)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceInit: Error creating hash table"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ /* Create the kernel buffer */
+ PVRSRVTimeTraceBufferCreate(KERNEL_ID);
+
+ g_psTimer = OSFuncHighResTimerCreate();
+
+ if (!g_psTimer)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceInit: Error creating timer"));
+ return PVRSRV_ERROR_INIT_FAILURE;
+ }
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR _PVRSRVTimeTraceBufferDestroy(IMG_UINTPTR_T hKey, IMG_UINTPTR_T hData)
+{
+ PVR_UNREFERENCED_PARAMETER(hData);
+ PVR_DPF((PVR_DBG_MESSAGE, "_PVRSRVTimeTraceBufferDestroy: Destroying buffer for PID %u", (IMG_UINT32) hKey));
+
+ PVRSRVTimeTraceBufferDestroy(hKey);
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVTimeTraceDeinit
+
+ @Description
+
+ De-initialise the timed trace subsystem.
+
+ @Return Error
+
+******************************************************************************/
+IMG_VOID PVRSRVTimeTraceDeinit(IMG_VOID)
+{
+ PVRSRVTimeTraceBufferDestroy(KERNEL_ID);
+ /* Free any buffers the where created at alloc item time */
+ HASH_Iterate(g_psBufferTable, _PVRSRVTimeTraceBufferDestroy);
+ HASH_Delete(g_psBufferTable);
+ OSFuncHighResTimerDestroy(g_psTimer);
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVTimeTraceWriteHeader
+
+ @Description
+
+ Write the header for a trace item.
+
+ @Input pui32TraceItem : Pointer to trace item
+
+ @Input ui32Group : Trace item's group ID
+
+ @Input ui32Class : Trace item's class ID
+
+ @Input ui32Token : Trace item's ui32Token ID
+
+ @Input ui32Size : Trace item's data payload size
+
+ @Input ui32Type : Trace item's data type
+
+ @Input ui32Count : Trace item's data count
+
+ @Return Pointer to data payload space, or NULL if no data payload
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceWriteHeader)
+#endif
+static INLINE IMG_VOID *PVRSRVTimeTraceWriteHeader(IMG_UINT32 *pui32TraceItem, IMG_UINT32 ui32Group,
+ IMG_UINT32 ui32Class, IMG_UINT32 ui32Token,
+ IMG_UINT32 ui32Size, IMG_UINT32 ui32Type,
+ IMG_UINT32 ui32Count)
+{
+ /* Sanity check arg's */
+ CHECKSIZE(ui32Group, PVRSRV_TRACE_GROUP_MASK);
+ CHECKSIZE(ui32Class, PVRSRV_TRACE_CLASS_MASK);
+ CHECKSIZE(ui32Token, PVRSRV_TRACE_TOKEN_MASK);
+
+ CHECKSIZE(ui32Size, PVRSRV_TRACE_SIZE_MASK);
+ CHECKSIZE(ui32Type, PVRSRV_TRACE_TYPE_MASK);
+ CHECKSIZE(ui32Count, PVRSRV_TRACE_COUNT_MASK);
+
+ /* Trace header */
+ pui32TraceItem[PVRSRV_TRACE_HEADER] = WRITE_HEADER(GROUP, ui32Group);
+ pui32TraceItem[PVRSRV_TRACE_HEADER] |= WRITE_HEADER(CLASS, ui32Class);
+ pui32TraceItem[PVRSRV_TRACE_HEADER] |= WRITE_HEADER(TOKEN, ui32Token);
+
+ /* Data header */
+ pui32TraceItem[PVRSRV_TRACE_DATA_HEADER] = WRITE_HEADER(SIZE, ui32Size);
+ pui32TraceItem[PVRSRV_TRACE_DATA_HEADER] |= WRITE_HEADER(TYPE, ui32Type);
+ pui32TraceItem[PVRSRV_TRACE_DATA_HEADER] |= WRITE_HEADER(COUNT, ui32Count);
+
+ pui32TraceItem[PVRSRV_TRACE_TIMESTAMP] = OSFuncHighResTimerGetus(g_psTimer);
+ pui32TraceItem[PVRSRV_TRACE_HOSTUID] = g_ui32HostUID++;
+
+ return ui32Size?((IMG_VOID *) &pui32TraceItem[PVRSRV_TRACE_DATA_PAYLOAD]):NULL;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVTimeTraceArray
+
+ @Description
+
+ Write trace item with an array of data
+
+ @Input ui32Group : Trace item's group ID
+
+ @Input ui32Class : Trace item's class ID
+
+ @Input ui32Token : Trace item's ui32Token ID
+
+ @Input ui32Size : Trace item's data payload size
+
+ @Input ui32Type : Trace item's data type
+
+ @Input ui32Count : Trace item's data count
+
+ @Input pui8Data : Pointer to data array
+
+ @Return Pointer to data payload space, or NULL if no data payload
+
+******************************************************************************/
+IMG_VOID PVRSRVTimeTraceArray(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class, IMG_UINT32 ui32Token,
+ IMG_UINT32 ui32Type, IMG_UINT32 ui32Count, IMG_UINT8 *pui8Data)
+{
+ IMG_UINT32 *pui32TraceItem;
+ IMG_UINT32 ui32Size, ui32TypeSize;
+ IMG_UINT8 *ui8Ptr;
+
+ /* Only the 1st 4 sizes are for ui types, others are "special" */
+ switch (ui32Type)
+ {
+ case PVRSRV_TRACE_TYPE_UI8: ui32TypeSize = 1;
+ break;
+ case PVRSRV_TRACE_TYPE_UI16: ui32TypeSize = 2;
+ break;
+ case PVRSRV_TRACE_TYPE_UI32: ui32TypeSize = 4;
+ break;
+ case PVRSRV_TRACE_TYPE_UI64: ui32TypeSize = 8;
+ break;
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "Unsupported size\n"));
+ return;
+ }
+
+ ui32Size = ui32TypeSize * ui32Count;
+
+ /* Allocate space from the buffer */
+ PVRSRVTimeTraceAllocItem(&pui32TraceItem, ui32Size);
+
+ if (!pui32TraceItem)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Can't find buffer\n"));
+ return;
+ }
+
+ ui8Ptr = PVRSRVTimeTraceWriteHeader(pui32TraceItem, ui32Group, ui32Class, ui32Token,
+ ui32Size, ui32Type, ui32Count);
+
+ if (ui8Ptr)
+ {
+ OSMemCopy(ui8Ptr, pui8Data, ui32Size);
+ }
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVTimeTraceSyncObject
+
+ @Description
+
+ Write trace item with a sync object
+
+ @Input ui32Group : Trace item's group ID
+
+ @Input ui32Token : Trace item's ui32Token ID
+
+ @Input psSync : Sync object
+
+ @Input ui8SyncOpp : Sync object operation
+
+ @Return None
+
+******************************************************************************/
+IMG_VOID PVRSRVTimeTraceSyncObject(IMG_UINT32 ui32Group, IMG_UINT32 ui32Token,
+ PVRSRV_KERNEL_SYNC_INFO *psSync, IMG_UINT8 ui8SyncOp)
+{
+ IMG_UINT32 *pui32TraceItem;
+ IMG_UINT32 *ui32Ptr;
+ IMG_UINT32 ui32Size = PVRSRV_TRACE_TYPE_SYNC_SIZE;
+
+
+ PVRSRVTimeTraceAllocItem(&pui32TraceItem, ui32Size);
+
+ if (!pui32TraceItem)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Can't find buffer\n"));
+ return;
+ }
+
+ ui32Ptr = PVRSRVTimeTraceWriteHeader(pui32TraceItem, ui32Group, PVRSRV_TRACE_CLASS_SYNC,
+ ui32Token, ui32Size, PVRSRV_TRACE_TYPE_SYNC, 1);
+
+ ui32Ptr[PVRSRV_TRACE_SYNC_UID] = psSync->ui32UID;
+ ui32Ptr[PVRSRV_TRACE_SYNC_WOP] = psSync->psSyncData->ui32WriteOpsPending;
+ ui32Ptr[PVRSRV_TRACE_SYNC_WOC] = psSync->psSyncData->ui32WriteOpsComplete;
+ ui32Ptr[PVRSRV_TRACE_SYNC_ROP] = psSync->psSyncData->ui32ReadOpsPending;
+ ui32Ptr[PVRSRV_TRACE_SYNC_ROC] = psSync->psSyncData->ui32ReadOpsComplete;
+ ui32Ptr[PVRSRV_TRACE_SYNC_RO2P] = psSync->psSyncData->ui32ReadOps2Pending;
+ ui32Ptr[PVRSRV_TRACE_SYNC_RO2C] = psSync->psSyncData->ui32ReadOps2Complete;
+ ui32Ptr[PVRSRV_TRACE_SYNC_WO_DEV_VADDR] = psSync->sWriteOpsCompleteDevVAddr.uiAddr;
+ ui32Ptr[PVRSRV_TRACE_SYNC_RO_DEV_VADDR] = psSync->sReadOpsCompleteDevVAddr.uiAddr;
+ ui32Ptr[PVRSRV_TRACE_SYNC_RO2_DEV_VADDR] = psSync->sReadOps2CompleteDevVAddr.uiAddr;
+ ui32Ptr[PVRSRV_TRACE_SYNC_OP] = ui8SyncOp;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVDumpTimeTraceBuffer
+
+ @Description
+
+ Dump the contents of the trace buffer.
+
+ @Input hKey : Trace item's group ID
+
+ @Input hData : Trace item's ui32Token ID
+
+ @Return Error
+
+******************************************************************************/
+static PVRSRV_ERROR PVRSRVDumpTimeTraceBuffer(IMG_UINTPTR_T hKey, IMG_UINTPTR_T hData)
+{
+ sTimeTraceBuffer *psBuffer = (sTimeTraceBuffer *) hData;
+ IMG_UINT32 ui32ByteCount = psBuffer->ui32ByteCount;
+ IMG_UINT32 ui32Walker = psBuffer->ui32Roff;
+ IMG_UINT32 ui32Read, ui32LineLen, ui32EOL, ui32MinLine;
+
+ PVR_DPF((PVR_DBG_ERROR, "TTB for PID %u:\n", (IMG_UINT32) hKey));
+
+ while (ui32ByteCount)
+ {
+ IMG_UINT32 *pui32Buffer = (IMG_UINT32 *) &psBuffer->ui8Data[ui32Walker];
+
+ ui32LineLen = (ui32ByteCount/sizeof(IMG_UINT32));
+ ui32EOL = (TIME_TRACE_BUFFER_SIZE - ui32Walker)/sizeof(IMG_UINT32);
+ ui32MinLine = (ui32LineLen < ui32EOL)?ui32LineLen:ui32EOL;
+
+ if (ui32MinLine >= 4)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "\t(TTB-%X) %08X %08X %08X %08X", ui32ByteCount,
+ pui32Buffer[0], pui32Buffer[1], pui32Buffer[2], pui32Buffer[3]));
+ ui32Read = 4 * sizeof(IMG_UINT32);
+ }
+ else if (ui32MinLine >= 3)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "\t(TTB-%X) %08X %08X %08X", ui32ByteCount,
+ pui32Buffer[0], pui32Buffer[1], pui32Buffer[2]));
+ ui32Read = 3 * sizeof(IMG_UINT32);
+ }
+ else if (ui32MinLine >= 2)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "\t(TTB-%X) %08X %08X", ui32ByteCount,
+ pui32Buffer[0], pui32Buffer[1]));
+ ui32Read = 2 * sizeof(IMG_UINT32);
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "\t(TTB-%X) %08X", ui32ByteCount,
+ pui32Buffer[0]));
+ ui32Read = sizeof(IMG_UINT32);
+ }
+
+ ui32Walker = (ui32Walker + ui32Read) & (TIME_TRACE_BUFFER_SIZE - 1);
+ ui32ByteCount -= ui32Read;
+ }
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVDumpTimeTraceBuffers
+
+ @Description
+
+ Dump the contents of all the trace buffers.
+
+ @Return None
+
+******************************************************************************/
+IMG_VOID PVRSRVDumpTimeTraceBuffers(IMG_VOID)
+{
+ HASH_Iterate(g_psBufferTable, PVRSRVDumpTimeTraceBuffer);
+}
+
+#endif /* TTRACE */
diff --git a/pvr-source/services4/srvkm/devices/sgx/mmu.c b/pvr-source/services4/srvkm/devices/sgx/mmu.c
new file mode 100644
index 0000000..44dc824
--- /dev/null
+++ b/pvr-source/services4/srvkm/devices/sgx/mmu.c
@@ -0,0 +1,4600 @@
+/*************************************************************************/ /*!
+@Title MMU Management
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Implements basic low level control of MMU.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#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"
+#include "sgxconfig.h"
+#include "sgx_bridge_km.h"
+#include "pdump_osfunc.h"
+
+#define UINT32_MAX_VALUE 0xFFFFFFFFUL
+
+/*
+ MMU performs device virtual to physical translation.
+ terminology:
+ page directory (PD)
+ pagetable (PT)
+ data page (DP)
+
+ Incoming 32bit Device Virtual Addresses are deconstructed into 3 fields:
+ ---------------------------------------------------------
+ | PD Index/tag: | PT Index: | DP offset: |
+ | bits 31:22 | bits 21:n | bits (n-1):0 |
+ ---------------------------------------------------------
+ where typically n=12 for a standard 4k DP
+ but n=16 for a 64k DP
+
+ MMU page directory (PD), pagetable (PT) and data page (DP) config:
+ PD:
+ - always one page per address space
+ - up to 4k in size to span 4Gb (32bit)
+ - contains up to 1024 32bit entries
+ - entries are indexed by the top 12 bits of an incoming 32bit device virtual address
+ - the PD entry selected contains the physical address of the PT to
+ perform the next stage of the V to P translation
+
+ PT:
+ - size depends on the DP size, e.g. 4k DPs have 4k PTs but 16k DPs have 1k PTs
+ - each PT always spans 4Mb of device virtual address space irrespective of DP size
+ - number of entries in a PT depend on DP size and ranges from 1024 to 4 entries
+ - entries are indexed by the PT Index field of the device virtual address (21:n)
+ - the PT entry selected contains the physical address of the DP to access
+
+ DP:
+ - size varies from 4k to 4M in multiple of 4 steppings
+ - DP offset field of the device virtual address ((n-1):0) is used as a byte offset
+ to address into the DP itself
+*/
+
+#define SGX_MAX_PD_ENTRIES (1<<(SGX_FEATURE_ADDRESS_SPACE_SIZE - SGX_MMU_PT_SHIFT - SGX_MMU_PAGE_SHIFT))
+
+#if defined(FIX_HW_BRN_31620)
+/* Sim doesn't use the address mask */
+#define SGX_MMU_PDE_DUMMY_PAGE (0)//(0x00000020U)
+#define SGX_MMU_PTE_DUMMY_PAGE (0)//(0x00000020U)
+
+/* 4MB adress range per page table */
+#define BRN31620_PT_ADDRESS_RANGE_SHIFT 22
+#define BRN31620_PT_ADDRESS_RANGE_SIZE (1 << BRN31620_PT_ADDRESS_RANGE_SHIFT)
+
+/* 64MB address range per PDE cache line */
+#define BRN31620_PDE_CACHE_FILL_SHIFT 26
+#define BRN31620_PDE_CACHE_FILL_SIZE (1 << BRN31620_PDE_CACHE_FILL_SHIFT)
+#define BRN31620_PDE_CACHE_FILL_MASK (BRN31620_PDE_CACHE_FILL_SIZE - 1)
+
+/* Page Directory Enteries per cache line */
+#define BRN31620_PDES_PER_CACHE_LINE_SHIFT (BRN31620_PDE_CACHE_FILL_SHIFT - BRN31620_PT_ADDRESS_RANGE_SHIFT)
+#define BRN31620_PDES_PER_CACHE_LINE_SIZE (1 << BRN31620_PDES_PER_CACHE_LINE_SHIFT)
+#define BRN31620_PDES_PER_CACHE_LINE_MASK (BRN31620_PDES_PER_CACHE_LINE_SIZE - 1)
+
+/* Macros for working out offset for dummy pages */
+#define BRN31620_DUMMY_PAGE_OFFSET (1 * SGX_MMU_PAGE_SIZE)
+#define BRN31620_DUMMY_PDE_INDEX (BRN31620_DUMMY_PAGE_OFFSET / BRN31620_PT_ADDRESS_RANGE_SIZE)
+#define BRN31620_DUMMY_PTE_INDEX ((BRN31620_DUMMY_PAGE_OFFSET - (BRN31620_DUMMY_PDE_INDEX * BRN31620_PT_ADDRESS_RANGE_SIZE))/SGX_MMU_PAGE_SIZE)
+
+/* Cache number of cache lines */
+#define BRN31620_CACHE_FLUSH_SHIFT (32 - BRN31620_PDE_CACHE_FILL_SHIFT)
+#define BRN31620_CACHE_FLUSH_SIZE (1 << BRN31620_CACHE_FLUSH_SHIFT)
+
+/* Cache line bits in a UINT32 */
+#define BRN31620_CACHE_FLUSH_BITS_SHIFT 5
+#define BRN31620_CACHE_FLUSH_BITS_SIZE (1 << BRN31620_CACHE_FLUSH_BITS_SHIFT)
+#define BRN31620_CACHE_FLUSH_BITS_MASK (BRN31620_CACHE_FLUSH_BITS_SIZE - 1)
+
+/* Cache line index in array */
+#define BRN31620_CACHE_FLUSH_INDEX_BITS (BRN31620_CACHE_FLUSH_SHIFT - BRN31620_CACHE_FLUSH_BITS_SHIFT)
+#define BRN31620_CACHE_FLUSH_INDEX_SIZE (1 << BRN31620_CACHE_FLUSH_INDEX_BITS)
+
+#define BRN31620_DUMMY_PAGE_SIGNATURE 0xFEEBEE01
+#endif
+
+typedef struct _MMU_PT_INFO_
+{
+ /* note: may need a union here to accommodate a PT page address for local memory */
+ IMG_VOID *hPTPageOSMemHandle;
+ IMG_CPU_VIRTADDR PTPageCpuVAddr;
+ /* Map of reserved PTEs.
+ * Reserved PTEs are like "valid" PTEs in that they (and the DevVAddrs they represent)
+ * cannot be assigned to another allocation but their "reserved" status persists through
+ * any amount of mapping and unmapping, until the allocation is finally destroyed.
+ *
+ * Reserved and Valid are independent.
+ * When a PTE is first reserved, it will have Reserved=1 and Valid=0.
+ * When the PTE is actually mapped, it will have Reserved=1 and Valid=1.
+ * When the PTE is unmapped, it will have Reserved=1 and Valid=0.
+ * At this point, the PT will can not be destroyed because although there is
+ * not an active mapping on the PT, it is known a PTE is reserved for use.
+ *
+ * The above sequence of mapping and unmapping may repeat any number of times
+ * until the allocation is unmapped and destroyed which causes the PTE to have
+ * Valid=0 and Reserved=0.
+ */
+ /* Number of PTEs set up.
+ * i.e. have a valid SGX Phys Addr and the "VALID" PTE bit == 1
+ */
+ IMG_UINT32 ui32ValidPTECount;
+} MMU_PT_INFO;
+
+#define MMU_CONTEXT_NAME_SIZE 50
+struct _MMU_CONTEXT_
+{
+ /* the device node */
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+
+ /* Page Directory CPUVirt and DevPhys Addresses */
+ IMG_CPU_VIRTADDR pvPDCpuVAddr;
+ IMG_DEV_PHYADDR sPDDevPAddr;
+
+ IMG_VOID *hPDOSMemHandle;
+
+ /* information about dynamically allocated pagetables */
+ MMU_PT_INFO *apsPTInfoList[SGX_MAX_PD_ENTRIES];
+
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+
+#if defined(PDUMP)
+ IMG_UINT32 ui32PDumpMMUContextID;
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ IMG_BOOL bPDumpActive;
+#endif
+#endif
+
+ IMG_UINT32 ui32PID;
+ IMG_CHAR szName[MMU_CONTEXT_NAME_SIZE];
+
+#if defined (FIX_HW_BRN_31620)
+ IMG_UINT32 ui32PDChangeMask[BRN31620_CACHE_FLUSH_INDEX_SIZE];
+ IMG_UINT32 ui32PDCacheRangeRefCount[BRN31620_CACHE_FLUSH_SIZE];
+ MMU_PT_INFO *apsPTInfoListSave[SGX_MAX_PD_ENTRIES];
+#endif
+ struct _MMU_CONTEXT_ *psNext;
+};
+
+struct _MMU_HEAP_
+{
+ /* MMU context */
+ MMU_CONTEXT *psMMUContext;
+
+ /*
+ heap specific details:
+ */
+ /* the Base PD index for the heap */
+ IMG_UINT32 ui32PDBaseIndex;
+ /* number of pagetables in this heap */
+ IMG_UINT32 ui32PageTableCount;
+ /* total number of pagetable entries in this heap which may be mapped to data pages */
+ IMG_UINT32 ui32PTETotalUsable;
+ /* PD entry DP size control field */
+ IMG_UINT32 ui32PDEPageSizeCtrl;
+
+ /*
+ Data Page (DP) Details:
+ */
+ /* size in bytes of a data page */
+ IMG_UINT32 ui32DataPageSize;
+ /* bit width of the data page offset addressing field */
+ IMG_UINT32 ui32DataPageBitWidth;
+ /* bit mask of the data page offset addressing field */
+ IMG_UINT32 ui32DataPageMask;
+
+ /*
+ PageTable (PT) Details:
+ */
+ /* bit shift to base of PT addressing field */
+ IMG_UINT32 ui32PTShift;
+ /* bit width of the PT addressing field */
+ IMG_UINT32 ui32PTBitWidth;
+ /* bit mask of the PT addressing field */
+ IMG_UINT32 ui32PTMask;
+ /* size in bytes of a pagetable */
+ IMG_UINT32 ui32PTSize;
+ /* Allocated PT Entries per PT */
+ IMG_UINT32 ui32PTNumEntriesAllocated;
+ /* Usable PT Entries per PT (may be different to num allocated for 4MB data page) */
+ IMG_UINT32 ui32PTNumEntriesUsable;
+
+ /*
+ PageDirectory Details:
+ */
+ /* bit shift to base of PD addressing field */
+ IMG_UINT32 ui32PDShift;
+ /* bit width of the PD addressing field */
+ IMG_UINT32 ui32PDBitWidth;
+ /* bit mask of the PT addressing field */
+ IMG_UINT32 ui32PDMask;
+
+ /*
+ Arena Info:
+ */
+ RA_ARENA *psVMArena;
+ DEV_ARENA_DESCRIPTOR *psDevArena;
+
+ /* If we have sparse mappings then we can't do PT level sanity checks */
+ IMG_BOOL bHasSparseMappings;
+#if defined(PDUMP)
+ PDUMP_MMU_ATTRIB sMMUAttrib;
+#endif
+};
+
+
+
+#if defined (SUPPORT_SGX_MMU_DUMMY_PAGE)
+#define DUMMY_DATA_PAGE_SIGNATURE 0xDEADBEEF
+#endif
+
+/* local prototypes: */
+static IMG_VOID
+_DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOSFreePT);
+
+#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 /* #if defined(PDUMP) */
+
+/* This option tests page table memory, for use during device bring-up. */
+#define PAGE_TEST 0
+#if PAGE_TEST
+static IMG_VOID PageTest(IMG_VOID* pMem, IMG_DEV_PHYADDR sDevPAddr);
+#endif
+
+/* This option dumps out the PT if an assert fails */
+#define PT_DUMP 1
+
+/* This option sanity checks page table PTE valid count matches active PTEs */
+#define PT_DEBUG 0
+#if (PT_DEBUG || PT_DUMP) && defined(PVRSRV_NEED_PVR_DPF)
+static IMG_VOID DumpPT(MMU_PT_INFO *psPTInfoList)
+{
+ IMG_UINT32 *p = (IMG_UINT32*)psPTInfoList->PTPageCpuVAddr;
+ IMG_UINT32 i;
+
+ /* 1024 entries in a 4K page table */
+ for(i = 0; i < 1024; i += 8)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%08X %08X %08X %08X %08X %08X %08X %08X\n",
+ p[i + 0], p[i + 1], p[i + 2], p[i + 3],
+ p[i + 4], p[i + 5], p[i + 6], p[i + 7]));
+ }
+}
+#else /* (PT_DEBUG || PT_DUMP) && defined(PVRSRV_NEED_PVR_DPF) */
+static INLINE IMG_VOID DumpPT(MMU_PT_INFO *psPTInfoList)
+{
+ PVR_UNREFERENCED_PARAMETER(psPTInfoList);
+}
+#endif /* (PT_DEBUG || PT_DUMP) && defined(PVRSRV_NEED_PVR_DPF) */
+
+#if PT_DEBUG
+static IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList)
+{
+ IMG_UINT32 *p = (IMG_UINT32*) psPTInfoList->PTPageCpuVAddr;
+ IMG_UINT32 i, ui32Count = 0;
+
+ /* 1024 entries in a 4K page table */
+ for(i = 0; i < 1024; i++)
+ if(p[i] & SGX_MMU_PTE_VALID)
+ ui32Count++;
+
+ if(psPTInfoList->ui32ValidPTECount != ui32Count)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "ui32ValidPTECount: %u ui32Count: %u\n",
+ psPTInfoList->ui32ValidPTECount, ui32Count));
+ DumpPT(psPTInfoList);
+ BUG();
+ }
+}
+#else /* PT_DEBUG */
+static INLINE IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList)
+{
+ PVR_UNREFERENCED_PARAMETER(psPTInfoList);
+}
+#endif /* PT_DEBUG */
+
+/*
+ Debug functionality that allows us to make the CPU
+ mapping of pagetable memory readonly and only make
+ it read/write when we alter it. This allows us
+ to check that our memory isn't being overwritten
+*/
+#if defined(PVRSRV_MMU_MAKE_READWRITE_ON_DEMAND)
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#else
+#include <generated/autoconf.h>
+#endif
+
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/highmem.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+
+static IMG_VOID MakeKernelPageReadWrite(IMG_PVOID ulCPUVAddr)
+{
+ pgd_t *psPGD;
+ pud_t *psPUD;
+ pmd_t *psPMD;
+ pte_t *psPTE;
+ pte_t ptent;
+ IMG_UINT32 ui32CPUVAddr = (IMG_UINT32) ulCPUVAddr;
+
+ psPGD = pgd_offset_k(ui32CPUVAddr);
+ if (pgd_none(*psPGD) || pgd_bad(*psPGD))
+ {
+ PVR_ASSERT(0);
+ }
+
+ psPUD = pud_offset(psPGD, ui32CPUVAddr);
+ if (pud_none(*psPUD) || pud_bad(*psPUD))
+ {
+ PVR_ASSERT(0);
+ }
+
+ psPMD = pmd_offset(psPUD, ui32CPUVAddr);
+ if (pmd_none(*psPMD) || pmd_bad(*psPMD))
+ {
+ PVR_ASSERT(0);
+ }
+ psPTE = (pte_t *)pte_offset_kernel(psPMD, ui32CPUVAddr);
+
+ ptent = ptep_modify_prot_start(&init_mm, ui32CPUVAddr, psPTE);
+ ptent = pte_mkwrite(ptent);
+ ptep_modify_prot_commit(&init_mm, ui32CPUVAddr, psPTE, ptent);
+
+ flush_tlb_all();
+}
+
+static IMG_VOID MakeKernelPageReadOnly(IMG_PVOID ulCPUVAddr)
+{
+ pgd_t *psPGD;
+ pud_t *psPUD;
+ pmd_t *psPMD;
+ pte_t *psPTE;
+ pte_t ptent;
+ IMG_UINT32 ui32CPUVAddr = (IMG_UINT32) ulCPUVAddr;
+
+ OSWriteMemoryBarrier();
+
+ psPGD = pgd_offset_k(ui32CPUVAddr);
+ if (pgd_none(*psPGD) || pgd_bad(*psPGD))
+ {
+ PVR_ASSERT(0);
+ }
+
+ psPUD = pud_offset(psPGD, ui32CPUVAddr);
+ if (pud_none(*psPUD) || pud_bad(*psPUD))
+ {
+ PVR_ASSERT(0);
+ }
+
+ psPMD = pmd_offset(psPUD, ui32CPUVAddr);
+ if (pmd_none(*psPMD) || pmd_bad(*psPMD))
+ {
+ PVR_ASSERT(0);
+ }
+
+ psPTE = (pte_t *)pte_offset_kernel(psPMD, ui32CPUVAddr);
+
+ ptent = ptep_modify_prot_start(&init_mm, ui32CPUVAddr, psPTE);
+ ptent = pte_wrprotect(ptent);
+ ptep_modify_prot_commit(&init_mm, ui32CPUVAddr, psPTE, ptent);
+
+ flush_tlb_all();
+
+}
+
+#else /* defined(PVRSRV_MMU_MAKE_READWRITE_ON_DEMAND) */
+
+static INLINE IMG_VOID MakeKernelPageReadWrite(IMG_PVOID ulCPUVAddr)
+{
+ PVR_UNREFERENCED_PARAMETER(ulCPUVAddr);
+}
+
+static INLINE IMG_VOID MakeKernelPageReadOnly(IMG_PVOID ulCPUVAddr)
+{
+ PVR_UNREFERENCED_PARAMETER(ulCPUVAddr);
+}
+
+#endif /* defined(PVRSRV_MMU_MAKE_READWRITE_ON_DEMAND) */
+
+/*___________________________________________________________________________
+
+ Information for SUPPORT_PDUMP_MULTI_PROCESS feature.
+
+ The client marked for pdumping will set the bPDumpActive flag in
+ the MMU Context (see MMU_Initialise).
+
+ Shared heap allocations should be persistent so all apps which
+ are pdumped will see the allocation. Persistent flag over-rides
+ the bPDumpActive flag (see pdump_common.c/DbgWrite function).
+
+ The idea is to dump PT,DP for shared heap allocations, but only
+ dump the PDE if the allocation is mapped into the kernel or active
+ client context. This ensures if a background app allocates on a
+ shared heap then all clients can access it in the pdump toolchain.
+
+
+
+ PD PT DP
+ +-+
+ | |---> +-+
+ +-+ | |---> +-+
+ +-+ + +
+ +-+
+
+ PD allocation/free: pdump flags are 0 (only need PD for active apps)
+ PT allocation/free: pdump flags are 0
+ unless PT is for a shared heap, in which case persistent is set
+ PD entries (MMU init/insert shared heap):
+ only pdump if PDE is on the active MMU context, flags are 0
+ PD entries (PT alloc):
+ pdump flags are 0 if kernel heap
+ pdump flags are 0 if shared heap and PDE is on active MMU context
+ otherwise ignore.
+ PT entries pdump flags are 0
+ unless PTE is for a shared heap, in which case persistent is set
+
+ NOTE: PDump common code:-
+ PDumpMallocPages and PDumpMemKM also set the persistent flag for
+ shared heap allocations.
+
+ ___________________________________________________________________________
+*/
+
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_IsHeapShared
+
+ PURPOSE: Is this heap shared?
+ PARAMETERS: In: pMMU_Heap
+ RETURNS: true if heap is shared
+******************************************************************************/
+IMG_BOOL MMU_IsHeapShared(MMU_HEAP* pMMUHeap)
+{
+ switch(pMMUHeap->psDevArena->DevMemHeapType)
+ {
+ case DEVICE_MEMORY_HEAP_SHARED :
+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED :
+ return IMG_TRUE;
+ case DEVICE_MEMORY_HEAP_PERCONTEXT :
+ case DEVICE_MEMORY_HEAP_KERNEL :
+ return IMG_FALSE;
+ default:
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_IsHeapShared: ERROR invalid heap type"));
+ return IMG_FALSE;
+ }
+ }
+}
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+/*!
+******************************************************************************
+ FUNCTION: EnableHostAccess
+
+ PURPOSE: Enables Host accesses to device memory, by passing the device
+ MMU address translation
+
+ PARAMETERS: In: psMMUContext
+ RETURNS: None
+******************************************************************************/
+IMG_VOID
+EnableHostAccess (MMU_CONTEXT *psMMUContext)
+{
+ IMG_UINT32 ui32RegVal;
+ IMG_VOID *pvRegsBaseKM = psMMUContext->psDevInfo->pvRegsBaseKM;
+
+ /*
+ bypass the MMU for the host port requestor,
+ conserving bypass state of other requestors
+ */
+ ui32RegVal = OSReadHWReg(pvRegsBaseKM, EUR_CR_BIF_CTRL);
+
+ OSWriteHWReg(pvRegsBaseKM,
+ EUR_CR_BIF_CTRL,
+ ui32RegVal | EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK);
+ /* assume we're not wiping-out any other bits */
+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK);
+}
+
+/*!
+******************************************************************************
+ FUNCTION: DisableHostAccess
+
+ PURPOSE: Disables Host accesses to device memory, by passing the device
+ MMU address translation
+
+ PARAMETERS: In: psMMUContext
+ RETURNS: None
+******************************************************************************/
+IMG_VOID
+DisableHostAccess (MMU_CONTEXT *psMMUContext)
+{
+ IMG_UINT32 ui32RegVal;
+ IMG_VOID *pvRegsBaseKM = psMMUContext->psDevInfo->pvRegsBaseKM;
+
+ /*
+ disable MMU-bypass for the host port requestor,
+ conserving bypass state of other requestors
+ and flushing all caches/tlbs
+ */
+ OSWriteHWReg(pvRegsBaseKM,
+ EUR_CR_BIF_CTRL,
+ ui32RegVal & ~EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK);
+ /* assume we're not wiping-out any other bits */
+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, 0);
+}
+#endif
+
+
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+/*!
+******************************************************************************
+ FUNCTION: MMU_InvalidateSystemLevelCache
+
+ PURPOSE: Invalidates the System Level Cache to purge stale PDEs and PTEs
+
+ PARAMETERS: In: psDevInfo
+ RETURNS: None
+
+******************************************************************************/
+static IMG_VOID MMU_InvalidateSystemLevelCache(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+ #if defined(SGX_FEATURE_MP)
+ psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_SL;
+ #else
+ /* The MMU always bypasses the SLC */
+ PVR_UNREFERENCED_PARAMETER(psDevInfo);
+ #endif /* SGX_FEATURE_MP */
+}
+#endif /* SGX_FEATURE_SYSTEM_CACHE */
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_InvalidateDirectoryCache
+
+ PURPOSE: Invalidates the page directory cache + page table cache + requestor TLBs
+
+ PARAMETERS: In: psDevInfo
+ RETURNS: None
+
+******************************************************************************/
+IMG_VOID MMU_InvalidateDirectoryCache(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+ psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_PD;
+ #if defined(SGX_FEATURE_SYSTEM_CACHE)
+ MMU_InvalidateSystemLevelCache(psDevInfo);
+ #endif /* SGX_FEATURE_SYSTEM_CACHE */
+}
+
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_InvalidatePageTableCache
+
+ PURPOSE: Invalidates the page table cache + requestor TLBs
+
+ PARAMETERS: In: psDevInfo
+ RETURNS: None
+
+******************************************************************************/
+static IMG_VOID MMU_InvalidatePageTableCache(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+ psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_PT;
+ #if defined(SGX_FEATURE_SYSTEM_CACHE)
+ MMU_InvalidateSystemLevelCache(psDevInfo);
+ #endif /* SGX_FEATURE_SYSTEM_CACHE */
+}
+
+#if defined(FIX_HW_BRN_31620)
+/*!
+******************************************************************************
+ FUNCTION: BRN31620InvalidatePageTableEntry
+
+ PURPOSE: Frees page tables in PDE cache line chunks re-wiring the
+ dummy page when required
+
+ PARAMETERS: In: psMMUContext, ui32PDIndex, ui32PTIndex
+ RETURNS: None
+
+******************************************************************************/
+static IMG_VOID BRN31620InvalidatePageTableEntry(MMU_CONTEXT *psMMUContext, IMG_UINT32 ui32PDIndex, IMG_UINT32 ui32PTIndex, IMG_UINT32 *pui32PTE)
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo = psMMUContext->psDevInfo;
+
+ /*
+ * Note: We can't tell at this stage if this PT will be freed before
+ * the end of the function so we always wire up the dummy page to
+ * to the PT.
+ */
+ if (((ui32PDIndex % (BRN31620_PDE_CACHE_FILL_SIZE/BRN31620_PT_ADDRESS_RANGE_SIZE)) == BRN31620_DUMMY_PDE_INDEX)
+ && (ui32PTIndex == BRN31620_DUMMY_PTE_INDEX))
+ {
+ *pui32PTE = (psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PTE_DUMMY_PAGE
+ | SGX_MMU_PTE_READONLY
+ | SGX_MMU_PTE_VALID;
+ }
+ else
+ {
+ *pui32PTE = 0;
+ }
+}
+
+/*!
+******************************************************************************
+ FUNCTION: BRN31620FreePageTable
+
+ PURPOSE: Frees page tables in PDE cache line chunks re-wiring the
+ dummy page when required
+
+ PARAMETERS: In: psMMUContext, ui32PDIndex
+ RETURNS: IMG_TRUE if we freed any PT's
+
+******************************************************************************/
+static IMG_BOOL BRN31620FreePageTable(MMU_HEAP *psMMUHeap, IMG_UINT32 ui32PDIndex)
+{
+ MMU_CONTEXT *psMMUContext = psMMUHeap->psMMUContext;
+ PVRSRV_SGXDEV_INFO *psDevInfo = psMMUContext->psDevInfo;
+ IMG_UINT32 ui32PDCacheLine = ui32PDIndex >> BRN31620_PDES_PER_CACHE_LINE_SHIFT;
+ IMG_UINT32 bFreePTs = IMG_FALSE;
+ IMG_UINT32 *pui32Tmp;
+
+ PVR_ASSERT(psMMUHeap != IMG_NULL);
+
+ /*
+ * Clear the PT info for this PD index so even if we don't
+ * free the memory here apsPTInfoList[PDIndex] will trigger
+ * an "allocation" in _DeferredAllocPagetables which
+ * bumps up the refcount.
+ */
+ PVR_ASSERT(psMMUContext->apsPTInfoListSave[ui32PDIndex] == IMG_NULL);
+
+ psMMUContext->apsPTInfoListSave[ui32PDIndex] = psMMUContext->apsPTInfoList[ui32PDIndex];
+ psMMUContext->apsPTInfoList[ui32PDIndex] = IMG_NULL;
+
+ /* Check if this was the last PT in the cache line */
+ if (--psMMUContext->ui32PDCacheRangeRefCount[ui32PDCacheLine] == 0)
+ {
+ IMG_UINT32 i;
+ IMG_UINT32 ui32PDIndexStart = ui32PDCacheLine * BRN31620_PDES_PER_CACHE_LINE_SIZE;
+ IMG_UINT32 ui32PDIndexEnd = ui32PDIndexStart + BRN31620_PDES_PER_CACHE_LINE_SIZE;
+ IMG_UINT32 ui32PDBitMaskIndex, ui32PDBitMaskShift;
+
+ /* Free all PT's in cache line */
+ for (i=ui32PDIndexStart;i<ui32PDIndexEnd;i++)
+ {
+ /* This PT is _really_ being freed now */
+ psMMUContext->apsPTInfoList[i] = psMMUContext->apsPTInfoListSave[i];
+ psMMUContext->apsPTInfoListSave[i] = IMG_NULL;
+ _DeferredFreePageTable(psMMUHeap, i - psMMUHeap->ui32PDBaseIndex, IMG_TRUE);
+ }
+
+ ui32PDBitMaskIndex = ui32PDCacheLine >> BRN31620_CACHE_FLUSH_BITS_SHIFT;
+ ui32PDBitMaskShift = ui32PDCacheLine & BRN31620_CACHE_FLUSH_BITS_MASK;
+
+ /* Check if this is a shared heap */
+ if (MMU_IsHeapShared(psMMUHeap))
+ {
+ /* Mark the remove of the Page Table from all memory contexts */
+ MMU_CONTEXT *psMMUContextWalker = (MMU_CONTEXT*) psMMUHeap->psMMUContext->psDevInfo->pvMMUContextList;
+
+ while(psMMUContextWalker)
+ {
+ psMMUContextWalker->ui32PDChangeMask[ui32PDBitMaskIndex] |= 1 << ui32PDBitMaskShift;
+
+ /*
+ * We've just cleared a cache line's worth of PDE's so we need
+ * to wire up the dummy PT
+ */
+ MakeKernelPageReadWrite(psMMUContextWalker->pvPDCpuVAddr);
+ pui32Tmp = (IMG_UINT32 *) psMMUContextWalker->pvPDCpuVAddr;
+ pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PDE_PAGE_SIZE_4K
+ | SGX_MMU_PDE_DUMMY_PAGE
+ | SGX_MMU_PDE_VALID;
+ MakeKernelPageReadOnly(psMMUContextWalker->pvPDCpuVAddr);
+
+ PDUMPCOMMENT("BRN31620 Re-wire dummy PT due to releasing PT allocation block");
+ PDUMPPDENTRIES(&psMMUHeap->sMMUAttrib, psMMUContextWalker->hPDOSMemHandle, (IMG_VOID*)&pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ psMMUContextWalker = psMMUContextWalker->psNext;
+ }
+ }
+ else
+ {
+ psMMUContext->ui32PDChangeMask[ui32PDBitMaskIndex] |= 1 << ui32PDBitMaskShift;
+
+ /*
+ * We've just cleared a cache line's worth of PDE's so we need
+ * to wire up the dummy PT
+ */
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
+ pui32Tmp = (IMG_UINT32 *) psMMUContext->pvPDCpuVAddr;
+ pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PDE_PAGE_SIZE_4K
+ | SGX_MMU_PDE_DUMMY_PAGE
+ | SGX_MMU_PDE_VALID;
+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr);
+
+ PDUMPCOMMENT("BRN31620 Re-wire dummy PT due to releasing PT allocation block");
+ PDUMPPDENTRIES(&psMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ }
+ /* We've freed a cachline's worth of PDE's so trigger a PD cache flush */
+ bFreePTs = IMG_TRUE;
+ }
+
+ return bFreePTs;
+}
+#endif
+
+/*!
+******************************************************************************
+ FUNCTION: _AllocPageTableMemory
+
+ PURPOSE: Allocate physical memory for a page table
+
+ PARAMETERS: In: pMMUHeap - the mmu
+ In: psPTInfoList - PT info
+ Out: psDevPAddr - device physical address for new PT
+ RETURNS: IMG_TRUE - Success
+ IMG_FALSE - Failed
+******************************************************************************/
+static IMG_BOOL
+_AllocPageTableMemory (MMU_HEAP *pMMUHeap,
+ MMU_PT_INFO *psPTInfoList,
+ IMG_DEV_PHYADDR *psDevPAddr)
+{
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_CPU_PHYADDR sCpuPAddr;
+
+ /*
+ depending on the specific system, pagetables are allocated from system memory
+ or device local memory. For now, just look for at least a valid local heap/arena
+ */
+ if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL)
+ {
+ //FIXME: replace with an RA, this allocator only handles 4k allocs
+ if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ pMMUHeap->ui32PTSize,
+ SGX_MMU_PAGE_SIZE,//FIXME: assume 4K page size for now (wastes memory for smaller pagetables
+ IMG_NULL,
+ 0,
+ IMG_NULL,
+ (IMG_VOID **)&psPTInfoList->PTPageCpuVAddr,
+ &psPTInfoList->hPTPageOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR call to OSAllocPages failed"));
+ return IMG_FALSE;
+ }
+
+ /*
+ Force the page to read only, we will make it read/write as
+ and when we need to
+ */
+ MakeKernelPageReadOnly(psPTInfoList->PTPageCpuVAddr);
+
+ /* translate address to device physical */
+ if(psPTInfoList->PTPageCpuVAddr)
+ {
+ sCpuPAddr = OSMapLinToCPUPhys(psPTInfoList->hPTPageOSMemHandle,
+ psPTInfoList->PTPageCpuVAddr);
+ }
+ else
+ {
+ /* This isn't used in all cases since not all ports currently support
+ * OSMemHandleToCpuPAddr() */
+ sCpuPAddr = OSMemHandleToCpuPAddr(psPTInfoList->hPTPageOSMemHandle, 0);
+ }
+
+ sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+ }
+ else
+ {
+ IMG_SYS_PHYADDR sSysPAddr;
+
+ /*
+ just allocate from the first local memory arena
+ (unlikely to be more than one local mem area(?))
+ */
+ //FIXME: just allocate a 4K page for each PT for now
+ if(RA_Alloc(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena,
+ SGX_MMU_PAGE_SIZE,//pMMUHeap->ui32PTSize,
+ IMG_NULL,
+ IMG_NULL,
+ 0,
+ SGX_MMU_PAGE_SIZE,//pMMUHeap->ui32PTSize,
+ 0,
+ IMG_NULL,
+ 0,
+ &(sSysPAddr.uiAddr))!= IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR call to RA_Alloc failed"));
+ return IMG_FALSE;
+ }
+
+ /* derive the CPU virtual address */
+ sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+ /* note: actual ammount is pMMUHeap->ui32PTSize but must be a multiple of 4k pages */
+ psPTInfoList->PTPageCpuVAddr = OSMapPhysToLin(sCpuPAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ &psPTInfoList->hPTPageOSMemHandle);
+ if(!psPTInfoList->PTPageCpuVAddr)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR failed to map page tables"));
+ return IMG_FALSE;
+ }
+
+ /* translate address to device physical */
+ sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+
+ #if PAGE_TEST
+ PageTest(psPTInfoList->PTPageCpuVAddr, sDevPAddr);
+ #endif
+ }
+
+ MakeKernelPageReadWrite(psPTInfoList->PTPageCpuVAddr);
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+ {
+ IMG_UINT32 *pui32Tmp;
+ IMG_UINT32 i;
+
+ pui32Tmp = (IMG_UINT32*)psPTInfoList->PTPageCpuVAddr;
+ /* point the new PT entries to the dummy data page */
+ for(i=0; i<pMMUHeap->ui32PTNumEntriesUsable; i++)
+ {
+ pui32Tmp[i] = (pMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PTE_VALID;
+ }
+ /* zero the remaining allocated entries, if any */
+ for(; i<pMMUHeap->ui32PTNumEntriesAllocated; i++)
+ {
+ pui32Tmp[i] = 0;
+ }
+ }
+#else
+ /* Zero the page table. */
+ OSMemSet(psPTInfoList->PTPageCpuVAddr, 0, pMMUHeap->ui32PTSize);
+#endif
+ MakeKernelPageReadOnly(psPTInfoList->PTPageCpuVAddr);
+
+#if defined(PDUMP)
+ {
+ IMG_UINT32 ui32Flags = 0;
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ /* make sure shared heap PT allocs are always pdumped */
+ ui32Flags |= ( MMU_IsHeapShared(pMMUHeap) ) ? PDUMP_FLAGS_PERSISTENT : 0;
+#endif
+ /* pdump the PT malloc */
+ PDUMPMALLOCPAGETABLE(&pMMUHeap->psMMUContext->psDeviceNode->sDevId, psPTInfoList->hPTPageOSMemHandle, 0, psPTInfoList->PTPageCpuVAddr, pMMUHeap->ui32PTSize, ui32Flags, PDUMP_PT_UNIQUETAG);
+ /* pdump the PT Pages */
+ PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psPTInfoList->hPTPageOSMemHandle, psPTInfoList->PTPageCpuVAddr, pMMUHeap->ui32PTSize, ui32Flags, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ }
+#endif
+
+ /* return the DevPAddr */
+ *psDevPAddr = sDevPAddr;
+
+ return IMG_TRUE;
+}
+
+
+/*!
+******************************************************************************
+ FUNCTION: _FreePageTableMemory
+
+ PURPOSE: Free physical memory for a page table
+
+ PARAMETERS: In: pMMUHeap - the mmu
+ In: psPTInfoList - PT info to free
+ RETURNS: NONE
+******************************************************************************/
+static IMG_VOID
+_FreePageTableMemory (MMU_HEAP *pMMUHeap, MMU_PT_INFO *psPTInfoList)
+{
+ /*
+ free the PT page:
+ depending on the specific system, pagetables are allocated from system memory
+ or device local memory. For now, just look for at least a valid local heap/arena
+ */
+ if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL)
+ {
+ /* Force the page to read write before we free it*/
+ MakeKernelPageReadWrite(psPTInfoList->PTPageCpuVAddr);
+
+ //FIXME: replace with an RA, this allocator only handles 4k allocs
+ OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ pMMUHeap->ui32PTSize,
+ psPTInfoList->PTPageCpuVAddr,
+ psPTInfoList->hPTPageOSMemHandle);
+ }
+ else
+ {
+ IMG_SYS_PHYADDR sSysPAddr;
+ IMG_CPU_PHYADDR sCpuPAddr;
+
+ /* derive the system physical address */
+ sCpuPAddr = OSMapLinToCPUPhys(psPTInfoList->hPTPageOSMemHandle,
+ psPTInfoList->PTPageCpuVAddr);
+ sSysPAddr = SysCpuPAddrToSysPAddr (sCpuPAddr);
+
+ /* unmap the CPU mapping */
+ /* note: actual ammount is pMMUHeap->ui32PTSize but must be a multiple of 4k pages */
+ OSUnMapPhysToLin(psPTInfoList->PTPageCpuVAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ psPTInfoList->hPTPageOSMemHandle);
+
+ /*
+ just free from the first local memory arena
+ (unlikely to be more than one local mem area(?))
+ */
+ RA_Free (pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+ }
+}
+
+
+
+/*!
+******************************************************************************
+ FUNCTION: _DeferredFreePageTable
+
+ PURPOSE: Free one page table associated with an MMU.
+
+ PARAMETERS: In: pMMUHeap - the mmu heap
+ In: ui32PTIndex - index of the page table to free relative
+ to the base of heap.
+ RETURNS: None
+******************************************************************************/
+static IMG_VOID
+_DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOSFreePT)
+{
+ IMG_UINT32 *pui32PDEntry;
+ IMG_UINT32 i;
+ IMG_UINT32 ui32PDIndex;
+ SYS_DATA *psSysData;
+ MMU_PT_INFO **ppsPTInfoList;
+
+ SysAcquireData(&psSysData);
+
+ /* find the index/offset in PD entries */
+ ui32PDIndex = pMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+ /* set the base PT info */
+ ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
+
+ {
+#if PT_DEBUG
+ if(ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount > 0)
+ {
+ DumpPT(ppsPTInfoList[ui32PTIndex]);
+ /* Fall-through, will fail assert */
+ }
+#endif
+
+ /* Assert that all mappings have gone */
+ PVR_ASSERT(ppsPTInfoList[ui32PTIndex] == IMG_NULL || ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount == 0);
+ }
+
+#if defined(PDUMP)
+ {
+ IMG_UINT32 ui32Flags = 0;
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ ui32Flags |= ( MMU_IsHeapShared(pMMUHeap) ) ? PDUMP_FLAGS_PERSISTENT : 0;
+#endif
+ /* pdump the PT free */
+ PDUMPCOMMENT("Free page table (page count == %08X)", pMMUHeap->ui32PageTableCount);
+ if(ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr)
+ {
+ PDUMPFREEPAGETABLE(&pMMUHeap->psMMUContext->psDeviceNode->sDevId, ppsPTInfoList[ui32PTIndex]->hPTPageOSMemHandle, ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr, pMMUHeap->ui32PTSize, ui32Flags, PDUMP_PT_UNIQUETAG);
+ }
+ }
+#endif
+
+ switch(pMMUHeap->psDevArena->DevMemHeapType)
+ {
+ case DEVICE_MEMORY_HEAP_SHARED :
+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED :
+ {
+ /* Remove Page Table from all memory contexts */
+ MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList;
+
+ while(psMMUContext)
+ {
+ /* get the PD CPUVAddr base and advance to the first entry */
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
+ pui32PDEntry = (IMG_UINT32*)psMMUContext->pvPDCpuVAddr;
+ pui32PDEntry += ui32PDIndex;
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+ /* point the PD entry to the dummy PT */
+ pui32PDEntry[ui32PTIndex] = (psMMUContext->psDevInfo->sDummyPTDevPAddr.uiAddr
+ >>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PDE_PAGE_SIZE_4K
+ | SGX_MMU_PDE_VALID;
+#else
+ /* free the entry */
+ if(bOSFreePT)
+ {
+ pui32PDEntry[ui32PTIndex] = 0;
+ }
+#endif
+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr);
+ #if defined(PDUMP)
+ /* pdump the PD Page modifications */
+ #if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ if(psMMUContext->bPDumpActive)
+ #endif
+ {
+ PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ }
+ #endif
+ /* advance to next context */
+ psMMUContext = psMMUContext->psNext;
+ }
+ break;
+ }
+ case DEVICE_MEMORY_HEAP_PERCONTEXT :
+ case DEVICE_MEMORY_HEAP_KERNEL :
+ {
+ MakeKernelPageReadWrite(pMMUHeap->psMMUContext->pvPDCpuVAddr);
+ /* Remove Page Table from this memory context only */
+ pui32PDEntry = (IMG_UINT32*)pMMUHeap->psMMUContext->pvPDCpuVAddr;
+ pui32PDEntry += ui32PDIndex;
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+ /* point the PD entry to the dummy PT */
+ pui32PDEntry[ui32PTIndex] = (pMMUHeap->psMMUContext->psDevInfo->sDummyPTDevPAddr.uiAddr
+ >>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PDE_PAGE_SIZE_4K
+ | SGX_MMU_PDE_VALID;
+#else
+ /* free the entry */
+ if(bOSFreePT)
+ {
+ pui32PDEntry[ui32PTIndex] = 0;
+ }
+#endif
+ MakeKernelPageReadOnly(pMMUHeap->psMMUContext->pvPDCpuVAddr);
+
+ /* pdump the PD Page modifications */
+ PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, pMMUHeap->psMMUContext->hPDOSMemHandle, (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;
+ }
+ }
+
+ /* clear the PT entries in each PT page */
+ if(ppsPTInfoList[ui32PTIndex] != IMG_NULL)
+ {
+ if(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr != IMG_NULL)
+ {
+ IMG_PUINT32 pui32Tmp;
+
+ MakeKernelPageReadWrite(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr);
+ pui32Tmp = (IMG_UINT32*)ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr;
+
+ /* clear the entries */
+ for(i=0;
+ (i<pMMUHeap->ui32PTETotalUsable) && (i<pMMUHeap->ui32PTNumEntriesUsable);
+ i++)
+ {
+ /* over-allocated PT entries for 4MB data page case should never be non-zero */
+ pui32Tmp[i] = 0;
+ }
+ MakeKernelPageReadOnly(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr);
+
+ /*
+ free the pagetable memory
+ */
+ if(bOSFreePT)
+ {
+ _FreePageTableMemory(pMMUHeap, ppsPTInfoList[ui32PTIndex]);
+ }
+
+ /*
+ decrement the PT Entry Count by the number
+ of entries we've cleared in this pass
+ */
+ pMMUHeap->ui32PTETotalUsable -= i;
+ }
+ else
+ {
+ /* decrement the PT Entry Count by a page's worth of entries */
+ pMMUHeap->ui32PTETotalUsable -= pMMUHeap->ui32PTNumEntriesUsable;
+ }
+
+ if(bOSFreePT)
+ {
+ /* free the pt info */
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(MMU_PT_INFO),
+ ppsPTInfoList[ui32PTIndex],
+ IMG_NULL);
+ ppsPTInfoList[ui32PTIndex] = IMG_NULL;
+ }
+ }
+ else
+ {
+ /* decrement the PT Entry Count by a page's worth of usable entries */
+ pMMUHeap->ui32PTETotalUsable -= pMMUHeap->ui32PTNumEntriesUsable;
+ }
+
+ PDUMPCOMMENT("Finished free page table (page count == %08X)", pMMUHeap->ui32PageTableCount);
+}
+
+/*!
+******************************************************************************
+ FUNCTION: _DeferredFreePageTables
+
+ PURPOSE: Free the page tables associated with an MMU.
+
+ PARAMETERS: In: pMMUHeap - the mmu
+ RETURNS: None
+******************************************************************************/
+static IMG_VOID
+_DeferredFreePageTables (MMU_HEAP *pMMUHeap)
+{
+ IMG_UINT32 i;
+#if defined(FIX_HW_BRN_31620)
+ MMU_CONTEXT *psMMUContext = pMMUHeap->psMMUContext;
+ IMG_BOOL bInvalidateDirectoryCache = IMG_FALSE;
+ IMG_UINT32 ui32PDIndex;
+ IMG_UINT32 *pui32Tmp;
+ IMG_UINT32 j;
+#endif
+#if defined(PDUMP)
+ PDUMPCOMMENT("Free PTs (MMU Context ID == %u, PDBaseIndex == %u, PT count == 0x%x)",
+ pMMUHeap->psMMUContext->ui32PDumpMMUContextID,
+ pMMUHeap->ui32PDBaseIndex,
+ pMMUHeap->ui32PageTableCount);
+#endif
+#if defined(FIX_HW_BRN_31620)
+ for(i=0; i<pMMUHeap->ui32PageTableCount; i++)
+ {
+ ui32PDIndex = (pMMUHeap->ui32PDBaseIndex + i);
+
+ if (psMMUContext->apsPTInfoList[ui32PDIndex])
+ {
+ if (psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr)
+ {
+ /*
+ * We have to do this to setup the dummy page as
+ * not all heaps are PD cache size or aligned
+ */
+ for (j=0;j<SGX_MMU_PT_SIZE;j++)
+ {
+ pui32Tmp = (IMG_UINT32 *) psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr;
+ BRN31620InvalidatePageTableEntry(psMMUContext, ui32PDIndex, j, &pui32Tmp[j]);
+ }
+ }
+ /* Free the PT and NULL's out the PTInfo */
+ if (BRN31620FreePageTable(pMMUHeap, ui32PDIndex) == IMG_TRUE)
+ {
+ bInvalidateDirectoryCache = IMG_TRUE;
+ }
+ }
+ }
+
+ /*
+ * Due to freeing PT's in chunks we might need to flush the PT cache
+ * rather then the directory cache
+ */
+ if (bInvalidateDirectoryCache)
+ {
+ MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo);
+ }
+ else
+ {
+ MMU_InvalidatePageTableCache(pMMUHeap->psMMUContext->psDevInfo);
+ }
+#else
+ for(i=0; i<pMMUHeap->ui32PageTableCount; i++)
+ {
+ _DeferredFreePageTable(pMMUHeap, i, IMG_TRUE);
+ }
+ MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo);
+#endif
+}
+
+
+/*!
+******************************************************************************
+ FUNCTION: _DeferredAllocPagetables
+
+ PURPOSE: allocates page tables at time of allocation
+
+ PARAMETERS: In: pMMUHeap - the mmu heap
+ DevVAddr - devVAddr of allocation
+ ui32Size - size of allocation
+ RETURNS: IMG_TRUE - Success
+ IMG_FALSE - Failed
+******************************************************************************/
+static IMG_BOOL
+_DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT32 ui32Size)
+{
+ IMG_UINT32 ui32PageTableCount;
+ IMG_UINT32 ui32PDIndex;
+ IMG_UINT32 i;
+ IMG_UINT32 *pui32PDEntry;
+ MMU_PT_INFO **ppsPTInfoList;
+ SYS_DATA *psSysData;
+ IMG_DEV_VIRTADDR sHighDevVAddr;
+#if defined(FIX_HW_BRN_31620)
+ IMG_BOOL bFlushSystemCache = IMG_FALSE;
+ IMG_BOOL bSharedPT = IMG_FALSE;
+ IMG_DEV_VIRTADDR sDevVAddrRequestStart;
+ IMG_DEV_VIRTADDR sDevVAddrRequestEnd;
+ IMG_UINT32 ui32PDRequestStart;
+ IMG_UINT32 ui32PDRequestEnd;
+ IMG_UINT32 ui32ModifiedCachelines[BRN31620_CACHE_FLUSH_INDEX_SIZE];
+#endif
+
+ /* Check device linear address */
+#if SGX_FEATURE_ADDRESS_SPACE_SIZE < 32
+ PVR_ASSERT(DevVAddr.uiAddr < (1<<SGX_FEATURE_ADDRESS_SPACE_SIZE));
+#endif
+
+ /* get the sysdata */
+ SysAcquireData(&psSysData);
+
+ /* find the index/offset in PD entries */
+ ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+ /* how many PDs does the allocation occupy? */
+ /* first check for overflows */
+ if((UINT32_MAX_VALUE - DevVAddr.uiAddr)
+ < (ui32Size + pMMUHeap->ui32DataPageMask + pMMUHeap->ui32PTMask))
+ {
+ /* detected overflow, clamp to highest address */
+ sHighDevVAddr.uiAddr = UINT32_MAX_VALUE;
+ }
+ else
+ {
+ sHighDevVAddr.uiAddr = DevVAddr.uiAddr
+ + ui32Size
+ + pMMUHeap->ui32DataPageMask
+ + pMMUHeap->ui32PTMask;
+ }
+
+ ui32PageTableCount = sHighDevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+ /* Fix allocation of last 4MB */
+ if (ui32PageTableCount == 0)
+ ui32PageTableCount = 1024;
+
+#if defined(FIX_HW_BRN_31620)
+ for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
+ {
+ ui32ModifiedCachelines[i] = 0;
+ }
+
+ /*****************************************************************/
+ /* Save off requested data and round allocation to PD cache line */
+ /*****************************************************************/
+ sDevVAddrRequestStart = DevVAddr;
+ ui32PDRequestStart = ui32PDIndex;
+ sDevVAddrRequestEnd = sHighDevVAddr;
+ ui32PDRequestEnd = ui32PageTableCount - 1;
+
+ /* Round allocations down to the PD cacheline */
+ DevVAddr.uiAddr = DevVAddr.uiAddr & (~BRN31620_PDE_CACHE_FILL_MASK);
+
+ /* Round the end address of the PD allocation to cacheline */
+ sHighDevVAddr.uiAddr = ((sHighDevVAddr.uiAddr + (BRN31620_PDE_CACHE_FILL_SIZE - 1)) & (~BRN31620_PDE_CACHE_FILL_MASK));
+
+ ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+ ui32PageTableCount = sHighDevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+ /* Fix allocation of last 4MB */
+ if (ui32PageTableCount == 0)
+ ui32PageTableCount = 1024;
+#endif
+
+ ui32PageTableCount -= ui32PDIndex;
+
+ /* get the PD CPUVAddr base and advance to the first entry */
+ pui32PDEntry = (IMG_UINT32*)pMMUHeap->psMMUContext->pvPDCpuVAddr;
+ pui32PDEntry += ui32PDIndex;
+
+ /* and advance to the first PT info list */
+ ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
+
+#if defined(PDUMP)
+ {
+ IMG_UINT32 ui32Flags = 0;
+
+ /* pdump the PD Page modifications */
+ if( MMU_IsHeapShared(pMMUHeap) )
+ {
+ ui32Flags |= PDUMP_FLAGS_CONTINUOUS;
+ }
+ PDUMPCOMMENTWITHFLAGS(ui32Flags, "Alloc PTs (MMU Context ID == %u, PDBaseIndex == %u, Size == 0x%x)",
+ pMMUHeap->psMMUContext->ui32PDumpMMUContextID,
+ pMMUHeap->ui32PDBaseIndex,
+ ui32Size);
+ PDUMPCOMMENTWITHFLAGS(ui32Flags, "Alloc page table (page count == %08X)", ui32PageTableCount);
+ PDUMPCOMMENTWITHFLAGS(ui32Flags, "Page directory mods (page count == %08X)", ui32PageTableCount);
+ }
+#endif
+ /* walk the psPTInfoList to see what needs allocating: */
+ for(i=0; i<ui32PageTableCount; i++)
+ {
+ if(ppsPTInfoList[i] == IMG_NULL)
+ {
+#if defined(FIX_HW_BRN_31620)
+ /* Check if we have a saved PT (i.e. this PDE cache line is still live) */
+ if (pMMUHeap->psMMUContext->apsPTInfoListSave[ui32PDIndex + i])
+ {
+ /* Only make this PTInfo "live" if it's requested */
+ if (((ui32PDIndex + i) >= ui32PDRequestStart) && ((ui32PDIndex + i) <= ui32PDRequestEnd))
+ {
+ IMG_UINT32 ui32PDCacheLine = (ui32PDIndex + i) >> BRN31620_PDES_PER_CACHE_LINE_SHIFT;
+
+ ppsPTInfoList[i] = pMMUHeap->psMMUContext->apsPTInfoListSave[ui32PDIndex + i];
+ pMMUHeap->psMMUContext->apsPTInfoListSave[ui32PDIndex + i] = IMG_NULL;
+
+ pMMUHeap->psMMUContext->ui32PDCacheRangeRefCount[ui32PDCacheLine]++;
+ }
+ }
+ else
+ {
+#endif
+ OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof (MMU_PT_INFO),
+ (IMG_VOID **)&ppsPTInfoList[i], IMG_NULL,
+ "MMU Page Table Info");
+ 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 defined(FIX_HW_BRN_31620)
+ }
+#endif
+ }
+#if defined(FIX_HW_BRN_31620)
+ /* Only try to allocate if ppsPTInfoList[i] is valid */
+ if (ppsPTInfoList[i])
+ {
+#endif
+ if(ppsPTInfoList[i]->hPTPageOSMemHandle == IMG_NULL
+ && ppsPTInfoList[i]->PTPageCpuVAddr == IMG_NULL)
+ {
+ IMG_DEV_PHYADDR sDevPAddr;
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+ IMG_UINT32 *pui32Tmp;
+ IMG_UINT32 j;
+#else
+#if !defined(FIX_HW_BRN_31620)
+ /* no page table has been allocated so allocate one */
+ PVR_ASSERT(pui32PDEntry[i] == 0);
+#endif
+#endif
+ if(_AllocPageTableMemory (pMMUHeap, ppsPTInfoList[i], &sDevPAddr) != IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to _AllocPageTableMemory failed"));
+ return IMG_FALSE;
+ }
+#if defined(FIX_HW_BRN_31620)
+ bFlushSystemCache = IMG_TRUE;
+ /* Bump up the page table count if required */
+ {
+ IMG_UINT32 ui32PD;
+ IMG_UINT32 ui32PDCacheLine;
+ IMG_UINT32 ui32PDBitMaskIndex;
+ IMG_UINT32 ui32PDBitMaskShift;
+
+ ui32PD = ui32PDIndex + i;
+ ui32PDCacheLine = ui32PD >> BRN31620_PDES_PER_CACHE_LINE_SHIFT;
+ ui32PDBitMaskIndex = ui32PDCacheLine >> BRN31620_CACHE_FLUSH_BITS_SHIFT;
+ ui32PDBitMaskShift = ui32PDCacheLine & BRN31620_CACHE_FLUSH_BITS_MASK;
+ ui32ModifiedCachelines[ui32PDBitMaskIndex] |= 1 << ui32PDBitMaskShift;
+
+ /* Add 1 to ui32PD as we want the count, not a range */
+ if ((pMMUHeap->ui32PDBaseIndex + pMMUHeap->ui32PageTableCount) < (ui32PD + 1))
+ {
+ pMMUHeap->ui32PageTableCount = (ui32PD + 1) - pMMUHeap->ui32PDBaseIndex;
+ }
+
+ if (((ui32PDIndex + i) >= ui32PDRequestStart) && ((ui32PDIndex + i) <= ui32PDRequestEnd))
+ {
+ pMMUHeap->psMMUContext->ui32PDCacheRangeRefCount[ui32PDCacheLine]++;
+ }
+ }
+#endif
+ switch(pMMUHeap->psDevArena->DevMemHeapType)
+ {
+ case DEVICE_MEMORY_HEAP_SHARED :
+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED :
+ {
+ /* insert Page Table into all memory contexts */
+ MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList;
+
+ while(psMMUContext)
+ {
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
+ /* get the PD CPUVAddr base and advance to the first entry */
+ pui32PDEntry = (IMG_UINT32*)psMMUContext->pvPDCpuVAddr;
+ pui32PDEntry += ui32PDIndex;
+
+ /* insert the page, specify the data page size and make the pde valid */
+ pui32PDEntry[i] = (sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+ | pMMUHeap->ui32PDEPageSizeCtrl
+ | SGX_MMU_PDE_VALID;
+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr);
+ #if defined(PDUMP)
+ /* pdump the PD Page modifications */
+ #if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ if(psMMUContext->bPDumpActive)
+ #endif
+ {
+ //PDUMPCOMMENT("_DeferredAllocPTs: Dumping shared PDEs on context %d (%s)", psMMUContext->ui32PDumpMMUContextID, (psMMUContext->bPDumpActive) ? "active" : "");
+ PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ }
+ #endif /* PDUMP */
+ /* advance to next context */
+ psMMUContext = psMMUContext->psNext;
+ }
+#if defined(FIX_HW_BRN_31620)
+ bSharedPT = IMG_TRUE;
+#endif
+ break;
+ }
+ case DEVICE_MEMORY_HEAP_PERCONTEXT :
+ case DEVICE_MEMORY_HEAP_KERNEL :
+ {
+ MakeKernelPageReadWrite(pMMUHeap->psMMUContext->pvPDCpuVAddr);
+ /* insert Page Table into only this memory context */
+ pui32PDEntry[i] = (sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+ | pMMUHeap->ui32PDEPageSizeCtrl
+ | SGX_MMU_PDE_VALID;
+ MakeKernelPageReadOnly(pMMUHeap->psMMUContext->pvPDCpuVAddr);
+ /* pdump the PD Page modifications */
+ //PDUMPCOMMENT("_DeferredAllocPTs: Dumping kernel PDEs on context %d (%s)", pMMUHeap->psMMUContext->ui32PDumpMMUContextID, (pMMUHeap->psMMUContext->bPDumpActive) ? "active" : "");
+ PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, pMMUHeap->psMMUContext->hPDOSMemHandle, (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)
+ /* This is actually not to do with multiple mem contexts, but to do with the directory cache.
+ In the 1 context implementation of the MMU, the directory "cache" is actually a copy of the
+ page directory memory, and requires updating whenever the page directory changes, even if there
+ was no previous value in a particular entry
+ */
+ MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo);
+#endif
+#if defined(FIX_HW_BRN_31620)
+ /* If this PT is not in the requested range then save it and null out the main PTInfo */
+ if (((ui32PDIndex + i) < ui32PDRequestStart) || ((ui32PDIndex + i) > ui32PDRequestEnd))
+ {
+ pMMUHeap->psMMUContext->apsPTInfoListSave[ui32PDIndex + i] = ppsPTInfoList[i];
+ ppsPTInfoList[i] = IMG_NULL;
+ }
+#endif
+ }
+ else
+ {
+#if !defined(FIX_HW_BRN_31620)
+ /* already have an allocated PT */
+ PVR_ASSERT(pui32PDEntry[i] != 0);
+#endif
+ }
+#if defined(FIX_HW_BRN_31620)
+ }
+#endif
+ }
+
+ #if defined(SGX_FEATURE_SYSTEM_CACHE)
+ #if defined(FIX_HW_BRN_31620)
+ /* This function might not allocate any new PT's so check before flushing */
+ if (bFlushSystemCache)
+ {
+ #endif
+
+ MMU_InvalidateSystemLevelCache(pMMUHeap->psMMUContext->psDevInfo);
+ #endif /* SGX_FEATURE_SYSTEM_CACHE */
+ #if defined(FIX_HW_BRN_31620)
+ }
+
+ /* Handle the last 4MB roll over */
+ sHighDevVAddr.uiAddr = sHighDevVAddr.uiAddr - 1;
+
+ /* Update our PD flush mask if required */
+ if (bFlushSystemCache)
+ {
+ MMU_CONTEXT *psMMUContext;
+
+ if (bSharedPT)
+ {
+ MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList;
+
+ while(psMMUContext)
+ {
+ for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
+ {
+ psMMUContext->ui32PDChangeMask[i] |= ui32ModifiedCachelines[i];
+ }
+
+ /* advance to next context */
+ psMMUContext = psMMUContext->psNext;
+ }
+ }
+ else
+ {
+ for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
+ {
+ pMMUHeap->psMMUContext->ui32PDChangeMask[i] |= ui32ModifiedCachelines[i];
+ }
+ }
+
+ /*
+ * Always hook up the dummy page when we allocate a new range of PTs.
+ * It might be this is overwritten before the SGX access the dummy page
+ * but we don't care, it's a lot simpler to add this logic here.
+ */
+ psMMUContext = pMMUHeap->psMMUContext;
+ for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
+ {
+ IMG_UINT32 j;
+
+ for(j=0;j<BRN31620_CACHE_FLUSH_BITS_SIZE;j++)
+ {
+ if (ui32ModifiedCachelines[i] & (1 << j))
+ {
+ PVRSRV_SGXDEV_INFO *psDevInfo = psMMUContext->psDevInfo;
+ MMU_PT_INFO *psTempPTInfo = IMG_NULL;
+ IMG_UINT32 *pui32Tmp;
+
+ ui32PDIndex = (((i * BRN31620_CACHE_FLUSH_BITS_SIZE) + j) * BRN31620_PDES_PER_CACHE_LINE_SIZE) + BRN31620_DUMMY_PDE_INDEX;
+
+ /* The PT for the dummy page might not be "live". If not get it from the saved pointer */
+ if (psMMUContext->apsPTInfoList[ui32PDIndex])
+ {
+ psTempPTInfo = psMMUContext->apsPTInfoList[ui32PDIndex];
+ }
+ else
+ {
+ psTempPTInfo = psMMUContext->apsPTInfoListSave[ui32PDIndex];
+ }
+
+ PVR_ASSERT(psTempPTInfo != IMG_NULL);
+
+ MakeKernelPageReadWrite(psTempPTInfo->PTPageCpuVAddr);
+ pui32Tmp = (IMG_UINT32 *) psTempPTInfo->PTPageCpuVAddr;
+ PVR_ASSERT(pui32Tmp != IMG_NULL);
+ pui32Tmp[BRN31620_DUMMY_PTE_INDEX] = (psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PTE_DUMMY_PAGE
+ | SGX_MMU_PTE_READONLY
+ | SGX_MMU_PTE_VALID;
+ MakeKernelPageReadOnly(psTempPTInfo->PTPageCpuVAddr);
+ PDUMPCOMMENT("BRN31620 Dump PTE for dummy page after wireing up new PT");
+ PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psTempPTInfo->hPTPageOSMemHandle, (IMG_VOID *) &pui32Tmp[BRN31620_DUMMY_PTE_INDEX], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ }
+ }
+ }
+ }
+ #endif
+
+ return IMG_TRUE;
+}
+
+
+#if defined(PDUMP)
+/*!
+ * FUNCTION: MMU_GetPDumpContextID
+ *
+ * RETURNS: pdump MMU context ID
+ */
+IMG_UINT32 MMU_GetPDumpContextID(IMG_HANDLE hDevMemContext)
+{
+ BM_CONTEXT *pBMContext = hDevMemContext;
+ PVR_ASSERT(pBMContext);
+ /* PRQA S 0505 1 */ /* PVR_ASSERT should catch NULL ptr */
+ return pBMContext->psMMUContext->ui32PDumpMMUContextID;
+}
+
+/*!
+ * FUNCTION: MMU_SetPDumpAttribs
+ *
+ * PURPOSE: Called from MMU_Initialise and MMU_Create.
+ * Sets up device-specific attributes for pdumping.
+ * FIXME: breaks variable size PTs. Really need separate per context
+ * and per heap attribs.
+ *
+ * INPUT: psDeviceNode - used to access deviceID
+ * INPUT: ui32DataPageMask - data page mask
+ * INPUT: ui32PTSize - PT size
+ *
+ * OUTPUT: psMMUAttrib - pdump MMU attributes
+ *
+ * RETURNS: none
+ */
+#if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
+# error "FIXME: breaks variable size pagetables"
+#endif
+static IMG_VOID MMU_SetPDumpAttribs(PDUMP_MMU_ATTRIB *psMMUAttrib,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_UINT32 ui32DataPageMask,
+ IMG_UINT32 ui32PTSize)
+{
+ /* Sets up device ID, contains pdump memspace name */
+ psMMUAttrib->sDevId = psDeviceNode->sDevId;
+
+ psMMUAttrib->pszPDRegRegion = IMG_NULL;
+ psMMUAttrib->ui32DataPageMask = ui32DataPageMask;
+
+ psMMUAttrib->ui32PTEValid = SGX_MMU_PTE_VALID;
+ psMMUAttrib->ui32PTSize = ui32PTSize;
+ psMMUAttrib->ui32PTEAlignShift = SGX_MMU_PTE_ADDR_ALIGNSHIFT;
+
+ psMMUAttrib->ui32PDEMask = SGX_MMU_PDE_ADDR_MASK;
+ psMMUAttrib->ui32PDEAlignShift = SGX_MMU_PDE_ADDR_ALIGNSHIFT;
+}
+#endif /* PDUMP */
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_Initialise
+
+ PURPOSE: Called from BM_CreateContext.
+ Allocates the top level Page Directory 4k Page for the new context.
+
+ PARAMETERS: None
+ RETURNS: PVRSRV_ERROR
+******************************************************************************/
+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 = IMG_NULL;
+ SYS_DATA *psSysData;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+#if defined(PDUMP)
+ PDUMP_MMU_ATTRIB sMMUAttrib;
+#endif
+ PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Initialise"));
+
+ SysAcquireData(&psSysData);
+#if defined(PDUMP)
+ /* Note: these attribs are on the stack, used only to pdump the MMU context
+ * creation. */
+ MMU_SetPDumpAttribs(&sMMUAttrib, psDeviceNode,
+ SGX_MMU_PAGE_MASK,
+ SGX_MMU_PT_SIZE * sizeof(IMG_UINT32));
+#endif
+
+ OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof (MMU_CONTEXT),
+ (IMG_VOID **)&psMMUContext, IMG_NULL,
+ "MMU Context");
+ if (psMMUContext == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocMem failed"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ OSMemSet (psMMUContext, 0, sizeof(MMU_CONTEXT));
+
+ /* stick the devinfo in the context for subsequent use */
+ psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+ psMMUContext->psDevInfo = psDevInfo;
+
+ /* record device node for subsequent use */
+ psMMUContext->psDeviceNode = psDeviceNode;
+
+ /* allocate 4k page directory page for the new context */
+ if(psDeviceNode->psLocalDevMemArena == IMG_NULL)
+ {
+ if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ 0,
+ IMG_NULL,
+ &pvPDCpuVAddr,
+ &hPDOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
+ }
+
+ if(pvPDCpuVAddr)
+ {
+ sCpuPAddr = OSMapLinToCPUPhys(hPDOSMemHandle,
+ pvPDCpuVAddr);
+ }
+ else
+ {
+ /* This is not used in all cases, since not all ports currently
+ * support OSMemHandleToCpuPAddr */
+ 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)
+ /* Allocate dummy PT and Data pages for the first context to be created */
+ if(!psDevInfo->pvMMUContextList)
+ {
+ /* Dummy PT page */
+ if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ 0,
+ IMG_NULL,
+ &psDevInfo->pvDummyPTPageCpuVAddr,
+ &psDevInfo->hDummyPTPageOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
+ }
+
+ if(psDevInfo->pvDummyPTPageCpuVAddr)
+ {
+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hDummyPTPageOSMemHandle,
+ psDevInfo->pvDummyPTPageCpuVAddr);
+ }
+ else
+ {
+ /* This is not used in all cases, since not all ports currently
+ * support OSMemHandleToCpuPAddr */
+ sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hDummyPTPageOSMemHandle, 0);
+ }
+ psDevInfo->sDummyPTDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+
+ /* Dummy Data page */
+ if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ 0,
+ IMG_NULL,
+ &psDevInfo->pvDummyDataPageCpuVAddr,
+ &psDevInfo->hDummyDataPageOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
+ }
+
+ if(psDevInfo->pvDummyDataPageCpuVAddr)
+ {
+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hDummyPTPageOSMemHandle,
+ psDevInfo->pvDummyDataPageCpuVAddr);
+ }
+ else
+ {
+ sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hDummyDataPageOSMemHandle, 0);
+ }
+ psDevInfo->sDummyDataDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+ }
+#endif /* #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) */
+#if defined(FIX_HW_BRN_31620)
+ /* Allocate dummy Data pages for the first context to be created */
+ if(!psDevInfo->pvMMUContextList)
+ {
+ IMG_UINT32 j;
+ /* Allocate dummy page */
+ if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ 0,
+ IMG_NULL,
+ &psDevInfo->pvBRN31620DummyPageCpuVAddr,
+ &psDevInfo->hBRN31620DummyPageOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
+ }
+
+ /* Get a physical address */
+ if(psDevInfo->pvBRN31620DummyPageCpuVAddr)
+ {
+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hBRN31620DummyPageOSMemHandle,
+ psDevInfo->pvBRN31620DummyPageCpuVAddr);
+ }
+ else
+ {
+ sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hBRN31620DummyPageOSMemHandle, 0);
+ }
+
+ pui32Tmp = (IMG_UINT32 *)psDevInfo->pvBRN31620DummyPageCpuVAddr;
+ for(j=0; j<(SGX_MMU_PAGE_SIZE/4); j++)
+ {
+ pui32Tmp[j] = BRN31620_DUMMY_PAGE_SIGNATURE;
+ }
+
+ psDevInfo->sBRN31620DummyPageDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+ PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, 0, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+
+ /* Allocate dummy PT */
+ if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ 0,
+ IMG_NULL,
+ &psDevInfo->pvBRN31620DummyPTCpuVAddr,
+ &psDevInfo->hBRN31620DummyPTOSMemHandle) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
+ }
+
+ /* Get a physical address */
+ if(psDevInfo->pvBRN31620DummyPTCpuVAddr)
+ {
+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hBRN31620DummyPTOSMemHandle,
+ psDevInfo->pvBRN31620DummyPTCpuVAddr);
+ }
+ else
+ {
+ sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hBRN31620DummyPTOSMemHandle, 0);
+ }
+
+ OSMemSet(psDevInfo->pvBRN31620DummyPTCpuVAddr,0,SGX_MMU_PAGE_SIZE);
+ psDevInfo->sBRN31620DummyPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
+ PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPTOSMemHandle, 0, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+ }
+#endif
+ }
+ else
+ {
+ IMG_SYS_PHYADDR sSysPAddr;
+
+ /* allocate from the device's local memory arena */
+ if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ IMG_NULL,
+ 0,
+ SGX_MMU_PAGE_SIZE,
+ 0,
+ IMG_NULL,
+ 0,
+ &(sSysPAddr.uiAddr))!= IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY;
+ }
+
+ /* derive the CPU virtual address */
+ 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_FAILED_TO_MAP_PAGE_TABLE;
+ }
+
+ #if PAGE_TEST
+ PageTest(pvPDCpuVAddr, sPDDevPAddr);
+ #endif
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+ /* Allocate dummy PT and Data pages for the first context to be created */
+ if(!psDevInfo->pvMMUContextList)
+ {
+ /* Dummy PT page */
+ if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ IMG_NULL,
+ 0,
+ SGX_MMU_PAGE_SIZE,
+ 0,
+ IMG_NULL,
+ 0,
+ &(sSysPAddr.uiAddr))!= IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY;
+ }
+
+ /* derive the CPU virtual address */
+ 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_FAILED_TO_MAP_PAGE_TABLE;
+ }
+
+ /* Dummy Data page */
+ if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ IMG_NULL,
+ 0,
+ SGX_MMU_PAGE_SIZE,
+ 0,
+ IMG_NULL,
+ 0,
+ &(sSysPAddr.uiAddr))!= IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY;
+ }
+
+ /* derive the CPU virtual address */
+ 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_FAILED_TO_MAP_PAGE_TABLE;
+ }
+ }
+#endif /* #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) */
+#if defined(FIX_HW_BRN_31620)
+ /* Allocate dummy PT and Data pages for the first context to be created */
+ if(!psDevInfo->pvMMUContextList)
+ {
+ IMG_UINT32 j;
+ /* Allocate dummy page */
+ if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ IMG_NULL,
+ 0,
+ SGX_MMU_PAGE_SIZE,
+ 0,
+ IMG_NULL,
+ 0,
+ &(sSysPAddr.uiAddr))!= IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY;
+ }
+
+ /* derive the CPU virtual address */
+ sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+ psDevInfo->sBRN31620DummyPageDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
+ psDevInfo->pvBRN31620DummyPageCpuVAddr = OSMapPhysToLin(sCpuPAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ &psDevInfo->hBRN31620DummyPageOSMemHandle);
+ if(!psDevInfo->pvBRN31620DummyPageCpuVAddr)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
+ return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
+ }
+
+ MakeKernelPageReadWrite(psDevInfo->pvBRN31620DummyPageCpuVAddr);
+ pui32Tmp = (IMG_UINT32 *)psDevInfo->pvBRN31620DummyPageCpuVAddr;
+ for(j=0; j<(SGX_MMU_PAGE_SIZE/4); j++)
+ {
+ pui32Tmp[j] = BRN31620_DUMMY_PAGE_SIGNATURE;
+ }
+ MakeKernelPageReadOnly(psDevInfo->pvBRN31620DummyPageCpuVAddr);
+ PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, 0, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+
+ /* Allocate dummy PT */
+ if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ IMG_NULL,
+ 0,
+ SGX_MMU_PAGE_SIZE,
+ 0,
+ IMG_NULL,
+ 0,
+ &(sSysPAddr.uiAddr))!= IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY;
+ }
+
+ /* derive the CPU virtual address */
+ sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
+ psDevInfo->sBRN31620DummyPTDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
+ psDevInfo->pvBRN31620DummyPTCpuVAddr = OSMapPhysToLin(sCpuPAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ &psDevInfo->hBRN31620DummyPTOSMemHandle);
+
+ if(!psDevInfo->pvBRN31620DummyPTCpuVAddr)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
+ return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
+ }
+
+ OSMemSet(psDevInfo->pvBRN31620DummyPTCpuVAddr,0,SGX_MMU_PAGE_SIZE);
+ PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPTOSMemHandle, 0, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+ }
+#endif /* #if defined(FIX_HW_BRN_31620) */
+ }
+
+#if defined(FIX_HW_BRN_31620)
+ if (!psDevInfo->pvMMUContextList)
+ {
+ /* Save the kernel MMU context which is always the 1st to be created */
+ psDevInfo->hKernelMMUContext = psMMUContext;
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: saving kernel mmu context: %p", psMMUContext));
+ }
+#endif
+
+#if defined(PDUMP)
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ /* Find out if this context is for the active pdump client.
+ * If it is, need to ensure PD entries are pdumped whenever another
+ * process allocates from a shared heap. */
+ {
+ PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+ if(psPerProc == IMG_NULL)
+ {
+ /* changes to the kernel context PD/PTs should be pdumped */
+ psMMUContext->bPDumpActive = IMG_TRUE;
+ }
+ else
+ {
+ psMMUContext->bPDumpActive = psPerProc->bPDumpActive;
+ }
+ }
+#endif /* SUPPORT_PDUMP_MULTI_PROCESS */
+ /* pdump the PD malloc */
+#if IMG_ADDRSPACE_PHYSADDR_BITS == 32
+ PDUMPCOMMENT("Alloc page directory for new MMU context (PDDevPAddr == 0x%08x)",
+ sPDDevPAddr.uiAddr);
+#else
+ PDUMPCOMMENT("Alloc page directory for new MMU context, 64-bit arch detected (PDDevPAddr == 0x%08x%08x)",
+ sPDDevPAddr.uiHighAddr, sPDDevPAddr.uiAddr);
+#endif
+ PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, hPDOSMemHandle, 0, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PD_UNIQUETAG);
+#endif /* PDUMP */
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+ EnableHostAccess(psMMUContext);
+#endif
+
+ if (pvPDCpuVAddr)
+ {
+ pui32Tmp = (IMG_UINT32 *)pvPDCpuVAddr;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: pvPDCpuVAddr invalid"));
+ return PVRSRV_ERROR_INVALID_CPU_ADDR;
+ }
+
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+ MakeKernelPageReadWrite(pvPDCpuVAddr);
+ /* wire-up the new PD to the dummy PT */
+ for(i=0; i<SGX_MMU_PD_SIZE; i++)
+ {
+ pui32Tmp[i] = (psDevInfo->sDummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PDE_PAGE_SIZE_4K
+ | SGX_MMU_PDE_VALID;
+ }
+ MakeKernelPageReadOnly(pvPDCpuVAddr);
+
+ if(!psDevInfo->pvMMUContextList)
+ {
+ /*
+ if we've just allocated the dummy pages
+ wire up the dummy PT to the dummy data page
+ */
+ MakeKernelPageReadWrite(psDevInfo->pvDummyPTPageCpuVAddr);
+ pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyPTPageCpuVAddr;
+ for(i=0; i<SGX_MMU_PT_SIZE; i++)
+ {
+ pui32Tmp[i] = (psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PTE_VALID;
+ }
+ MakeKernelPageReadOnly(psDevInfo->pvDummyPTPageCpuVAddr);
+ /* pdump the Dummy PT Page */
+ PDUMPCOMMENT("Dummy Page table contents");
+ PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hDummyPTOSMemHandle, psDevInfo->pvDummyPTPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+
+ /*
+ write a signature to the dummy data page
+ */
+ MakeKernelPageReadWrite(psDevInfo->pvDummyDataPageCpuVAddr);
+ pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyDataPageCpuVAddr;
+ for(i=0; i<(SGX_MMU_PAGE_SIZE/4); i++)
+ {
+ pui32Tmp[i] = DUMMY_DATA_PAGE_SIGNATURE;
+ }
+ MakeKernelPageReadOnly(psDevInfo->pvDummyDataPageCpuVAddr);
+ /* pdump the Dummy Data Page */
+ PDUMPCOMMENT("Dummy Data Page contents");
+ PDUMPMEMPTENTRIES(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->hDummyDataPageOSMemHandle, psDevInfo->pvDummyDataPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ }
+#else /* #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) */
+ /* initialise the PD to invalid address state */
+ MakeKernelPageReadWrite(pvPDCpuVAddr);
+ for(i=0; i<SGX_MMU_PD_SIZE; i++)
+ {
+ /* invalid, no read, no write, no cache consistency */
+ pui32Tmp[i] = 0;
+ }
+ MakeKernelPageReadOnly(pvPDCpuVAddr);
+#endif /* #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) */
+
+#if defined(PDUMP)
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ if(psMMUContext->bPDumpActive)
+#endif /* SUPPORT_PDUMP_MULTI_PROCESS */
+ {
+ /* pdump the PD Page */
+ PDUMPCOMMENT("Page directory contents");
+ PDUMPPDENTRIES(&sMMUAttrib, hPDOSMemHandle, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ }
+#endif
+#if defined(FIX_HW_BRN_31620)
+ {
+ IMG_UINT32 i;
+ IMG_UINT32 ui32PDCount = 0;
+ IMG_UINT32 *pui32PT;
+ pui32Tmp = (IMG_UINT32 *)pvPDCpuVAddr;
+
+ PDUMPCOMMENT("BRN31620 Set up dummy PT");
+
+ MakeKernelPageReadWrite(psDevInfo->pvBRN31620DummyPTCpuVAddr);
+ pui32PT = (IMG_UINT32 *) psDevInfo->pvBRN31620DummyPTCpuVAddr;
+ pui32PT[BRN31620_DUMMY_PTE_INDEX] = (psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PTE_DUMMY_PAGE
+ | SGX_MMU_PTE_READONLY
+ | SGX_MMU_PTE_VALID;
+ MakeKernelPageReadOnly(psDevInfo->pvBRN31620DummyPTCpuVAddr);
+
+#if defined(PDUMP)
+ /* Dump initial contents */
+ PDUMPCOMMENT("BRN31620 Dump dummy PT contents");
+ PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hBRN31620DummyPTOSMemHandle, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ PDUMPCOMMENT("BRN31620 Dump dummy page contents");
+ PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hBRN31620DummyPageOSMemHandle, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+
+ /* Dump the wiring */
+ for(i=0;i<SGX_MMU_PT_SIZE;i++)
+ {
+ PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hBRN31620DummyPTOSMemHandle, &pui32PT[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ }
+#endif
+ PDUMPCOMMENT("BRN31620 Dump PDE wire up");
+ /* Walk the PD wireing up the PT's */
+ for(i=0;i<SGX_MMU_PD_SIZE;i++)
+ {
+ pui32Tmp[i] = 0;
+
+ if (ui32PDCount == BRN31620_DUMMY_PDE_INDEX)
+ {
+ MakeKernelPageReadWrite(pvPDCpuVAddr);
+ pui32Tmp[i] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PDE_PAGE_SIZE_4K
+ | SGX_MMU_PDE_DUMMY_PAGE
+ | SGX_MMU_PDE_VALID;
+ MakeKernelPageReadOnly(pvPDCpuVAddr);
+ }
+ PDUMPMEMPTENTRIES(&sMMUAttrib, hPDOSMemHandle, (IMG_VOID *) &pui32Tmp[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ ui32PDCount++;
+ if (ui32PDCount == BRN31620_PDES_PER_CACHE_LINE_SIZE)
+ {
+ /* Reset PT count */
+ ui32PDCount = 0;
+ }
+ }
+
+
+ /* pdump the Dummy PT Page */
+ PDUMPCOMMENT("BRN31620 dummy Page table contents");
+ PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hBRN31620DummyPageOSMemHandle, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ }
+#endif
+#if defined(PDUMP)
+ /* pdump set MMU context */
+ {
+ PVRSRV_ERROR eError;
+ /* default MMU type is 1, 4k page */
+ IMG_UINT32 ui32MMUType = 1;
+
+ #if defined(SGX_FEATURE_36BIT_MMU)
+ ui32MMUType = 3;
+ #else
+ #if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
+ ui32MMUType = 2;
+ #endif
+ #endif
+
+ eError = PDumpSetMMUContext(PVRSRV_DEVICE_TYPE_SGX,
+ psDeviceNode->sDevId.pszPDumpDevName,
+ &psMMUContext->ui32PDumpMMUContextID,
+ ui32MMUType,
+ PDUMP_PT_UNIQUETAG,
+ hPDOSMemHandle,
+ pvPDCpuVAddr);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to PDumpSetMMUContext failed"));
+ return eError;
+ }
+ }
+
+ /* PDump the context ID */
+ PDUMPCOMMENT("Set MMU context complete (MMU Context ID == %u)", psMMUContext->ui32PDumpMMUContextID);
+#endif
+
+#if defined(FIX_HW_BRN_31620)
+ for(i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
+ {
+ psMMUContext->ui32PDChangeMask[i] = 0;
+ }
+
+ for(i=0;i<BRN31620_CACHE_FLUSH_SIZE;i++)
+ {
+ psMMUContext->ui32PDCacheRangeRefCount[i] = 0;
+ }
+
+ for(i=0;i<SGX_MAX_PD_ENTRIES;i++)
+ {
+ psMMUContext->apsPTInfoListSave[i] = IMG_NULL;
+ }
+#endif
+ /* store PD info in the MMU context */
+ psMMUContext->pvPDCpuVAddr = pvPDCpuVAddr;
+ psMMUContext->sPDDevPAddr = sPDDevPAddr;
+ psMMUContext->hPDOSMemHandle = hPDOSMemHandle;
+
+ /* Get some process information to aid debug */
+ psMMUContext->ui32PID = OSGetCurrentProcessIDKM();
+ psMMUContext->szName[0] = '\0';
+ OSGetCurrentProcessNameKM(psMMUContext->szName, MMU_CONTEXT_NAME_SIZE);
+
+ /* return context */
+ *ppsMMUContext = psMMUContext;
+
+ /* return the PD DevVAddr */
+ *psPDDevPAddr = sPDDevPAddr;
+
+
+ /* add the new MMU context onto the list of MMU contexts */
+ psMMUContext->psNext = (MMU_CONTEXT*)psDevInfo->pvMMUContextList;
+ psDevInfo->pvMMUContextList = (IMG_VOID*)psMMUContext;
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+ DisableHostAccess(psMMUContext);
+#endif
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_Finalise
+
+ PURPOSE: Finalise the mmu module, deallocate all resources.
+
+ PARAMETERS: In: psMMUContext - MMU context to deallocate
+ RETURNS: None.
+******************************************************************************/
+IMG_VOID
+MMU_Finalise (MMU_CONTEXT *psMMUContext)
+{
+ IMG_UINT32 *pui32Tmp, i;
+ SYS_DATA *psSysData;
+ MMU_CONTEXT **ppsMMUContext;
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) || defined(FIX_HW_BRN_31620)
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psMMUContext->psDevInfo;
+ MMU_CONTEXT *psMMUContextList = (MMU_CONTEXT*)psDevInfo->pvMMUContextList;
+#endif
+
+ SysAcquireData(&psSysData);
+
+#if defined(PDUMP)
+ /* pdump the MMU context clear */
+ PDUMPCOMMENT("Clear MMU context (MMU Context ID == %u)", psMMUContext->ui32PDumpMMUContextID);
+ PDUMPCLEARMMUCONTEXT(PVRSRV_DEVICE_TYPE_SGX, psMMUContext->psDeviceNode->sDevId.pszPDumpDevName, psMMUContext->ui32PDumpMMUContextID, 2);
+
+ /* pdump the PD free */
+#if IMG_ADDRSPACE_PHYSADDR_BITS == 32
+ PDUMPCOMMENT("Free page directory (PDDevPAddr == 0x%08x)",
+ psMMUContext->sPDDevPAddr.uiAddr);
+#else
+ PDUMPCOMMENT("Free page directory, 64-bit arch detected (PDDevPAddr == 0x%08x%08x)",
+ psMMUContext->sPDDevPAddr.uiHighAddr, psMMUContext->sPDDevPAddr.uiAddr);
+#endif
+#endif /* PDUMP */
+
+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psMMUContext->hPDOSMemHandle, psMMUContext->pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hDummyPTPageOSMemHandle, psDevInfo->pvDummyPTPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hDummyDataPageOSMemHandle, psDevInfo->pvDummyDataPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+#endif
+
+ pui32Tmp = (IMG_UINT32 *)psMMUContext->pvPDCpuVAddr;
+
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
+ /* initialise the PD to invalid address state */
+ for(i=0; i<SGX_MMU_PD_SIZE; i++)
+ {
+ /* invalid, no read, no write, no cache consistency */
+ pui32Tmp[i] = 0;
+ }
+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr);
+
+ /*
+ free the PD:
+ depending on the specific system, the PD is allocated from system memory
+ or device local memory. For now, just look for at least a valid local heap/arena
+ */
+ if(psMMUContext->psDeviceNode->psLocalDevMemArena == IMG_NULL)
+ {
+#if defined(FIX_HW_BRN_31620)
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psMMUContext->psDevInfo;
+#endif
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
+ OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ psMMUContext->pvPDCpuVAddr,
+ psMMUContext->hPDOSMemHandle);
+
+#if defined(FIX_HW_BRN_31620)
+ /* If this is the _last_ MMU context it must be the uKernel */
+ if (!psMMUContextList->psNext)
+ {
+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+ OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ psDevInfo->pvBRN31620DummyPageCpuVAddr,
+ psDevInfo->hBRN31620DummyPageOSMemHandle);
+
+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPTOSMemHandle, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+ OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ SGX_MMU_PAGE_SIZE,
+ psDevInfo->pvBRN31620DummyPTCpuVAddr,
+ psDevInfo->hBRN31620DummyPTOSMemHandle);
+
+ }
+#endif
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+ /* if this is the last context free the dummy pages too */
+ 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;
+
+ /* derive the system physical address */
+ sCpuPAddr = OSMapLinToCPUPhys(psMMUContext->hPDOSMemHandle,
+ psMMUContext->pvPDCpuVAddr);
+ sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
+
+ /* unmap the CPU mapping */
+ OSUnMapPhysToLin(psMMUContext->pvPDCpuVAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ psMMUContext->hPDOSMemHandle);
+ /* and free the memory */
+ RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+ /* if this is the last context free the dummy pages too */
+ if(!psMMUContextList->psNext)
+ {
+ /* free the Dummy PT Page */
+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hDummyPTPageOSMemHandle,
+ psDevInfo->pvDummyPTPageCpuVAddr);
+ sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
+
+ /* unmap the CPU mapping */
+ OSUnMapPhysToLin(psDevInfo->pvDummyPTPageCpuVAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ psDevInfo->hDummyPTPageOSMemHandle);
+ /* and free the memory */
+ RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+
+ /* free the Dummy Data Page */
+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hDummyDataPageOSMemHandle,
+ psDevInfo->pvDummyDataPageCpuVAddr);
+ sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
+
+ /* unmap the CPU mapping */
+ OSUnMapPhysToLin(psDevInfo->pvDummyDataPageCpuVAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ psDevInfo->hDummyDataPageOSMemHandle);
+ /* and free the memory */
+ RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+ }
+#endif
+#if defined(FIX_HW_BRN_31620)
+ /* if this is the last context free the dummy pages too */
+ if(!psMMUContextList->psNext)
+ {
+ /* free the Page */
+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+
+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hBRN31620DummyPageOSMemHandle,
+ psDevInfo->pvBRN31620DummyPageCpuVAddr);
+ sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
+
+ /* unmap the CPU mapping */
+ OSUnMapPhysToLin(psDevInfo->pvBRN31620DummyPageCpuVAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ psDevInfo->hBRN31620DummyPageOSMemHandle);
+ /* and free the memory */
+ RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+
+ /* free the Dummy PT */
+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPTOSMemHandle, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
+
+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hBRN31620DummyPTOSMemHandle,
+ psDevInfo->pvBRN31620DummyPTCpuVAddr);
+ sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
+
+ /* unmap the CPU mapping */
+ OSUnMapPhysToLin(psDevInfo->pvBRN31620DummyPTCpuVAddr,
+ SGX_MMU_PAGE_SIZE,
+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
+ psDevInfo->hBRN31620DummyPTOSMemHandle);
+ /* and free the memory */
+ RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
+ }
+#endif
+ }
+
+ PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Finalise"));
+
+ /* remove the MMU context from the list of MMU contexts */
+ ppsMMUContext = (MMU_CONTEXT**)&psMMUContext->psDevInfo->pvMMUContextList;
+ while(*ppsMMUContext)
+ {
+ if(*ppsMMUContext == psMMUContext)
+ {
+ /* remove item from the list */
+ *ppsMMUContext = psMMUContext->psNext;
+ break;
+ }
+
+ /* advance to next next */
+ ppsMMUContext = &((*ppsMMUContext)->psNext);
+ }
+
+ /* free the context itself. */
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_CONTEXT), psMMUContext, IMG_NULL);
+ /*not nulling pointer, copy on stack*/
+}
+
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_InsertHeap
+
+ PURPOSE: Copies PDEs from shared/exported heap into current MMU context.
+
+ PARAMETERS: In: psMMUContext - the mmu
+ In: psMMUHeap - a shared/exported heap
+
+ RETURNS: None
+******************************************************************************/
+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
+
+ /* advance to the first entry */
+ pui32PDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
+ pui32KernelPDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
+
+ /*
+ update the PD range relating to the heap's
+ device virtual address range
+ */
+#if defined(PDUMP)
+ PDUMPCOMMENT("Page directory shared heap range copy");
+ PDUMPCOMMENT(" (Source heap MMU Context ID == %u, PT count == 0x%x)",
+ psMMUHeap->psMMUContext->ui32PDumpMMUContextID,
+ psMMUHeap->ui32PageTableCount);
+ PDUMPCOMMENT(" (Destination MMU Context ID == %u)", psMMUContext->ui32PDumpMMUContextID);
+#endif /* PDUMP */
+#ifdef SUPPORT_SGX_MMU_BYPASS
+ EnableHostAccess(psMMUContext);
+#endif
+
+ for (ui32PDEntry = 0; ui32PDEntry < psMMUHeap->ui32PageTableCount; ui32PDEntry++)
+ {
+#if (!defined(SUPPORT_SGX_MMU_DUMMY_PAGE)) && (!defined(FIX_HW_BRN_31620))
+ /* check we have invalidated target PDEs */
+ PVR_ASSERT(pui32PDCpuVAddr[ui32PDEntry] == 0);
+#endif
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
+ /* copy over the PDEs */
+ pui32PDCpuVAddr[ui32PDEntry] = pui32KernelPDCpuVAddr[ui32PDEntry];
+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr);
+ if (pui32PDCpuVAddr[ui32PDEntry])
+ {
+ /* Ensure the shared heap allocation is mapped into the context/PD
+ * for the active pdump process/app. The PTs and backing physical
+ * should also be pdumped (elsewhere).
+ * MALLOC (PT)
+ * LDB (init PT)
+ * MALLOC (data page)
+ * WRW (PTE->data page)
+ * LDB (init data page) -- could be useful to ensure page is initialised
+ */
+ #if defined(PDUMP)
+ //PDUMPCOMMENT("MMU_InsertHeap: Mapping shared heap to new context %d (%s)", psMMUContext->ui32PDumpMMUContextID, (psMMUContext->bPDumpActive) ? "active" : "");
+ #if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ if(psMMUContext->bPDumpActive)
+ #endif /* SUPPORT_PDUMP_MULTI_PROCESS */
+ {
+ PDUMPPDENTRIES(&psMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID *) &pui32PDCpuVAddr[ui32PDEntry], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ }
+ #endif
+#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)
+ {
+ /* This is actually not to do with multiple mem contexts, but to do with the directory cache.
+ In the 1 context implementation of the MMU, the directory "cache" is actually a copy of the
+ page directory memory, and requires updating whenever the page directory changes, even if there
+ was no previous value in a particular entry
+ */
+ MMU_InvalidateDirectoryCache(psMMUContext->psDevInfo);
+ }
+#endif
+}
+
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_UnmapPagesAndFreePTs
+
+ PURPOSE: unmap pages, invalidate virtual address and try to free the PTs
+
+ PARAMETERS: In: psMMUHeap - the mmu.
+ In: sDevVAddr - the device virtual address.
+ In: ui32PageCount - page count
+ In: hUniqueTag - A unique ID for use as a tag identifier
+
+ RETURNS: None
+******************************************************************************/
+static IMG_VOID
+MMU_UnmapPagesAndFreePTs (MMU_HEAP *psMMUHeap,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_UINT32 ui32PageCount,
+ IMG_HANDLE hUniqueTag)
+{
+ 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
+ /* setup tmp devvaddr to base of allocation */
+ sTmpDevVAddr = sDevVAddr;
+
+ for(i=0; i<ui32PageCount; i++)
+ {
+ MMU_PT_INFO **ppsPTInfoList;
+
+ /* find the index/offset in PD entries */
+ ui32PDIndex = sTmpDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
+
+ /* and advance to the first PT info list */
+ ppsPTInfoList = &psMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
+
+ {
+ /* find the index/offset of the first PT in the first PT page */
+ ui32PTIndex = (sTmpDevVAddr.uiAddr & psMMUHeap->ui32PTMask) >> psMMUHeap->ui32PTShift;
+
+ /* Is the PT page valid? */
+ if (!ppsPTInfoList[0])
+ {
+ /*
+ With sparse mappings we expect that the PT could be freed
+ before we reach the end of it as the unmapped pages don't
+ bump ui32ValidPTECount so it can reach zero before we reach
+ the end of the PT.
+ */
+ if (!psMMUHeap->bHasSparseMappings)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "MMU_UnmapPagesAndFreePTs: Invalid PT for alloc at VAddr:0x%08X (VaddrIni:0x%08X AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex ));
+ }
+
+ /* advance the sTmpDevVAddr by one page */
+ sTmpDevVAddr.uiAddr += psMMUHeap->ui32DataPageSize;
+
+ /* Try to unmap the remaining allocation pages */
+ continue;
+ }
+
+ /* setup pointer to the first entry in the PT page */
+ pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
+
+ /* Is PTPageCpuVAddr valid ? */
+ if (!pui32Tmp)
+ {
+ continue;
+ }
+
+ CheckPT(ppsPTInfoList[0]);
+
+ /* Decrement the valid page count only if the current page is valid*/
+ if (pui32Tmp[ui32PTIndex] & SGX_MMU_PTE_VALID)
+ {
+ ppsPTInfoList[0]->ui32ValidPTECount--;
+ }
+ else
+ {
+ if (!psMMUHeap->bHasSparseMappings)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "MMU_UnmapPagesAndFreePTs: Page is already invalid for alloc at VAddr:0x%08X (VAddrIni:0x%08X AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex ));
+ }
+ }
+
+ /* The page table count should not go below zero */
+ PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0);
+ MakeKernelPageReadWrite(ppsPTInfoList[0]->PTPageCpuVAddr);
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+ /* point the PT entry to the dummy data page */
+ pui32Tmp[ui32PTIndex] = (psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PTE_VALID;
+#else
+ /* invalidate entry */
+#if defined(FIX_HW_BRN_31620)
+ BRN31620InvalidatePageTableEntry(psMMUHeap->psMMUContext, ui32PDIndex, ui32PTIndex, &pui32Tmp[ui32PTIndex]);
+#else
+ pui32Tmp[ui32PTIndex] = 0;
+#endif
+#endif
+ MakeKernelPageReadOnly(ppsPTInfoList[0]->PTPageCpuVAddr);
+ CheckPT(ppsPTInfoList[0]);
+ }
+
+ /*
+ Free a page table if we can.
+ */
+ if (ppsPTInfoList[0] && (ppsPTInfoList[0]->ui32ValidPTECount == 0)
+ )
+ {
+#if defined(FIX_HW_BRN_31620)
+ if (BRN31620FreePageTable(psMMUHeap, ui32PDIndex) == IMG_TRUE)
+ {
+ bInvalidateDirectoryCache = IMG_TRUE;
+ }
+#else
+ _DeferredFreePageTable(psMMUHeap, ui32PDIndex - psMMUHeap->ui32PDBaseIndex, IMG_TRUE);
+ bInvalidateDirectoryCache = IMG_TRUE;
+#endif
+ }
+
+ /* advance the sTmpDevVAddr by one page */
+ sTmpDevVAddr.uiAddr += psMMUHeap->ui32DataPageSize;
+ }
+
+ if(bInvalidateDirectoryCache)
+ {
+ MMU_InvalidateDirectoryCache(psMMUHeap->psMMUContext->psDevInfo);
+ }
+ else
+ {
+ MMU_InvalidatePageTableCache(psMMUHeap->psMMUContext->psDevInfo);
+ }
+
+#if defined(PDUMP)
+ MMU_PDumpPageTables(psMMUHeap,
+ sDevVAddr,
+ psMMUHeap->ui32DataPageSize * ui32PageCount,
+ IMG_TRUE,
+ hUniqueTag);
+#endif /* #if defined(PDUMP) */
+}
+
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_FreePageTables
+
+ PURPOSE: Call back from RA_Free to zero page table entries used by freed
+ spans.
+
+ PARAMETERS: In: pvMMUHeap
+ In: ui32Start
+ In: ui32End
+ In: hUniqueTag - A unique ID for use as a tag identifier
+ RETURNS:
+******************************************************************************/
+static IMG_VOID MMU_FreePageTables(IMG_PVOID pvMMUHeap,
+ IMG_SIZE_T ui32Start,
+ IMG_SIZE_T ui32End,
+ IMG_HANDLE hUniqueTag)
+{
+ MMU_HEAP *pMMUHeap = (MMU_HEAP*)pvMMUHeap;
+ IMG_DEV_VIRTADDR Start;
+
+ Start.uiAddr = (IMG_UINT32)ui32Start;
+
+ MMU_UnmapPagesAndFreePTs(pMMUHeap, Start, (IMG_UINT32)((ui32End - ui32Start) >> pMMUHeap->ui32PTShift), hUniqueTag);
+}
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_Create
+
+ PURPOSE: Create an mmu device virtual heap.
+
+ PARAMETERS: In: psMMUContext - MMU context
+ In: psDevArena - device memory resource arena
+ Out: ppsVMArena - virtual mapping arena
+ RETURNS: MMU_HEAP
+ RETURNS:
+******************************************************************************/
+MMU_HEAP *
+MMU_Create (MMU_CONTEXT *psMMUContext,
+ DEV_ARENA_DESCRIPTOR *psDevArena,
+ RA_ARENA **ppsVMArena,
+ PDUMP_MMU_ATTRIB **ppsMMUAttrib)
+{
+ MMU_HEAP *pMMUHeap;
+ IMG_UINT32 ui32ScaleSize;
+
+ PVR_UNREFERENCED_PARAMETER(ppsMMUAttrib);
+
+ 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,
+ "MMU Heap");
+ 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;
+
+ /*
+ generate page table and data page mask and shift values
+ based on the data page size
+ */
+ switch(pMMUHeap->psDevArena->ui32DataPageSize)
+ {
+ case 0x1000:
+ ui32ScaleSize = 0;
+ pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_4K;
+ break;
+#if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
+ case 0x4000:
+ ui32ScaleSize = 2;
+ pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_16K;
+ break;
+ case 0x10000:
+ ui32ScaleSize = 4;
+ pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_64K;
+ break;
+ case 0x40000:
+ ui32ScaleSize = 6;
+ pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_256K;
+ break;
+ case 0x100000:
+ ui32ScaleSize = 8;
+ pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_1M;
+ break;
+ case 0x400000:
+ ui32ScaleSize = 10;
+ pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_4M;
+ break;
+#endif /* #if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE) */
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "MMU_Create: invalid data page size"));
+ goto ErrorFreeHeap;
+ }
+
+ /* number of bits of address offset into the data page */
+ pMMUHeap->ui32DataPageSize = psDevArena->ui32DataPageSize;
+ pMMUHeap->ui32DataPageBitWidth = SGX_MMU_PAGE_SHIFT + ui32ScaleSize;
+ pMMUHeap->ui32DataPageMask = pMMUHeap->ui32DataPageSize - 1;
+ /* number of bits of address indexing into a pagetable */
+ pMMUHeap->ui32PTShift = pMMUHeap->ui32DataPageBitWidth;
+ pMMUHeap->ui32PTBitWidth = SGX_MMU_PT_SHIFT - ui32ScaleSize;
+ pMMUHeap->ui32PTMask = SGX_MMU_PT_MASK & (SGX_MMU_PT_MASK<<ui32ScaleSize);
+ pMMUHeap->ui32PTSize = (IMG_UINT32)(1UL<<pMMUHeap->ui32PTBitWidth) * sizeof(IMG_UINT32);
+
+ /* note: PT size must be at least 4 entries, even for 4Mb data page size */
+ if(pMMUHeap->ui32PTSize < 4 * sizeof(IMG_UINT32))
+ {
+ pMMUHeap->ui32PTSize = 4 * sizeof(IMG_UINT32);
+ }
+ pMMUHeap->ui32PTNumEntriesAllocated = pMMUHeap->ui32PTSize >> 2;
+
+ /* find the number of actual PT entries per PD entry range. For 4MB data
+ * pages we only use the first entry although the PT has 16 byte allocation/alignment
+ * (due to 4 LSbits of the PDE are reserved for control) */
+ pMMUHeap->ui32PTNumEntriesUsable = (IMG_UINT32)(1UL << pMMUHeap->ui32PTBitWidth);
+
+ /* number of bits of address indexing into a page directory */
+ pMMUHeap->ui32PDShift = pMMUHeap->ui32PTBitWidth + pMMUHeap->ui32PTShift;
+ pMMUHeap->ui32PDBitWidth = SGX_FEATURE_ADDRESS_SPACE_SIZE - pMMUHeap->ui32PTBitWidth - pMMUHeap->ui32DataPageBitWidth;
+ pMMUHeap->ui32PDMask = SGX_MMU_PD_MASK & (SGX_MMU_PD_MASK>>(32-SGX_FEATURE_ADDRESS_SPACE_SIZE));
+
+ /* External system cache violates this rule */
+#if !defined (SUPPORT_EXTERNAL_SYSTEM_CACHE)
+ /*
+ The heap must start on a PT boundary to avoid PT sharing across heaps
+ The only exception is the first heap which can start at any address
+ from 0 to the end of the first PT boundary
+ */
+ if(psDevArena->BaseDevVAddr.uiAddr > (pMMUHeap->ui32DataPageMask | pMMUHeap->ui32PTMask))
+ {
+ /*
+ if for some reason the first heap starts after the end of the first PT boundary
+ but is not aligned to a PT boundary then the assert will trigger unncessarily
+ */
+ PVR_ASSERT ((psDevArena->BaseDevVAddr.uiAddr
+ & (pMMUHeap->ui32DataPageMask
+ | pMMUHeap->ui32PTMask)) == 0);
+ }
+#endif
+ /* how many PT entries do we need? */
+ pMMUHeap->ui32PTETotalUsable = pMMUHeap->psDevArena->ui32Size >> pMMUHeap->ui32PTShift;
+
+ /* calculate the PD Base index for the Heap (required for page mapping) */
+ pMMUHeap->ui32PDBaseIndex = (pMMUHeap->psDevArena->BaseDevVAddr.uiAddr & pMMUHeap->ui32PDMask) >> pMMUHeap->ui32PDShift;
+
+ /*
+ how many page tables?
+ round up to nearest entries to the nearest page table sized block
+ */
+ pMMUHeap->ui32PageTableCount = (pMMUHeap->ui32PTETotalUsable + pMMUHeap->ui32PTNumEntriesUsable - 1)
+ >> pMMUHeap->ui32PTBitWidth;
+ PVR_ASSERT(pMMUHeap->ui32PageTableCount > 0);
+
+ /* Create the arena */
+ pMMUHeap->psVMArena = RA_Create(psDevArena->pszName,
+ psDevArena->BaseDevVAddr.uiAddr,
+ psDevArena->ui32Size,
+ IMG_NULL,
+ MAX(HOST_PAGESIZE(), pMMUHeap->ui32DataPageSize),
+ 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"));
+ goto ErrorFreePagetables;
+ }
+
+#if defined(PDUMP)
+ /* setup per-heap PDUMP MMU attributes */
+ MMU_SetPDumpAttribs(&pMMUHeap->sMMUAttrib,
+ psMMUContext->psDeviceNode,
+ pMMUHeap->ui32DataPageMask,
+ pMMUHeap->ui32PTSize);
+ *ppsMMUAttrib = &pMMUHeap->sMMUAttrib;
+
+ PDUMPCOMMENT("Create MMU device from arena %s (Size == 0x%x, DataPageSize == 0x%x, BaseDevVAddr == 0x%x)",
+ psDevArena->pszName,
+ psDevArena->ui32Size,
+ pMMUHeap->ui32DataPageSize,
+ psDevArena->BaseDevVAddr.uiAddr);
+#endif /* PDUMP */
+
+ /*
+ And return the RA for VM arena management
+ */
+ *ppsVMArena = pMMUHeap->psVMArena;
+
+ return pMMUHeap;
+
+ /* drop into here if errors */
+ErrorFreePagetables:
+ _DeferredFreePageTables (pMMUHeap);
+
+ErrorFreeHeap:
+ OSFreeMem (PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_HEAP), pMMUHeap, IMG_NULL);
+ /*not nulling pointer, out of scope*/
+
+ return IMG_NULL;
+}
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_Delete
+
+ PURPOSE: Delete an MMU device virtual heap.
+
+ PARAMETERS: In: pMMUHeap - The MMU heap to delete.
+ RETURNS:
+******************************************************************************/
+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);
+ }
+
+#if defined(PDUMP)
+ PDUMPCOMMENT("Delete MMU device from arena %s (BaseDevVAddr == 0x%x, PT count for deferred free == 0x%x)",
+ pMMUHeap->psDevArena->pszName,
+ pMMUHeap->psDevArena->BaseDevVAddr.uiAddr,
+ pMMUHeap->ui32PageTableCount);
+#endif /* PDUMP */
+
+#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);
+ /*not nulling pointer, copy on stack*/
+ }
+}
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_Alloc
+ PURPOSE: Allocate space in an mmu's virtual address space.
+ PARAMETERS: In: pMMUHeap - MMU to allocate on.
+ In: uSize - Size in bytes to allocate.
+ Out: pActualSize - If non null receives actual size allocated.
+ In: uFlags - Allocation flags.
+ In: uDevVAddrAlignment - Required alignment.
+ Out: DevVAddr - Receives base address of allocation.
+ RETURNS: IMG_TRUE - Success
+ IMG_FALSE - Failure
+******************************************************************************/
+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));
+
+ /*
+ Only allocate a VM address if the caller did not supply one
+ */
+ if((uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) == 0)
+ {
+ IMG_UINTPTR_T uiAddr;
+
+ bStatus = RA_Alloc (pMMUHeap->psVMArena,
+ uSize,
+ pActualSize,
+ IMG_NULL,
+ 0,
+ uDevVAddrAlignment,
+ 0,
+ IMG_NULL,
+ 0,
+ &uiAddr);
+ if(!bStatus)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: RA_Alloc of VMArena failed"));
+ PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: Alloc of DevVAddr failed from heap %s ID%d",
+ pMMUHeap->psDevArena->pszName,
+ pMMUHeap->psDevArena->ui32HeapID));
+ return bStatus;
+ }
+
+ psDevVAddr->uiAddr = IMG_CAST_TO_DEVVADDR_UINT(uiAddr);
+ }
+
+ #ifdef SUPPORT_SGX_MMU_BYPASS
+ EnableHostAccess(pMMUHeap->psMMUContext);
+ #endif
+
+ /* allocate page tables to cover allocation as required */
+ bStatus = _DeferredAllocPagetables(pMMUHeap, *psDevVAddr, (IMG_UINT32)uSize);
+
+ #ifdef SUPPORT_SGX_MMU_BYPASS
+ DisableHostAccess(pMMUHeap->psMMUContext);
+ #endif
+
+ if (!bStatus)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: _DeferredAllocPagetables failed"));
+ PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: Failed to alloc pagetable(s) for DevVAddr 0x%8.8x from heap %s ID%d",
+ psDevVAddr->uiAddr,
+ pMMUHeap->psDevArena->pszName,
+ pMMUHeap->psDevArena->ui32HeapID));
+ if((uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) == 0)
+ {
+ /* free the VM address */
+ RA_Free (pMMUHeap->psVMArena, psDevVAddr->uiAddr, IMG_FALSE);
+ }
+ }
+
+ return bStatus;
+}
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_Free
+ PURPOSE: Free space in an mmu's virtual address space.
+ PARAMETERS: In: pMMUHeap - MMU to deallocate on.
+ In: DevVAddr - Base address to deallocate.
+ RETURNS: None
+******************************************************************************/
+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: Freeing DevVAddr 0x%08X from heap %s ID%d",
+ DevVAddr.uiAddr,
+ pMMUHeap->psDevArena->pszName,
+ pMMUHeap->psDevArena->ui32HeapID));
+
+ 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 free DevVAddr %08X from heap %s ID%d (not in range of heap))",
+ DevVAddr.uiAddr,
+ pMMUHeap->psDevArena->pszName,
+ pMMUHeap->psDevArena->ui32HeapID));
+}
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_Enable
+
+ PURPOSE: Enable an mmu. Establishes pages tables and takes the mmu out
+ of bypass and waits for the mmu to acknowledge enabled.
+
+ PARAMETERS: In: pMMUHeap - the mmu
+ RETURNS: None
+******************************************************************************/
+IMG_VOID
+MMU_Enable (MMU_HEAP *pMMUHeap)
+{
+ PVR_UNREFERENCED_PARAMETER(pMMUHeap);
+ /* SGX mmu is always enabled (stub function) */
+}
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_Disable
+
+ PURPOSE: Disable an mmu, takes the mmu into bypass.
+
+ PARAMETERS: In: pMMUHeap - the mmu
+ RETURNS: None
+******************************************************************************/
+IMG_VOID
+MMU_Disable (MMU_HEAP *pMMUHeap)
+{
+ PVR_UNREFERENCED_PARAMETER(pMMUHeap);
+ /* SGX mmu is always enabled (stub function) */
+}
+
+#if defined(FIX_HW_BRN_31620)
+/*!
+******************************************************************************
+ FUNCTION: MMU_GetCacheFlushRange
+
+ PURPOSE: Gets device physical address of the mmu context.
+
+ PARAMETERS: In: pMMUContext - the mmu context
+ Out: pui32RangeMask - Bit mask showing which PD cache
+ lines have changed
+ RETURNS: None
+******************************************************************************/
+
+IMG_VOID MMU_GetCacheFlushRange(MMU_CONTEXT *pMMUContext, IMG_UINT32 *pui32RangeMask)
+{
+ IMG_UINT32 i;
+
+ for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
+ {
+ pui32RangeMask[i] = pMMUContext->ui32PDChangeMask[i];
+
+ /* Clear bit mask for the next set of allocations */
+ pMMUContext->ui32PDChangeMask[i] = 0;
+ }
+}
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_GetPDPhysAddr
+
+ PURPOSE: Gets device physical address of the mmu contexts PD.
+
+ PARAMETERS: In: pMMUContext - the mmu context
+ Out: psDevPAddr - Address of PD
+ RETURNS: None
+******************************************************************************/
+
+IMG_VOID MMU_GetPDPhysAddr(MMU_CONTEXT *pMMUContext, IMG_DEV_PHYADDR *psDevPAddr)
+{
+ *psDevPAddr = pMMUContext->sPDDevPAddr;
+}
+
+#endif
+#if defined(PDUMP)
+/*!
+******************************************************************************
+ FUNCTION: MMU_PDumpPageTables
+
+ PURPOSE: PDump the linear mapping for a range of pages at a specified
+ virtual address.
+
+ PARAMETERS: In: pMMUHeap - the mmu.
+ In: DevVAddr - the device virtual address.
+ In: uSize - size of memory range in bytes
+ In: hUniqueTag - A unique ID for use as a tag identifier
+ RETURNS: None
+******************************************************************************/
+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;
+
+#if defined(FIX_HW_BRN_31620)
+ PVRSRV_SGXDEV_INFO *psDevInfo = pMMUHeap->psMMUContext->psDevInfo;
+#endif
+ /* find number of PT entries to dump */
+ ui32NumPTEntries = (IMG_UINT32)((uSize + pMMUHeap->ui32DataPageMask) >> pMMUHeap->ui32PTShift);
+
+ /* find the index/offset in PD entries */
+ ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+ /* set the base PT info */
+ ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
+
+ /* find the index/offset of the first PT entry in the first PT page */
+ ui32PTIndex = (DevVAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift;
+
+ /* pdump the PT Page modification */
+ PDUMPCOMMENT("Page table mods (num entries == %08X) %s", ui32NumPTEntries, bForUnmap ? "(for unmap)" : "");
+
+ /* walk the PT pages, dumping as we go */
+ while(ui32NumPTEntries > 0)
+ {
+ MMU_PT_INFO* psPTInfo = *ppsPTInfoList++;
+
+ if(ui32NumPTEntries <= pMMUHeap->ui32PTNumEntriesUsable - ui32PTIndex)
+ {
+ ui32PTDumpCount = ui32NumPTEntries;
+ }
+ else
+ {
+ ui32PTDumpCount = pMMUHeap->ui32PTNumEntriesUsable - ui32PTIndex;
+ }
+
+ if (psPTInfo)
+ {
+#if defined(FIX_HW_BRN_31620)
+ IMG_UINT32 i;
+#endif
+ IMG_UINT32 ui32Flags = 0;
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ ui32Flags |= ( MMU_IsHeapShared(pMMUHeap) ) ? PDUMP_FLAGS_PERSISTENT : 0;
+#endif
+ pui32PTEntry = (IMG_UINT32*)psPTInfo->PTPageCpuVAddr;
+#if defined(FIX_HW_BRN_31620)
+ if ((ui32PDIndex % (BRN31620_PDE_CACHE_FILL_SIZE/BRN31620_PT_ADDRESS_RANGE_SIZE)) == BRN31620_DUMMY_PDE_INDEX)
+ {
+ for (i=ui32PTIndex;i<(ui32PTIndex + ui32PTDumpCount);i++)
+ {
+ if (pui32PTEntry[i] == ((psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PTE_DUMMY_PAGE
+ | SGX_MMU_PTE_READONLY
+ | SGX_MMU_PTE_VALID))
+ {
+ PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psPTInfo->hPTPageOSMemHandle, (IMG_VOID *) &pui32PTEntry[i], sizeof(IMG_UINT32), ui32Flags, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG);
+ }
+ else
+ {
+ PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psPTInfo->hPTPageOSMemHandle, (IMG_VOID *) &pui32PTEntry[i], sizeof(IMG_UINT32), ui32Flags, IMG_FALSE, PDUMP_PT_UNIQUETAG, hUniqueTag);
+ }
+ }
+ }
+ else
+#endif
+ {
+ PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psPTInfo->hPTPageOSMemHandle, (IMG_VOID *) &pui32PTEntry[ui32PTIndex], ui32PTDumpCount * sizeof(IMG_UINT32), ui32Flags, IMG_FALSE, PDUMP_PT_UNIQUETAG, hUniqueTag);
+ }
+ }
+
+ /* decrement PT entries left */
+ ui32NumPTEntries -= ui32PTDumpCount;
+
+ /* reset offset in page */
+ ui32PTIndex = 0;
+
+#if defined(FIX_HW_BRN_31620)
+ /* For 31620 we need to know which PD index we're working on */
+ ui32PDIndex++;
+#endif
+ }
+
+ PDUMPCOMMENT("Finished page table mods %s", bForUnmap ? "(for unmap)" : "");
+}
+#endif /* #if defined(PDUMP) */
+
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_MapPage
+
+ PURPOSE: Create a mapping for one page at a specified virtual address.
+
+ PARAMETERS: In: pMMUHeap - the mmu.
+ In: DevVAddr - the device virtual address.
+ In: DevPAddr - the device physical address of the page to map.
+ In: ui32MemFlags - BM r/w/cache flags
+ RETURNS: None
+******************************************************************************/
+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;
+
+ /* check the physical alignment of the memory to map */
+ PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
+
+ /*
+ unravel the read/write/cache flags
+ */
+ if(((PVRSRV_MEM_READ|PVRSRV_MEM_WRITE) & ui32MemFlags) == (PVRSRV_MEM_READ|PVRSRV_MEM_WRITE))
+ {
+ /* read/write */
+ ui32MMUFlags = 0;
+ }
+ else if(PVRSRV_MEM_READ & ui32MemFlags)
+ {
+ /* read only */
+ ui32MMUFlags |= SGX_MMU_PTE_READONLY;
+ }
+ else if(PVRSRV_MEM_WRITE & ui32MemFlags)
+ {
+ /* write only */
+ ui32MMUFlags |= SGX_MMU_PTE_WRITEONLY;
+ }
+
+ /* cache coherency */
+ if(PVRSRV_MEM_CACHE_CONSISTENT & ui32MemFlags)
+ {
+ ui32MMUFlags |= SGX_MMU_PTE_CACHECONSISTENT;
+ }
+
+#if !defined(FIX_HW_BRN_25503)
+ /* EDM protection */
+ if(PVRSRV_MEM_EDM_PROTECT & ui32MemFlags)
+ {
+ ui32MMUFlags |= SGX_MMU_PTE_EDMPROTECT;
+ }
+#endif
+
+ /*
+ we receive a device physical address for the page that is to be mapped
+ and a device virtual address representing where it should be mapped to
+ */
+
+ /* find the index/offset in PD entries */
+ ui32Index = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+ /* and advance to the first PT info list */
+ ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32Index];
+
+ CheckPT(ppsPTInfoList[0]);
+
+ /* find the index/offset of the first PT in the first PT page */
+ ui32Index = (DevVAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift;
+
+ /* setup pointer to the first entry in the PT page */
+ pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
+
+#if !defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+ {
+ IMG_UINT32 uTmp = pui32Tmp[ui32Index];
+
+ /* Is the current page already valid? (should not be unless it was allocated and not deallocated) */
+#if defined(FIX_HW_BRN_31620)
+ if ((uTmp & SGX_MMU_PTE_VALID) && ((DevVAddr.uiAddr & BRN31620_PDE_CACHE_FILL_MASK) != BRN31620_DUMMY_PAGE_OFFSET))
+#else
+ if ((uTmp & SGX_MMU_PTE_VALID) != 0)
+#endif
+
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page is already valid for alloc at VAddr:0x%08X PDIdx:%u PTIdx:%u",
+ DevVAddr.uiAddr,
+ DevVAddr.uiAddr >> pMMUHeap->ui32PDShift,
+ ui32Index ));
+ PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page table entry value: 0x%08X", uTmp));
+ PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Physical page to map: 0x%08X", DevPAddr.uiAddr));
+#if PT_DUMP
+ DumpPT(ppsPTInfoList[0]);
+#endif
+ }
+#if !defined(FIX_HW_BRN_31620)
+ PVR_ASSERT((uTmp & SGX_MMU_PTE_VALID) == 0);
+#endif
+ }
+#endif
+
+ /* One more valid entry in the page table. */
+ ppsPTInfoList[0]->ui32ValidPTECount++;
+
+ MakeKernelPageReadWrite(ppsPTInfoList[0]->PTPageCpuVAddr);
+ /* map in the physical page */
+ pui32Tmp[ui32Index] = ((DevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ & ((~pMMUHeap->ui32DataPageMask)>>SGX_MMU_PTE_ADDR_ALIGNSHIFT))
+ | SGX_MMU_PTE_VALID
+ | ui32MMUFlags;
+ MakeKernelPageReadOnly(ppsPTInfoList[0]->PTPageCpuVAddr);
+ CheckPT(ppsPTInfoList[0]);
+}
+
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_MapScatter
+
+ PURPOSE: Create a linear mapping for a range of pages at a specified
+ virtual address.
+
+ PARAMETERS: In: pMMUHeap - the mmu.
+ In: DevVAddr - the device virtual address.
+ In: psSysAddr - the device physical address of the page to
+ map.
+ In: uSize - size of memory range in bytes
+ In: ui32MemFlags - page table flags.
+ In: hUniqueTag - A unique ID for use as a tag identifier
+ RETURNS: None
+******************************************************************************/
+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 /*PDUMP*/
+ IMG_UINT32 uCount, i;
+ IMG_DEV_PHYADDR DevPAddr;
+
+ PVR_ASSERT (pMMUHeap != IMG_NULL);
+
+#if defined(PDUMP)
+ MapBaseDevVAddr = DevVAddr;
+#else
+ PVR_UNREFERENCED_PARAMETER(hUniqueTag);
+#endif /*PDUMP*/
+
+ for (i=0, uCount=0; uCount<uSize; i++, uCount+=pMMUHeap->ui32DataPageSize)
+ {
+ IMG_SYS_PHYADDR sSysAddr;
+
+ sSysAddr = psSysAddr[i];
+
+
+ /* check the physical alignment of the memory to map */
+ PVR_ASSERT((sSysAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
+
+ DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysAddr);
+
+ MMU_MapPage (pMMUHeap, DevVAddr, DevPAddr, ui32MemFlags);
+ DevVAddr.uiAddr += pMMUHeap->ui32DataPageSize;
+
+ 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 /* #if defined(PDUMP) */
+}
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_MapPages
+
+ PURPOSE: Create a linear mapping for a ranege of pages at a specified
+ virtual address.
+
+ PARAMETERS: In: pMMUHeap - the mmu.
+ In: DevVAddr - the device virtual address.
+ In: SysPAddr - the system physical address of the page to
+ map.
+ In: uSize - size of memory range in bytes
+ In: ui32MemFlags - page table flags.
+ In: hUniqueTag - A unique ID for use as a tag identifier
+ RETURNS: None
+******************************************************************************/
+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 /*PDUMP*/
+ IMG_UINT32 uCount;
+ IMG_UINT32 ui32VAdvance;
+ IMG_UINT32 ui32PAdvance;
+
+ PVR_ASSERT (pMMUHeap != IMG_NULL);
+
+ PVR_DPF ((PVR_DBG_MESSAGE, "MMU_MapPages: heap:%s, heap_id:%d devVAddr=%08X, SysPAddr=%08X, size=0x%x",
+ pMMUHeap->psDevArena->pszName,
+ pMMUHeap->psDevArena->ui32HeapID,
+ DevVAddr.uiAddr,
+ SysPAddr.uiAddr,
+ uSize));
+
+ /* set the virtual and physical advance */
+ ui32VAdvance = pMMUHeap->ui32DataPageSize;
+ ui32PAdvance = pMMUHeap->ui32DataPageSize;
+
+#if defined(PDUMP)
+ MapBaseDevVAddr = DevVAddr;
+#else
+ PVR_UNREFERENCED_PARAMETER(hUniqueTag);
+#endif /*PDUMP*/
+
+ DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, SysPAddr);
+
+ /* check the physical alignment of the memory to map */
+ PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
+
+ /*
+ for dummy allocations there is only one physical
+ page backing the virtual range
+ */
+ 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 /* #if defined(PDUMP) */
+}
+
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_MapPagesSparse
+
+ PURPOSE: Create a linear mapping for a ranege of pages at a specified
+ virtual address.
+
+ PARAMETERS: In: pMMUHeap - the mmu.
+ In: DevVAddr - the device virtual address.
+ In: SysPAddr - the system physical address of the page to
+ map.
+ In: ui32ChunkSize - Size of the chunk (must be page multiple)
+ In: ui32NumVirtChunks - Number of virtual chunks
+ In: ui32NumPhysChunks - Number of physical chunks
+ In: pabMapChunk - Mapping array
+ In: ui32MemFlags - page table flags.
+ In: hUniqueTag - A unique ID for use as a tag identifier
+ RETURNS: None
+******************************************************************************/
+IMG_VOID
+MMU_MapPagesSparse (MMU_HEAP *pMMUHeap,
+ IMG_DEV_VIRTADDR DevVAddr,
+ IMG_SYS_PHYADDR SysPAddr,
+ IMG_UINT32 ui32ChunkSize,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_BOOL *pabMapChunk,
+ IMG_UINT32 ui32MemFlags,
+ IMG_HANDLE hUniqueTag)
+{
+ IMG_DEV_PHYADDR DevPAddr;
+#if defined(PDUMP)
+ IMG_DEV_VIRTADDR MapBaseDevVAddr;
+#endif /*PDUMP*/
+ IMG_UINT32 uCount;
+ IMG_UINT32 ui32VAdvance;
+ IMG_UINT32 ui32PAdvance;
+ IMG_SIZE_T uSizeVM = ui32ChunkSize * ui32NumVirtChunks;
+#if !defined(PVRSRV_NEED_PVR_DPF)
+ PVR_UNREFERENCED_PARAMETER(ui32NumPhysChunks);
+#endif
+
+ PVR_ASSERT (pMMUHeap != IMG_NULL);
+
+ PVR_DPF ((PVR_DBG_MESSAGE, "MMU_MapPagesSparse: heap:%s, heap_id:%d devVAddr=%08X, SysPAddr=%08X, VM space=0x%x, PHYS space=0x%x",
+ pMMUHeap->psDevArena->pszName,
+ pMMUHeap->psDevArena->ui32HeapID,
+ DevVAddr.uiAddr,
+ SysPAddr.uiAddr,
+ uSizeVM,
+ ui32ChunkSize * ui32NumPhysChunks));
+
+ /* set the virtual and physical advance */
+ ui32VAdvance = pMMUHeap->ui32DataPageSize;
+ ui32PAdvance = pMMUHeap->ui32DataPageSize;
+
+#if defined(PDUMP)
+ MapBaseDevVAddr = DevVAddr;
+#else
+ PVR_UNREFERENCED_PARAMETER(hUniqueTag);
+#endif /*PDUMP*/
+
+ DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, SysPAddr);
+
+ /* check the physical alignment of the memory to map */
+ PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
+
+ /*
+ for dummy allocations there is only one physical
+ page backing the virtual range
+ */
+ if(ui32MemFlags & PVRSRV_MEM_DUMMY)
+ {
+ ui32PAdvance = 0;
+ }
+
+ for (uCount=0; uCount<uSizeVM; uCount+=ui32VAdvance)
+ {
+ if (pabMapChunk[uCount/ui32ChunkSize])
+ {
+ MMU_MapPage (pMMUHeap, DevVAddr, DevPAddr, ui32MemFlags);
+ DevPAddr.uiAddr += ui32PAdvance;
+ }
+ DevVAddr.uiAddr += ui32VAdvance;
+ }
+ pMMUHeap->bHasSparseMappings = IMG_TRUE;
+
+#if defined(PDUMP)
+ MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uSizeVM, IMG_FALSE, hUniqueTag);
+#endif /* #if defined(PDUMP) */
+}
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_MapShadow
+
+ PURPOSE: Create a mapping for a range of pages from either a CPU
+ virtual adddress, (or if NULL a hOSMemHandle) to a specified
+ device virtual address.
+
+ PARAMETERS: In: pMMUHeap - the mmu.
+ In: MapBaseDevVAddr - A page aligned device virtual address
+ to start mapping from.
+ In: uByteSize - A page aligned mapping length in bytes.
+ In: CpuVAddr - A page aligned CPU virtual address.
+ In: hOSMemHandle - An alternative OS specific memory handle
+ for mapping RAM without a CPU virtual
+ address
+ Out: pDevVAddr - deprecated - It used to return a byte aligned
+ device virtual address corresponding to the
+ cpu virtual address (When CpuVAddr wasn't
+ constrained to be page aligned.) Now it just
+ returns MapBaseDevVAddr. Unaligned semantics
+ can easily be handled above this API if required.
+ In: hUniqueTag - A unique ID for use as a tag identifier
+ In: ui32MemFlags - page table flags.
+ RETURNS: None
+******************************************************************************/
+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;
+ IMG_UINT32 ui32PAdvance;
+
+#if !defined (PDUMP)
+ PVR_UNREFERENCED_PARAMETER(hUniqueTag);
+#endif
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "MMU_MapShadow: DevVAddr:%08X, Bytes:0x%x, CPUVAddr:%08X",
+ MapBaseDevVAddr.uiAddr,
+ uByteSize,
+ (IMG_UINTPTR_T)CpuVAddr));
+
+ /* set the virtual and physical advance */
+ ui32VAdvance = pMMUHeap->ui32DataPageSize;
+ ui32PAdvance = pMMUHeap->ui32DataPageSize;
+
+ /* note: can't do useful check on the CPU Addr other than it being at least 4k alignment */
+ PVR_ASSERT(((IMG_UINTPTR_T)CpuVAddr & (SGX_MMU_PAGE_SIZE - 1)) == 0);
+ PVR_ASSERT(((IMG_UINT32)uByteSize & pMMUHeap->ui32DataPageMask) == 0);
+ pDevVAddr->uiAddr = MapBaseDevVAddr.uiAddr;
+
+ /*
+ for dummy allocations there is only one physical
+ page backing the virtual range
+ */
+ if(ui32MemFlags & PVRSRV_MEM_DUMMY)
+ {
+ ui32PAdvance = 0;
+ }
+
+ /* Loop through cpu memory and map page by page */
+ MapDevVAddr = MapBaseDevVAddr;
+ for (i=0; i<uByteSize; i+=ui32VAdvance)
+ {
+ IMG_CPU_PHYADDR CpuPAddr;
+ IMG_DEV_PHYADDR DevPAddr;
+
+ if(CpuVAddr)
+ {
+ CpuPAddr = OSMapLinToCPUPhys (hOSMemHandle,
+ (IMG_VOID *)((IMG_UINTPTR_T)CpuVAddr + uOffset));
+ }
+ else
+ {
+ CpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, uOffset);
+ }
+ DevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, CpuPAddr);
+
+ /* check the physical alignment of the memory to map */
+ PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "Offset=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);
+
+ /* loop update */
+ MapDevVAddr.uiAddr += ui32VAdvance;
+ uOffset += ui32PAdvance;
+ }
+
+#if defined(PDUMP)
+ MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uByteSize, IMG_FALSE, hUniqueTag);
+#endif /* #if defined(PDUMP) */
+}
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_MapShadowSparse
+
+ PURPOSE: Create a mapping for a range of pages from either a CPU
+ virtual adddress, (or if NULL a hOSMemHandle) to a specified
+ device virtual address.
+
+ PARAMETERS: In: pMMUHeap - the mmu.
+ In: MapBaseDevVAddr - A page aligned device virtual address
+ to start mapping from.
+ In: ui32ChunkSize - Size of the chunk (must be page multiple)
+ In: ui32NumVirtChunks - Number of virtual chunks
+ In: ui32NumPhysChunks - Number of physical chunks
+ In: pabMapChunk - Mapping array
+ In: CpuVAddr - A page aligned CPU virtual address.
+ In: hOSMemHandle - An alternative OS specific memory handle
+ for mapping RAM without a CPU virtual
+ address
+ Out: pDevVAddr - deprecated - It used to return a byte aligned
+ device virtual address corresponding to the
+ cpu virtual address (When CpuVAddr wasn't
+ constrained to be page aligned.) Now it just
+ returns MapBaseDevVAddr. Unaligned semantics
+ can easily be handled above this API if required.
+ In: hUniqueTag - A unique ID for use as a tag identifier
+ In: ui32MemFlags - page table flags.
+ RETURNS: None
+******************************************************************************/
+IMG_VOID
+MMU_MapShadowSparse (MMU_HEAP *pMMUHeap,
+ IMG_DEV_VIRTADDR MapBaseDevVAddr,
+ IMG_UINT32 ui32ChunkSize,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_BOOL *pabMapChunk,
+ 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;
+ IMG_UINT32 ui32PAdvance;
+ IMG_SIZE_T uiSizeVM = ui32ChunkSize * ui32NumVirtChunks;
+ IMG_UINT32 ui32ChunkIndex = 0;
+ IMG_UINT32 ui32ChunkOffset = 0;
+#if !defined(PVRSRV_NEED_PVR_DPF)
+ PVR_UNREFERENCED_PARAMETER(ui32NumPhysChunks);
+#endif
+#if !defined (PDUMP)
+ PVR_UNREFERENCED_PARAMETER(hUniqueTag);
+#endif
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "MMU_MapShadowSparse: DevVAddr:%08X, VM space:0x%x, CPUVAddr:%08X PHYS space:0x%x",
+ MapBaseDevVAddr.uiAddr,
+ uiSizeVM,
+ (IMG_UINTPTR_T)CpuVAddr,
+ ui32ChunkSize * ui32NumPhysChunks));
+
+ /* set the virtual and physical advance */
+ ui32VAdvance = pMMUHeap->ui32DataPageSize;
+ ui32PAdvance = pMMUHeap->ui32DataPageSize;
+
+ /* note: can't do useful check on the CPU Addr other than it being at least 4k alignment */
+ PVR_ASSERT(((IMG_UINTPTR_T)CpuVAddr & (SGX_MMU_PAGE_SIZE - 1)) == 0);
+ PVR_ASSERT(((IMG_UINT32)uiSizeVM & pMMUHeap->ui32DataPageMask) == 0);
+ pDevVAddr->uiAddr = MapBaseDevVAddr.uiAddr;
+
+ /* Shouldn't come through the sparse interface */
+ PVR_ASSERT((ui32MemFlags & PVRSRV_MEM_DUMMY) == 0);
+
+ /* Loop through cpu memory and map page by page */
+ MapDevVAddr = MapBaseDevVAddr;
+ for (i=0; i<uiSizeVM; i+=ui32VAdvance)
+ {
+ IMG_CPU_PHYADDR CpuPAddr;
+ IMG_DEV_PHYADDR DevPAddr;
+
+ if (pabMapChunk[i/ui32ChunkSize])
+ /*if (pabMapChunk[ui32ChunkIndex])*/
+ {
+ if(CpuVAddr)
+ {
+ CpuPAddr = OSMapLinToCPUPhys (hOSMemHandle,
+ (IMG_VOID *)((IMG_UINTPTR_T)CpuVAddr + uOffset));
+ }
+ else
+ {
+ CpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, uOffset);
+ }
+ DevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, CpuPAddr);
+
+ /* check the physical alignment of the memory to map */
+ PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
+
+ PVR_DPF ((PVR_DBG_MESSAGE,
+ "Offset=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);
+ uOffset += ui32PAdvance;
+ }
+
+ /* loop update */
+ MapDevVAddr.uiAddr += ui32VAdvance;
+
+ if (ui32ChunkOffset == ui32ChunkSize)
+ {
+ ui32ChunkIndex++;
+ ui32ChunkOffset = 0;
+ }
+ }
+
+ pMMUHeap->bHasSparseMappings = IMG_TRUE;
+#if defined(PDUMP)
+ MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uiSizeVM, IMG_FALSE, hUniqueTag);
+#endif /* #if defined(PDUMP) */
+}
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_UnmapPages
+
+ PURPOSE: unmap pages and invalidate virtual address
+
+ PARAMETERS: In: psMMUHeap - the mmu.
+ In: sDevVAddr - the device virtual address.
+ In: ui32PageCount - page count
+ In: hUniqueTag - A unique ID for use as a tag identifier
+
+ RETURNS: None
+******************************************************************************/
+IMG_VOID
+MMU_UnmapPages (MMU_HEAP *psMMUHeap,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_UINT32 ui32PageCount,
+ IMG_HANDLE hUniqueTag)
+{
+ IMG_UINT32 uPageSize = psMMUHeap->ui32DataPageSize;
+ IMG_DEV_VIRTADDR sTmpDevVAddr;
+ IMG_UINT32 i;
+ IMG_UINT32 ui32PDIndex;
+ IMG_UINT32 ui32PTIndex;
+ IMG_UINT32 *pui32Tmp;
+
+#if !defined (PDUMP)
+ PVR_UNREFERENCED_PARAMETER(hUniqueTag);
+#endif
+
+ /* setup tmp devvaddr to base of allocation */
+ sTmpDevVAddr = sDevVAddr;
+
+ for(i=0; i<ui32PageCount; i++)
+ {
+ MMU_PT_INFO **ppsPTInfoList;
+
+ /* find the index/offset in PD entries */
+ ui32PDIndex = sTmpDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
+
+ /* and advance to the first PT info list */
+ ppsPTInfoList = &psMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
+
+ /* find the index/offset of the first PT in the first PT page */
+ ui32PTIndex = (sTmpDevVAddr.uiAddr & psMMUHeap->ui32PTMask) >> psMMUHeap->ui32PTShift;
+
+ /* Is the PT page valid? */
+ if ((!ppsPTInfoList[0]) && (!psMMUHeap->bHasSparseMappings))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: ERROR Invalid PT for alloc at VAddr:0x%08X (VaddrIni:0x%08X AllocPage:%u) PDIdx:%u PTIdx:%u",
+ sTmpDevVAddr.uiAddr,
+ sDevVAddr.uiAddr,
+ i,
+ ui32PDIndex,
+ ui32PTIndex));
+
+ /* advance the sTmpDevVAddr by one page */
+ sTmpDevVAddr.uiAddr += uPageSize;
+
+ /* Try to unmap the remaining allocation pages */
+ continue;
+ }
+
+ CheckPT(ppsPTInfoList[0]);
+
+ /* setup pointer to the first entry in the PT page */
+ pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
+
+ /* Decrement the valid page count only if the current page is valid*/
+ 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%08X (VAddrIni:0x%08X AllocPage:%u) PDIdx:%u PTIdx:%u",
+ sTmpDevVAddr.uiAddr,
+ sDevVAddr.uiAddr,
+ i,
+ ui32PDIndex,
+ ui32PTIndex));
+ PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: Page table entry value: 0x%08X", pui32Tmp[ui32PTIndex]));
+ }
+
+ /* The page table count should not go below zero */
+ PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0);
+
+ MakeKernelPageReadWrite(ppsPTInfoList[0]->PTPageCpuVAddr);
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+ /* point the PT entry to the dummy data page */
+ pui32Tmp[ui32PTIndex] = (psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PTE_VALID;
+#else
+ /* invalidate entry */
+#if defined(FIX_HW_BRN_31620)
+ BRN31620InvalidatePageTableEntry(psMMUHeap->psMMUContext, ui32PDIndex, ui32PTIndex, &pui32Tmp[ui32PTIndex]);
+#else
+ pui32Tmp[ui32PTIndex] = 0;
+#endif
+#endif
+ MakeKernelPageReadOnly(ppsPTInfoList[0]->PTPageCpuVAddr);
+
+ CheckPT(ppsPTInfoList[0]);
+
+ /* advance the sTmpDevVAddr by one page */
+ sTmpDevVAddr.uiAddr += uPageSize;
+ }
+
+ MMU_InvalidatePageTableCache(psMMUHeap->psMMUContext->psDevInfo);
+
+#if defined(PDUMP)
+ MMU_PDumpPageTables (psMMUHeap, sDevVAddr, uPageSize*ui32PageCount, IMG_TRUE, hUniqueTag);
+#endif /* #if defined(PDUMP) */
+}
+
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_GetPhysPageAddr
+
+ PURPOSE: extracts physical address from MMU page tables
+
+ PARAMETERS: In: pMMUHeap - the mmu
+ PARAMETERS: In: sDevVPageAddr - the virtual address to extract physical
+ page mapping from
+ RETURNS: None
+******************************************************************************/
+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;
+
+ /* find the index/offset in PD entries */
+ ui32Index = sDevVPageAddr.uiAddr >> pMMUHeap->ui32PDShift;
+
+ /* and advance to the first PT info list */
+ ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32Index];
+ if (!ppsPTInfoList[0])
+ {
+ /* Heaps with sparse mappings are allowed invalid pages */
+ if (!pMMUHeap->bHasSparseMappings)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"MMU_GetPhysPageAddr: Not mapped in at 0x%08x", sDevVPageAddr.uiAddr));
+ }
+ sDevPAddr.uiAddr = 0;
+ return sDevPAddr;
+ }
+
+ /* find the index/offset of the first PT in the first PT page */
+ ui32Index = (sDevVPageAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift;
+
+ /* setup pointer to the first entry in the PT page */
+ pui32PageTable = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
+
+ /* read back physical page */
+ sDevPAddr.uiAddr = pui32PageTable[ui32Index];
+
+ /* Mask off non-address bits */
+ sDevPAddr.uiAddr &= ~(pMMUHeap->ui32DataPageMask>>SGX_MMU_PTE_ADDR_ALIGNSHIFT);
+
+ /* and align the address */
+ sDevPAddr.uiAddr <<= SGX_MMU_PTE_ADDR_ALIGNSHIFT;
+
+ return sDevPAddr;
+}
+
+
+IMG_DEV_PHYADDR MMU_GetPDDevPAddr(MMU_CONTEXT *pMMUContext)
+{
+ return (pMMUContext->sPDDevPAddr);
+}
+
+
+/*!
+******************************************************************************
+ FUNCTION: SGXGetPhysPageAddr
+
+ PURPOSE: Gets DEV and CPU physical address of sDevVAddr
+
+ PARAMETERS: In: hDevMemHeap - device mem heap handle
+ PARAMETERS: In: sDevVAddr - the base virtual address to unmap from
+ PARAMETERS: Out: pDevPAddr - DEV physical address
+ PARAMETERS: Out: pCpuPAddr - CPU physical address
+ RETURNS: None
+******************************************************************************/
+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;
+
+ /*
+ Get MMU Heap From hDevMemHeap
+ */
+ pMMUHeap = (MMU_HEAP*)BM_GetMMUHeap(hDevMemHeap);
+
+ DevPAddr = MMU_GetPhysPageAddr(pMMUHeap, sDevVAddr);
+ pCpuPAddr->uiAddr = DevPAddr.uiAddr; /* SysDevPAddrToCPUPAddr(DevPAddr) */
+ pDevPAddr->uiAddr = DevPAddr.uiAddr;
+
+ return (pDevPAddr->uiAddr != 0) ? PVRSRV_OK : PVRSRV_ERROR_INVALID_PARAMS;
+}
+
+
+/*!
+******************************************************************************
+ FUNCTION: SGXGetMMUPDAddrKM
+
+ PURPOSE: Gets PD device physical address of hDevMemContext
+
+ PARAMETERS: In: hDevCookie - device cookie
+ PARAMETERS: In: hDevMemContext - memory context
+ PARAMETERS: Out: psPDDevPAddr - MMU PD address
+ RETURNS: None
+******************************************************************************/
+PVRSRV_ERROR SGXGetMMUPDAddrKM(IMG_HANDLE hDevCookie,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_PHYADDR *psPDDevPAddr)
+{
+ if (!hDevCookie || !hDevMemContext || !psPDDevPAddr)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ /* return the address */
+ *psPDDevPAddr = ((BM_CONTEXT*)hDevMemContext)->psMMUContext->sPDDevPAddr;
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_BIFResetPDAlloc
+
+ PURPOSE: Allocate a dummy Page Directory, Page Table and Page which can
+ be used for dynamic dummy page mapping during SGX reset.
+ Note: since this is only used for hardware recovery, no
+ pdumping is performed.
+
+ PARAMETERS: In: psDevInfo - device info
+ RETURNS: PVRSRV_OK or error
+******************************************************************************/
+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;
+
+ SysAcquireData(&psSysData);
+
+ psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
+
+ /* allocate 3 pages - for the PD, PT and dummy page */
+ if(psLocalDevMemArena == IMG_NULL)
+ {
+ /* UMA system */
+ eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
+ 3 * SGX_MMU_PAGE_SIZE,
+ SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ 0,
+ IMG_NULL,
+ (IMG_VOID **)&pui8MemBlock,
+ &hOSMemHandle);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR call to OSAllocPages failed"));
+ return eError;
+ }
+
+ /* translate address to device physical */
+ if(pui8MemBlock)
+ {
+ sMemBlockCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle,
+ pui8MemBlock);
+ }
+ else
+ {
+ /* This isn't used in all cases since not all ports currently support
+ * OSMemHandleToCpuPAddr() */
+ sMemBlockCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, 0);
+ }
+ }
+ else
+ {
+ /* non-UMA system */
+
+ if(RA_Alloc(psLocalDevMemArena,
+ 3 * SGX_MMU_PAGE_SIZE,
+ IMG_NULL,
+ IMG_NULL,
+ 0,
+ SGX_MMU_PAGE_SIZE,
+ 0,
+ IMG_NULL,
+ 0,
+ &(sMemBlockSysPAddr.uiAddr)) != IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR call to RA_Alloc failed"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ /* derive the CPU virtual address */
+ 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;
+ /* override pointer cast warnings */
+ /* PRQA S 3305,509 2 */
+ psDevInfo->pui32BIFResetPD = (IMG_UINT32 *)pui8MemBlock;
+ psDevInfo->pui32BIFResetPT = (IMG_UINT32 *)(pui8MemBlock + SGX_MMU_PAGE_SIZE);
+
+ /* Invalidate entire PD and PT. */
+ OSMemSet(psDevInfo->pui32BIFResetPD, 0, SGX_MMU_PAGE_SIZE);
+ OSMemSet(psDevInfo->pui32BIFResetPT, 0, SGX_MMU_PAGE_SIZE);
+ /* Fill dummy page with markers. */
+ OSMemSet(pui8MemBlock + (2 * SGX_MMU_PAGE_SIZE), 0xDB, SGX_MMU_PAGE_SIZE);
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_BIFResetPDFree
+
+ PURPOSE: Free resources allocated in MMU_BIFResetPDAlloc.
+
+ PARAMETERS: In: psDevInfo - device info
+ RETURNS:
+******************************************************************************/
+IMG_VOID MMU_BIFResetPDFree(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+ SYS_DATA *psSysData;
+ RA_ARENA *psLocalDevMemArena;
+ IMG_SYS_PHYADDR sPDSysPAddr;
+
+ SysAcquireData(&psSysData);
+
+ psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
+
+ /* free the page directory */
+ 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);
+ }
+}
+
+IMG_VOID MMU_CheckFaultAddr(PVRSRV_SGXDEV_INFO *psDevInfo, IMG_UINT32 ui32PDDevPAddr, IMG_UINT32 ui32FaultAddr)
+{
+ MMU_CONTEXT *psMMUContext = psDevInfo->pvMMUContextList;
+
+ while (psMMUContext && (psMMUContext->sPDDevPAddr.uiAddr != ui32PDDevPAddr))
+ {
+ psMMUContext = psMMUContext->psNext;
+ }
+
+ if (psMMUContext)
+ {
+ IMG_UINT32 ui32PTIndex;
+ IMG_UINT32 ui32PDIndex;
+
+ PVR_LOG(("Found MMU context for page fault 0x%08x", ui32FaultAddr));
+ PVR_LOG(("GPU memory context is for PID=%d (%s)", psMMUContext->ui32PID, psMMUContext->szName));
+
+ ui32PTIndex = (ui32FaultAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT;
+ ui32PDIndex = (ui32FaultAddr & SGX_MMU_PD_MASK) >> (SGX_MMU_PT_SHIFT + SGX_MMU_PAGE_SHIFT);
+
+ if (psMMUContext->apsPTInfoList[ui32PDIndex])
+ {
+ if (psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr)
+ {
+ IMG_UINT32 *pui32Ptr = psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr;
+ IMG_UINT32 ui32PTE = pui32Ptr[ui32PTIndex];
+
+ PVR_LOG(("PDE valid: PTE = 0x%08x (PhysAddr = 0x%08x, %s)",
+ ui32PTE,
+ ui32PTE & SGX_MMU_PTE_ADDR_MASK,
+ ui32PTE & SGX_MMU_PTE_VALID?"valid":"Invalid"));
+ }
+ else
+ {
+ PVR_LOG(("Found PT info but no CPU address"));
+ }
+ }
+ else
+ {
+ PVR_LOG(("No PDE found"));
+ }
+ }
+}
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+/*!
+******************************************************************************
+ FUNCTION: MMU_MapExtSystemCacheRegs
+
+ PURPOSE: maps external system cache control registers into SGX MMU
+
+ PARAMETERS: In: psDeviceNode - device node
+ RETURNS:
+******************************************************************************/
+PVRSRV_ERROR MMU_MapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ IMG_UINT32 *pui32PT;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+ IMG_UINT32 ui32PDIndex;
+ IMG_UINT32 ui32PTIndex;
+ PDUMP_MMU_ATTRIB sMMUAttrib;
+
+ psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+
+ sMMUAttrib = psDevInfo->sMMUAttrib;
+#if defined(PDUMP)
+ MMU_SetPDumpAttribs(&sMMUAttrib, psDeviceNode,
+ SGX_MMU_PAGE_MASK,
+ SGX_MMU_PT_SIZE * sizeof(IMG_UINT32));
+#endif
+
+#if defined(PDUMP)
+ {
+ IMG_CHAR szScript[128];
+
+ sprintf(szScript, "MALLOC :EXTSYSCACHE:PA_%08X%08X %u %u 0x%08X\r\n", 0, psDevInfo->sExtSysCacheRegsDevPBase.uiAddr, SGX_MMU_PAGE_SIZE, SGX_MMU_PAGE_SIZE, psDevInfo->sExtSysCacheRegsDevPBase.uiAddr);
+ PDumpOSWriteString2(szScript, PDUMP_FLAGS_CONTINUOUS);
+ }
+#endif
+
+ 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;
+
+ pui32PT = (IMG_UINT32 *) psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr;
+
+ MakeKernelPageReadWrite(pui32PT);
+ /* map the PT to the registers */
+ pui32PT[ui32PTIndex] = (psDevInfo->sExtSysCacheRegsDevPBase.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PTE_VALID;
+ MakeKernelPageReadOnly(pui32PT);
+#if defined(PDUMP)
+ /* Add the entery to the PT */
+ {
+ IMG_DEV_PHYADDR sDevPAddr;
+ IMG_CPU_PHYADDR sCpuPAddr;
+ IMG_UINT32 ui32PageMask;
+ IMG_UINT32 ui32PTE;
+ PVRSRV_ERROR eErr;
+
+ PDUMP_GET_SCRIPT_AND_FILE_STRING();
+
+ ui32PageMask = sMMUAttrib.ui32PTSize - 1;
+ sCpuPAddr = OSMapLinToCPUPhys(psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex]->hPTPageOSMemHandle, &pui32PT[ui32PTIndex]);
+ sDevPAddr = SysCpuPAddrToDevPAddr(sMMUAttrib.sDevId.eDeviceType, sCpuPAddr);
+ ui32PTE = *((IMG_UINT32 *) (&pui32PT[ui32PTIndex]));
+
+ eErr = PDumpOSBufprintf(hScript,
+ ui32MaxLenScript,
+ "WRW :%s:PA_%08X%08X:0x%08X :%s:PA_%08X%08X:0x%08X\r\n",
+ sMMUAttrib.sDevId.pszPDumpDevName,
+ (IMG_UINT32)(IMG_UINTPTR_T)PDUMP_PT_UNIQUETAG,
+ (sDevPAddr.uiAddr) & ~ui32PageMask,
+ (sDevPAddr.uiAddr) & ui32PageMask,
+ "EXTSYSCACHE",
+ (IMG_UINT32)(IMG_UINTPTR_T)PDUMP_PD_UNIQUETAG,
+ (ui32PTE & sMMUAttrib.ui32PDEMask) << sMMUAttrib.ui32PTEAlignShift,
+ ui32PTE & ~sMMUAttrib.ui32PDEMask);
+ if(eErr != PVRSRV_OK)
+ {
+ return eErr;
+ }
+ PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
+ }
+#endif
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+ FUNCTION: MMU_UnmapExtSystemCacheRegs
+
+ PURPOSE: unmaps external system cache control registers
+
+ PARAMETERS: In: psDeviceNode - device node
+ RETURNS:
+******************************************************************************/
+PVRSRV_ERROR MMU_UnmapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ SYS_DATA *psSysData;
+ RA_ARENA *psLocalDevMemArena;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+ IMG_UINT32 ui32PDIndex;
+ IMG_UINT32 ui32PTIndex;
+ IMG_UINT32 *pui32PT;
+ PDUMP_MMU_ATTRIB sMMUAttrib;
+
+ psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+
+ sMMUAttrib = psDevInfo->sMMUAttrib;
+
+#if defined(PDUMP)
+ MMU_SetPDumpAttribs(&sMMUAttrib, psDeviceNode,
+ SGX_MMU_PAGE_MASK,
+ SGX_MMU_PT_SIZE * sizeof(IMG_UINT32));
+#endif
+ SysAcquireData(&psSysData);
+
+ psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
+
+ /* unmap the MMU page table from the PD */
+ 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;
+
+ /* Only unmap it if the PT hasn't already been freed */
+ if (psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex])
+ {
+ if (psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr)
+ {
+ pui32PT = (IMG_UINT32 *) psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr;
+ }
+ }
+
+ MakeKernelPageReadWrite(pui32PT);
+ pui32PT[ui32PTIndex] = 0;
+ MakeKernelPageReadOnly(pui32PT);
+
+ PDUMPMEMPTENTRIES(&sMMUAttrib, psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->hPDOSMemHandle, &pui32PT[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+
+ return PVRSRV_OK;
+}
+#endif
+
+
+#if PAGE_TEST
+/*!
+******************************************************************************
+ FUNCTION: PageTest
+
+ PURPOSE: Tests page table memory, for use during device bring-up.
+
+ PARAMETERS: In: void* pMem - page address (CPU mapped)
+ PARAMETERS: In: IMG_DEV_PHYADDR sDevPAddr - page device phys address
+ RETURNS: None, provides debug output and breaks if an error is detected.
+******************************************************************************/
+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)
+ {
+ // Mem fault
+ 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)
+ {
+ // Mem fault
+ 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
+
+/******************************************************************************
+ End of file (mmu.c)
+******************************************************************************/
+
+
diff --git a/pvr-source/services4/srvkm/devices/sgx/mmu.h b/pvr-source/services4/srvkm/devices/sgx/mmu.h
new file mode 100644
index 0000000..3c849fc
--- /dev/null
+++ b/pvr-source/services4/srvkm/devices/sgx/mmu.h
@@ -0,0 +1,501 @@
+/*************************************************************************/ /*!
+@Title MMU Management
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Implements basic low level control of MMU.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _MMU_H_
+#define _MMU_H_
+
+#include "sgxinfokm.h"
+
+/*
+******************************************************************************
+ FUNCTION: MMU_Initialise
+
+ PURPOSE: Initialise the mmu module.
+
+ PARAMETERS: None
+ RETURNS: PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR
+MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, IMG_DEV_PHYADDR *psPDDevPAddr);
+
+/*
+******************************************************************************
+ FUNCTION: MMU_Finalise
+
+ PURPOSE: Finalise the mmu module, deallocate all resources.
+
+ PARAMETERS: None.
+ RETURNS: None.
+******************************************************************************/
+IMG_VOID
+MMU_Finalise (MMU_CONTEXT *psMMUContext);
+
+
+/*
+******************************************************************************
+ FUNCTION: MMU_InsertHeap
+
+ PURPOSE: Inserts shared heap into the specified context
+ from the kernel context
+
+ PARAMETERS: None.
+ RETURNS: None.
+******************************************************************************/
+IMG_VOID
+MMU_InsertHeap(MMU_CONTEXT *psMMUContext, MMU_HEAP *psMMUHeap);
+
+/*
+******************************************************************************
+ FUNCTION: MMU_Create
+
+ PURPOSE: Create an mmu device.
+
+ PARAMETERS: In: psMMUContext -
+ In: psDevArena -
+ Out: ppsVMArena
+ RETURNS: MMU_HEAP
+******************************************************************************/
+MMU_HEAP *
+MMU_Create (MMU_CONTEXT *psMMUContext,
+ DEV_ARENA_DESCRIPTOR *psDevArena,
+ RA_ARENA **ppsVMArena,
+ PDUMP_MMU_ATTRIB **ppsMMUAttrib);
+
+/*
+******************************************************************************
+ FUNCTION: MMU_Delete
+
+ PURPOSE: Delete an mmu device.
+
+ PARAMETERS: In: pMMUHeap - The mmu to delete.
+ RETURNS:
+******************************************************************************/
+IMG_VOID
+MMU_Delete (MMU_HEAP *pMMUHeap);
+
+/*
+******************************************************************************
+ FUNCTION: MMU_Alloc
+ PURPOSE: Allocate space in an mmu's virtual address space.
+ PARAMETERS: In: pMMUHeap - MMU to allocate on.
+ In: uSize - Size in bytes to allocate.
+ Out: pActualSize - If non null receives actual size allocated.
+ In: uFlags - Allocation flags.
+ In: uDevVAddrAlignment - Required alignment.
+ Out: pDevVAddr - Receives base address of allocation.
+ RETURNS: IMG_TRUE - Success
+ IMG_FALSE - Failure
+******************************************************************************/
+IMG_BOOL
+MMU_Alloc (MMU_HEAP *pMMUHeap,
+ IMG_SIZE_T uSize,
+ IMG_SIZE_T *pActualSize,
+ IMG_UINT32 uFlags,
+ IMG_UINT32 uDevVAddrAlignment,
+ IMG_DEV_VIRTADDR *pDevVAddr);
+
+/*
+******************************************************************************
+ FUNCTION: MMU_Free
+ PURPOSE: Frees space in an mmu's virtual address space.
+ PARAMETERS: In: pMMUHeap - MMU to free on.
+ In: DevVAddr - Base address of allocation.
+ RETURNS: IMG_TRUE - Success
+ IMG_FALSE - Failure
+******************************************************************************/
+IMG_VOID
+MMU_Free (MMU_HEAP *pMMUHeap,
+ IMG_DEV_VIRTADDR DevVAddr,
+ IMG_UINT32 ui32Size);
+
+/*
+******************************************************************************
+ FUNCTION: MMU_Enable
+
+ PURPOSE: Enable an mmu. Establishes pages tables and takes the mmu out
+ of bypass and waits for the mmu to acknowledge enabled.
+
+ PARAMETERS: In: pMMUHeap - the mmu
+ RETURNS: None
+******************************************************************************/
+IMG_VOID
+MMU_Enable (MMU_HEAP *pMMUHeap);
+
+/*
+******************************************************************************
+ FUNCTION: MMU_Disable
+
+ PURPOSE: Disable an mmu, takes the mmu into bypass.
+
+ PARAMETERS: In: pMMUHeap - the mmu
+ RETURNS: None
+******************************************************************************/
+IMG_VOID
+MMU_Disable (MMU_HEAP *pMMUHeap);
+
+/*
+******************************************************************************
+ FUNCTION: MMU_MapPages
+
+ PURPOSE: Create a mapping for a range of pages from a device physical
+ adddress to a specified device virtual address.
+
+ PARAMETERS: In: pMMUHeap - the mmu.
+ In: DevVAddr - the device virtual address.
+ In: SysPAddr - the system physical address of the page to map.
+ In: uSize - size of memory range in bytes
+ In: ui32MemFlags - page table flags.
+ In: hUniqueTag - A unique ID for use as a tag identifier
+ RETURNS: None
+******************************************************************************/
+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);
+
+/*
+******************************************************************************
+ FUNCTION: MMU_MapPagesSparse
+
+ PURPOSE: Create a mapping for a range of pages from a device physical
+ adddress to a specified device virtual address.
+
+ PARAMETERS: In: pMMUHeap - the mmu.
+ In: DevVAddr - the device virtual address.
+ In: SysPAddr - the system physical address of the page to map.
+ In: ui32ChunkSize - Size of the chunk (must be page multiple)
+ In: ui32NumVirtChunks - Number of virtual chunks
+ In: ui32NumPhysChunks - Number of physical chunks
+ In: pabMapChunk - Mapping array
+ In: ui32MemFlags - page table flags.
+ In: hUniqueTag - A unique ID for use as a tag identifier
+ RETURNS: None
+******************************************************************************/
+IMG_VOID
+MMU_MapPagesSparse (MMU_HEAP *pMMUHeap,
+ IMG_DEV_VIRTADDR DevVAddr,
+ IMG_SYS_PHYADDR SysPAddr,
+ IMG_UINT32 ui32ChunkSize,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_BOOL *pabMapChunk,
+ IMG_UINT32 ui32MemFlags,
+ IMG_HANDLE hUniqueTag);
+
+/*
+******************************************************************************
+ FUNCTION: MMU_MapShadow
+
+ PURPOSE: Create a mapping for a range of pages from a CPU virtual
+ adddress to a specified device virtual address.
+
+ PARAMETERS: In: pMMUHeap - the mmu.
+ In: MapBaseDevVAddr - A page aligned device virtual address
+ to start mapping from.
+ In: uByteSize - A page aligned mapping length in bytes.
+ In: CpuVAddr - A page aligned CPU virtual address.
+ In: hOSMemHandle - An alternative OS specific memory handle
+ for mapping RAM without a CPU virtual
+ address
+ Out: pDevVAddr - deprecated
+ In: hUniqueTag - A unique ID for use as a tag identifier
+ In: ui32MemFlags - page table flags.
+ RETURNS: None
+******************************************************************************/
+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);
+
+/*
+******************************************************************************
+ FUNCTION: MMU_MapShadowSparse
+
+ PURPOSE: Create a mapping for a range of pages from a CPU virtual
+ adddress to a specified device virtual address.
+
+ PARAMETERS: In: pMMUHeap - the mmu.
+ In: MapBaseDevVAddr - A page aligned device virtual address
+ to start mapping from.
+ In: ui32ChunkSize - Size of the chunk (must be page multiple)
+ In: ui32NumVirtChunks - Number of virtual chunks
+ In: ui32NumPhysChunks - Number of physical chunks
+ In: pabMapChunk - Mapping array
+ In: CpuVAddr - A page aligned CPU virtual address.
+ In: hOSMemHandle - An alternative OS specific memory handle
+ for mapping RAM without a CPU virtual
+ address
+ Out: pDevVAddr - deprecated
+ In: hUniqueTag - A unique ID for use as a tag identifier
+ In: ui32MemFlags - page table flags.
+ RETURNS: None
+******************************************************************************/
+IMG_VOID
+MMU_MapShadowSparse (MMU_HEAP * pMMUHeap,
+ IMG_DEV_VIRTADDR MapBaseDevVAddr,
+ IMG_UINT32 ui32ChunkSize,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_BOOL * pabMapChunk,
+ IMG_CPU_VIRTADDR CpuVAddr,
+ IMG_HANDLE hOSMemHandle,
+ IMG_DEV_VIRTADDR * pDevVAddr,
+ IMG_UINT32 ui32MemFlags,
+ IMG_HANDLE hUniqueTag);
+
+/*
+******************************************************************************
+ FUNCTION: MMU_UnmapPages
+
+ PURPOSE: unmaps pages and invalidates virtual address.
+
+ PARAMETERS: In: psMMUHeap - the mmu.
+ In: sDevVAddr - the device virtual address.
+ In: ui32PageCount - page count.
+ RETURNS: None
+******************************************************************************/
+IMG_VOID
+MMU_UnmapPages (MMU_HEAP *psMMUHeap,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_UINT32 ui32PageCount,
+ IMG_HANDLE hUniqueTag);
+
+/*
+******************************************************************************
+ FUNCTION: MMU_MapScatter
+
+ PURPOSE: Create a mapping for a list of pages to a specified device
+ virtual address.
+
+ PARAMETERS: In: pMMUHeap - the mmu.
+ In: DevVAddr - the device virtual address.
+ In: psSysAddr - the list of physical addresses of the pages to
+ map.
+ RETURNS: None
+******************************************************************************/
+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);
+
+
+/*
+******************************************************************************
+ FUNCTION: MMU_GetPhysPageAddr
+
+ PURPOSE: extracts physical address from MMU page tables
+
+ PARAMETERS: In: pMMUHeap - the mmu
+ PARAMETERS: In: sDevVPageAddr - the virtual address to extract physical
+ page mapping from
+ RETURNS: IMG_DEV_PHYADDR
+******************************************************************************/
+IMG_DEV_PHYADDR
+MMU_GetPhysPageAddr(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr);
+
+
+/*
+******************************************************************************
+ FUNCTION: MMU_GetPDDevPAddr
+
+ PURPOSE: returns PD given the MMU context (SGX to MMU API)
+
+ PARAMETERS: In: pMMUContext - the mmu
+ RETURNS: IMG_DEV_PHYADDR
+******************************************************************************/
+IMG_DEV_PHYADDR
+MMU_GetPDDevPAddr(MMU_CONTEXT *pMMUContext);
+
+
+#ifdef SUPPORT_SGX_MMU_BYPASS
+/*
+******************************************************************************
+ FUNCTION: EnableHostAccess
+
+ PURPOSE: Enables Host accesses to device memory, by passing the device
+ MMU address translation
+
+ PARAMETERS: In: psMMUContext
+ RETURNS: None
+******************************************************************************/
+IMG_VOID
+EnableHostAccess (MMU_CONTEXT *psMMUContext);
+
+
+/*
+******************************************************************************
+ FUNCTION: DisableHostAccess
+
+ PURPOSE: Disables Host accesses to device memory, by passing the device
+ MMU address translation
+
+ PARAMETERS: In: psMMUContext
+ RETURNS: None
+******************************************************************************/
+IMG_VOID
+DisableHostAccess (MMU_CONTEXT *psMMUContext);
+#endif
+
+/*
+******************************************************************************
+ FUNCTION: MMU_InvalidateDirectoryCache
+
+ PURPOSE: Invalidates the page directory cache
+
+ PARAMETERS: In: psDevInfo
+ RETURNS: None
+******************************************************************************/
+IMG_VOID MMU_InvalidateDirectoryCache(PVRSRV_SGXDEV_INFO *psDevInfo);
+
+/*
+******************************************************************************
+ FUNCTION: MMU_BIFResetPDAlloc
+
+ PURPOSE: Allocate a dummy Page Directory which causes all virtual
+ addresses to page fault.
+
+ PARAMETERS: In: psDevInfo - device info
+ RETURNS: PVRSRV_OK or error
+******************************************************************************/
+PVRSRV_ERROR MMU_BIFResetPDAlloc(PVRSRV_SGXDEV_INFO *psDevInfo);
+
+/*
+******************************************************************************
+ FUNCTION: MMU_BIFResetPDFree
+
+ PURPOSE: Free resources allocated in MMU_BIFResetPDAlloc.
+
+ PARAMETERS: In: psDevInfo - device info
+ RETURNS:
+******************************************************************************/
+IMG_VOID MMU_BIFResetPDFree(PVRSRV_SGXDEV_INFO *psDevInfo);
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+/*
+******************************************************************************
+ FUNCTION: MMU_MapExtSystemCacheRegs
+
+ PURPOSE: maps external system cache control registers into SGX MMU
+
+ PARAMETERS: In: psDeviceNode - device node
+ RETURNS:
+******************************************************************************/
+PVRSRV_ERROR MMU_MapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+/*
+******************************************************************************
+ FUNCTION: MMU_UnmapExtSystemCacheRegs
+
+ PURPOSE: unmaps external system cache control registers
+
+ PARAMETERS: In: psDeviceNode - device node
+ RETURNS:
+******************************************************************************/
+PVRSRV_ERROR MMU_UnmapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode);
+#endif /* #if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) */
+
+/*
+******************************************************************************
+ FUNCTION: MMU_IsHeapShared
+
+ PURPOSE: Is this heap shared?
+ PARAMETERS: In: pMMU_Heap
+ RETURNS: true if heap is shared
+******************************************************************************/
+IMG_BOOL MMU_IsHeapShared(MMU_HEAP* pMMU_Heap);
+
+#if defined(FIX_HW_BRN_31620)
+/*
+******************************************************************************
+ FUNCTION: MMU_GetCacheFlushRange
+
+ PURPOSE: Gets device physical address of the mmu context.
+
+ PARAMETERS: In: pMMUContext - the mmu context
+ Out: pui32RangeMask - Bit mask showing which PD cache
+ lines have changed
+ RETURNS: None
+******************************************************************************/
+IMG_VOID MMU_GetCacheFlushRange(MMU_CONTEXT *pMMUContext, IMG_UINT32 *pui32RangeMask);
+
+/*
+******************************************************************************
+ FUNCTION: MMU_GetPDPhysAddr
+
+ PURPOSE: Gets device physical address of the mmu contexts PD.
+
+ PARAMETERS: In: pMMUContext - the mmu context
+ Out: psDevPAddr - Address of PD
+ RETURNS: None
+******************************************************************************/
+IMG_VOID MMU_GetPDPhysAddr(MMU_CONTEXT *pMMUContext, IMG_DEV_PHYADDR *psDevPAddr);
+
+#endif
+
+
+IMG_VOID MMU_CheckFaultAddr(PVRSRV_SGXDEV_INFO *psDevInfo, IMG_UINT32 ui32PDDevPAddr, IMG_UINT32 ui32RegVal);
+
+#if defined(PDUMP)
+/*
+******************************************************************************
+ FUNCTION: MMU_GetPDumpContextID
+
+ PURPOSE: translates device mem context to unique pdump identifier
+
+ PARAMETERS: In: hDevMemContext - device memory per-process context
+ RETURNS: context identifier used internally in pdump
+******************************************************************************/
+IMG_UINT32 MMU_GetPDumpContextID(IMG_HANDLE hDevMemContext);
+#endif /* #ifdef PDUMP */
+
+#endif /* #ifndef _MMU_H_ */
diff --git a/pvr-source/services4/srvkm/devices/sgx/pb.c b/pvr-source/services4/srvkm/devices/sgx/pb.c
new file mode 100644
index 0000000..4ed18bb
--- /dev/null
+++ b/pvr-source/services4/srvkm/devices/sgx/pb.c
@@ -0,0 +1,493 @@
+/*************************************************************************/ /*!
+@Title Parameter Buffer management functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+
+#include "services_headers.h"
+#include "sgx_bridge_km.h"
+#include "sgxapi_km.h"
+#include "sgxinfo.h"
+#include "sgxinfokm.h"
+#include "pvr_bridge_km.h"
+#include "pdump_km.h"
+#include "sgxutils.h"
+
+#if !defined(__linux__) && !defined(__QNXNTO__)
+#pragma message("FIXME: Review use of OS_PAGEABLE vs OS_NON_PAGEABLE")
+#endif
+
+#include "lists.h"
+
+static IMPLEMENT_LIST_INSERT(PVRSRV_STUB_PBDESC)
+static IMPLEMENT_LIST_REMOVE(PVRSRV_STUB_PBDESC)
+
+static PRESMAN_ITEM psResItemCreateSharedPB = IMG_NULL;
+static PVRSRV_PER_PROCESS_DATA *psPerProcCreateSharedPB = IMG_NULL;
+
+static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bDummy);
+static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bDummy);
+
+/* override level pointer indirection */
+/* PRQA S 5102 12 */
+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 **ppsHWBlockKernelMemInfo,
+ 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,
+ "Array of Kernel Memory Info") != 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);
+ /*not nulling pointer, out of scope*/
+
+ PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed"));
+
+ eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
+ goto ExitNotFound;
+ }
+
+ *ppsSharedPBDescKernelMemInfo = psStubPBDesc->psSharedPBDescKernelMemInfo;
+ *ppsHWPBDescKernelMemInfo = psStubPBDesc->psHWPBDescKernelMemInfo;
+ *ppsBlockKernelMemInfo = psStubPBDesc->psBlockKernelMemInfo;
+ *ppsHWBlockKernelMemInfo = psStubPBDesc->psHWBlockKernelMemInfo;
+
+ *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_UNABLE_TO_REGISTER_RESOURCE;
+ 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;
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE*)psStubPBDescIn->hDevCookie;
+
+ psStubPBDescIn->ui32RefCount--;
+ if (psStubPBDescIn->ui32RefCount == 0)
+ {
+ IMG_DEV_VIRTADDR sHWPBDescDevVAddr = psStubPBDescIn->sHWPBDescDevVAddr;
+ List_PVRSRV_STUB_PBDESC_Remove(psStubPBDescIn);
+ for(i=0 ; i<psStubPBDescIn->ui32SubKernelMemInfosCount; i++)
+ {
+ PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie,
+ psStubPBDescIn->ppsSubKernelMemInfos[i]);
+ }
+
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDescIn->ui32SubKernelMemInfosCount,
+ psStubPBDescIn->ppsSubKernelMemInfos,
+ 0);
+ psStubPBDescIn->ppsSubKernelMemInfos = IMG_NULL;
+
+ PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psBlockKernelMemInfo);
+
+ PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWBlockKernelMemInfo);
+
+ PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWPBDescKernelMemInfo);
+
+ PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psSharedPBDescKernelMemInfo);
+
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_STUB_PBDESC),
+ psStubPBDescIn,
+ 0);
+ /*not nulling pointer, copy on stack*/
+
+ /* signal the microkernel to clear its sTAHWPBDesc and s3DHWPBDesc values in sTA3DCtl */
+ SGXCleanupRequest(psDeviceNode,
+ &sHWPBDescDevVAddr,
+ PVRSRV_CLEANUPCMD_PB,
+ CLEANUP_WITH_POLL);
+ }
+ return PVRSRV_OK;
+ /*return PVRSRV_ERROR_INVALID_PARAMS;*/
+}
+
+static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bDummy)
+{
+ PVRSRV_STUB_PBDESC *psStubPBDesc = (PVRSRV_STUB_PBDESC *)pvParam;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ return SGXCleanupSharedPBDescKM(psStubPBDesc);
+}
+
+static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bDummy)
+{
+#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);
+ PVR_UNREFERENCED_PARAMETER(bDummy);
+
+ 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, CLEANUP_WITH_POLL);
+}
+
+
+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,
+ PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo,
+ IMG_UINT32 ui32TotalPBSize,
+ IMG_HANDLE *phSharedPBDesc,
+ PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos,
+ IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount,
+ IMG_DEV_VIRTADDR sHWPBDescDevVAddr)
+{
+ PVRSRV_STUB_PBDESC *psStubPBDesc=IMG_NULL;
+ PVRSRV_ERROR eRet = PVRSRV_ERROR_INVALID_PERPROC;
+ IMG_UINT32 i;
+ PVRSRV_SGXDEV_INFO *psSGXDevInfo;
+ PRESMAN_ITEM psResItem;
+
+ /*
+ * The caller must have previously called SGXFindSharedPBDesc with
+ * bLockOnFailure set, and not managed to find a suitable shared PB.
+ */
+ if (psPerProcCreateSharedPB != psPerProc)
+ {
+ goto NoAdd;
+ }
+ else
+ {
+ PVR_ASSERT(psResItemCreateSharedPB != IMG_NULL);
+
+ ResManFreeResByPtr(psResItemCreateSharedPB, CLEANUP_WITH_POLL);
+
+ 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));
+
+ }
+
+ /*
+ * We make the caller think the add was successful,
+ * but return the existing shared PB desc rather than
+ * a new one.
+ */
+ 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;
+ }
+
+ /*
+ * The caller will unreference the PB desc after
+ * a successful add, so up the reference count.
+ */
+ 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,
+ "Stub Parameter Buffer Description") != 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,
+ "Array of Kernel Memory Info") != 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;
+ }
+
+ if(PVRSRVDissociateMemFromResmanKM(psHWBlockKernelMemInfo)
+ != PVRSRV_OK)
+ {
+ goto NoAdd;
+ }
+
+ psStubPBDesc->ui32RefCount = 1;
+ psStubPBDesc->ui32TotalPBSize = ui32TotalPBSize;
+ psStubPBDesc->psSharedPBDescKernelMemInfo = psSharedPBDescKernelMemInfo;
+ psStubPBDesc->psHWPBDescKernelMemInfo = psHWPBDescKernelMemInfo;
+ psStubPBDesc->psBlockKernelMemInfo = psBlockKernelMemInfo;
+ psStubPBDesc->psHWBlockKernelMemInfo = psHWBlockKernelMemInfo;
+
+ 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;
+ }
+ }
+
+ psStubPBDesc->sHWPBDescDevVAddr = sHWPBDescDevVAddr;
+
+ 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;
+
+ /* Finally everything was prepared successfully so link the new
+ * PB in to place. */
+ List_PVRSRV_STUB_PBDESC_Insert(&(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);
+ psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL;
+ }
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_STUB_PBDESC),
+ psStubPBDesc,
+ 0);
+ /*not nulling pointer, out of scope*/
+ }
+
+NoAddKeepPB:
+ for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++)
+ {
+ PVRSRVFreeDeviceMemKM(hDevCookie, ppsSharedPBDescSubKernelMemInfos[i]);
+ }
+
+ PVRSRVFreeSharedSysMemoryKM(psSharedPBDescKernelMemInfo);
+ PVRSRVFreeDeviceMemKM(hDevCookie, psHWPBDescKernelMemInfo);
+
+ PVRSRVFreeSharedSysMemoryKM(psBlockKernelMemInfo);
+ PVRSRVFreeDeviceMemKM(hDevCookie, psHWBlockKernelMemInfo);
+
+ return eRet;
+}
+
+/******************************************************************************
+ End of file (pb.c)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/devices/sgx/sgx_bridge_km.h b/pvr-source/services4/srvkm/devices/sgx/sgx_bridge_km.h
new file mode 100644
index 0000000..f281c4e
--- /dev/null
+++ b/pvr-source/services4/srvkm/devices/sgx/sgx_bridge_km.h
@@ -0,0 +1,279 @@
+/*************************************************************************/ /*!
+@Title SGX Bridge Functionality
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Header for the SGX Bridge code
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#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
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK_KM *psKick);
+#else
+PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK *psKick);
+#endif
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+IMG_IMPORT
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK_KM *psKick);
+#else
+PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK *psKick);
+#endif
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle,
+#if defined (SUPPORT_SID_INTERFACE)
+ SGX_CCB_KICK_KM *psCCBKick);
+#else
+ SGX_CCB_KICK *psCCBKick);
+#endif
+
+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,
+ IMG_HANDLE hDevMemContext);
+
+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);
+
+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,
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_HEAP_INFO_KM *pasHeapInfo,
+ IMG_DEV_PHYADDR *psPDDevPAddr);
+#else
+ SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo);
+#endif
+
+IMG_IMPORT
+PVRSRV_ERROR DevInitSGXPart2KM(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE hDevHandle,
+#if defined (SUPPORT_SID_INTERFACE)
+ SGX_BRIDGE_INIT_INFO_KM *psInitInfo);
+#else
+ SGX_BRIDGE_INIT_INFO *psInitInfo);
+#endif
+
+/*!
+ * *****************************************************************************
+ * @brief Looks for a parameter buffer description that corresponds to
+ * a buffer of size ui32TotalPBSize, optionally taking the lock
+ * needed for SharedPBCreation on failure.
+ *
+ * Note if a PB Desc is found then its internal reference counter
+ * is automatically incremented. It is your responsability to call
+ * SGXUnrefSharedPBDesc to decrement this reference and free associated
+ * resources when you are done.
+ *
+ * If bLockOnFailure is set, and a suitable shared PB isn't found,
+ * an internal flag is set, allowing this process to create a
+ * shared PB. Any other process calling this function with
+ * bLockOnFailure set, will receive the return code
+ * PVRSRV_ERROR_PROCESSING_BLOCKED, indicating that it needs
+ * to retry the function call. The internal flag is cleared
+ * when this process creates a shared PB.
+ *
+ * Note: You are responsible for freeing the list returned in
+ * pppsSharedPBDescSubKernelMemInfos
+ * via OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ * sizeof(PVRSRV_KERNEL_MEM_INFO *)
+ * * ui32SharedPBDescSubKernelMemInfosCount,
+ * ppsSharedPBDescSubKernelMemInfos,
+ * NULL);
+ *
+ * @param[in] psPerProc
+ * @param[in] hDevCookie
+ * @param[in] bLockOnError
+ * @param[in] ui32TotalPBSize
+ * @param[in] phSharedPBDesc
+ * @param[out] ppsSharedPBDescKernelMemInfo
+ * @param[out] ppsHWPBDescKernelMemInfo
+ * @param[out] pppsSharedPBDescSubKernelMemInfos A list of integral sub meminfos.
+ * @param[out] ui32SharedPBDescSubKernelMemInfosCount
+ *
+ * @return PVRSRV_ERROR
+ ********************************************************************************/
+/* disable QAC pointer level check for over 2 */
+/* PRQA S 5102++ */
+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 **ppsHWBlockKernelMemInfo,
+ PVRSRV_KERNEL_MEM_INFO ***pppsSharedPBDescSubKernelMemInfos,
+ IMG_UINT32 *ui32SharedPBDescSubKernelMemInfosCount);
+
+/*!
+ * *****************************************************************************
+ * @brief Decrements the reference counter and frees all userspace resources
+ * associated with a SharedPBDesc.
+ *
+ * @param hSharedPBDesc
+ *
+ * @return PVRSRV_ERROR
+ ********************************************************************************/
+IMG_IMPORT PVRSRV_ERROR
+SGXUnrefSharedPBDescKM(IMG_HANDLE hSharedPBDesc);
+
+/*!
+ * *****************************************************************************
+ * @brief Links a new SharedPBDesc into a kernel managed list that can
+ * then be queried by other clients.
+ *
+ * As a side affect this function also dissociates the SharedPBDesc
+ * from the calling process so that the memory won't be freed if the
+ * process dies/exits. (The kernel assumes responsability over the
+ * memory at the same time)
+ *
+ * As well as the psSharedPBDescKernelMemInfo you must also pass
+ * a complete list of other meminfos that are integral to the
+ * shared PB description. (Although the kernel doesn't have direct
+ * access to the shared PB desc it still needs to be able to
+ * clean up all the associated resources when it is no longer
+ * in use.)
+ *
+ * If the dissociation fails then all the memory associated with
+ * the psSharedPBDescKernelMemInfo and all entries in psKernelMemInfos
+ * will be freed by kernel services! Because of this, you are
+ * responsible for freeing the corresponding client meminfos _before_
+ * calling SGXAddSharedPBDescKM.
+ *
+ * This function will return an error unless a succesful call to
+ * SGXFindSharedPBDesc, with bLockOnFailure set, has been made.
+ *
+ * @param psPerProc
+ * @param hDevCookie
+ * @param psSharedPBDescKernelMemInfo
+ * @param psHWPBDescKernelMemInfo
+ * @param psBlockKernelMemInfo
+ * @param ui32TotalPBSize The size of the associated parameter buffer
+ * @param ppsSharedPBDescSubKernelMemInfos A list of other meminfos integral to
+ * the shared PB description.
+ * @param ui32SharedPBDescSubKernelMemInfosCount The number of entires in
+ * psKernelMemInfos
+ * @param sHWPBDescDevVAddr The device virtual address of the HWPBDesc
+ *
+ * @return PVRSRV_ERROR
+ ********************************************************************************/
+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,
+ PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo,
+ IMG_UINT32 ui32TotalPBSize,
+ IMG_HANDLE *phSharedPBDesc,
+ PVRSRV_KERNEL_MEM_INFO **psSharedPBDescSubKernelMemInfos,
+ IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount,
+ IMG_DEV_VIRTADDR sHWPBDescDevVAddr);
+
+
+/*!
+ * *****************************************************************************
+ * @brief Gets device information that is not intended to be passed
+ on beyond the srvclient libs.
+ *
+ * @param[in] hDevCookie
+ * @param[out] psSGXInternalDevInfo
+ *
+ * @return
+ ********************************************************************************/
+IMG_IMPORT PVRSRV_ERROR
+SGXGetInternalDevInfoKM(IMG_HANDLE hDevCookie,
+#if defined (SUPPORT_SID_INTERFACE)
+ SGX_INTERNAL_DEVINFO_KM *psSGXInternalDevInfo);
+#else
+ SGX_INTERNAL_DEVINFO *psSGXInternalDevInfo);
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* __SGX_BRIDGE_KM_H__ */
+
+/******************************************************************************
+ End of file (sgx_bridge_km.h)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/devices/sgx/sgxconfig.h b/pvr-source/services4/srvkm/devices/sgx/sgxconfig.h
new file mode 100644
index 0000000..b9ebab9
--- /dev/null
+++ b/pvr-source/services4/srvkm/devices/sgx/sgxconfig.h
@@ -0,0 +1,481 @@
+/*************************************************************************/ /*!
+@Title device configuration
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __SGXCONFIG_H__
+#define __SGXCONFIG_H__
+
+#include "sgxdefs.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 defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+#define SGX_KERNEL_DATA_HEAP_OFFSET 0x00001000
+#else
+#define SGX_KERNEL_DATA_HEAP_OFFSET 0x00000000
+#endif
+
+#if !defined(ION_HEAP_SIZE) && defined(SUPPORT_ION)
+ /* Default the Ion heap to 16MB */
+ #define ION_HEAP_SIZE 0x01000000
+#else
+ #define ION_HEAP_SIZE 0
+#endif
+
+
+#if SGX_FEATURE_ADDRESS_SPACE_SIZE == 32
+#if defined(FIX_HW_BRN_31620)
+ #if defined(SGX_FEATURE_2D_HARDWARE)
+ #define SGX_2D_HEAP_BASE 0x04000000
+ #define SGX_2D_HEAP_SIZE (0x08000000-0x04000000-0x00001000)
+ #endif
+
+ #define SGX_GENERAL_HEAP_BASE 0x08000000
+ #define SGX_GENERAL_HEAP_SIZE (0xB8000000-0x00001000)
+
+ /*
+ * For hybrid PB we have to split virtual PB range between the shared
+ * PB and percontext PB due to the fact we only have one heap config
+ * per device.
+ * If hybrid PB is enabled we split the space acording to HYBRID_SHARED_PB_SIZE.
+ * i.e. HYBRID_SHARED_PB_SIZE defines the size of the shared PB and the
+ * remainder is the size of the percontext PB.
+ * If hybrid PB is not enabled then we still create both heaps (helps keep
+ * the code clean) and define the size of the unused one to 0
+ */
+
+ #define SGX_3DPARAMETERS_HEAP_SIZE 0x10000000
+
+ /* By default we split the PB 50/50 */
+#if !defined(HYBRID_SHARED_PB_SIZE)
+ #define HYBRID_SHARED_PB_SIZE (SGX_3DPARAMETERS_HEAP_SIZE >> 1)
+#endif
+#if defined(SUPPORT_HYBRID_PB)
+ #define SGX_SHARED_3DPARAMETERS_SIZE (HYBRID_SHARED_PB_SIZE)
+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE (HYBRID_SHARED_PB_SIZE-0x00001000)
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - SGX_SHARED_3DPARAMETERS_SIZE - 0x00001000)
+#else
+#if defined(SUPPORT_PERCONTEXT_PB)
+ #define SGX_SHARED_3DPARAMETERS_SIZE 0
+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE 0
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000)
+#endif
+#if defined(SUPPORT_SHARED_PB)
+ #define SGX_SHARED_3DPARAMETERS_SIZE SGX_3DPARAMETERS_HEAP_SIZE
+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000)
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE 0
+#endif
+#endif
+
+ #define SGX_SHARED_3DPARAMETERS_HEAP_BASE 0xC0000000
+ /* Size is defiend above */
+
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE (SGX_SHARED_3DPARAMETERS_HEAP_BASE + SGX_SHARED_3DPARAMETERS_SIZE)
+ /* Size is defiend above */
+
+ #define SGX_TADATA_HEAP_BASE 0xD0000000
+ #define SGX_TADATA_HEAP_SIZE (0x0D000000-0x00001000)
+
+ #define SGX_SYNCINFO_HEAP_BASE 0xE0000000
+ #define SGX_SYNCINFO_HEAP_SIZE (0x01000000-0x00001000)
+
+ #define SGX_PDSPIXEL_CODEDATA_HEAP_BASE 0xE4000000
+ #define SGX_PDSPIXEL_CODEDATA_HEAP_SIZE (0x02000000-0x00001000)
+
+ #define SGX_KERNEL_CODE_HEAP_BASE 0xE8000000
+ #define SGX_KERNEL_CODE_HEAP_SIZE (0x00080000-0x00001000)
+
+ #define SGX_PDSVERTEX_CODEDATA_HEAP_BASE 0xEC000000
+ #define SGX_PDSVERTEX_CODEDATA_HEAP_SIZE (0x01C00000-0x00001000)
+
+ #define SGX_KERNEL_DATA_HEAP_BASE (0xF0000000+SGX_KERNEL_DATA_HEAP_OFFSET)
+ #define SGX_KERNEL_DATA_HEAP_SIZE (0x03000000-(0x00001000+SGX_KERNEL_DATA_HEAP_OFFSET))
+
+ /* Actual Pixel and Vertex shared heaps sizes may be reduced by
+ * override - see SGX_USE_CODE_SEGMENT_RANGE_BITS.*/
+ #define SGX_PIXELSHADER_HEAP_BASE 0xF4000000
+ #define SGX_PIXELSHADER_HEAP_SIZE (0x05000000-0x00001000)
+
+ #define SGX_VERTEXSHADER_HEAP_BASE 0xFC000000
+ #define SGX_VERTEXSHADER_HEAP_SIZE (0x02000000-0x00001000)
+#else /* FIX_HW_BRN_31620 */
+ #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
+
+ #if !defined(SUPPORT_MEMORY_TILING)
+ #if defined (SUPPORT_ION)
+ #define SGX_GENERAL_HEAP_BASE 0x10000000
+ #define SGX_GENERAL_HEAP_SIZE (0xC2000000-ION_HEAP_SIZE-0x00001000)
+
+ #define SGX_ION_HEAP_BASE (SGX_GENERAL_HEAP_BASE+SGX_GENERAL_HEAP_SIZE+0x00001000)
+ #define SGX_ION_HEAP_SIZE (ION_HEAP_SIZE-0x00001000)
+ #else
+ #define SGX_GENERAL_HEAP_BASE 0x10000000
+ #define SGX_GENERAL_HEAP_SIZE (0xC2000000-0x00001000)
+ #endif
+ #else
+ #include <sgx_msvdx_defs.h>
+ /* Create heaps with memory tiling enabled.
+ * SGX HW limit is 10 heaps.
+ */
+ /* Tiled heap space is taken from general heap */
+ #define SGX_GENERAL_HEAP_BASE 0x10000000
+ #define SGX_GENERAL_HEAP_SIZE (0xB5000000-0x00001000)
+
+ #define SGX_VPB_TILED_HEAP_STRIDE TILING_TILE_STRIDE_2K
+ #define SGX_VPB_TILED_HEAP_BASE 0xC5000000
+ #define SGX_VPB_TILED_HEAP_SIZE (0x0D000000-0x00001000)
+
+ /* Check tiled heap base alignment */
+ #if((SGX_VPB_TILED_HEAP_BASE & SGX_BIF_TILING_ADDR_INV_MASK) != 0)
+ #error "sgxconfig.h: SGX_VPB_TILED_HEAP has insufficient alignment"
+ #endif
+
+ #endif /* SUPPORT_MEMORY_TILING */
+
+ /*
+ * For hybrid PB we have to split virtual PB range between the shared
+ * PB and percontext PB due to the fact we only have one heap config
+ * per device.
+ * If hybrid PB is enabled we split the space acording to HYBRID_SHARED_PB_SIZE.
+ * i.e. HYBRID_SHARED_PB_SIZE defines the size of the shared PB and the
+ * remainder is the size of the percontext PB.
+ * If hybrid PB is not enabled then we still create both heaps (helps keep
+ * the code clean) and define the size of the unused one to 0
+ */
+
+ #define SGX_3DPARAMETERS_HEAP_SIZE 0x10000000
+
+ /* By default we split the PB 50/50 */
+#if !defined(HYBRID_SHARED_PB_SIZE)
+ #define HYBRID_SHARED_PB_SIZE (SGX_3DPARAMETERS_HEAP_SIZE >> 1)
+#endif
+#if defined(SUPPORT_HYBRID_PB)
+ #define SGX_SHARED_3DPARAMETERS_SIZE (HYBRID_SHARED_PB_SIZE)
+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE (HYBRID_SHARED_PB_SIZE-0x00001000)
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - SGX_SHARED_3DPARAMETERS_SIZE - 0x00001000)
+#else
+#if defined(SUPPORT_PERCONTEXT_PB)
+ #define SGX_SHARED_3DPARAMETERS_SIZE 0
+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE 0
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000)
+#endif
+#if defined(SUPPORT_SHARED_PB)
+ #define SGX_SHARED_3DPARAMETERS_SIZE SGX_3DPARAMETERS_HEAP_SIZE
+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000)
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE 0
+#endif
+#endif
+
+ #define SGX_SHARED_3DPARAMETERS_HEAP_BASE 0xD2000000
+ /* Size is defiend above */
+
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE (SGX_SHARED_3DPARAMETERS_HEAP_BASE + SGX_SHARED_3DPARAMETERS_SIZE)
+ /* Size is defiend above */
+
+ #define SGX_TADATA_HEAP_BASE 0xE2000000
+ #define SGX_TADATA_HEAP_SIZE (0x0D000000-0x00001000)
+
+ #define SGX_SYNCINFO_HEAP_BASE 0xEF000000
+ #define SGX_SYNCINFO_HEAP_SIZE (0x01000000-0x00001000)
+
+ #define SGX_PDSPIXEL_CODEDATA_HEAP_BASE 0xF0000000
+ #define SGX_PDSPIXEL_CODEDATA_HEAP_SIZE (0x02000000-0x00001000)
+
+ #define SGX_KERNEL_CODE_HEAP_BASE 0xF2000000
+ #define SGX_KERNEL_CODE_HEAP_SIZE (0x00080000-0x00001000)
+
+ #define SGX_PDSVERTEX_CODEDATA_HEAP_BASE 0xF2400000
+ #define SGX_PDSVERTEX_CODEDATA_HEAP_SIZE (0x01C00000-0x00001000)
+
+ #define SGX_KERNEL_DATA_HEAP_BASE (0xF4000000+SGX_KERNEL_DATA_HEAP_OFFSET)
+ #define SGX_KERNEL_DATA_HEAP_SIZE (0x05000000-(0x00001000+SGX_KERNEL_DATA_HEAP_OFFSET))
+
+ /* Actual Pixel and Vertex shared heaps sizes may be reduced by
+ * override - see SGX_USE_CODE_SEGMENT_RANGE_BITS.*/
+ #define SGX_PIXELSHADER_HEAP_BASE 0xF9000000
+ #define SGX_PIXELSHADER_HEAP_SIZE (0x05000000-0x00001000)
+
+ #define SGX_VERTEXSHADER_HEAP_BASE 0xFE000000
+ #define SGX_VERTEXSHADER_HEAP_SIZE (0x02000000-0x00001000)
+#endif /* FIX_HW_BRN_31620 */
+ /* signal we've identified the core by the build */
+ #define SGX_CORE_IDENTIFIED
+#endif /* SGX_FEATURE_ADDRESS_SPACE_SIZE == 32 */
+
+#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)
+
+ #define SGX_GENERAL_HEAP_BASE 0x01800000
+ #define SGX_GENERAL_HEAP_SIZE (0x07000000-ION_HEAP_SIZE-0x00001000)
+
+#else
+ #define SGX_GENERAL_HEAP_BASE 0x00001000
+#if defined(SUPPORT_LARGE_GENERAL_HEAP)
+ #define SGX_GENERAL_HEAP_SIZE (0x0B800000-ION_HEAP_SIZE-0x00001000-0x00001000)
+#else
+ #define SGX_GENERAL_HEAP_SIZE (0x08800000-ION_HEAP_SIZE-0x00001000-0x00001000)
+#endif
+#endif
+
+#if defined(SUPPORT_ION)
+ #define SGX_ION_HEAP_BASE (SGX_GENERAL_HEAP_BASE+SGX_GENERAL_HEAP_SIZE+0x00001000)
+ #define SGX_ION_HEAP_SIZE (ION_HEAP_SIZE-0x00001000)
+#endif
+ /*
+ * For hybrid PB we have to split virtual PB range between the shared
+ * PB and percontext PB due to the fact we only have one heap config
+ * per device.
+ * If hybrid PB is enabled we split the space acording to HYBRID_SHARED_PB_SIZE.
+ * i.e. HYBRID_SHARED_PB_SIZE defines the size of the shared PB and the
+ * remainder is the size of the percontext PB.
+ * If hybrid PB is not enabled then we still create both heaps (helps keep
+ * the code clean) and define the size of the unused one to 0
+ */
+#if defined(SUPPORT_LARGE_GENERAL_HEAP)
+ #define SGX_3DPARAMETERS_HEAP_SIZE 0x01000000
+#else
+ #define SGX_3DPARAMETERS_HEAP_SIZE 0x04000000
+#endif
+
+ /* By default we split the PB 50/50 */
+#if !defined(HYBRID_SHARED_PB_SIZE)
+ #define HYBRID_SHARED_PB_SIZE (SGX_3DPARAMETERS_HEAP_SIZE >> 1)
+#endif
+#if defined(SUPPORT_HYBRID_PB)
+ #define SGX_SHARED_3DPARAMETERS_SIZE (HYBRID_SHARED_PB_SIZE)
+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE (HYBRID_SHARED_PB_SIZE-0x00001000)
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - SGX_SHARED_3DPARAMETERS_SIZE - 0x00001000)
+#else
+#if defined(SUPPORT_PERCONTEXT_PB)
+ #define SGX_SHARED_3DPARAMETERS_SIZE 0
+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE 0
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000)
+#endif
+#if defined(SUPPORT_SHARED_PB)
+ #define SGX_SHARED_3DPARAMETERS_SIZE SGX_3DPARAMETERS_HEAP_SIZE
+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000)
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE 0
+#endif
+#endif
+
+#if defined(SUPPORT_LARGE_GENERAL_HEAP)
+ #define SGX_SHARED_3DPARAMETERS_HEAP_BASE 0x0B800000
+#else
+ #define SGX_SHARED_3DPARAMETERS_HEAP_BASE 0x08800000
+#endif
+
+ /* Size is defined above */
+
+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE (SGX_SHARED_3DPARAMETERS_HEAP_BASE + SGX_SHARED_3DPARAMETERS_SIZE)
+ /* Size is defined above */
+
+ #define SGX_TADATA_HEAP_BASE 0x0C800000
+ #define SGX_TADATA_HEAP_SIZE (0x01000000-0x00001000)
+
+ #define SGX_SYNCINFO_HEAP_BASE 0x0D800000
+ #define SGX_SYNCINFO_HEAP_SIZE (0x00400000-0x00001000)
+
+ #define SGX_PDSPIXEL_CODEDATA_HEAP_BASE 0x0DC00000
+ #define SGX_PDSPIXEL_CODEDATA_HEAP_SIZE (0x00800000-0x00001000)
+
+ #define SGX_KERNEL_CODE_HEAP_BASE 0x0E400000
+ #define SGX_KERNEL_CODE_HEAP_SIZE (0x00080000-0x00001000)
+
+ #define SGX_PDSVERTEX_CODEDATA_HEAP_BASE 0x0E800000
+ #define SGX_PDSVERTEX_CODEDATA_HEAP_SIZE (0x00800000-0x00001000)
+
+ #define SGX_KERNEL_DATA_HEAP_BASE (0x0F000000+SGX_KERNEL_DATA_HEAP_OFFSET)
+ #define SGX_KERNEL_DATA_HEAP_SIZE (0x00400000-(0x00001000+SGX_KERNEL_DATA_HEAP_OFFSET))
+
+ #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)
+
+ /* signal we've identified the core by the build */
+ #define SGX_CORE_IDENTIFIED
+
+#endif /* SGX_FEATURE_ADDRESS_SPACE_SIZE == 28 */
+
+#if !defined(SGX_CORE_IDENTIFIED)
+ #error "sgxconfig.h: ERROR: unspecified SGX Core version"
+#endif
+
+/*********************************************************************************
+ *
+ * SGX_PDSPIXEL_CODEDATA_HEAP_BASE + 64MB range must include PDSVERTEX_CODEDATA and KERNEL_CODE heaps
+ *
+ ********************************************************************************/
+#if !defined (SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE)
+ #if ((SGX_KERNEL_CODE_HEAP_BASE + SGX_KERNEL_CODE_HEAP_SIZE - SGX_PDSPIXEL_CODEDATA_HEAP_BASE) > 0x4000000)
+ #error "sgxconfig.h: ERROR: SGX_KERNEL_CODE_HEAP_BASE out of range of SGX_PDSPIXEL_CODEDATA_HEAP_BASE"
+ #endif
+
+ #if ((SGX_PDSVERTEX_CODEDATA_HEAP_BASE + SGX_PDSVERTEX_CODEDATA_HEAP_SIZE - SGX_PDSPIXEL_CODEDATA_HEAP_BASE) > 0x4000000)
+ #error "sgxconfig.h: ERROR: SGX_PDSVERTEX_CODEDATA_HEAP_BASE out of range of SGX_PDSPIXEL_CODEDATA_HEAP_BASE"
+ #endif
+#endif
+
+/*********************************************************************************
+ *
+ * The General Mapping heap must be within the 2D requestor range of the 2D heap base
+ *
+ ********************************************************************************/
+#if defined(SGX_FEATURE_2D_HARDWARE) && defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+ #if ((SGX_GENERAL_MAPPING_HEAP_BASE + SGX_GENERAL_MAPPING_HEAP_SIZE - SGX_2D_HEAP_BASE) >= EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK)
+ #error "sgxconfig.h: ERROR: SGX_GENERAL_MAPPING_HEAP inaccessable by 2D requestor"
+ #endif
+#endif
+
+/*********************************************************************************
+ *
+ * The kernel code heap base must be aligned to a USSE code page
+ *
+ ********************************************************************************/
+#if defined (EURASIA_USE_CODE_PAGE_SIZE)
+ #if ((SGX_KERNEL_CODE_HEAP_BASE & (EURASIA_USE_CODE_PAGE_SIZE - 1)) != 0)
+ #error "sgxconfig.h: ERROR: Kernel code heap base misalignment"
+ #endif
+#endif
+
+/*********************************************************************************
+ *
+ * Heap overlap check
+ *
+ ********************************************************************************/
+#if defined(SGX_FEATURE_2D_HARDWARE)
+ #if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+ #if ((SGX_2D_HEAP_BASE + SGX_2D_HEAP_SIZE) >= SGX_GENERAL_MAPPING_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_2D_HEAP overlaps SGX_GENERAL_MAPPING_HEAP"
+ #endif
+ #else
+ #if ((SGX_2D_HEAP_BASE + SGX_2D_HEAP_SIZE) >= SGX_GENERAL_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_2D_HEAP overlaps SGX_GENERAL_HEAP_BASE"
+ #endif
+ #endif
+#endif
+
+#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+ #if ((SGX_GENERAL_MAPPING_HEAP_BASE + SGX_GENERAL_MAPPING_HEAP_SIZE) >= SGX_GENERAL_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_GENERAL_MAPPING_HEAP overlaps SGX_GENERAL_HEAP"
+ #endif
+#endif
+
+#if defined(SUPPORT_HYBRID_PB)
+ #if ((HYBRID_SHARED_PB_SIZE + 0x000001000) > SGX_3DPARAMETERS_HEAP_SIZE)
+ #error "sgxconfig.h: ERROR: HYBRID_SHARED_PB_SIZE too large"
+ #endif
+#endif
+
+#if defined(SUPPORT_MEMORY_TILING)
+ #if ((SGX_GENERAL_HEAP_BASE + SGX_GENERAL_HEAP_SIZE) >= SGX_VPB_TILED_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_GENERAL_HEAP overlaps SGX_VPB_TILED_HEAP"
+ #endif
+ #if ((SGX_VPB_TILED_HEAP_BASE + SGX_VPB_TILED_HEAP_SIZE) >= SGX_SHARED_3DPARAMETERS_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_VPB_TILED_HEAP overlaps SGX_3DPARAMETERS_HEAP"
+ #endif
+#else
+ #if defined(SUPPORT_ION)
+ #if ((SGX_ION_HEAP_BASE + SGX_ION_HEAP_SIZE) >= SGX_SHARED_3DPARAMETERS_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_ION_HEAP overlaps SGX_3DPARAMETERS_HEAP"
+ #endif
+ #endif
+ #if ((SGX_GENERAL_HEAP_BASE + SGX_GENERAL_HEAP_SIZE) >= SGX_SHARED_3DPARAMETERS_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_GENERAL_HEAP overlaps SGX_3DPARAMETERS_HEAP"
+ #endif
+#endif
+
+#if (((SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE + SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE) >= SGX_TADATA_HEAP_BASE) && (SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE > 0))
+ #error "sgxconfig.h: ERROR: SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE overlaps SGX_TADATA_HEAP"
+#endif
+
+#if ((SGX_TADATA_HEAP_BASE + SGX_TADATA_HEAP_SIZE) >= SGX_SYNCINFO_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_TADATA_HEAP overlaps SGX_SYNCINFO_HEAP"
+#endif
+
+#if ((SGX_SYNCINFO_HEAP_BASE + SGX_SYNCINFO_HEAP_SIZE) >= SGX_PDSPIXEL_CODEDATA_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_SYNCINFO_HEAP overlaps SGX_PDSPIXEL_CODEDATA_HEAP"
+#endif
+
+#if ((SGX_PDSPIXEL_CODEDATA_HEAP_BASE + SGX_PDSPIXEL_CODEDATA_HEAP_SIZE) >= SGX_KERNEL_CODE_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_PDSPIXEL_CODEDATA_HEAP overlaps SGX_KERNEL_CODE_HEAP"
+#endif
+
+#if ((SGX_KERNEL_CODE_HEAP_BASE + SGX_KERNEL_CODE_HEAP_SIZE) >= SGX_PDSVERTEX_CODEDATA_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_KERNEL_CODE_HEAP overlaps SGX_PDSVERTEX_CODEDATA_HEAP"
+#endif
+
+#if ((SGX_PDSVERTEX_CODEDATA_HEAP_BASE + SGX_PDSVERTEX_CODEDATA_HEAP_SIZE) >= SGX_KERNEL_DATA_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_PDSVERTEX_CODEDATA_HEAP overlaps SGX_KERNEL_DATA_HEAP"
+#endif
+
+#if ((SGX_KERNEL_DATA_HEAP_BASE + SGX_KERNEL_DATA_HEAP_SIZE) >= SGX_PIXELSHADER_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_KERNEL_DATA_HEAP overlaps SGX_PIXELSHADER_HEAP"
+#endif
+
+#if ((SGX_PIXELSHADER_HEAP_BASE + SGX_PIXELSHADER_HEAP_SIZE) >= SGX_VERTEXSHADER_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_PIXELSHADER_HEAP overlaps SGX_VERTEXSHADER_HEAP"
+#endif
+
+#if ((SGX_VERTEXSHADER_HEAP_BASE + SGX_VERTEXSHADER_HEAP_SIZE) < SGX_VERTEXSHADER_HEAP_BASE)
+ #error "sgxconfig.h: ERROR: SGX_VERTEXSHADER_HEAP_BASE size cause wraparound"
+#endif
+
+#endif /* __SGXCONFIG_H__ */
+
+/*****************************************************************************
+ End of file (sgxconfig.h)
+*****************************************************************************/
diff --git a/pvr-source/services4/srvkm/devices/sgx/sgxinfokm.h b/pvr-source/services4/srvkm/devices/sgx/sgxinfokm.h
new file mode 100644
index 0000000..125da09
--- /dev/null
+++ b/pvr-source/services4/srvkm/devices/sgx/sgxinfokm.h
@@ -0,0 +1,610 @@
+/*************************************************************************/ /*!
+@Title SGX kernel services structues/functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Structures and inline functions for KM services component
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef __SGXINFOKM_H__
+#define __SGXINFOKM_H__
+
+#include "sgxdefs.h"
+#include "device.h"
+#include "power.h"
+#include "sysconfig.h"
+#include "sgxscript.h"
+#include "sgxinfo.h"
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/****************************************************************************/
+/* kernel only defines: */
+/****************************************************************************/
+/* SGXDeviceMap Flag defines */
+#define SGX_HOSTPORT_PRESENT 0x00000001UL
+
+
+/*
+ SGX PDUMP register bank name (prefix)
+*/
+#define SGX_PDUMPREG_NAME "SGXREG"
+
+/****************************************************************************/
+/* kernel only structures: */
+/****************************************************************************/
+
+/*Forward declaration*/
+typedef struct _PVRSRV_STUB_PBDESC_ PVRSRV_STUB_PBDESC;
+
+
+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;
+
+ /* Kernel mode linear address of device registers */
+ IMG_PVOID pvRegsBaseKM;
+
+#if defined(SGX_FEATURE_HOST_PORT)
+ /* Kernel mode linear address of host port */
+ IMG_PVOID pvHostPortBaseKM;
+ /* HP size */
+ IMG_UINT32 ui32HPSize;
+ /* HP syspaddr */
+ IMG_SYS_PHYADDR sHPSysPAddr;
+#endif
+
+ /* FIXME: The alloc for this should go through OSAllocMem in future */
+ IMG_HANDLE hRegMapping;
+
+ /* System physical address of device registers*/
+ IMG_SYS_PHYADDR sRegsPhysBase;
+ /* Register region size in bytes */
+ IMG_UINT32 ui32RegSize;
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+ /* external system cache register region size in bytes */
+ IMG_UINT32 ui32ExtSysCacheRegsSize;
+ /* external system cache register device relative physical address */
+ IMG_DEV_PHYADDR sExtSysCacheRegsDevPBase;
+ /* ptr to page table */
+ IMG_UINT32 *pui32ExtSystemCacheRegsPT;
+ /* handle to page table alloc/mapping */
+ IMG_HANDLE hExtSystemCacheRegsPTPageOSMemHandle;
+ /* sys phys addr of PT */
+ IMG_SYS_PHYADDR sExtSystemCacheRegsPTSysPAddr;
+#endif
+
+ /* SGX clock speed */
+ IMG_UINT32 ui32CoreClockSpeed;
+ IMG_UINT32 ui32uKernelTimerClock;
+ IMG_BOOL bSGXIdle;
+
+ PVRSRV_STUB_PBDESC *psStubPBDescListKM;
+
+
+ /* kernel memory context info */
+ IMG_DEV_PHYADDR sKernelPDDevPAddr;
+
+ IMG_UINT32 ui32HeapCount; /*!< heap count */
+ IMG_VOID *pvDeviceMemoryHeap;
+ PPVRSRV_KERNEL_MEM_INFO psKernelCCBMemInfo; /*!< meminfo for CCB in device accessible memory */
+ PVRSRV_SGX_KERNEL_CCB *psKernelCCB; /*!< kernel mode linear address of CCB in device accessible memory */
+ PPVRSRV_SGX_CCB_INFO psKernelCCBInfo; /*!< CCB information structure */
+ PPVRSRV_KERNEL_MEM_INFO psKernelCCBCtlMemInfo; /*!< meminfo for CCB control in device accessible memory */
+ PVRSRV_SGX_CCB_CTL *psKernelCCBCtl; /*!< kernel mode linear address of CCB control in device accessible memory */
+ PPVRSRV_KERNEL_MEM_INFO psKernelCCBEventKickerMemInfo; /*!< meminfo for kernel CCB event kicker */
+ IMG_UINT32 *pui32KernelCCBEventKicker; /*!< kernel mode linear address of kernel CCB event kicker */
+#if defined(PDUMP)
+ IMG_UINT32 ui32KernelCCBEventKickerDumpVal; /*!< pdump copy of the kernel CCB event kicker */
+#endif /* PDUMP */
+ PVRSRV_KERNEL_MEM_INFO *psKernelSGXMiscMemInfo; /*!< kernel mode linear address of SGX misc info buffer */
+ IMG_UINT32 aui32HostKickAddr[SGXMKIF_CMD_MAX]; /*!< ukernel host kick offests */
+#if defined(SGX_SUPPORT_HWPROFILING)
+ PPVRSRV_KERNEL_MEM_INFO psKernelHWProfilingMemInfo;
+#endif
+ PPVRSRV_KERNEL_MEM_INFO psKernelHWPerfCBMemInfo; /*!< Meminfo for hardware performace circular buffer */
+ PPVRSRV_KERNEL_MEM_INFO psKernelTASigBufferMemInfo; /*!< Meminfo for TA signature buffer */
+ PPVRSRV_KERNEL_MEM_INFO psKernel3DSigBufferMemInfo; /*!< Meminfo for 3D signature buffer */
+#if defined(FIX_HW_BRN_29702)
+ PPVRSRV_KERNEL_MEM_INFO psKernelCFIMemInfo; /*!< Meminfo for cfi */
+#endif
+#if defined(FIX_HW_BRN_29823)
+ PPVRSRV_KERNEL_MEM_INFO psKernelDummyTermStreamMemInfo; /*!< Meminfo for dummy terminate stream */
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31559)
+ PPVRSRV_KERNEL_MEM_INFO psKernelVDMSnapShotBufferMemInfo; /*!< Meminfo for dummy snapshot buffer */
+ PPVRSRV_KERNEL_MEM_INFO psKernelVDMCtrlStreamBufferMemInfo; /*!< Meminfo for dummy control stream */
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \
+ defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX)
+ PPVRSRV_KERNEL_MEM_INFO psKernelVDMStateUpdateBufferMemInfo; /*!< Meminfo for state update buffer */
+#endif
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+ PPVRSRV_KERNEL_MEM_INFO psKernelEDMStatusBufferMemInfo; /*!< Meminfo for EDM status buffer */
+#endif
+ /* Client reference count */
+ IMG_UINT32 ui32ClientRefCount;
+
+ /* cache control word for micro kernel cache flush/invalidates */
+ IMG_UINT32 ui32CacheControl;
+
+ /* client-side build options */
+ IMG_UINT32 ui32ClientBuildOptions;
+
+ /* client-side microkernel structure sizes */
+ SGX_MISCINFO_STRUCT_SIZES sSGXStructSizes;
+
+ /*
+ if we don't preallocate the pagetables we must
+ insert newly allocated page tables dynamically
+ */
+ IMG_VOID *pvMMUContextList;
+
+ /* Copy of registry ForcePTOff entry */
+ IMG_BOOL bForcePTOff;
+
+ IMG_UINT32 ui32EDMTaskReg0;
+ IMG_UINT32 ui32EDMTaskReg1;
+
+ IMG_UINT32 ui32ClkGateCtl;
+ IMG_UINT32 ui32ClkGateCtl2;
+ IMG_UINT32 ui32ClkGateStatusReg;
+ IMG_UINT32 ui32ClkGateStatusMask;
+#if defined(SGX_FEATURE_MP)
+ IMG_UINT32 ui32MasterClkGateStatusReg;
+ IMG_UINT32 ui32MasterClkGateStatusMask;
+ IMG_UINT32 ui32MasterClkGateStatus2Reg;
+ IMG_UINT32 ui32MasterClkGateStatus2Mask;
+#endif /* SGX_FEATURE_MP */
+ SGX_INIT_SCRIPTS sScripts;
+
+ /* Members associated with dummy PD needed for BIF reset */
+ IMG_HANDLE hBIFResetPDOSMemHandle;
+ IMG_DEV_PHYADDR sBIFResetPDDevPAddr;
+ IMG_DEV_PHYADDR sBIFResetPTDevPAddr;
+ IMG_DEV_PHYADDR sBIFResetPageDevPAddr;
+ IMG_UINT32 *pui32BIFResetPD;
+ IMG_UINT32 *pui32BIFResetPT;
+
+
+#if defined(SUPPORT_HW_RECOVERY)
+ /* Timeout callback handle */
+ IMG_HANDLE hTimer;
+ /* HW recovery Time stamp */
+ IMG_UINT32 ui32TimeStamp;
+#endif
+
+ /* Number of SGX resets */
+ IMG_UINT32 ui32NumResets;
+
+ /* host control */
+ PVRSRV_KERNEL_MEM_INFO *psKernelSGXHostCtlMemInfo;
+ SGXMKIF_HOST_CTL *psSGXHostCtl;
+
+ /* TA/3D control */
+ PVRSRV_KERNEL_MEM_INFO *psKernelSGXTA3DCtlMemInfo;
+
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+ PVRSRV_KERNEL_MEM_INFO *psKernelSGXPTLAWriteBackMemInfo;
+#endif
+
+ IMG_UINT32 ui32Flags;
+
+ /* memory tiling range usage */
+ IMG_UINT32 ui32MemTilingUsage;
+
+ #if defined(PDUMP)
+ PVRSRV_SGX_PDUMP_CONTEXT sPDContext;
+ #endif
+
+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+ /* SGX MMU dummy page details */
+ IMG_VOID *pvDummyPTPageCpuVAddr;
+ IMG_DEV_PHYADDR sDummyPTDevPAddr;
+ IMG_HANDLE hDummyPTPageOSMemHandle;
+ IMG_VOID *pvDummyDataPageCpuVAddr;
+ IMG_DEV_PHYADDR sDummyDataDevPAddr;
+ IMG_HANDLE hDummyDataPageOSMemHandle;
+#endif
+#if defined(PDUMP)
+ PDUMP_MMU_ATTRIB sMMUAttrib;
+#endif
+ IMG_UINT32 asSGXDevData[SGX_MAX_DEV_DATA];
+
+#if defined(FIX_HW_BRN_31620)
+ /* Dummy page refs */
+ IMG_VOID *pvBRN31620DummyPageCpuVAddr;
+ IMG_HANDLE hBRN31620DummyPageOSMemHandle;
+ IMG_DEV_PHYADDR sBRN31620DummyPageDevPAddr;
+
+ /* Dummy PT refs */
+ IMG_VOID *pvBRN31620DummyPTCpuVAddr;
+ IMG_HANDLE hBRN31620DummyPTOSMemHandle;
+ IMG_DEV_PHYADDR sBRN31620DummyPTDevPAddr;
+
+ IMG_HANDLE hKernelMMUContext;
+#endif
+
+} PVRSRV_SGXDEV_INFO;
+
+
+typedef struct _SGX_TIMING_INFORMATION_
+{
+ IMG_UINT32 ui32CoreClockSpeed;
+ IMG_UINT32 ui32HWRecoveryFreq;
+ IMG_BOOL bEnableActivePM;
+ IMG_UINT32 ui32ActivePowManLatencyms;
+ IMG_UINT32 ui32uKernelFreq;
+} SGX_TIMING_INFORMATION;
+
+/* FIXME Rename this structure to sg more generalised as it's been extended*/
+/* SGX device map */
+typedef struct _SGX_DEVICE_MAP_
+{
+ IMG_UINT32 ui32Flags;
+
+ /* Registers */
+ 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
+
+ /* Local Device Memory Region: (if present) */
+ 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
+
+ /* device interrupt IRQ */
+ IMG_UINT32 ui32IRQ;
+
+#if !defined(SGX_DYNAMIC_TIMING_INFO)
+ /* timing information*/
+ SGX_TIMING_INFORMATION sTimingInfo;
+#endif
+#if defined(PDUMP)
+ /* pdump memory region name */
+ IMG_CHAR *pszPDumpDevName;
+#endif
+} SGX_DEVICE_MAP;
+
+
+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_KERNEL_MEM_INFO *psHWBlockKernelMemInfo;
+ IMG_DEV_VIRTADDR sHWPBDescDevVAddr;
+ PVRSRV_STUB_PBDESC *psNext;
+ PVRSRV_STUB_PBDESC **ppsThis;
+};
+
+/*!
+ ******************************************************************************
+ * CCB control structure for SGX
+ *****************************************************************************/
+typedef struct _PVRSRV_SGX_CCB_INFO_
+{
+ PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo; /*!< meminfo for CCB in device accessible memory */
+ PVRSRV_KERNEL_MEM_INFO *psCCBCtlMemInfo; /*!< meminfo for CCB control in device accessible memory */
+ SGXMKIF_COMMAND *psCommands; /*!< linear address of the array of commands */
+ IMG_UINT32 *pui32WriteOffset; /*!< linear address of the write offset into array of commands */
+ volatile IMG_UINT32 *pui32ReadOffset; /*!< linear address of the read offset into array of commands */
+#if defined(PDUMP)
+ IMG_UINT32 ui32CCBDumpWOff; /*!< for pdumping */
+#endif
+} PVRSRV_SGX_CCB_INFO;
+
+
+typedef struct _SGX_BRIDGE_INIT_INFO_KM_
+{
+ IMG_HANDLE hKernelCCBMemInfo;
+ IMG_HANDLE hKernelCCBCtlMemInfo;
+ IMG_HANDLE hKernelCCBEventKickerMemInfo;
+ IMG_HANDLE hKernelSGXHostCtlMemInfo;
+ IMG_HANDLE hKernelSGXTA3DCtlMemInfo;
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+ IMG_HANDLE hKernelSGXPTLAWriteBackMemInfo;
+#endif
+ IMG_HANDLE hKernelSGXMiscMemInfo;
+
+ IMG_UINT32 aui32HostKickAddr[SGXMKIF_CMD_MAX];
+
+ SGX_INIT_SCRIPTS sScripts;
+
+ IMG_UINT32 ui32ClientBuildOptions;
+ SGX_MISCINFO_STRUCT_SIZES sSGXStructSizes;
+
+#if defined(SGX_SUPPORT_HWPROFILING)
+ IMG_HANDLE hKernelHWProfilingMemInfo;
+#endif
+#if defined(SUPPORT_SGX_HWPERF)
+ IMG_HANDLE hKernelHWPerfCBMemInfo;
+#endif
+ IMG_HANDLE hKernelTASigBufferMemInfo;
+ IMG_HANDLE hKernel3DSigBufferMemInfo;
+
+#if defined(FIX_HW_BRN_29702)
+ IMG_HANDLE hKernelCFIMemInfo;
+#endif
+#if defined(FIX_HW_BRN_29823)
+ IMG_HANDLE hKernelDummyTermStreamMemInfo;
+#endif
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+ IMG_HANDLE hKernelEDMStatusBufferMemInfo;
+#endif
+
+ IMG_UINT32 ui32EDMTaskReg0;
+ IMG_UINT32 ui32EDMTaskReg1;
+
+ IMG_UINT32 ui32ClkGateStatusReg;
+ IMG_UINT32 ui32ClkGateStatusMask;
+#if defined(SGX_FEATURE_MP)
+// IMG_UINT32 ui32MasterClkGateStatusReg;
+// IMG_UINT32 ui32MasterClkGateStatusMask;
+// IMG_UINT32 ui32MasterClkGateStatus2Reg;
+// IMG_UINT32 ui32MasterClkGateStatus2Mask;
+#endif /* SGX_FEATURE_MP */
+
+ IMG_UINT32 ui32CacheControl;
+
+ IMG_UINT32 asInitDevData[SGX_MAX_DEV_DATA];
+ IMG_HANDLE asInitMemHandles[SGX_MAX_INIT_MEM_HANDLES];
+
+} SGX_BRIDGE_INIT_INFO_KM;
+
+
+typedef struct _SGX_INTERNEL_STATUS_UPDATE_KM_
+{
+ CTL_STATUS sCtlStatus;
+ IMG_HANDLE hKernelMemInfo;
+} SGX_INTERNEL_STATUS_UPDATE_KM;
+
+
+typedef struct _SGX_CCB_KICK_KM_
+{
+ SGXMKIF_COMMAND sCommand;
+ IMG_HANDLE hCCBKernelMemInfo;
+
+ IMG_UINT32 ui32NumDstSyncObjects;
+ IMG_HANDLE hKernelHWSyncListMemInfo;
+
+ /* DST syncs */
+ IMG_HANDLE *pahDstSyncHandles;
+
+ IMG_UINT32 ui32NumTAStatusVals;
+ IMG_UINT32 ui32Num3DStatusVals;
+
+#if defined(SUPPORT_SGX_NEW_STATUS_VALS)
+ SGX_INTERNEL_STATUS_UPDATE_KM asTAStatusUpdate[SGX_MAX_TA_STATUS_VALS];
+ SGX_INTERNEL_STATUS_UPDATE_KM 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
+
+ /* CCB offset of data structure associated with this kick */
+ IMG_UINT32 ui32CCBOffset;
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+ /* SRC and DST syncs */
+ IMG_UINT32 ui32NumTASrcSyncs;
+ IMG_HANDLE ahTASrcKernelSyncInfo[SGX_MAX_TA_SRC_SYNCS];
+ IMG_UINT32 ui32NumTADstSyncs;
+ IMG_HANDLE ahTADstKernelSyncInfo[SGX_MAX_TA_DST_SYNCS];
+ IMG_UINT32 ui32Num3DSrcSyncs;
+ IMG_HANDLE ah3DSrcKernelSyncInfo[SGX_MAX_3D_SRC_SYNCS];
+#else
+ /* SRC syncs */
+ IMG_UINT32 ui32NumSrcSyncs;
+ IMG_HANDLE ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS_TA];
+#endif
+
+ /* TA/3D dependency data */
+ 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_KM;
+
+
+#if defined(TRANSFER_QUEUE)
+typedef struct _PVRSRV_TRANSFER_SGX_KICK_KM_
+{
+ 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_KM, *PPVRSRV_TRANSFER_SGX_KICK_KM;
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+typedef struct _PVRSRV_2D_SGX_KICK_KM_
+{
+ IMG_HANDLE hCCBMemInfo;
+ IMG_UINT32 ui32SharedCmdCCBOffset;
+
+ IMG_DEV_VIRTADDR sHW2DContextDevVAddr;
+
+ IMG_UINT32 ui32NumSrcSync;
+ IMG_HANDLE ahSrcSyncInfo[SGX_MAX_2D_SRC_SYNC_OPS];
+
+ /* need to be able to check reads and writes on dest, and update writes */
+ IMG_HANDLE hDstSyncInfo;
+
+ /* need to be able to check reads and writes on TA ops, and update writes */
+ IMG_HANDLE hTASyncInfo;
+
+ /* need to be able to check reads and writes on 2D ops, and update writes */
+ IMG_HANDLE h3DSyncInfo;
+
+ IMG_UINT32 ui32PDumpFlags;
+#if defined(PDUMP)
+ IMG_UINT32 ui32CCBDumpWOff;
+#endif
+} PVRSRV_2D_SGX_KICK_KM, *PPVRSRV_2D_SGX_KICK_KM;
+#endif /* defined(SGX_FEATURE_2D_HARDWARE) */
+#endif /* #if defined(TRANSFER_QUEUE) */
+
+/****************************************************************************/
+/* kernel only functions prototypes */
+/****************************************************************************/
+PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode);
+
+IMG_VOID SGXOSTimer(IMG_VOID *pvData);
+
+IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_BOOL bHardwareRecovery,
+ IMG_UINT32 ui32PDUMPFlags);
+
+IMG_VOID SGXInitClocks(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32PDUMPFlags);
+
+PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_BOOL bHardwareRecovery);
+PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie);
+
+PVRSRV_ERROR SGXPrePowerState(IMG_HANDLE hDevHandle,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+
+PVRSRV_ERROR SGXPostPowerState(IMG_HANDLE hDevHandle,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+
+PVRSRV_ERROR SGXPreClockSpeedChange(IMG_HANDLE hDevHandle,
+ IMG_BOOL bIdleDevice,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+
+PVRSRV_ERROR SGXPostClockSpeedChange(IMG_HANDLE hDevHandle,
+ IMG_BOOL bIdleDevice,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+
+IMG_VOID SGXPanic(PVRSRV_SGXDEV_INFO *psDevInfo);
+
+IMG_VOID SGXDumpDebugInfo (PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_BOOL bDumpSGXRegs);
+
+PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+#if defined(SGX_DYNAMIC_TIMING_INFO)
+IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psSGXTimingInfo);
+#endif
+
+/****************************************************************************/
+/* kernel only functions: */
+/****************************************************************************/
+#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 /* __SGXINFOKM_H__ */
+
+/*****************************************************************************
+ End of file (sgxinfokm.h)
+*****************************************************************************/
diff --git a/pvr-source/services4/srvkm/devices/sgx/sgxinit.c b/pvr-source/services4/srvkm/devices/sgx/sgxinit.c
new file mode 100644
index 0000000..199aa9d
--- /dev/null
+++ b/pvr-source/services4/srvkm/devices/sgx/sgxinit.c
@@ -0,0 +1,3428 @@
+/*************************************************************************/ /*!
+@Title Device specific initialisation routines
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+
+#include "sgxdefs.h"
+#include "sgxmmu.h"
+#include "services_headers.h"
+#include "buffer_manager.h"
+#include "sgxapi_km.h"
+#include "sgxinfo.h"
+#include "sgx_mkif_km.h"
+#include "sgxconfig.h"
+#include "sysconfig.h"
+#include "pvr_bridge_km.h"
+
+#include "sgx_bridge_km.h"
+
+#include "pdump_km.h"
+#include "ra.h"
+#include "mmu.h"
+#include "handle.h"
+#include "perproc.h"
+
+#include "sgxutils.h"
+#include "pvrversion.h"
+#include "sgx_options.h"
+
+#include "lists.h"
+#include "srvkm.h"
+#include "ttrace.h"
+
+extern int powering_down;
+
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+
+static const IMG_CHAR *SGXUKernelStatusString(IMG_UINT32 code)
+{
+ switch(code)
+ {
+#define MKTC_ST(x) \
+ case x: \
+ return #x;
+#include "sgx_ukernel_status_codes.h"
+ default:
+ return "(Unknown)";
+ }
+}
+
+#endif /* defined(PVRSRV_USSE_EDM_STATUS_DEBUG) */
+
+#define VAR(x) #x
+/* PRQA S 0881 11 */ /* ignore 'order of evaluation' warning */
+#define CHECK_SIZE(NAME) \
+{ \
+ if (psSGXStructSizes->ui32Sizeof_##NAME != psDevInfo->sSGXStructSizes.ui32Sizeof_##NAME) \
+ { \
+ PVR_DPF((PVR_DBG_ERROR, "SGXDevInitCompatCheck: Size check failed for SGXMKIF_%s (client) = %d bytes, (ukernel) = %d bytes\n", \
+ VAR(NAME), \
+ psDevInfo->sSGXStructSizes.ui32Sizeof_##NAME, \
+ psSGXStructSizes->ui32Sizeof_##NAME )); \
+ bStructSizesFailed = IMG_TRUE; \
+ } \
+}
+
+#if defined (SYS_USING_INTERRUPTS)
+IMG_BOOL SGX_ISRHandler(IMG_VOID *pvData);
+#endif
+
+
+static
+PVRSRV_ERROR SGXGetMiscInfoUkernel(PVRSRV_SGXDEV_INFO *psDevInfo,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_HANDLE hDevMemContext);
+#if defined(PDUMP)
+static
+PVRSRV_ERROR SGXResetPDump(PVRSRV_DEVICE_NODE *psDeviceNode);
+#endif
+
+/*!
+*******************************************************************************
+
+ @Function SGXCommandComplete
+
+ @Description
+
+ SGX command complete handler
+
+ @Input psDeviceNode - SGX device node
+
+ @Return none
+
+******************************************************************************/
+static IMG_VOID SGXCommandComplete(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+#if defined(OS_SUPPORTS_IN_LISR)
+ if (OSInLISR(psDeviceNode->psSysData))
+ {
+ /*
+ * We shouldn't call SGXScheduleProcessQueuesKM in an
+ * LISR, as it may attempt to power up SGX.
+ * We assume that the LISR will schedule the MISR, which
+ * will test the following flag, and call
+ * SGXScheduleProcessQueuesKM if the flag is set.
+ */
+ psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE;
+ }
+ else
+ {
+ SGXScheduleProcessQueuesKM(psDeviceNode);
+ }
+#else
+ SGXScheduleProcessQueuesKM(psDeviceNode);
+#endif
+}
+
+/*!
+*******************************************************************************
+
+ @Function DeinitDevInfo
+
+ @Description
+
+ Deinits DevInfo
+
+ @Input none
+
+ @Return none
+
+******************************************************************************/
+static IMG_UINT32 DeinitDevInfo(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+ if (psDevInfo->psKernelCCBInfo != IMG_NULL)
+ {
+ /*
+ Free CCB info.
+ */
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_SGX_CCB_INFO), psDevInfo->psKernelCCBInfo, IMG_NULL);
+ }
+
+ return PVRSRV_OK;
+}
+
+/*!
+*******************************************************************************
+
+ @Function InitDevInfo
+
+ @Description
+
+ Loads DevInfo
+
+ @Input psDeviceNode
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+static PVRSRV_ERROR InitDevInfo(PVRSRV_PER_PROCESS_DATA *psPerProc,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+#if defined (SUPPORT_SID_INTERFACE)
+ SGX_BRIDGE_INIT_INFO_KM *psInitInfo)
+#else
+ SGX_BRIDGE_INIT_INFO *psInitInfo)
+#endif
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
+ PVRSRV_ERROR eError;
+
+ PVRSRV_SGX_CCB_INFO *psKernelCCBInfo = IMG_NULL;
+
+ PVR_UNREFERENCED_PARAMETER(psPerProc);
+ psDevInfo->sScripts = psInitInfo->sScripts;
+
+ psDevInfo->psKernelCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBMemInfo;
+ psDevInfo->psKernelCCB = (PVRSRV_SGX_KERNEL_CCB *) psDevInfo->psKernelCCBMemInfo->pvLinAddrKM;
+
+ psDevInfo->psKernelCCBCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBCtlMemInfo;
+ psDevInfo->psKernelCCBCtl = (PVRSRV_SGX_CCB_CTL *) psDevInfo->psKernelCCBCtlMemInfo->pvLinAddrKM;
+
+ psDevInfo->psKernelCCBEventKickerMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBEventKickerMemInfo;
+ psDevInfo->pui32KernelCCBEventKicker = (IMG_UINT32 *)psDevInfo->psKernelCCBEventKickerMemInfo->pvLinAddrKM;
+
+ psDevInfo->psKernelSGXHostCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXHostCtlMemInfo;
+ psDevInfo->psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM;
+
+ psDevInfo->psKernelSGXTA3DCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXTA3DCtlMemInfo;
+
+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920)
+ psDevInfo->psKernelSGXPTLAWriteBackMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXPTLAWriteBackMemInfo;
+#endif
+
+ psDevInfo->psKernelSGXMiscMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXMiscMemInfo;
+
+#if defined(SGX_SUPPORT_HWPROFILING)
+ psDevInfo->psKernelHWProfilingMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWProfilingMemInfo;
+#endif
+#if defined(SUPPORT_SGX_HWPERF)
+ psDevInfo->psKernelHWPerfCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWPerfCBMemInfo;
+#endif
+ psDevInfo->psKernelTASigBufferMemInfo = psInitInfo->hKernelTASigBufferMemInfo;
+ psDevInfo->psKernel3DSigBufferMemInfo = psInitInfo->hKernel3DSigBufferMemInfo;
+#if defined(FIX_HW_BRN_29702)
+ psDevInfo->psKernelCFIMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCFIMemInfo;
+#endif
+#if defined(FIX_HW_BRN_29823)
+ psDevInfo->psKernelDummyTermStreamMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelDummyTermStreamMemInfo;
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && defined(FIX_HW_BRN_31559)
+ psDevInfo->psKernelVDMSnapShotBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelVDMSnapShotBufferMemInfo;
+ psDevInfo->psKernelVDMCtrlStreamBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelVDMCtrlStreamBufferMemInfo;
+#endif
+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \
+ defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX)
+ psDevInfo->psKernelVDMStateUpdateBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelVDMStateUpdateBufferMemInfo;
+#endif
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+ psDevInfo->psKernelEDMStatusBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelEDMStatusBufferMemInfo;
+#endif
+ /*
+ * Assign client-side build options for later verification
+ */
+ psDevInfo->ui32ClientBuildOptions = psInitInfo->ui32ClientBuildOptions;
+
+ /*
+ * Assign microkernel IF structure sizes for later verification
+ */
+ psDevInfo->sSGXStructSizes = psInitInfo->sSGXStructSizes;
+
+ /*
+ Setup the kernel version of the CCB control
+ */
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_SGX_CCB_INFO),
+ (IMG_VOID **)&psKernelCCBInfo, 0,
+ "SGX Circular Command Buffer Info");
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"InitDevInfo: Failed to alloc memory"));
+ goto failed_allockernelccb;
+ }
+
+
+ OSMemSet(psKernelCCBInfo, 0, sizeof(PVRSRV_SGX_CCB_INFO));
+ psKernelCCBInfo->psCCBMemInfo = psDevInfo->psKernelCCBMemInfo;
+ psKernelCCBInfo->psCCBCtlMemInfo = psDevInfo->psKernelCCBCtlMemInfo;
+ psKernelCCBInfo->psCommands = psDevInfo->psKernelCCB->asCommands;
+ psKernelCCBInfo->pui32WriteOffset = &psDevInfo->psKernelCCBCtl->ui32WriteOffset;
+ psKernelCCBInfo->pui32ReadOffset = &psDevInfo->psKernelCCBCtl->ui32ReadOffset;
+ psDevInfo->psKernelCCBInfo = psKernelCCBInfo;
+
+ /*
+ Copy the USE code addresses for the host kick.
+ */
+ OSMemCopy(psDevInfo->aui32HostKickAddr, psInitInfo->aui32HostKickAddr,
+ SGXMKIF_CMD_MAX * sizeof(psDevInfo->aui32HostKickAddr[0]));
+
+ psDevInfo->bForcePTOff = IMG_FALSE;
+
+ psDevInfo->ui32CacheControl = psInitInfo->ui32CacheControl;
+
+ psDevInfo->ui32EDMTaskReg0 = psInitInfo->ui32EDMTaskReg0;
+ psDevInfo->ui32EDMTaskReg1 = psInitInfo->ui32EDMTaskReg1;
+ psDevInfo->ui32ClkGateCtl = psInitInfo->ui32ClkGateCtl;
+ psDevInfo->ui32ClkGateCtl2 = psInitInfo->ui32ClkGateCtl2;
+ psDevInfo->ui32ClkGateStatusReg = psInitInfo->ui32ClkGateStatusReg;
+ psDevInfo->ui32ClkGateStatusMask = psInitInfo->ui32ClkGateStatusMask;
+#if defined(SGX_FEATURE_MP)
+ psDevInfo->ui32MasterClkGateStatusReg = psInitInfo->ui32MasterClkGateStatusReg;
+ psDevInfo->ui32MasterClkGateStatusMask = psInitInfo->ui32MasterClkGateStatusMask;
+ psDevInfo->ui32MasterClkGateStatus2Reg = psInitInfo->ui32MasterClkGateStatus2Reg;
+ psDevInfo->ui32MasterClkGateStatus2Mask = psInitInfo->ui32MasterClkGateStatus2Mask;
+#endif /* SGX_FEATURE_MP */
+
+
+ /* Initialise Dev Data */
+ OSMemCopy(&psDevInfo->asSGXDevData, &psInitInfo->asInitDevData, sizeof(psDevInfo->asSGXDevData));
+
+ return PVRSRV_OK;
+
+failed_allockernelccb:
+ DeinitDevInfo(psDevInfo);
+
+ return eError;
+}
+
+
+
+
+static PVRSRV_ERROR SGXRunScript(PVRSRV_SGXDEV_INFO *psDevInfo, SGX_INIT_COMMAND *psScript, IMG_UINT32 ui32NumInitCommands)
+{
+ IMG_UINT32 ui32PC;
+ SGX_INIT_COMMAND *psComm;
+
+ for (ui32PC = 0, psComm = psScript;
+ ui32PC < ui32NumInitCommands;
+ ui32PC++, psComm++)
+ {
+ switch (psComm->eOp)
+ {
+ case SGX_INIT_OP_WRITE_HW_REG:
+ {
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value);
+ PDUMPCOMMENT("SGXRunScript: Write HW reg operation");
+ PDUMPREG(SGX_PDUMPREG_NAME, psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value);
+ break;
+ }
+ case SGX_INIT_OP_READ_HW_REG:
+ {
+ OSReadHWReg(psDevInfo->pvRegsBaseKM, psComm->sReadHWReg.ui32Offset);
+#if defined(PDUMP)
+ PDUMPCOMMENT("SGXRunScript: Read HW reg operation");
+ PDumpRegRead(SGX_PDUMPREG_NAME, psComm->sReadHWReg.ui32Offset, PDUMP_FLAGS_CONTINUOUS);
+#endif
+ break;
+ }
+#if defined(PDUMP)
+ case SGX_INIT_OP_PDUMP_HW_REG:
+ {
+ PDUMPCOMMENT("SGXRunScript: Dump HW reg operation");
+ PDUMPREG(SGX_PDUMPREG_NAME, psComm->sPDumpHWReg.ui32Offset, psComm->sPDumpHWReg.ui32Value);
+ break;
+ }
+#endif
+ case SGX_INIT_OP_HALT:
+ {
+ return PVRSRV_OK;
+ }
+ case SGX_INIT_OP_ILLEGAL:
+ /* FALLTHROUGH */
+ default:
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXRunScript: PC %d: Illegal command: %d", ui32PC, psComm->eOp));
+ return PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION;
+ }
+ }
+
+ }
+
+ return PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION;
+}
+
+#if defined(SUPPORT_MEMORY_TILING)
+static PVRSRV_ERROR SGX_AllocMemTilingRangeInt(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32Start,
+ IMG_UINT32 ui32End,
+ IMG_UINT32 ui32TilingStride,
+ IMG_UINT32 *pui32RangeIndex)
+{
+ IMG_UINT32 i;
+ IMG_UINT32 ui32Offset;
+ IMG_UINT32 ui32Val;
+
+ /* HW supports 10 ranges */
+ for(i=0; i < SGX_BIF_NUM_TILING_RANGES; i++)
+ {
+ if((psDevInfo->ui32MemTilingUsage & (1U << i)) == 0)
+ {
+ /* mark in use */
+ psDevInfo->ui32MemTilingUsage |= 1U << i;
+ /* output range index if the caller wants it */
+ if(pui32RangeIndex != IMG_NULL)
+ {
+ *pui32RangeIndex = i;
+ }
+ goto RangeAllocated;
+ }
+ }
+
+ PVR_DPF((PVR_DBG_ERROR,"SGX_AllocMemTilingRange: all tiling ranges in use"));
+ return PVRSRV_ERROR_EXCEEDED_HW_LIMITS;
+
+RangeAllocated:
+
+ /* An improperly aligned range could cause BIF not to tile some memory which is intended to be tiled,
+ * or cause BIF to tile some memory which is not intended to be.
+ */
+ if(ui32Start & ~SGX_BIF_TILING_ADDR_MASK)
+ {
+ PVR_DPF((PVR_DBG_WARNING,"SGX_AllocMemTilingRangeInt: Tiling range start (0x%08X) fails"
+ "alignment test", ui32Start));
+ }
+ if((ui32End + 0x00001000) & ~SGX_BIF_TILING_ADDR_MASK)
+ {
+ PVR_DPF((PVR_DBG_WARNING,"SGX_AllocMemTilingRangeInt: Tiling range end (0x%08X) fails"
+ "alignment test", ui32End));
+ }
+
+ ui32Offset = EUR_CR_BIF_TILE0 + (i<<2);
+
+ ui32Val = ((ui32TilingStride << EUR_CR_BIF_TILE0_CFG_SHIFT) & EUR_CR_BIF_TILE0_CFG_MASK)
+ | (((ui32End>>SGX_BIF_TILING_ADDR_LSB) << EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT) & EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK)
+ | (((ui32Start>>SGX_BIF_TILING_ADDR_LSB) << EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT) & EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK)
+ | (EUR_CR_BIF_TILE0_ENABLE << EUR_CR_BIF_TILE0_CFG_SHIFT);
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val);
+ PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val);
+
+#if defined(SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS)
+ ui32Offset = EUR_CR_BIF_TILE0_ADDR_EXT + (i<<2);
+
+ ui32Val = (((ui32End>>SGX_BIF_TILING_EXT_ADDR_LSB) << EUR_CR_BIF_TILE0_ADDR_EXT_MAX_SHIFT) & EUR_CR_BIF_TILE0_ADDR_EXT_MAX_MASK)
+ | (((ui32Start>>SGX_BIF_TILING_EXT_ADDR_LSB) << EUR_CR_BIF_TILE0_ADDR_EXT_MIN_SHIFT) & EUR_CR_BIF_TILE0_ADDR_EXT_MIN_MASK);
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val);
+ PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val);
+#endif /* SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS */
+
+ return PVRSRV_OK;
+}
+
+#endif /* SUPPORT_MEMORY_TILING */
+
+/*!
+*******************************************************************************
+
+ @Function SGXInitialise
+
+ @Description
+
+ (client invoked) chip-reset and initialisation
+
+ @Input pvDeviceNode - device info. structure
+ @Input bHardwareRecovery - true if recovering powered hardware,
+ false if powering up
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_BOOL bHardwareRecovery)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_KERNEL_MEM_INFO *psSGXHostCtlMemInfo = psDevInfo->psKernelSGXHostCtlMemInfo;
+ SGXMKIF_HOST_CTL *psSGXHostCtl = psSGXHostCtlMemInfo->pvLinAddrKM;
+ static IMG_BOOL bFirstTime = IMG_TRUE;
+#if defined(PDUMP)
+ IMG_BOOL bPDumpIsSuspended = PDumpIsSuspended();
+#endif /* PDUMP */
+
+#if defined(SGX_FEATURE_MP)
+ /* Slave core clocks must be enabled during reset */
+#else
+ SGXInitClocks(psDevInfo, PDUMP_FLAGS_CONTINUOUS);
+#endif /* SGX_FEATURE_MP */
+
+ /*
+ Part 1 of the initialisation script runs before resetting SGX.
+ */
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 1\n");
+ eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart1, SGX_MAX_INIT_COMMANDS);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 1) failed (%d)", eError));
+ return eError;
+ }
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 1\n");
+
+ /* Reset the chip */
+ psDevInfo->ui32NumResets++;
+
+#if !defined(SGX_FEATURE_MP)
+ bHardwareRecovery |= bFirstTime;
+#endif /* SGX_FEATURE_MP */
+
+ SGXReset(psDevInfo, bHardwareRecovery, PDUMP_FLAGS_CONTINUOUS);
+
+#if defined(EUR_CR_POWER)
+#if defined(SGX531)
+ /*
+ Disable half the pipes.
+ 531 has 2 pipes within a 4 pipe framework, so
+ the 2 redundant pipes must be disabled even
+ though they do not exist.
+ */
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 1);
+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_POWER, 1);
+#else
+ /* set the default pipe count (all fully enabled) */
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 0);
+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_POWER, 0);
+#endif
+#endif
+
+ /* Initialise the kernel CCB event kicker value */
+ *psDevInfo->pui32KernelCCBEventKicker = 0;
+#if defined(PDUMP)
+ if (!bPDumpIsSuspended)
+ {
+ psDevInfo->ui32KernelCCBEventKickerDumpVal = 0;
+ PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal,
+ psDevInfo->psKernelCCBEventKickerMemInfo, 0,
+ sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
+ }
+#endif /* PDUMP */
+
+#if defined(SUPPORT_MEMORY_TILING)
+ {
+ /* Initialise EUR_CR_BIF_TILE registers for any tiling heaps */
+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap = psDevInfo->pvDeviceMemoryHeap;
+ IMG_UINT32 i;
+
+ psDevInfo->ui32MemTilingUsage = 0;
+
+ for(i=0; i<psDevInfo->ui32HeapCount; i++)
+ {
+ if(psDeviceMemoryHeap[i].ui32XTileStride > 0)
+ {
+ /* Set up the HW control registers */
+ eError = SGX_AllocMemTilingRangeInt(
+ psDevInfo,
+ psDeviceMemoryHeap[i].sDevVAddrBase.uiAddr,
+ psDeviceMemoryHeap[i].sDevVAddrBase.uiAddr
+ + psDeviceMemoryHeap[i].ui32HeapSize,
+ psDeviceMemoryHeap[i].ui32XTileStride,
+ NULL);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Unable to allocate SGX BIF tiling range for heap: %s",
+ psDeviceMemoryHeap[i].pszName));
+ break;
+ }
+ }
+ }
+ }
+#endif
+
+ /*
+ Part 2 of the initialisation script runs after resetting SGX.
+ */
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 2\n");
+ eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart2, SGX_MAX_INIT_COMMANDS);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 2) failed (%d)", eError));
+ return eError;
+ }
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 2\n");
+
+ /* Record the system timestamp for the microkernel */
+ psSGXHostCtl->ui32HostClock = OSClockus();
+
+ psSGXHostCtl->ui32InitStatus = 0;
+#if defined(PDUMP)
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
+ "Reset the SGX microkernel initialisation status\n");
+ PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, ui32InitStatus),
+ sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psSGXHostCtlMemInfo));
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
+ "Initialise the microkernel\n");
+#endif /* PDUMP */
+
+#if defined(SGX_FEATURE_MULTI_EVENT_KICK)
+ OSWriteMemoryBarrier();
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM,
+ SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0),
+ EUR_CR_EVENT_KICK2_NOW_MASK);
+#else
+ *psDevInfo->pui32KernelCCBEventKicker = (*psDevInfo->pui32KernelCCBEventKicker + 1) & 0xFF;
+ OSWriteMemoryBarrier();
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM,
+ SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0),
+ EUR_CR_EVENT_KICK_NOW_MASK);
+#endif /* SGX_FEATURE_MULTI_EVENT_KICK */
+
+ OSMemoryBarrier();
+
+#if defined(PDUMP)
+ /*
+ Dump the host kick.
+ */
+ if (!bPDumpIsSuspended)
+ {
+#if defined(SGX_FEATURE_MULTI_EVENT_KICK)
+ PDUMPREG(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), EUR_CR_EVENT_KICK2_NOW_MASK);
+#else
+ psDevInfo->ui32KernelCCBEventKickerDumpVal = 1;
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
+ "First increment of the SGX event kicker value\n");
+ PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal,
+ psDevInfo->psKernelCCBEventKickerMemInfo,
+ 0,
+ sizeof(IMG_UINT32),
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
+ PDUMPREG(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), EUR_CR_EVENT_KICK_NOW_MASK);
+#endif /* SGX_FEATURE_MULTI_EVENT_KICK */
+ }
+#endif /* PDUMP */
+
+#if !defined(NO_HARDWARE)
+ /*
+ Wait for the microkernel to finish initialising.
+ */
+ if (PollForValueKM(&psSGXHostCtl->ui32InitStatus,
+ PVRSRV_USSE_EDM_INIT_COMPLETE,
+ PVRSRV_USSE_EDM_INIT_COMPLETE,
+ MAX_HW_TIME_US,
+ MAX_HW_TIME_US/WAIT_TRY_COUNT,
+ IMG_FALSE) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXInitialise: Wait for uKernel initialisation failed"));
+
+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
+ PVR_DBG_BREAK;
+
+ return PVRSRV_ERROR_RETRY;
+ }
+#endif /* NO_HARDWARE */
+
+#if defined(PDUMP)
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
+ "Wait for the SGX microkernel initialisation to complete");
+ PDUMPMEMPOL(psSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, ui32InitStatus),
+ PVRSRV_USSE_EDM_INIT_COMPLETE,
+ PVRSRV_USSE_EDM_INIT_COMPLETE,
+ PDUMP_POLL_OPERATOR_EQUAL,
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psSGXHostCtlMemInfo));
+#endif /* PDUMP */
+
+ PVR_ASSERT(psDevInfo->psKernelCCBCtl->ui32ReadOffset == psDevInfo->psKernelCCBCtl->ui32WriteOffset);
+
+ bFirstTime = IMG_FALSE;
+
+ return PVRSRV_OK;
+}
+
+/*!
+*******************************************************************************
+
+ @Function SGXDeinitialise
+
+ @Description
+
+ (client invoked) chip-reset and deinitialisation
+
+ @Input hDevCookie - device info. handle
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie)
+
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *) hDevCookie;
+ PVRSRV_ERROR eError;
+
+ /* Did SGXInitialise map the SGX registers in? */
+ if (psDevInfo->pvRegsBaseKM == IMG_NULL)
+ {
+ return PVRSRV_OK;
+ }
+
+ eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asDeinitCommands, SGX_MAX_DEINIT_COMMANDS);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXDeinitialise: SGXRunScript failed (%d)", eError));
+ return eError;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+*******************************************************************************
+
+ @Function DevInitSGXPart1
+
+ @Description
+
+ Reset and initialise Chip
+
+ @Input pvDeviceNode - device info. structure
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+static PVRSRV_ERROR DevInitSGXPart1 (IMG_VOID *pvDeviceNode)
+{
+ IMG_HANDLE hDevMemHeap = IMG_NULL;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+ IMG_HANDLE hKernelDevMemContext;
+ IMG_DEV_PHYADDR sPDDevPAddr;
+ IMG_UINT32 i;
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode;
+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
+ PVRSRV_ERROR eError;
+
+ /* pdump info about the core */
+ PDUMPCOMMENT("SGX Core Version Information: %s", SGX_CORE_FRIENDLY_NAME);
+
+ #if defined(SGX_FEATURE_MP)
+ #if !defined(SGX_FEATURE_MP_PLUS)
+ PDUMPCOMMENT("SGX Multi-processor: %d cores", SGX_FEATURE_MP_CORE_COUNT);
+ #else
+ PDUMPCOMMENT("SGX Multi-processor: %d TA cores, %d 3D cores", SGX_FEATURE_MP_CORE_COUNT_TA, SGX_FEATURE_MP_CORE_COUNT_3D);
+ #endif
+ #endif /* SGX_FEATURE_MP */
+
+#if (SGX_CORE_REV == 0)
+ PDUMPCOMMENT("SGX Core Revision Information: head RTL");
+#else
+ PDUMPCOMMENT("SGX Core Revision Information: %d", SGX_CORE_REV);
+#endif
+
+ #if defined(SGX_FEATURE_SYSTEM_CACHE)
+ PDUMPCOMMENT("SGX System Level Cache is present\r\n");
+ #if defined(SGX_BYPASS_SYSTEM_CACHE)
+ PDUMPCOMMENT("SGX System Level Cache is bypassed\r\n");
+ #endif /* SGX_BYPASS_SYSTEM_CACHE */
+ #endif /* SGX_FEATURE_SYSTEM_CACHE */
+
+ PDUMPCOMMENT("SGX Initialisation Part 1");
+
+ /* Allocate device control block */
+ if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_SGXDEV_INFO),
+ (IMG_VOID **)&psDevInfo, IMG_NULL,
+ "SGX Device Info") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1 : Failed to alloc memory for DevInfo"));
+ return (PVRSRV_ERROR_OUT_OF_MEMORY);
+ }
+ OSMemSet (psDevInfo, 0, sizeof(PVRSRV_SGXDEV_INFO));
+
+ /* setup info from jdisplayconfig.h (variations controlled by build) */
+ psDevInfo->eDeviceType = DEV_DEVICE_TYPE;
+ psDevInfo->eDeviceClass = DEV_DEVICE_CLASS;
+
+ /* Initialize SGX idle status */
+ psDevInfo->bSGXIdle = IMG_TRUE;
+
+ /* Store the devinfo as its needed by dynamically enumerated systems called from BM */
+ psDeviceNode->pvDevice = (IMG_PVOID)psDevInfo;
+
+ /* get heap info from the devnode */
+ psDevInfo->ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
+ psDevInfo->pvDeviceMemoryHeap = (IMG_VOID*)psDeviceMemoryHeap;
+
+ /* create the kernel memory context */
+ hKernelDevMemContext = BM_CreateContext(psDeviceNode,
+ &sPDDevPAddr,
+ IMG_NULL,
+ IMG_NULL);
+ if (hKernelDevMemContext == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1: Failed BM_CreateContext"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ psDevInfo->sKernelPDDevPAddr = sPDDevPAddr;
+
+ /* create the kernel, shared and shared_exported heaps */
+ for(i=0; i<psDeviceNode->sDevMemoryInfo.ui32HeapCount; i++)
+ {
+ switch(psDeviceMemoryHeap[i].DevMemHeapType)
+ {
+ case DEVICE_MEMORY_HEAP_KERNEL:
+ case DEVICE_MEMORY_HEAP_SHARED:
+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
+ {
+ /* Shared PB heap could be zero size */
+ if (psDeviceMemoryHeap[i].ui32HeapSize > 0)
+ {
+ hDevMemHeap = BM_CreateHeap (hKernelDevMemContext,
+ &psDeviceMemoryHeap[i]);
+ /*
+ in the case of kernel context heaps just store
+ the heap handle in the heap info structure
+ */
+ psDeviceMemoryHeap[i].hDevMemHeap = hDevMemHeap;
+ }
+ break;
+ }
+ }
+ }
+#if defined(PDUMP)
+ if(hDevMemHeap)
+ {
+ /* set up the MMU pdump info */
+ psDevInfo->sMMUAttrib = *((BM_HEAP*)hDevMemHeap)->psMMUAttrib;
+ }
+#endif
+ eError = MMU_BIFResetPDAlloc(psDevInfo);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGX : Failed to alloc memory for BIF reset"));
+ return eError;
+ }
+
+ return PVRSRV_OK;
+}
+
+/*!
+*******************************************************************************
+
+ @Function SGXGetInfoForSrvinitKM
+
+ @Description
+
+ Get SGX related information necessary for initilisation server
+
+ @Input hDevHandle - device handle
+ psInitInfo - pointer to structure for returned information
+
+ @Output psInitInfo - pointer to structure containing returned information
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle, PVRSRV_HEAP_INFO_KM *pasHeapInfo, IMG_DEV_PHYADDR *psPDDevPAddr)
+#else
+PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle, SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo)
+#endif
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+ PVRSRV_ERROR eError;
+
+ PDUMPCOMMENT("SGXGetInfoForSrvinit");
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle;
+ psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ *psPDDevPAddr = psDevInfo->sKernelPDDevPAddr;
+
+ eError = PVRSRVGetDeviceMemHeapsKM(hDevHandle, pasHeapInfo);
+#else
+ psInitInfo->sPDDevPAddr = psDevInfo->sKernelPDDevPAddr;
+
+ eError = PVRSRVGetDeviceMemHeapsKM(hDevHandle, &psInitInfo->asHeapInfo[0]);
+#endif
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXGetInfoForSrvinit: PVRSRVGetDeviceMemHeapsKM failed (%d)", eError));
+ return eError;
+ }
+
+ return eError;
+}
+
+/*!
+*******************************************************************************
+
+ @Function DevInitSGXPart2KM
+
+ @Description
+
+ Reset and initialise Chip
+
+ @Input pvDeviceNode - device info. structure
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR DevInitSGXPart2KM (PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_HANDLE hDevHandle,
+#if defined (SUPPORT_SID_INTERFACE)
+ SGX_BRIDGE_INIT_INFO_KM *psInitInfo)
+#else
+ SGX_BRIDGE_INIT_INFO *psInitInfo)
+#endif
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+ PVRSRV_ERROR eError;
+ SGX_DEVICE_MAP *psSGXDeviceMap;
+ PVRSRV_DEV_POWER_STATE eDefaultPowerState;
+
+ PDUMPCOMMENT("SGX Initialisation Part 2");
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle;
+ psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
+
+ /*
+ Init devinfo
+ */
+ eError = InitDevInfo(psPerProc, psDeviceNode, psInitInfo);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to load EDM program"));
+ goto failed_init_dev_info;
+ }
+
+
+ eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
+ (IMG_VOID**)&psSGXDeviceMap);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to get device memory map!"));
+ return PVRSRV_ERROR_INIT_FAILURE;
+ }
+
+ /* Registers already mapped? */
+ if (psSGXDeviceMap->pvRegsCpuVBase)
+ {
+ psDevInfo->pvRegsBaseKM = psSGXDeviceMap->pvRegsCpuVBase;
+ }
+ else
+ {
+ /* Map Regs */
+ psDevInfo->pvRegsBaseKM = OSMapPhysToLin(psSGXDeviceMap->sRegsCpuPBase,
+ psSGXDeviceMap->ui32RegsSize,
+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+ IMG_NULL);
+ if (!psDevInfo->pvRegsBaseKM)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in regs\n"));
+ return PVRSRV_ERROR_BAD_MAPPING;
+ }
+ }
+ psDevInfo->ui32RegSize = psSGXDeviceMap->ui32RegsSize;
+ psDevInfo->sRegsPhysBase = psSGXDeviceMap->sRegsSysPBase;
+
+
+#if defined(SGX_FEATURE_HOST_PORT)
+ if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT)
+ {
+ /* Map Host Port */
+ psDevInfo->pvHostPortBaseKM = OSMapPhysToLin(psSGXDeviceMap->sHPCpuPBase,
+ psSGXDeviceMap->ui32HPSize,
+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+ IMG_NULL);
+ if (!psDevInfo->pvHostPortBaseKM)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in host port\n"));
+ return PVRSRV_ERROR_BAD_MAPPING;
+ }
+ psDevInfo->ui32HPSize = psSGXDeviceMap->ui32HPSize;
+ psDevInfo->sHPSysPAddr = psSGXDeviceMap->sHPSysPBase;
+ }
+#endif/* #ifdef SGX_FEATURE_HOST_PORT */
+
+#if defined (SYS_USING_INTERRUPTS)
+
+ /* Set up ISR callback information. */
+ psDeviceNode->pvISRData = psDeviceNode;
+ /* ISR handler address was set up earlier */
+ PVR_ASSERT(psDeviceNode->pfnDeviceISR == SGX_ISRHandler);
+
+#endif /* SYS_USING_INTERRUPTS */
+
+ /* Prevent the microkernel being woken up before there is something to do. */
+ psDevInfo->psSGXHostCtl->ui32PowerStatus |= PVRSRV_USSE_EDM_POWMAN_NO_WORK;
+ eDefaultPowerState = PVRSRV_DEV_POWER_STATE_OFF;
+ /* Register the device with the power manager. */
+ eError = PVRSRVRegisterPowerDevice (psDeviceNode->sDevId.ui32DeviceIndex,
+ &SGXPrePowerState, &SGXPostPowerState,
+ &SGXPreClockSpeedChange, &SGXPostClockSpeedChange,
+ (IMG_HANDLE)psDeviceNode,
+ PVRSRV_DEV_POWER_STATE_OFF,
+ eDefaultPowerState);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: failed to register device with power manager"));
+ return eError;
+ }
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+ /* map the external system cache control registers into the SGX MMU */
+ psDevInfo->ui32ExtSysCacheRegsSize = psSGXDeviceMap->ui32ExtSysCacheRegsSize;
+ psDevInfo->sExtSysCacheRegsDevPBase = psSGXDeviceMap->sExtSysCacheRegsDevPBase;
+ eError = MMU_MapExtSystemCacheRegs(psDeviceNode);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to map external system cache registers"));
+ return eError;
+ }
+#endif /* SUPPORT_EXTERNAL_SYSTEM_CACHE */
+
+ /*
+ Initialise the Kernel CCB
+ */
+ OSMemSet(psDevInfo->psKernelCCB, 0, sizeof(PVRSRV_SGX_KERNEL_CCB));
+ OSMemSet(psDevInfo->psKernelCCBCtl, 0, sizeof(PVRSRV_SGX_CCB_CTL));
+ OSMemSet(psDevInfo->pui32KernelCCBEventKicker, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker));
+ PDUMPCOMMENT("Initialise Kernel CCB");
+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBMemInfo, 0, sizeof(PVRSRV_SGX_KERNEL_CCB), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBMemInfo));
+ PDUMPCOMMENT("Initialise Kernel CCB Control");
+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBCtlMemInfo, 0, sizeof(PVRSRV_SGX_CCB_CTL), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBCtlMemInfo));
+ PDUMPCOMMENT("Initialise Kernel CCB Event Kicker");
+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBEventKickerMemInfo, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
+
+ return PVRSRV_OK;
+
+failed_init_dev_info:
+ return eError;
+}
+
+/*!
+*******************************************************************************
+
+ @Function DevDeInitSGX
+
+ @Description
+
+ Reset and deinitialise Chip
+
+ @Input pvDeviceNode - device info. structure
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+static PVRSRV_ERROR DevDeInitSGX (IMG_VOID *pvDeviceNode)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode;
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32Heap;
+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+ SGX_DEVICE_MAP *psSGXDeviceMap;
+
+ if (!psDevInfo)
+ {
+ /* Can happen if DevInitSGX failed */
+ PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Null DevInfo"));
+ return PVRSRV_OK;
+ }
+
+#if defined(SUPPORT_HW_RECOVERY)
+ if (psDevInfo->hTimer)
+ {
+ eError = OSRemoveTimer(psDevInfo->hTimer);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to remove timer"));
+ return eError;
+ }
+ psDevInfo->hTimer = IMG_NULL;
+ }
+#endif /* SUPPORT_HW_RECOVERY */
+
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
+ /* unmap the external system cache control registers */
+ eError = MMU_UnmapExtSystemCacheRegs(psDeviceNode);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to unmap ext system cache registers"));
+ return eError;
+ }
+#endif /* SUPPORT_EXTERNAL_SYSTEM_CACHE */
+
+ MMU_BIFResetPDFree(psDevInfo);
+
+ /*
+ DeinitDevInfo the DevInfo
+ */
+ DeinitDevInfo(psDevInfo);
+
+ /* Destroy heaps. */
+ psDeviceMemoryHeap = (DEVICE_MEMORY_HEAP_INFO *)psDevInfo->pvDeviceMemoryHeap;
+ for(ui32Heap=0; ui32Heap<psDeviceNode->sDevMemoryInfo.ui32HeapCount; ui32Heap++)
+ {
+ switch(psDeviceMemoryHeap[ui32Heap].DevMemHeapType)
+ {
+ case DEVICE_MEMORY_HEAP_KERNEL:
+ case DEVICE_MEMORY_HEAP_SHARED:
+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
+ {
+ if (psDeviceMemoryHeap[ui32Heap].hDevMemHeap != IMG_NULL)
+ {
+ BM_DestroyHeap(psDeviceMemoryHeap[ui32Heap].hDevMemHeap);
+ }
+ break;
+ }
+ }
+ }
+
+ /* Destroy the kernel context. */
+ eError = BM_DestroyContext(psDeviceNode->sDevMemoryInfo.pBMKernelContext, IMG_NULL);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX : Failed to destroy kernel context"));
+ return eError;
+ }
+
+ /* remove the device from the power manager */
+ eError = PVRSRVRemovePowerDevice (((PVRSRV_DEVICE_NODE*)pvDeviceNode)->sDevId.ui32DeviceIndex);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
+ (IMG_VOID**)&psSGXDeviceMap);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to get device memory map!"));
+ return eError;
+ }
+
+ /* Only unmap the registers if they were mapped here */
+ if (!psSGXDeviceMap->pvRegsCpuVBase)
+ {
+ /* UnMap Regs */
+ if (psDevInfo->pvRegsBaseKM != IMG_NULL)
+ {
+ OSUnMapPhysToLin(psDevInfo->pvRegsBaseKM,
+ psDevInfo->ui32RegSize,
+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+ IMG_NULL);
+ }
+ }
+
+#if defined(SGX_FEATURE_HOST_PORT)
+ if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT)
+ {
+ /* unMap Host Port */
+ if (psDevInfo->pvHostPortBaseKM != IMG_NULL)
+ {
+ OSUnMapPhysToLin(psDevInfo->pvHostPortBaseKM,
+ psDevInfo->ui32HPSize,
+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+ IMG_NULL);
+ }
+ }
+#endif /* #ifdef SGX_FEATURE_HOST_PORT */
+
+
+ /* DeAllocate devinfo */
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_SGXDEV_INFO),
+ psDevInfo,
+ 0);
+
+ psDeviceNode->pvDevice = IMG_NULL;
+
+ if (psDeviceMemoryHeap != IMG_NULL)
+ {
+ /* Free the device memory heap info. */
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID,
+ psDeviceMemoryHeap,
+ 0);
+ }
+
+ return PVRSRV_OK;
+}
+
+
+#if defined(RESTRICTED_REGISTERS) && defined(SGX_FEATURE_MP)
+
+/*!
+*******************************************************************************
+
+ @Function SGXDumpMasterDebugReg
+
+ @Description
+
+ Dump a single SGX debug register value
+
+ @Input psDevInfo - SGX device info
+ @Input pszName - string used for logging
+ @Input ui32RegAddr - SGX register offset
+
+ @Return IMG_VOID
+
+******************************************************************************/
+static IMG_VOID SGXDumpMasterDebugReg (PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_CHAR *pszName,
+ IMG_UINT32 ui32RegAddr)
+{
+ IMG_UINT32 ui32RegVal;
+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32RegAddr);
+ PVR_LOG(("(HYD) %s%08X", pszName, ui32RegVal));
+}
+
+#endif /* defined(RESTRICTED_REGISTERS) */
+
+/*!
+*******************************************************************************
+
+ @Function SGXDumpDebugReg
+
+ @Description
+
+ Dump a single SGX debug register value
+
+ @Input psDevInfo - SGX device info
+ @Input ui32CoreNum - processor number
+ @Input pszName - string used for logging
+ @Input ui32RegAddr - SGX register offset
+
+ @Return IMG_VOID
+
+******************************************************************************/
+static IMG_VOID SGXDumpDebugReg (PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32CoreNum,
+ IMG_CHAR *pszName,
+ IMG_UINT32 ui32RegAddr)
+{
+ IMG_UINT32 ui32RegVal;
+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(ui32RegAddr, ui32CoreNum));
+ PVR_LOG(("(P%u) %s%08X", ui32CoreNum, pszName, ui32RegVal));
+}
+
+#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) || defined(FIX_HW_BRN_31620)
+static INLINE IMG_UINT32 GetDirListBaseReg(IMG_UINT32 ui32Index)
+{
+ if (ui32Index == 0)
+ {
+ return EUR_CR_BIF_DIR_LIST_BASE0;
+ }
+ else
+ {
+ return (EUR_CR_BIF_DIR_LIST_BASE1 + ((ui32Index - 1) * 0x4));
+ }
+}
+#endif
+
+void dsscomp_kdump(void);
+/*!
+*******************************************************************************
+
+ @Function SGXDumpDebugInfo
+
+ @Description
+
+ Dump useful debugging info
+
+ @Input psDevInfo - SGX device info
+ @Input bDumpSGXRegs - Whether to dump SGX debug registers. Must not be done
+ when SGX is not powered.
+
+ @Return IMG_VOID
+
+******************************************************************************/
+IMG_VOID SGXDumpDebugInfo (PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_BOOL bDumpSGXRegs)
+{
+ IMG_UINT32 ui32CoreNum;
+
+ dsscomp_kdump();
+
+ PVR_LOG(("SGX debug (%s)", PVRVERSION_STRING));
+
+ if (bDumpSGXRegs)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGX Register Base Address (Linear): 0x%08X", (IMG_UINTPTR_T)psDevInfo->pvRegsBaseKM));
+ PVR_DPF((PVR_DBG_ERROR,"SGX Register Base Address (Physical): 0x%08X", psDevInfo->sRegsPhysBase.uiAddr));
+
+ SGXDumpDebugReg(psDevInfo, 0, "EUR_CR_CORE_ID: ", EUR_CR_CORE_ID);
+ SGXDumpDebugReg(psDevInfo, 0, "EUR_CR_CORE_REVISION: ", EUR_CR_CORE_REVISION);
+#if defined(RESTRICTED_REGISTERS) && defined(SGX_FEATURE_MP)
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_BIF_INT_STAT: ", EUR_CR_MASTER_BIF_INT_STAT);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_BIF_FAULT: ",EUR_CR_MASTER_BIF_FAULT);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_CLKGATESTATUS2: ",EUR_CR_MASTER_CLKGATESTATUS2 );
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_PIM_STATUS: ",EUR_CR_MASTER_VDM_PIM_STATUS);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_BIF_BANK_SET: ",EUR_CR_MASTER_BIF_BANK_SET);
+
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_EVENT_STATUS: ",EUR_CR_MASTER_EVENT_STATUS);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_EVENT_STATUS2: ",EUR_CR_MASTER_EVENT_STATUS2);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_MP_PRIMITIVE: ",EUR_CR_MASTER_MP_PRIMITIVE);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_DPM_DPLIST_STATUS: ",EUR_CR_MASTER_DPM_DPLIST_STATUS);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_DPM_PROACTIVE_PIM_SPEC: ",EUR_CR_MASTER_DPM_PROACTIVE_PIM_SPEC);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_PAGE_MANAGEOP: ",EUR_CR_MASTER_DPM_PAGE_MANAGEOP);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_STORE_SNAPSHOT: ",EUR_CR_MASTER_VDM_CONTEXT_STORE_SNAPSHOT);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_LOAD_STATUS: ",EUR_CR_MASTER_VDM_CONTEXT_LOAD_STATUS);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_STORE_STREAM: ",EUR_CR_MASTER_VDM_CONTEXT_STORE_STREAM);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_STORE_STATUS: ",EUR_CR_MASTER_VDM_CONTEXT_STORE_STATUS);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_STORE_STATE0: ",EUR_CR_MASTER_VDM_CONTEXT_STORE_STATE0);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_CONTEXT_STORE_STATE1: ",EUR_CR_MASTER_VDM_CONTEXT_STORE_STATE1);
+ SGXDumpMasterDebugReg(psDevInfo, "EUR_CR_MASTER_VDM_WAIT_FOR_KICK: ",EUR_CR_MASTER_VDM_WAIT_FOR_KICK);
+#endif
+ for (ui32CoreNum = 0; ui32CoreNum < SGX_FEATURE_MP_CORE_COUNT_3D; ui32CoreNum++)
+ {
+ /* Dump HW event status */
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_EVENT_STATUS: ", EUR_CR_EVENT_STATUS);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_EVENT_STATUS2: ", EUR_CR_EVENT_STATUS2);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_CTRL: ", EUR_CR_BIF_CTRL);
+ #if defined(EUR_CR_BIF_BANK0)
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_BANK0: ", EUR_CR_BIF_BANK0);
+ #endif
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_INT_STAT: ", EUR_CR_BIF_INT_STAT);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_FAULT: ", EUR_CR_BIF_FAULT);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_MEM_REQ_STAT: ", EUR_CR_BIF_MEM_REQ_STAT);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_CLKGATECTL: ", EUR_CR_CLKGATECTL);
+ #if defined(EUR_CR_PDS_PC_BASE)
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_PDS_PC_BASE: ", EUR_CR_PDS_PC_BASE);
+ #endif
+#if defined(RESTRICTED_REGISTERS)
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_BANK_SET: ", EUR_CR_BIF_BANK_SET);
+
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_CLKGATECTL: ", EUR_CR_CLKGATECTL);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_CLKGATESTATUS: ", EUR_CR_CLKGATESTATUS);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_MTE_CTRL: ", EUR_CR_MTE_CTRL);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_EVENT_OTHER_PDS_EXEC: ", EUR_CR_EVENT_OTHER_PDS_EXEC);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_EVENT_OTHER_PDS_DATA: ", EUR_CR_EVENT_OTHER_PDS_DATA);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_EVENT_OTHER_PDS_INFO: ", EUR_CR_EVENT_OTHER_PDS_INFO);
+
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_DPM_ZLS_PAGE_THRESHOLD: ", EUR_CR_DPM_ZLS_PAGE_THRESHOLD);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_DPM_TA_GLOBAL_LIST: ", EUR_CR_DPM_TA_GLOBAL_LIST);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_DPM_STATE_CONTEXT_ID: ", EUR_CR_DPM_STATE_CONTEXT_ID);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_DPM_CONTEXT_PB_BASE: ", EUR_CR_DPM_CONTEXT_PB_BASE);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_DPM_TA_ALLOC_FREE_LIST_STATUS1: ", EUR_CR_DPM_TA_ALLOC_FREE_LIST_STATUS1);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_DPM_3D_FREE_LIST_STATUS1: ", EUR_CR_DPM_3D_FREE_LIST_STATUS1);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_DPM_TA_ALLOC_FREE_LIST_STATUS2: ", EUR_CR_DPM_TA_ALLOC_FREE_LIST_STATUS2);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_DPM_3D_FREE_LIST_STATUS2: ", EUR_CR_DPM_3D_FREE_LIST_STATUS2);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_DPM_ABORT_STATUS_MTILE: ", EUR_CR_DPM_ABORT_STATUS_MTILE);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_DPM_PAGE_STATUS: ", EUR_CR_DPM_PAGE_STATUS);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_DPM_PAGE: ", EUR_CR_DPM_PAGE);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_DPM_GLOBAL_PAGE_STATUS: ", EUR_CR_DPM_GLOBAL_PAGE_STATUS);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_VDM_CONTEXT_LOAD_STATUS: ", EUR_CR_VDM_CONTEXT_LOAD_STATUS);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_VDM_CONTEXT_STORE_STATUS: ", EUR_CR_VDM_CONTEXT_STORE_STATUS);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_VDM_TASK_KICK_STATUS: ", EUR_CR_VDM_TASK_KICK_STATUS);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_VDM_CONTEXT_STORE_STATE0: ", EUR_CR_VDM_CONTEXT_STORE_STATE0);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_VDM_CONTEXT_STORE_STATE1: ", EUR_CR_VDM_CONTEXT_STORE_STATE1);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_DPM_REQUESTING: ", EUR_CR_DPM_REQUESTING);
+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_DPM_REQUESTING: ", EUR_CR_DPM_REQUESTING);
+
+#endif
+ }
+
+ #if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) && !defined(FIX_HW_BRN_31620)
+ {
+ IMG_UINT32 ui32RegVal;
+ IMG_UINT32 ui32PDDevPAddr;
+
+ /*
+ If there was a SGX pagefault check the page table too see if the
+ host thinks the fault is correct
+ */
+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT);
+ if (ui32RegVal & EUR_CR_BIF_INT_STAT_PF_N_RW_MASK)
+ {
+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_FAULT);
+ ui32RegVal &= EUR_CR_BIF_FAULT_ADDR_MASK;
+ ui32PDDevPAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0);
+ ui32PDDevPAddr &= EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK;
+ MMU_CheckFaultAddr(psDevInfo, ui32PDDevPAddr, ui32RegVal);
+ }
+ }
+ #else
+ {
+ IMG_UINT32 ui32FaultAddress;
+ IMG_UINT32 ui32Bank0;
+ IMG_UINT32 ui32DirListIndex;
+ IMG_UINT32 ui32PDDevPAddr;
+
+ ui32FaultAddress = OSReadHWReg(psDevInfo->pvRegsBaseKM,
+ EUR_CR_BIF_FAULT);
+ ui32FaultAddress = ui32FaultAddress & EUR_CR_BIF_FAULT_ADDR_MASK;
+
+ ui32Bank0 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0);
+
+ /* Check the EDM's's memory context */
+ ui32DirListIndex = (ui32Bank0 & EUR_CR_BIF_BANK0_INDEX_EDM_MASK) >> EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT;
+ ui32PDDevPAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM,
+ GetDirListBaseReg(ui32DirListIndex));
+ PVR_LOG(("Checking EDM memory context (index = %d, PD = 0x%08x)", ui32DirListIndex, ui32PDDevPAddr));
+ MMU_CheckFaultAddr(psDevInfo, ui32PDDevPAddr, ui32FaultAddress);
+
+ /* Check the TA's memory context */
+ ui32DirListIndex = (ui32Bank0 & EUR_CR_BIF_BANK0_INDEX_TA_MASK) >> EUR_CR_BIF_BANK0_INDEX_TA_SHIFT;
+ ui32PDDevPAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM,
+ GetDirListBaseReg(ui32DirListIndex));
+ PVR_LOG(("Checking TA memory context (index = %d, PD = 0x%08x)", ui32DirListIndex, ui32PDDevPAddr));
+ MMU_CheckFaultAddr(psDevInfo, ui32PDDevPAddr, ui32FaultAddress);
+
+ /* Check the 3D's memory context */
+ ui32DirListIndex = (ui32Bank0 & EUR_CR_BIF_BANK0_INDEX_3D_MASK) >> EUR_CR_BIF_BANK0_INDEX_3D_SHIFT;
+ ui32PDDevPAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM,
+ GetDirListBaseReg(ui32DirListIndex));
+ PVR_LOG(("Checking 3D memory context (index = %d, PD = 0x%08x)", ui32DirListIndex, ui32PDDevPAddr));
+ MMU_CheckFaultAddr(psDevInfo, ui32PDDevPAddr, ui32FaultAddress);
+
+ #if defined(EUR_CR_BIF_BANK0_INDEX_2D_MASK)
+ /* Check the 2D's memory context */
+ ui32DirListIndex = (ui32Bank0 & EUR_CR_BIF_BANK0_INDEX_2D_MASK) >> EUR_CR_BIF_BANK0_INDEX_2D_SHIFT;
+ ui32PDDevPAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM,
+ GetDirListBaseReg(ui32DirListIndex));
+ PVR_LOG(("Checking 2D memory context (index = %d, PD = 0x%08x)", ui32DirListIndex, ui32PDDevPAddr));
+ MMU_CheckFaultAddr(psDevInfo, ui32PDDevPAddr, ui32FaultAddress);
+ #endif
+
+ #if defined(EUR_CR_BIF_BANK0_INDEX_PTLA_MASK)
+ /* Check the 2D's memory context */
+ ui32DirListIndex = (ui32Bank0 & EUR_CR_BIF_BANK0_INDEX_PTLA_MASK) >> EUR_CR_BIF_BANK0_INDEX_PTLA_SHIFT;
+ ui32PDDevPAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM,
+ GetDirListBaseReg(ui32DirListIndex));
+ PVR_LOG(("Checking PTLA memory context (index = %d, PD = 0x%08x)", ui32DirListIndex, ui32PDDevPAddr));
+ MMU_CheckFaultAddr(psDevInfo, ui32PDDevPAddr, ui32FaultAddress);
+ #endif
+
+ #if defined(EUR_CR_BIF_BANK0_INDEX_HOST_MASK)
+ /* Check the Host's memory context */
+ ui32DirListIndex = (ui32Bank0 & EUR_CR_BIF_BANK0_INDEX_HOST_MASK) >> EUR_CR_BIF_BANK0_INDEX_HOST_SHIFT;
+ ui32PDDevPAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM,
+ GetDirListBaseReg(ui32DirListIndex));
+ PVR_LOG(("Checking Host memory context (index = %d, PD = 0x%08x)", ui32DirListIndex, ui32PDDevPAddr));
+ MMU_CheckFaultAddr(psDevInfo, ui32PDDevPAddr, ui32FaultAddress);
+ #endif
+ }
+ #endif
+ }
+ /*
+ Dump out the outstanding queue items.
+ */
+ QueueDumpDebugInfo();
+
+ {
+ /*
+ Dump out the Host control.
+ */
+ SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl;
+ IMG_UINT32 *pui32HostCtlBuffer = (IMG_UINT32 *)psSGXHostCtl;
+ IMG_UINT32 ui32LoopCounter;
+
+ if (psSGXHostCtl->ui32AssertFail != 0)
+ {
+ PVR_LOG(("SGX Microkernel assert fail: 0x%08X", psSGXHostCtl->ui32AssertFail));
+ psSGXHostCtl->ui32AssertFail = 0;
+ }
+
+ PVR_LOG(("SGX Host control:"));
+
+ for (ui32LoopCounter = 0;
+ ui32LoopCounter < sizeof(*psDevInfo->psSGXHostCtl) / sizeof(*pui32HostCtlBuffer);
+ ui32LoopCounter += 4)
+ {
+ PVR_LOG(("\t(HC-%X) 0x%08X 0x%08X 0x%08X 0x%08X", ui32LoopCounter * sizeof(*pui32HostCtlBuffer),
+ pui32HostCtlBuffer[ui32LoopCounter + 0], pui32HostCtlBuffer[ui32LoopCounter + 1],
+ pui32HostCtlBuffer[ui32LoopCounter + 2], pui32HostCtlBuffer[ui32LoopCounter + 3]));
+ }
+ }
+
+ {
+ /*
+ Dump out the TA/3D control.
+ */
+ IMG_UINT32 *pui32TA3DCtlBuffer = psDevInfo->psKernelSGXTA3DCtlMemInfo->pvLinAddrKM;
+ IMG_UINT32 ui32LoopCounter;
+
+ PVR_LOG(("SGX TA/3D control:"));
+
+ for (ui32LoopCounter = 0;
+ ui32LoopCounter < psDevInfo->psKernelSGXTA3DCtlMemInfo->uAllocSize / sizeof(*pui32TA3DCtlBuffer);
+ ui32LoopCounter += 4)
+ {
+ PVR_LOG(("\t(T3C-%X) 0x%08X 0x%08X 0x%08X 0x%08X", ui32LoopCounter * sizeof(*pui32TA3DCtlBuffer),
+ pui32TA3DCtlBuffer[ui32LoopCounter + 0], pui32TA3DCtlBuffer[ui32LoopCounter + 1],
+ pui32TA3DCtlBuffer[ui32LoopCounter + 2], pui32TA3DCtlBuffer[ui32LoopCounter + 3]));
+ }
+ }
+
+ #if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+ {
+ IMG_UINT32 *pui32MKTraceBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->pvLinAddrKM;
+ IMG_UINT32 ui32LastStatusCode, ui32WriteOffset;
+
+ ui32LastStatusCode = *pui32MKTraceBuffer;
+ pui32MKTraceBuffer++;
+ ui32WriteOffset = *pui32MKTraceBuffer;
+ pui32MKTraceBuffer++;
+
+ PVR_LOG(("Last SGX microkernel status code: %08X %s",
+ ui32LastStatusCode, SGXUKernelStatusString(ui32LastStatusCode)));
+
+ #if defined(PVRSRV_DUMP_MK_TRACE)
+ /*
+ Dump the raw microkernel trace buffer to the log.
+ */
+ {
+ IMG_UINT32 ui32LoopCounter;
+
+ for (ui32LoopCounter = 0;
+ ui32LoopCounter < SGXMK_TRACE_BUFFER_SIZE;
+ ui32LoopCounter++)
+ {
+ IMG_UINT32 *pui32BufPtr;
+ pui32BufPtr = pui32MKTraceBuffer +
+ (((ui32WriteOffset + ui32LoopCounter) % SGXMK_TRACE_BUFFER_SIZE) * 4);
+ PVR_LOG(("\t(MKT-%X) %08X %08X %08X %08X %s", ui32LoopCounter,
+ pui32BufPtr[2], pui32BufPtr[3], pui32BufPtr[1], pui32BufPtr[0],
+ SGXUKernelStatusString(pui32BufPtr[0])));
+ }
+ }
+ #endif /* PVRSRV_DUMP_MK_TRACE */
+ }
+ #endif /* PVRSRV_USSE_EDM_STATUS_DEBUG */
+
+ {
+ /*
+ Dump out the kernel CCB.
+ */
+ PVR_LOG(("SGX Kernel CCB WO:0x%X RO:0x%X",
+ psDevInfo->psKernelCCBCtl->ui32WriteOffset,
+ psDevInfo->psKernelCCBCtl->ui32ReadOffset));
+
+ #if defined(PVRSRV_DUMP_KERNEL_CCB)
+ {
+ IMG_UINT32 ui32LoopCounter;
+
+ for (ui32LoopCounter = 0;
+ ui32LoopCounter < sizeof(psDevInfo->psKernelCCB->asCommands) /
+ sizeof(psDevInfo->psKernelCCB->asCommands[0]);
+ ui32LoopCounter++)
+ {
+ SGXMKIF_COMMAND *psCommand = &psDevInfo->psKernelCCB->asCommands[ui32LoopCounter];
+
+ PVR_LOG(("\t(KCCB-%X) %08X %08X - %08X %08X %08X %08X", ui32LoopCounter,
+ psCommand->ui32ServiceAddress, psCommand->ui32CacheControl,
+ psCommand->ui32Data[0], psCommand->ui32Data[1],
+ psCommand->ui32Data[2], psCommand->ui32Data[3]));
+ }
+ }
+ #endif /* PVRSRV_DUMP_KERNEL_CCB */
+ }
+ #if defined (TTRACE)
+ PVRSRVDumpTimeTraceBuffers();
+ #endif
+
+}
+
+
+#if defined(SYS_USING_INTERRUPTS) || defined(SUPPORT_HW_RECOVERY)
+/*!
+*******************************************************************************
+
+ @Function HWRecoveryResetSGX
+
+ @Description
+
+ Resets SGX
+
+ Note: may be called from an ISR so should not call pdump.
+
+ @Input psDevInfo - dev info
+
+ @Input ui32Component - core component to reset
+
+ @Return IMG_VOID
+
+******************************************************************************/
+static
+IMG_VOID HWRecoveryResetSGX (PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_UINT32 ui32Component,
+ IMG_UINT32 ui32CallerID)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+ SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;
+
+#if defined(SUPPORT_HWRECOVERY_TRACE_LIMIT)
+ static IMG_UINT32 ui32Clockinus = 0;
+ static IMG_UINT32 ui32HWRecoveryCount=0;
+ IMG_UINT32 ui32TempClockinus=0;
+#endif
+
+ PVR_UNREFERENCED_PARAMETER(ui32Component);
+
+ /* Debug dumps associated with HWR can be long. Delay system suspend */
+ SysLockSystemSuspend();
+
+ /*
+ Ensure that hardware recovery is serialised with any power transitions.
+ */
+ eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE);
+ if(eError != PVRSRV_OK)
+ {
+ /*
+ Unable to obtain lock because there is already a power transition
+ in progress.
+ */
+ PVR_DPF((PVR_DBG_WARNING,"HWRecoveryResetSGX: Power transition in progress"));
+ return;
+ }
+
+ psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_HWR;
+
+ PVR_LOG(("HWRecoveryResetSGX: SGX Hardware Recovery triggered"));
+
+#if defined(SUPPORT_HWRECOVERY_TRACE_LIMIT)
+/*
+ * The following defines are system specific and should be defined in
+ * the corresponding sysconfig.h file. The values indicated are examples only.
+ SYS_SGX_HWRECOVERY_TRACE_RESET_TIME_PERIOD 5000000 //(5 Seconds)
+ SYS_SGX_MAX_HWRECOVERY_OCCURANCE_COUNT 5
+ */
+ ui32TempClockinus = OSClockus();
+ if((ui32TempClockinus-ui32Clockinus) < SYS_SGX_HWRECOVERY_TRACE_RESET_TIME_PERIOD){
+ ui32HWRecoveryCount++;
+ if(SYS_SGX_MAX_HWRECOVERY_OCCURANCE_COUNT <= ui32HWRecoveryCount){
+ OSPanic();
+ }
+ }else{
+ ui32Clockinus = ui32TempClockinus;
+ SGXDumpDebugInfo(psDeviceNode->pvDevice, IMG_TRUE);
+ ui32HWRecoveryCount = 0;
+ }
+#else
+ SGXDumpDebugInfo(psDeviceNode->pvDevice, IMG_TRUE);
+#endif
+
+ /* Suspend pdumping. */
+ PDUMPSUSPEND();
+
+ /* Reset and re-initialise SGX. */
+ eError = SGXInitialise(psDevInfo, IMG_TRUE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"HWRecoveryResetSGX: SGXInitialise failed (%d)", eError));
+ }
+
+ /* Resume pdumping. */
+ PDUMPRESUME();
+
+ PVRSRVPowerUnlock(ui32CallerID);
+
+ SysUnlockSystemSuspend();
+
+ /* Send a dummy kick so that we start processing again */
+ SGXScheduleProcessQueuesKM(psDeviceNode);
+
+ /* Flush any old commands from the queues. */
+ PVRSRVProcessQueues(IMG_TRUE);
+}
+#endif /* #if defined(SYS_USING_INTERRUPTS) || defined(SUPPORT_HW_RECOVERY) */
+
+
+#if defined(SUPPORT_HW_RECOVERY)
+/*!
+******************************************************************************
+
+ @Function SGXOSTimer
+
+ @Description
+
+ Timer function for SGX
+
+ @Input pvData - private data
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+IMG_VOID SGXOSTimer(IMG_VOID *pvData)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode = pvData;
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ static IMG_UINT32 ui32EDMTasks = 0;
+ static IMG_UINT32 ui32LockupCounter = 0; /* To prevent false positives */
+ static IMG_UINT32 ui32OpenCLDelayCounter = 0;
+ static IMG_UINT32 ui32NumResets = 0;
+#if defined(FIX_HW_BRN_31093)
+ static IMG_BOOL bBRN31093Inval = IMG_FALSE;
+#endif
+ IMG_UINT32 ui32CurrentEDMTasks;
+ IMG_UINT32 ui32CurrentOpenCLDelayCounter=0;
+ IMG_BOOL bLockup = IMG_FALSE;
+ IMG_BOOL bPoweredDown;
+
+ /* increment a timestamp */
+ psDevInfo->ui32TimeStamp++;
+
+#if defined(NO_HARDWARE)
+ bPoweredDown = IMG_TRUE;
+#else
+ bPoweredDown = (SGXIsDevicePowered(psDeviceNode)) ? IMG_FALSE : IMG_TRUE;
+#endif /* NO_HARDWARE */
+
+ /*
+ * Check whether EDM timer tasks are getting scheduled. If not, assume
+ * that SGX has locked up and reset the chip.
+ */
+
+ /* Check whether the timer should be running */
+ if (bPoweredDown)
+ {
+ ui32LockupCounter = 0;
+ #if defined(FIX_HW_BRN_31093)
+ bBRN31093Inval = IMG_FALSE;
+ #endif
+ }
+ else
+ {
+ /* The PDS timer should be running. */
+ ui32CurrentEDMTasks = OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg0);
+ if (psDevInfo->ui32EDMTaskReg1 != 0)
+ {
+ ui32CurrentEDMTasks ^= OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg1);
+ }
+ if ((ui32CurrentEDMTasks == ui32EDMTasks) &&
+ (psDevInfo->ui32NumResets == ui32NumResets))
+ {
+ ui32LockupCounter++;
+ if (ui32LockupCounter == 3)
+ {
+ ui32LockupCounter = 0;
+ ui32CurrentOpenCLDelayCounter = (psDevInfo->psSGXHostCtl)->ui32OpenCLDelayCount;
+ if(0 != ui32CurrentOpenCLDelayCounter)
+ {
+ if(ui32OpenCLDelayCounter != ui32CurrentOpenCLDelayCounter){
+ ui32OpenCLDelayCounter = ui32CurrentOpenCLDelayCounter;
+ }else{
+ ui32OpenCLDelayCounter -= 1;
+ (psDevInfo->psSGXHostCtl)->ui32OpenCLDelayCount = ui32OpenCLDelayCounter;
+ }
+ goto SGX_NoUKernel_LockUp;
+ }
+
+
+ #if defined(FIX_HW_BRN_31093)
+ if (bBRN31093Inval == IMG_FALSE)
+ {
+ /* It could be a BIF hang so do a INVAL_PTE */
+ #if defined(FIX_HW_BRN_29997)
+ IMG_UINT32 ui32BIFCtrl;
+ /* Pause the BIF before issuing the invalidate */
+ ui32BIFCtrl = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_PAUSE_MASK);
+ /* delay for 200 clocks */
+ SGXWaitClocks(psDevInfo, 200);
+ #endif
+ /* Flag that we have attempt to un-block the BIF */
+ bBRN31093Inval = IMG_TRUE;
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL_INVAL, EUR_CR_BIF_CTRL_INVAL_PTE_MASK);
+ /* delay for 200 clocks */
+ SGXWaitClocks(psDevInfo, 200);
+
+ #if defined(FIX_HW_BRN_29997)
+ /* un-pause the BIF by restoring the BIF_CTRL */
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl);
+ #endif
+ }
+ else
+ #endif
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXOSTimer() detected SGX lockup (0x%x tasks)", ui32EDMTasks));
+
+ bLockup = IMG_TRUE;
+ (psDevInfo->psSGXHostCtl)->ui32OpenCLDelayCount = 0;
+ }
+ }
+ }
+ else
+ {
+ #if defined(FIX_HW_BRN_31093)
+ bBRN31093Inval = IMG_FALSE;
+ #endif
+ ui32LockupCounter = 0;
+ ui32EDMTasks = ui32CurrentEDMTasks;
+ ui32NumResets = psDevInfo->ui32NumResets;
+ }
+ }
+SGX_NoUKernel_LockUp:
+
+ if (bLockup)
+ {
+ SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;
+
+ /* increment the counter so we know the host detected the lockup */
+ psSGXHostCtl->ui32HostDetectedLockups ++;
+
+ /* Reset the chip and process the queues. */
+ HWRecoveryResetSGX(psDeviceNode, 0, ISR_ID);
+ }
+}
+#endif /* defined(SUPPORT_HW_RECOVERY) */
+
+
+
+#if defined(SYS_USING_INTERRUPTS)
+
+/*
+ SGX ISR Handler
+*/
+IMG_BOOL SGX_ISRHandler (IMG_VOID *pvData)
+{
+ IMG_BOOL bInterruptProcessed = IMG_FALSE;
+
+
+ /* Real Hardware */
+ {
+ IMG_UINT32 ui32EventStatus = 0, ui32EventEnable = 0;
+ IMG_UINT32 ui32EventClear = 0;
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+ IMG_UINT32 ui32EventStatus2, ui32EventEnable2;
+#endif
+ IMG_UINT32 ui32EventClear2 = 0;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+
+ /* check for null pointers */
+ if(pvData == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGX_ISRHandler: Invalid params\n"));
+ return bInterruptProcessed;
+ }
+
+ psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData;
+ psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
+
+ if(!powering_down) {
+ ui32EventStatus = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS);
+ ui32EventEnable = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_ENABLE);
+ }
+
+ /* test only the unmasked bits */
+ ui32EventStatus &= ui32EventEnable;
+
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+ if(!powering_down) {
+ ui32EventStatus2 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS2);
+ ui32EventEnable2 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_ENABLE2);
+ }
+
+ /* test only the unmasked bits */
+ ui32EventStatus2 &= ui32EventEnable2;
+#endif /* defined(SGX_FEATURE_DATA_BREAKPOINTS) */
+
+ /* Thought: is it better to insist that the bit assignment in
+ the "clear" register(s) matches that of the "status" register(s)?
+ It would greatly simplify this LISR */
+
+ if (ui32EventStatus & EUR_CR_EVENT_STATUS_SW_EVENT_MASK)
+ {
+ ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK;
+ }
+
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+ if (ui32EventStatus2 & EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_MASK)
+ {
+ ui32EventClear2 |= EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_MASK;
+ }
+
+ if (ui32EventStatus2 & EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_MASK)
+ {
+ ui32EventClear2 |= EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_MASK;
+ }
+#endif /* defined(SGX_FEATURE_DATA_BREAKPOINTS) */
+
+ if (ui32EventClear || ui32EventClear2)
+ {
+ bInterruptProcessed = IMG_TRUE;
+
+ /* Clear master interrupt bit */
+ ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK;
+
+ if(!powering_down) {
+ /* clear the events */
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR, ui32EventClear);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR2, ui32EventClear2);
+ }
+ }
+ }
+
+ return bInterruptProcessed;
+}
+
+
+/*
+ SGX MISR Handler
+*/
+static IMG_VOID SGX_MISRHandler (IMG_VOID *pvData)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData;
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
+ SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;
+
+ if (((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) != 0UL) &&
+ ((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) == 0UL))
+ {
+ HWRecoveryResetSGX(psDeviceNode, 0, ISR_ID);
+ }
+
+#if defined(OS_SUPPORTS_IN_LISR)
+ if (psDeviceNode->bReProcessDeviceCommandComplete)
+ {
+ SGXScheduleProcessQueuesKM(psDeviceNode);
+ }
+#endif
+
+ SGXTestActivePowerEvent(psDeviceNode, ISR_ID);
+}
+#endif /* #if defined (SYS_USING_INTERRUPTS) */
+
+#if defined(SUPPORT_MEMORY_TILING)
+
+IMG_INTERNAL
+PVRSRV_ERROR SGX_AllocMemTilingRange(PVRSRV_DEVICE_NODE *psDeviceNode,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32XTileStride,
+ IMG_UINT32 *pui32RangeIndex)
+{
+ return SGX_AllocMemTilingRangeInt(psDeviceNode->pvDevice,
+ psMemInfo->sDevVAddr.uiAddr,
+ psMemInfo->sDevVAddr.uiAddr + ((IMG_UINT32) psMemInfo->uAllocSize) + SGX_MMU_PAGE_SIZE - 1,
+ ui32XTileStride,
+ pui32RangeIndex);
+}
+
+IMG_INTERNAL
+PVRSRV_ERROR SGX_FreeMemTilingRange(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_UINT32 ui32RangeIndex)
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ IMG_UINT32 ui32Offset;
+ IMG_UINT32 ui32Val;
+
+ if(ui32RangeIndex >= 10)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGX_FreeMemTilingRange: invalid Range index "));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ /* clear the usage bit */
+ psDevInfo->ui32MemTilingUsage &= ~(1<<ui32RangeIndex);
+
+ /* disable the range */
+ ui32Offset = EUR_CR_BIF_TILE0 + (ui32RangeIndex<<2);
+ ui32Val = 0;
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val);
+ PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val);
+
+ return PVRSRV_OK;
+}
+
+#endif /* defined(SUPPORT_MEMORY_TILING) */
+
+
+static IMG_VOID SGXCacheInvalidate(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+
+ #if defined(SGX_FEATURE_MP)
+ psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_SL;
+ #else
+ PVR_UNREFERENCED_PARAMETER(psDevInfo);
+ #endif /* SGX_FEATURE_MP */
+}
+
+/*!
+*******************************************************************************
+
+ @Function SGXRegisterDevice
+
+ @Description
+
+ Registers the device with the system
+
+ @Input: psDeviceNode - device node
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ DEVICE_MEMORY_INFO *psDevMemoryInfo;
+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+
+ /* setup details that never change */
+ psDeviceNode->sDevId.eDeviceType = DEV_DEVICE_TYPE;
+ psDeviceNode->sDevId.eDeviceClass = DEV_DEVICE_CLASS;
+#if defined(PDUMP)
+ {
+ /* memory space names are set up in system code */
+ SGX_DEVICE_MAP *psSGXDeviceMemMap;
+ SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,
+ (IMG_VOID**)&psSGXDeviceMemMap);
+
+ psDeviceNode->sDevId.pszPDumpDevName = psSGXDeviceMemMap->pszPDumpDevName;
+ PVR_ASSERT(psDeviceNode->sDevId.pszPDumpDevName != IMG_NULL);
+ }
+
+ psDeviceNode->sDevId.pszPDumpRegName = SGX_PDUMPREG_NAME;
+#endif /* PDUMP */
+
+ psDeviceNode->pfnInitDevice = &DevInitSGXPart1;
+ psDeviceNode->pfnDeInitDevice = &DevDeInitSGX;
+
+ psDeviceNode->pfnInitDeviceCompatCheck = &SGXDevInitCompatCheck;
+#if defined(PDUMP)
+ psDeviceNode->pfnPDumpInitDevice = &SGXResetPDump;
+ psDeviceNode->pfnMMUGetContextID = &MMU_GetPDumpContextID;
+#endif
+ /*
+ MMU callbacks
+ */
+ psDeviceNode->pfnMMUInitialise = &MMU_Initialise;
+ psDeviceNode->pfnMMUFinalise = &MMU_Finalise;
+ psDeviceNode->pfnMMUInsertHeap = &MMU_InsertHeap;
+ psDeviceNode->pfnMMUCreate = &MMU_Create;
+ psDeviceNode->pfnMMUDelete = &MMU_Delete;
+ psDeviceNode->pfnMMUAlloc = &MMU_Alloc;
+ psDeviceNode->pfnMMUFree = &MMU_Free;
+ psDeviceNode->pfnMMUMapPages = &MMU_MapPages;
+ psDeviceNode->pfnMMUMapShadow = &MMU_MapShadow;
+ psDeviceNode->pfnMMUUnmapPages = &MMU_UnmapPages;
+ psDeviceNode->pfnMMUMapScatter = &MMU_MapScatter;
+ psDeviceNode->pfnMMUGetPhysPageAddr = &MMU_GetPhysPageAddr;
+ psDeviceNode->pfnMMUGetPDDevPAddr = &MMU_GetPDDevPAddr;
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ psDeviceNode->pfnMMUIsHeapShared = &MMU_IsHeapShared;
+#endif
+#if defined(FIX_HW_BRN_31620)
+ psDeviceNode->pfnMMUGetCacheFlushRange = &MMU_GetCacheFlushRange;
+ psDeviceNode->pfnMMUGetPDPhysAddr = &MMU_GetPDPhysAddr;
+#else
+ psDeviceNode->pfnMMUGetCacheFlushRange = IMG_NULL;
+ psDeviceNode->pfnMMUGetPDPhysAddr = IMG_NULL;
+#endif
+ psDeviceNode->pfnMMUMapPagesSparse = &MMU_MapPagesSparse;
+ psDeviceNode->pfnMMUMapShadowSparse = &MMU_MapShadowSparse;
+
+#if defined (SYS_USING_INTERRUPTS)
+ /*
+ SGX ISR handler
+ */
+ psDeviceNode->pfnDeviceISR = SGX_ISRHandler;
+ psDeviceNode->pfnDeviceMISR = SGX_MISRHandler;
+#endif
+
+#if defined(SUPPORT_MEMORY_TILING)
+ psDeviceNode->pfnAllocMemTilingRange = SGX_AllocMemTilingRange;
+ psDeviceNode->pfnFreeMemTilingRange = SGX_FreeMemTilingRange;
+#endif
+
+ /*
+ SGX command complete handler
+ */
+ psDeviceNode->pfnDeviceCommandComplete = &SGXCommandComplete;
+
+ psDeviceNode->pfnCacheInvalidate = SGXCacheInvalidate;
+
+ /*
+ and setup the device's memory map:
+ */
+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+ /* size of address space */
+ psDevMemoryInfo->ui32AddressSpaceSizeLog2 = SGX_FEATURE_ADDRESS_SPACE_SIZE;
+
+ /* flags, backing store details to be specified by system */
+ psDevMemoryInfo->ui32Flags = 0;
+
+ /* device memory heap info about each heap in a device address space */
+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID,
+ (IMG_VOID **)&psDevMemoryInfo->psDeviceMemoryHeap, 0,
+ "Array of Device Memory Heap Info") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXRegisterDevice : Failed to alloc memory for DEVICE_MEMORY_HEAP_INFO"));
+ return (PVRSRV_ERROR_OUT_OF_MEMORY);
+ }
+ OSMemSet(psDevMemoryInfo->psDeviceMemoryHeap, 0, sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID);
+
+ psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
+
+ /*
+ setup heaps
+ Note: backing store to be setup by system (defaults to UMA)
+ */
+
+ /************* general ***************/
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_GENERAL_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_GENERAL_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_SINGLE_PROCESS;
+ psDeviceMemoryHeap->pszName = "General";
+ psDeviceMemoryHeap->pszBSName = "General BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+ /* set the default (4k). System can override these as required */
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+#if !defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+ /* specify the mapping heap ID for this device */
+ psDevMemoryInfo->ui32MappingHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
+#endif
+ psDeviceMemoryHeap++;/* advance to the next heap */
+
+#if defined(SUPPORT_MEMORY_TILING)
+ /************* VPB tiling ***************/
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_VPB_TILED_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_VPB_TILED_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_VPB_TILED_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_SINGLE_PROCESS;
+ psDeviceMemoryHeap->pszName = "VPB Tiled";
+ psDeviceMemoryHeap->pszBSName = "VPB Tiled BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+ /* set the default (4k). System can override these as required */
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap->ui32XTileStride = SGX_VPB_TILED_HEAP_STRIDE;
+ PVR_DPF((PVR_DBG_WARNING, "VPB tiling heap tiling stride = 0x%x", psDeviceMemoryHeap->ui32XTileStride));
+ psDeviceMemoryHeap++;/* advance to the next heap */
+#endif
+
+#if defined(SUPPORT_ION)
+ /************* Ion Heap ***************/
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_ION_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_ION_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_ION_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_HAP_SINGLE_PROCESS;
+ psDeviceMemoryHeap->pszName = "Ion";
+ psDeviceMemoryHeap->pszBSName = "Ion BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+ /* specify the ion heap ID for this device */
+ psDevMemoryInfo->ui32IonHeapID = SGX_ION_HEAP_ID;
+ /* set the default (4k). System can override these as required */
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;/* advance to the next heap */
+#endif
+
+ /************* TA data ***************/
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_TADATA_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_TADATA_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_TADATA_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_MULTI_PROCESS;
+ psDeviceMemoryHeap->pszName = "TA Data";
+ psDeviceMemoryHeap->pszBSName = "TA Data BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+ /* set the default (4k). System can override these as required */
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;/* advance to the next heap */
+
+
+ /************* kernel code ***************/
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_CODE_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_KERNEL_CODE_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_KERNEL_CODE_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_MULTI_PROCESS;
+ psDeviceMemoryHeap->pszName = "Kernel Code";
+ psDeviceMemoryHeap->pszBSName = "Kernel Code BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
+ /* set the default (4k). System can override these as required */
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;/* advance to the next heap */
+
+
+ /************* Kernel Video Data ***************/
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_DATA_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_KERNEL_DATA_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_KERNEL_DATA_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_MULTI_PROCESS;
+ psDeviceMemoryHeap->pszName = "KernelData";
+ psDeviceMemoryHeap->pszBSName = "KernelData BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
+ /* set the default (4k). System can override these as required */
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;/* advance to the next heap */
+
+
+ /************* PixelShaderUSSE ***************/
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PIXELSHADER_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PIXELSHADER_HEAP_BASE;
+ /*
+ The actual size of the pixel and vertex shader heap must be such that all
+ addresses are within range of the one of the USSE code base registers, but
+ the addressable range is hardware-dependent.
+ SGX_PIXELSHADER_HEAP_SIZE is defined to be the maximum possible size
+ to ensure that the heap layout is consistent across all SGXs.
+ */
+ psDeviceMemoryHeap->ui32HeapSize = ((10 << SGX_USE_CODE_SEGMENT_RANGE_BITS) - 0x00001000);
+ PVR_ASSERT(psDeviceMemoryHeap->ui32HeapSize <= SGX_PIXELSHADER_HEAP_SIZE);
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_SINGLE_PROCESS;
+ psDeviceMemoryHeap->pszName = "PixelShaderUSSE";
+ psDeviceMemoryHeap->pszBSName = "PixelShaderUSSE BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+ /* set the default (4k). System can override these as required */
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;/* advance to the next heap */
+
+
+ /************* VertexShaderUSSE ***************/
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_VERTEXSHADER_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_VERTEXSHADER_HEAP_BASE;
+ /* See comment above with PixelShaderUSSE ui32HeapSize */
+ psDeviceMemoryHeap->ui32HeapSize = ((4 << SGX_USE_CODE_SEGMENT_RANGE_BITS) - 0x00001000);
+ PVR_ASSERT(psDeviceMemoryHeap->ui32HeapSize <= SGX_VERTEXSHADER_HEAP_SIZE);
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_SINGLE_PROCESS;
+ psDeviceMemoryHeap->pszName = "VertexShaderUSSE";
+ psDeviceMemoryHeap->pszBSName = "VertexShaderUSSE BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+ /* set the default (4k). System can override these as required */
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;/* advance to the next heap */
+
+
+ /************* PDS Pixel Code/Data ***************/
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PDSPIXEL_CODEDATA_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PDSPIXEL_CODEDATA_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_PDSPIXEL_CODEDATA_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_SINGLE_PROCESS;
+ psDeviceMemoryHeap->pszName = "PDSPixelCodeData";
+ psDeviceMemoryHeap->pszBSName = "PDSPixelCodeData BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+ /* set the default (4k). System can override these as required */
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;/* advance to the next heap */
+
+
+ /************* PDS Vertex Code/Data ***************/
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PDSVERTEX_CODEDATA_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PDSVERTEX_CODEDATA_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_PDSVERTEX_CODEDATA_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_SINGLE_PROCESS;
+ psDeviceMemoryHeap->pszName = "PDSVertexCodeData";
+ psDeviceMemoryHeap->pszBSName = "PDSVertexCodeData BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+ /* set the default (4k). System can override these as required */
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;/* advance to the next heap */
+
+
+ /************* CacheCoherent ***************/
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_SYNCINFO_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_SYNCINFO_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_SYNCINFO_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_MULTI_PROCESS;
+ psDeviceMemoryHeap->pszName = "CacheCoherent";
+ psDeviceMemoryHeap->pszBSName = "CacheCoherent BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
+ /* set the default (4k). System can override these as required */
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ /* set the sync heap id */
+ psDevMemoryInfo->ui32SyncHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
+ psDeviceMemoryHeap++;/* advance to the next heap */
+
+
+ /************* Shared 3D Parameters ***************/
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_SHARED_3DPARAMETERS_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_SHARED_3DPARAMETERS_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_SHARED_3DPARAMETERS_HEAP_SIZE;
+ psDeviceMemoryHeap->pszName = "Shared 3DParameters";
+ psDeviceMemoryHeap->pszBSName = "Shared 3DParameters BS";
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_MULTI_PROCESS;
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
+
+ /* set the default (4k). System can override these as required */
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;/* advance to the next heap */
+
+ /************* Percontext 3D Parameters ***************/
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PERCONTEXT_3DPARAMETERS_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE;
+ psDeviceMemoryHeap->pszName = "Percontext 3DParameters";
+ psDeviceMemoryHeap->pszBSName = "Percontext 3DParameters BS";
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_SINGLE_PROCESS;
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+ /* set the default (4k). System can override these as required */
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;/* advance to the next heap */
+
+
+#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)
+ /************* General Mapping ***************/
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_MAPPING_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_GENERAL_MAPPING_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_GENERAL_MAPPING_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_MULTI_PROCESS;
+ psDeviceMemoryHeap->pszName = "GeneralMapping";
+ psDeviceMemoryHeap->pszBSName = "GeneralMapping BS";
+ #if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) && defined(FIX_HW_BRN_23410)
+ /*
+ if((2D hardware is enabled)
+ && (multi-mem contexts enabled)
+ && (BRN23410 is present))
+ - then don't make the heap per-context otherwise
+ the TA and 2D requestors must always be aligned to
+ the same address space which could affect performance
+ */
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
+ #else /* defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) && defined(FIX_HW_BRN_23410) */
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;
+ #endif /* defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) && defined(FIX_HW_BRN_23410) */
+
+ /* set the default (4k). System can override these as required */
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ /* specify the mapping heap ID for this device */
+ psDevMemoryInfo->ui32MappingHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
+ psDeviceMemoryHeap++;/* advance to the next heap */
+#endif /* #if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) */
+
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+ /************* 2D HW Heap ***************/
+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_2D_HEAP_ID);
+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_2D_HEAP_BASE;
+ psDeviceMemoryHeap->ui32HeapSize = SGX_2D_HEAP_SIZE;
+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE
+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION
+ | PVRSRV_HAP_SINGLE_PROCESS;
+ psDeviceMemoryHeap->pszName = "2D";
+ psDeviceMemoryHeap->pszBSName = "2D BS";
+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;
+ /* set the default (4k). System can override these as required */
+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE;
+ psDeviceMemoryHeap++;/* advance to the next heap */
+#endif /* #if defined(SGX_FEATURE_2D_HARDWARE) */
+
+
+ /* set the heap count */
+ psDevMemoryInfo->ui32HeapCount = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap);
+
+ return PVRSRV_OK;
+}
+
+#if defined(PDUMP)
+static
+PVRSRV_ERROR SGXResetPDump(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)(psDeviceNode->pvDevice);
+ psDevInfo->psKernelCCBInfo->ui32CCBDumpWOff = 0;
+ PVR_DPF((PVR_DBG_MESSAGE, "Reset pdump CCB write offset."));
+
+ return PVRSRV_OK;
+}
+#endif /* PDUMP */
+
+
+/*!
+*******************************************************************************
+
+ @Function SGXGetClientInfoKM
+
+ @Description Gets the client information
+
+ @Input hDevCookie
+
+ @Output psClientInfo
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR SGXGetClientInfoKM(IMG_HANDLE hDevCookie,
+ SGX_CLIENT_INFO* psClientInfo)
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
+
+ /*
+ If this is the first client to connect to SGX perform initialisation
+ */
+ psDevInfo->ui32ClientRefCount++;
+
+ /*
+ Copy information to the client info.
+ */
+ psClientInfo->ui32ProcessID = OSGetCurrentProcessIDKM();
+
+ /*
+ Copy requested information.
+ */
+ OSMemCopy(&psClientInfo->asDevData, &psDevInfo->asSGXDevData, sizeof(psClientInfo->asDevData));
+
+ /* just return OK */
+ return PVRSRV_OK;
+}
+
+
+/*!
+*******************************************************************************
+
+ @Function SGXPanic
+
+ @Description
+
+ Called when an unrecoverable situation is detected. Dumps SGX debug
+ information and tells the OS to panic.
+
+ @Input psDevInfo - SGX device info
+
+ @Return IMG_VOID
+
+******************************************************************************/
+IMG_VOID SGXPanic(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+ PVR_LOG(("SGX panic"));
+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
+ OSPanic();
+}
+
+
+/*!
+*******************************************************************************
+
+ @Function SGXDevInitCompatCheck
+
+ @Description
+
+ Check compatibility of host driver and microkernel (DDK and build options)
+ for SGX devices at services/device initialisation
+
+ @Input psDeviceNode - device node
+
+ @Return PVRSRV_ERROR - depending on mismatch found
+
+******************************************************************************/
+PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_SGXDEV_INFO *psDevInfo;
+ IMG_UINT32 ui32BuildOptions, ui32BuildOptionsMismatch;
+#if !defined(NO_HARDWARE)
+ PPVRSRV_KERNEL_MEM_INFO psMemInfo;
+ PVRSRV_SGX_MISCINFO_INFO *psSGXMiscInfoInt; /*!< internal misc info for ukernel */
+ PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures;
+ SGX_MISCINFO_STRUCT_SIZES *psSGXStructSizes; /*!< microkernel structure sizes */
+ IMG_BOOL bStructSizesFailed;
+
+ /* Exceptions list for core rev check, format is pairs of (hw rev, sw rev) */
+ IMG_BOOL bCheckCoreRev;
+ const IMG_UINT32 aui32CoreRevExceptions[] =
+ {
+ 0x10100, 0x10101
+ };
+ const IMG_UINT32 ui32NumCoreExceptions = sizeof(aui32CoreRevExceptions) / (2*sizeof(IMG_UINT32));
+ IMG_UINT i;
+#endif
+
+ /* Ensure it's a SGX device */
+ if(psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_SGX)
+ {
+ PVR_LOG(("(FAIL) SGXInit: Device not of type SGX"));
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ goto chk_exit;
+ }
+
+ psDevInfo = psDeviceNode->pvDevice;
+
+ /*
+ * 1. Check kernel-side and client-side build options
+ * 2. Ensure ukernel DDK version and driver DDK version are compatible
+ * 3. Check ukernel build options against kernel-side build options
+ */
+
+ /*
+ * Check KM build options against client-side host driver
+ */
+
+ ui32BuildOptions = (SGX_BUILD_OPTIONS);
+ if (ui32BuildOptions != psDevInfo->ui32ClientBuildOptions)
+ {
+ ui32BuildOptionsMismatch = ui32BuildOptions ^ psDevInfo->ui32ClientBuildOptions;
+ if ( (psDevInfo->ui32ClientBuildOptions & ui32BuildOptionsMismatch) != 0)
+ {
+ PVR_LOG(("(FAIL) SGXInit: Mismatch in client-side and KM driver build options; "
+ "extra options present in client-side driver: (0x%x). Please check sgx_options.h",
+ psDevInfo->ui32ClientBuildOptions & ui32BuildOptionsMismatch ));
+ }
+
+ if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0)
+ {
+ PVR_LOG(("(FAIL) SGXInit: Mismatch in client-side and KM driver build options; "
+ "extra options present in KM: (0x%x). Please check sgx_options.h",
+ ui32BuildOptions & ui32BuildOptionsMismatch ));
+ }
+ eError = PVRSRV_ERROR_BUILD_MISMATCH;
+ goto chk_exit;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: Client-side and KM driver build options match. [ OK ]"));
+ }
+
+#if !defined (NO_HARDWARE)
+ psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;
+
+ /* Clear state (not strictly necessary since this is the first call) */
+ psSGXMiscInfoInt = psMemInfo->pvLinAddrKM;
+ psSGXMiscInfoInt->ui32MiscInfoFlags = 0;
+ psSGXMiscInfoInt->ui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_GET_STRUCT_SIZES;
+ eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode, IMG_NULL);
+
+ /*
+ * Validate DDK version
+ */
+ if(eError != PVRSRV_OK)
+ {
+ PVR_LOG(("(FAIL) SGXInit: Unable to validate device DDK version"));
+ goto chk_exit;
+ }
+ psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
+ if( (psSGXFeatures->ui32DDKVersion !=
+ ((PVRVERSION_MAJ << 16) |
+ (PVRVERSION_MIN << 8) |
+ PVRVERSION_BRANCH) ) ||
+ (psSGXFeatures->ui32DDKBuild != PVRVERSION_BUILD) )
+ {
+ PVR_LOG(("(FAIL) SGXInit: Incompatible driver DDK revision (%d)/device DDK revision (%d).",
+ PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild));
+ eError = PVRSRV_ERROR_DDK_VERSION_MISMATCH;
+ goto chk_exit;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: driver DDK (%d) and device DDK (%d) match. [ OK ]",
+ PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild));
+ }
+
+ /*
+ * Check hardware core revision is compatible with the one in software
+ */
+ if (psSGXFeatures->ui32CoreRevSW == 0)
+ {
+ /*
+ Head core revision cannot be checked.
+ */
+ PVR_LOG(("SGXInit: HW core rev (%x) check skipped.",
+ psSGXFeatures->ui32CoreRev));
+ }
+ else
+ {
+ /* For some cores the hw/sw core revisions are expected not to match. For these
+ * exceptional cases the core rev compatibility check should be skipped.
+ */
+ bCheckCoreRev = IMG_TRUE;
+ for(i=0; i<ui32NumCoreExceptions; i+=2)
+ {
+ if( (psSGXFeatures->ui32CoreRev==aui32CoreRevExceptions[i]) &&
+ (psSGXFeatures->ui32CoreRevSW==aui32CoreRevExceptions[i+1]) )
+ {
+ PVR_LOG(("SGXInit: HW core rev (%x), SW core rev (%x) check skipped.",
+ psSGXFeatures->ui32CoreRev,
+ psSGXFeatures->ui32CoreRevSW));
+ bCheckCoreRev = IMG_FALSE;
+ }
+ }
+
+ if (bCheckCoreRev)
+ {
+ if (psSGXFeatures->ui32CoreRev != psSGXFeatures->ui32CoreRevSW)
+ {
+ PVR_LOG(("(FAIL) SGXInit: Incompatible HW core rev (%x) and SW core rev (%x).",
+ psSGXFeatures->ui32CoreRev, psSGXFeatures->ui32CoreRevSW));
+ eError = PVRSRV_ERROR_BUILD_MISMATCH;
+ goto chk_exit;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: HW core rev (%x) and SW core rev (%x) match. [ OK ]",
+ psSGXFeatures->ui32CoreRev, psSGXFeatures->ui32CoreRevSW));
+ }
+ }
+ }
+
+ /*
+ * Check ukernel structure sizes are the same as those in the driver
+ */
+ psSGXStructSizes = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXStructSizes;
+
+ bStructSizesFailed = IMG_FALSE;
+
+ CHECK_SIZE(HOST_CTL);
+ CHECK_SIZE(COMMAND);
+#if defined(SGX_FEATURE_2D_HARDWARE)
+ CHECK_SIZE(2DCMD);
+ CHECK_SIZE(2DCMD_SHARED);
+#endif
+ CHECK_SIZE(CMDTA);
+ CHECK_SIZE(CMDTA_SHARED);
+ CHECK_SIZE(TRANSFERCMD);
+ CHECK_SIZE(TRANSFERCMD_SHARED);
+
+ CHECK_SIZE(3DREGISTERS);
+ CHECK_SIZE(HWPBDESC);
+ CHECK_SIZE(HWRENDERCONTEXT);
+ CHECK_SIZE(HWRENDERDETAILS);
+ CHECK_SIZE(HWRTDATA);
+ CHECK_SIZE(HWRTDATASET);
+ CHECK_SIZE(HWTRANSFERCONTEXT);
+
+ if (bStructSizesFailed == IMG_TRUE)
+ {
+ PVR_LOG(("(FAIL) SGXInit: Mismatch in SGXMKIF structure sizes."));
+ eError = PVRSRV_ERROR_BUILD_MISMATCH;
+ goto chk_exit;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: SGXMKIF structure sizes match. [ OK ]"));
+ }
+
+ /*
+ * Check ukernel build options against KM host driver
+ */
+
+ ui32BuildOptions = psSGXFeatures->ui32BuildOptions;
+ if (ui32BuildOptions != (SGX_BUILD_OPTIONS))
+ {
+ ui32BuildOptionsMismatch = ui32BuildOptions ^ (SGX_BUILD_OPTIONS);
+ if ( ((SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch) != 0)
+ {
+ PVR_LOG(("(FAIL) SGXInit: Mismatch in driver and microkernel build options; "
+ "extra options present in driver: (0x%x). Please check sgx_options.h",
+ (SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch ));
+ }
+
+ if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0)
+ {
+ PVR_LOG(("(FAIL) SGXInit: Mismatch in driver and microkernel build options; "
+ "extra options present in microkernel: (0x%x). Please check sgx_options.h",
+ ui32BuildOptions & ui32BuildOptionsMismatch ));
+ }
+ eError = PVRSRV_ERROR_BUILD_MISMATCH;
+ goto chk_exit;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: Driver and microkernel build options match. [ OK ]"));
+ }
+#endif // NO_HARDWARE
+
+ eError = PVRSRV_OK;
+chk_exit:
+#if defined(IGNORE_SGX_INIT_COMPATIBILITY_CHECK)
+ return PVRSRV_OK;
+#else
+ return eError;
+#endif
+}
+
+/*
+ * @Function SGXGetMiscInfoUkernel
+ *
+ * @Description Returns misc info (e.g. SGX build info/flags) from microkernel
+ *
+ * @Input psDevInfo : device info from init phase
+ * @Input psDeviceNode : device node, used for scheduling ukernel to query SGX features
+ *
+ * @Return PVRSRV_ERROR :
+ *
+ */
+static
+PVRSRV_ERROR SGXGetMiscInfoUkernel(PVRSRV_SGXDEV_INFO *psDevInfo,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_HANDLE hDevMemContext)
+{
+ PVRSRV_ERROR eError;
+ SGXMKIF_COMMAND sCommandData; /* CCB command data */
+ PVRSRV_SGX_MISCINFO_INFO *psSGXMiscInfoInt; /*!< internal misc info for ukernel */
+ PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; /*!< sgx features for client */
+ SGX_MISCINFO_STRUCT_SIZES *psSGXStructSizes; /*!< internal info: microkernel structure sizes */
+
+ PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;
+
+ if (! psMemInfo->pvLinAddrKM)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: Invalid address."));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ psSGXMiscInfoInt = psMemInfo->pvLinAddrKM;
+ psSGXFeatures = &psSGXMiscInfoInt->sSGXFeatures;
+ psSGXStructSizes = &psSGXMiscInfoInt->sSGXStructSizes;
+
+ psSGXMiscInfoInt->ui32MiscInfoFlags &= ~PVRSRV_USSE_MISCINFO_READY;
+
+ /* Reset SGX features */
+ OSMemSet(psSGXFeatures, 0, sizeof(*psSGXFeatures));
+ OSMemSet(psSGXStructSizes, 0, sizeof(*psSGXStructSizes));
+
+ /* set up buffer address for SGX features in CCB */
+ sCommandData.ui32Data[1] = psMemInfo->sDevVAddr.uiAddr; /* device V addr of output buffer */
+
+ PDUMPCOMMENT("Microkernel kick for SGXGetMiscInfo");
+ eError = SGXScheduleCCBCommandKM(psDeviceNode,
+ SGXMKIF_CMD_GETMISCINFO,
+ &sCommandData,
+ KERNEL_ID,
+ 0,
+ hDevMemContext,
+ IMG_FALSE);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: SGXScheduleCCBCommandKM failed."));
+ return eError;
+ }
+
+ /* FIXME: DWORD value to determine code path in ukernel?
+ * E.g. could use getMiscInfo to obtain register values for diagnostics? */
+
+#if !defined(NO_HARDWARE)
+ {
+ IMG_BOOL bExit;
+
+ bExit = IMG_FALSE;
+ LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+ {
+ if ((psSGXMiscInfoInt->ui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_READY) != 0)
+ {
+ bExit = IMG_TRUE;
+ break;
+ }
+ } END_LOOP_UNTIL_TIMEOUT();
+
+ /*if the loop exited because a timeout*/
+ if (!bExit)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: Timeout occurred waiting for misc info."));
+ return PVRSRV_ERROR_TIMEOUT;
+ }
+ }
+#endif /* NO_HARDWARE */
+
+ return PVRSRV_OK;
+}
+
+
+
+/*
+ * @Function SGXGetMiscInfoKM
+ *
+ * @Description Returns miscellaneous SGX info
+ *
+ * @Input psDevInfo : device info from init phase
+ * @Input psDeviceNode : device node, used for scheduling ukernel to query SGX features
+ *
+ * @Output psMiscInfo : query request plus user-mode mem for holding returned data
+ *
+ * @Return PVRSRV_ERROR :
+ *
+ */
+IMG_EXPORT
+PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo,
+ SGX_MISC_INFO *psMiscInfo,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_HANDLE hDevMemContext)
+{
+ PVRSRV_ERROR eError;
+ PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;
+ IMG_UINT32 *pui32MiscInfoFlags = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->ui32MiscInfoFlags;
+
+ /* Reset the misc info state flags */
+ *pui32MiscInfoFlags = 0;
+
+#if !defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+ PVR_UNREFERENCED_PARAMETER(hDevMemContext);
+#endif
+
+ switch(psMiscInfo->eRequest)
+ {
+#if defined(SGX_FEATURE_DATA_BREAKPOINTS)
+ case SGX_MISC_INFO_REQUEST_SET_BREAKPOINT:
+ {
+ IMG_UINT32 ui32MaskDM;
+ IMG_UINT32 ui32CtrlWEnable;
+ IMG_UINT32 ui32CtrlREnable;
+ IMG_UINT32 ui32CtrlTrapEnable;
+ IMG_UINT32 ui32RegVal;
+ IMG_UINT32 ui32StartRegVal;
+ IMG_UINT32 ui32EndRegVal;
+ SGXMKIF_COMMAND sCommandData;
+
+ /* Set or Clear BP? */
+ if(psMiscInfo->uData.sSGXBreakpointInfo.bBPEnable)
+ {
+ /* set the break point */
+ IMG_DEV_VIRTADDR sBPDevVAddr = psMiscInfo->uData.sSGXBreakpointInfo.sBPDevVAddr;
+ IMG_DEV_VIRTADDR sBPDevVAddrEnd = psMiscInfo->uData.sSGXBreakpointInfo.sBPDevVAddrEnd;
+
+ /* BP address */
+ ui32StartRegVal = sBPDevVAddr.uiAddr & EUR_CR_BREAKPOINT0_START_ADDRESS_MASK;
+ ui32EndRegVal = sBPDevVAddrEnd.uiAddr & EUR_CR_BREAKPOINT0_END_ADDRESS_MASK;
+
+ ui32MaskDM = psMiscInfo->uData.sSGXBreakpointInfo.ui32DataMasterMask;
+ ui32CtrlWEnable = psMiscInfo->uData.sSGXBreakpointInfo.bWrite;
+ ui32CtrlREnable = psMiscInfo->uData.sSGXBreakpointInfo.bRead;
+ ui32CtrlTrapEnable = psMiscInfo->uData.sSGXBreakpointInfo.bTrapped;
+
+ /* normal data BP */
+ ui32RegVal = ((ui32MaskDM<<EUR_CR_BREAKPOINT0_MASK_DM_SHIFT) & EUR_CR_BREAKPOINT0_MASK_DM_MASK) |
+ ((ui32CtrlWEnable<<EUR_CR_BREAKPOINT0_CTRL_WENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_WENABLE_MASK) |
+ ((ui32CtrlREnable<<EUR_CR_BREAKPOINT0_CTRL_RENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_RENABLE_MASK) |
+ ((ui32CtrlTrapEnable<<EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_MASK);
+ }
+ else
+ {
+ /* clear the break point */
+ ui32RegVal = ui32StartRegVal = ui32EndRegVal = 0;
+ }
+
+ /* setup the command */
+ sCommandData.ui32Data[0] = psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex;
+ sCommandData.ui32Data[1] = ui32StartRegVal;
+ sCommandData.ui32Data[2] = ui32EndRegVal;
+ sCommandData.ui32Data[3] = ui32RegVal;
+
+ /* clear signal flags */
+ psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0;
+
+ PDUMPCOMMENT("Microkernel kick for setting a data breakpoint");
+ eError = SGXScheduleCCBCommandKM(psDeviceNode,
+ SGXMKIF_CMD_DATABREAKPOINT,
+ &sCommandData,
+ KERNEL_ID,
+ 0,
+ hDevMemContext,
+ IMG_FALSE);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoKM: SGXScheduleCCBCommandKM failed."));
+ return eError;
+ }
+
+#if defined(NO_HARDWARE)
+ /* clear signal flags */
+ psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0;
+#else
+ {
+ IMG_BOOL bExit;
+
+ bExit = IMG_FALSE;
+ LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+ {
+ if (psDevInfo->psSGXHostCtl->ui32BPSetClearSignal != 0)
+ {
+ bExit = IMG_TRUE;
+ /* clear signal flags */
+ psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0;
+ break;
+ }
+ } END_LOOP_UNTIL_TIMEOUT();
+
+ /*if the loop exited because a timeout*/
+ if (!bExit)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoKM: Timeout occurred waiting BP set/clear"));
+ return PVRSRV_ERROR_TIMEOUT;
+ }
+ }
+#endif /* NO_HARDWARE */
+
+ return PVRSRV_OK;
+ }
+
+ case SGX_MISC_INFO_REQUEST_POLL_BREAKPOINT:
+ {
+ /* This request checks to see whether a breakpoint has
+ been trapped. If so, it returns the number of the
+ breakpoint number that was trapped in ui32BPIndex,
+ sTrappedBPDevVAddr to the address which was trapped,
+ and sets bTrappedBP. Otherwise, bTrappedBP will be
+ false, and other fields should be ignored. */
+ /* The uKernel is not used, since if we are stopped on a
+ breakpoint, it is not possible to guarantee that the
+ uKernel would be able to run */
+#if !defined(NO_HARDWARE)
+#if defined(SGX_FEATURE_MP)
+ IMG_BOOL bTrappedBPMaster;
+ IMG_UINT32 ui32CoreNum, ui32TrappedBPCoreNum;
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+ IMG_UINT32 ui32PipeNum, ui32TrappedBPPipeNum;
+/* ui32PipeNum is the pipe number plus 1, or 0 to represent "partition" */
+#define NUM_PIPES_PLUS_ONE (SGX_FEATURE_PERPIPE_BKPT_REGS_NUMPIPES+1)
+#endif
+ IMG_BOOL bTrappedBPAny;
+#endif /* defined(SGX_FEATURE_MP) */
+ IMG_BOOL bFoundOne;
+
+#if defined(SGX_FEATURE_MP)
+ ui32TrappedBPCoreNum = 0;
+ bTrappedBPMaster = !!(EUR_CR_MASTER_BREAKPOINT_TRAPPED_MASK & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT));
+ bTrappedBPAny = bTrappedBPMaster;
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+ ui32TrappedBPPipeNum = 0; /* just to keep the (incorrect) compiler happy */
+#endif
+ for (ui32CoreNum = 0; ui32CoreNum < SGX_FEATURE_MP_CORE_COUNT_3D; ui32CoreNum++)
+ {
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+ /* FIXME: this macro makes the assumption that the PARTITION regs are the same
+ distance before the PIPE0 regs as the PIPE1 regs are after it, _and_
+ assumes that the fields in the partition regs are in the same place
+ in the pipe regs. Need to validate these assumptions, or assert them */
+#define SGX_MP_CORE_PIPE_SELECT(r,c,p) \
+ ((SGX_MP_CORE_SELECT(EUR_CR_PARTITION_##r,c) + p*(EUR_CR_PIPE0_##r-EUR_CR_PARTITION_##r)))
+ for (ui32PipeNum = 0; ui32PipeNum < NUM_PIPES_PLUS_ONE; ui32PipeNum++)
+ {
+ bFoundOne =
+ 0 != (EUR_CR_PARTITION_BREAKPOINT_TRAPPED_MASK &
+ OSReadHWReg(psDevInfo->pvRegsBaseKM,
+ SGX_MP_CORE_PIPE_SELECT(BREAKPOINT,
+ ui32CoreNum,
+ ui32PipeNum)));
+ if (bFoundOne)
+ {
+ bTrappedBPAny = IMG_TRUE;
+ ui32TrappedBPCoreNum = ui32CoreNum;
+ ui32TrappedBPPipeNum = ui32PipeNum;
+ }
+ }
+#else /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */
+ bFoundOne = !!(EUR_CR_BREAKPOINT_TRAPPED_MASK & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum)));
+ if (bFoundOne)
+ {
+ bTrappedBPAny = IMG_TRUE;
+ ui32TrappedBPCoreNum = ui32CoreNum;
+ }
+#endif /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */
+ }
+
+ psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBP = bTrappedBPAny;
+#else /* defined(SGX_FEATURE_MP) */
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+ #error Not yet considered the case for per-pipe regs in non-mp case
+#endif
+ psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBP = 0 != (EUR_CR_BREAKPOINT_TRAPPED_MASK & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BREAKPOINT));
+#endif /* defined(SGX_FEATURE_MP) */
+
+ if (psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBP)
+ {
+ IMG_UINT32 ui32Info0, ui32Info1;
+
+#if defined(SGX_FEATURE_MP)
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+ ui32Info0 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0:SGX_MP_CORE_PIPE_SELECT(BREAKPOINT_TRAP_INFO0, ui32TrappedBPCoreNum, ui32TrappedBPPipeNum));
+ ui32Info1 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1:SGX_MP_CORE_PIPE_SELECT(BREAKPOINT_TRAP_INFO1, ui32TrappedBPCoreNum, ui32TrappedBPPipeNum));
+#else /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */
+ ui32Info0 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0:SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP_INFO0, ui32TrappedBPCoreNum));
+ ui32Info1 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1:SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP_INFO1, ui32TrappedBPCoreNum));
+#endif /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */
+#else /* defined(SGX_FEATURE_MP) */
+ ui32Info0 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BREAKPOINT_TRAP_INFO0);
+ ui32Info1 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BREAKPOINT_TRAP_INFO1);
+#endif /* defined(SGX_FEATURE_MP) */
+
+#ifdef SGX_FEATURE_PERPIPE_BKPT_REGS
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex = (ui32Info1 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_NUMBER_MASK) >> EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT;
+ psMiscInfo->uData.sSGXBreakpointInfo.sTrappedBPDevVAddr.uiAddr = ui32Info0 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK;
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPBurstLength = (ui32Info1 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_SIZE_MASK) >> EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT;
+ psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBPRead = !!(ui32Info1 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_RNW_MASK);
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPDataMaster = (ui32Info1 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK) >> EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT;
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPTag = (ui32Info1 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_TAG_MASK) >> EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_TAG_SHIFT;
+#else /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_NUMBER_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT;
+ psMiscInfo->uData.sSGXBreakpointInfo.sTrappedBPDevVAddr.uiAddr = ui32Info0 & EUR_CR_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK;
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPBurstLength = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_SIZE_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT;
+ psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBPRead = !!(ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_RNW_MASK);
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPDataMaster = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT;
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPTag = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_TAG_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_TAG_SHIFT;
+#endif /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */
+#if defined(SGX_FEATURE_MP)
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+ /* mp, per-pipe regbanks */
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum = bTrappedBPMaster?65535:(ui32TrappedBPCoreNum + (ui32TrappedBPPipeNum<<10));
+#else /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */
+ /* mp, regbanks unsplit */
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum = bTrappedBPMaster?65535:ui32TrappedBPCoreNum;
+#endif /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */
+#else /* defined(SGX_FEATURE_MP) */
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+ /* non-mp, per-pipe regbanks */
+#error non-mp perpipe regs not yet supported
+#else /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */
+ /* non-mp */
+ psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum = 65534;
+#endif /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */
+#endif /* defined(SGX_FEATURE_MP) */
+ }
+#endif /* !defined(NO_HARDWARE) */
+ return PVRSRV_OK;
+ }
+
+ case SGX_MISC_INFO_REQUEST_RESUME_BREAKPOINT:
+ {
+ /* This request resumes from the currently trapped breakpoint. */
+ /* Core number must be supplied */
+ /* Polls for notify to be acknowledged by h/w */
+#if !defined(NO_HARDWARE)
+#if defined(SGX_FEATURE_MP)
+ IMG_UINT32 ui32CoreNum;
+ IMG_BOOL bMaster;
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+ IMG_UINT32 ui32PipeNum;
+#endif
+#endif /* defined(SGX_FEATURE_MP) */
+ IMG_UINT32 ui32OldSeqNum, ui32NewSeqNum;
+
+#if defined(SGX_FEATURE_MP)
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+ ui32PipeNum = psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum >> 10;
+ ui32CoreNum = psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum & 1023;
+ bMaster = psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum > 32767;
+#else /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */
+ ui32CoreNum = psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum;
+ bMaster = ui32CoreNum > SGX_FEATURE_MP_CORE_COUNT_3D;
+#endif /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */
+ if (bMaster)
+ {
+ /* master */
+ /* EUR_CR_MASTER_BREAKPOINT_TRAPPED_MASK | EUR_CR_MASTER_BREAKPOINT_SEQNUM_MASK */
+ ui32OldSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT_TRAP, EUR_CR_MASTER_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_MASTER_BREAKPOINT_TRAP_CONTINUE_MASK);
+ do
+ {
+ ui32NewSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT);
+ }
+ while (ui32OldSeqNum == ui32NewSeqNum);
+ }
+ else
+#endif /* defined(SGX_FEATURE_MP) */
+ {
+ /* core */
+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS)
+ ui32OldSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_PIPE_SELECT(BREAKPOINT, ui32CoreNum, ui32PipeNum));
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_PIPE_SELECT(BREAKPOINT_TRAP, ui32CoreNum, ui32PipeNum), EUR_CR_PARTITION_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_PARTITION_BREAKPOINT_TRAP_CONTINUE_MASK);
+ do
+ {
+ ui32NewSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_PIPE_SELECT(BREAKPOINT, ui32CoreNum, ui32PipeNum));
+ }
+ while (ui32OldSeqNum == ui32NewSeqNum);
+#else /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */
+ ui32OldSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum));
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP, ui32CoreNum), EUR_CR_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_BREAKPOINT_TRAP_CONTINUE_MASK);
+ do
+ {
+ ui32NewSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum));
+ }
+ while (ui32OldSeqNum == ui32NewSeqNum);
+#endif /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */
+ }
+#endif /* !defined(NO_HARDWARE) */
+ return PVRSRV_OK;
+ }
+#endif /* SGX_FEATURE_DATA_BREAKPOINTS) */
+
+ case SGX_MISC_INFO_REQUEST_CLOCKSPEED:
+ {
+ psMiscInfo->uData.ui32SGXClockSpeed = psDevInfo->ui32CoreClockSpeed;
+ return PVRSRV_OK;
+ }
+
+ case SGX_MISC_INFO_REQUEST_ACTIVEPOWER:
+ {
+ psMiscInfo->uData.sActivePower.ui32NumActivePowerEvents = psDevInfo->psSGXHostCtl->ui32NumActivePowerEvents;
+ return PVRSRV_OK;
+ }
+
+ case SGX_MISC_INFO_REQUEST_LOCKUPS:
+ {
+#if defined(SUPPORT_HW_RECOVERY)
+ psMiscInfo->uData.sLockups.ui32uKernelDetectedLockups = psDevInfo->psSGXHostCtl->ui32uKernelDetectedLockups;
+ psMiscInfo->uData.sLockups.ui32HostDetectedLockups = psDevInfo->psSGXHostCtl->ui32HostDetectedLockups;
+#else
+ psMiscInfo->uData.sLockups.ui32uKernelDetectedLockups = 0;
+ psMiscInfo->uData.sLockups.ui32HostDetectedLockups = 0;
+#endif
+ return PVRSRV_OK;
+ }
+
+ case SGX_MISC_INFO_REQUEST_SPM:
+ {
+ /* this is dealt with in UM */
+ return PVRSRV_OK;
+ }
+
+ case SGX_MISC_INFO_REQUEST_SGXREV:
+ {
+ PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures;
+// PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;
+
+ eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode, hDevMemContext);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "An error occurred in SGXGetMiscInfoUkernel: %d\n",
+ eError));
+ return eError;
+ }
+ psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
+
+ /* Copy SGX features into misc info struct, to return to client */
+ psMiscInfo->uData.sSGXFeatures = *psSGXFeatures;
+
+ /* Debug output */
+ PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: Core 0x%x, sw ID 0x%x, sw Rev 0x%x\n",
+ psSGXFeatures->ui32CoreRev,
+ psSGXFeatures->ui32CoreIdSW,
+ psSGXFeatures->ui32CoreRevSW));
+ PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: DDK version 0x%x, DDK build 0x%x\n",
+ psSGXFeatures->ui32DDKVersion,
+ psSGXFeatures->ui32DDKBuild));
+
+ /* done! */
+ return PVRSRV_OK;
+ }
+
+ case SGX_MISC_INFO_REQUEST_DRIVER_SGXREV:
+ {
+ PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures;
+
+ psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
+
+ /* Reset the misc information to prevent
+ * confusion with values returned from the ukernel
+ */
+ OSMemSet(psMemInfo->pvLinAddrKM, 0,
+ sizeof(PVRSRV_SGX_MISCINFO_INFO));
+
+ psSGXFeatures->ui32DDKVersion =
+ (PVRVERSION_MAJ << 16) |
+ (PVRVERSION_MIN << 8) |
+ PVRVERSION_BRANCH;
+ psSGXFeatures->ui32DDKBuild = PVRVERSION_BUILD;
+
+ /* Also report the kernel module build options -- used in SGXConnectionCheck() */
+ psSGXFeatures->ui32BuildOptions = (SGX_BUILD_OPTIONS);
+
+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG)
+ /* Report the EDM status buffer location in memory */
+ psSGXFeatures->sDevVAEDMStatusBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->sDevVAddr;
+ psSGXFeatures->pvEDMStatusBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->pvLinAddrKM;
+#endif
+
+ /* Copy SGX features into misc info struct, to return to client */
+ psMiscInfo->uData.sSGXFeatures = *psSGXFeatures;
+ return PVRSRV_OK;
+ }
+
+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG)
+ case SGX_MISC_INFO_REQUEST_MEMREAD:
+ case SGX_MISC_INFO_REQUEST_MEMCOPY:
+ {
+ PVRSRV_ERROR eError;
+ PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures;
+ PVRSRV_SGX_MISCINFO_MEMACCESS *psSGXMemSrc; /* user-defined mem read */
+ PVRSRV_SGX_MISCINFO_MEMACCESS *psSGXMemDest; /* user-defined mem write */
+
+ {
+ /* Set the mem read flag; src is user-defined */
+ *pui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_MEMREAD;
+ psSGXMemSrc = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXMemAccessSrc;
+
+ if(psMiscInfo->sDevVAddrSrc.uiAddr != 0)
+ {
+ psSGXMemSrc->sDevVAddr = psMiscInfo->sDevVAddrSrc; /* src address */
+ }
+ else
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ }
+
+ if( psMiscInfo->eRequest == SGX_MISC_INFO_REQUEST_MEMCOPY)
+ {
+ /* Set the mem write flag; dest is user-defined */
+ *pui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_MEMWRITE;
+ psSGXMemDest = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXMemAccessDest;
+
+ if(psMiscInfo->sDevVAddrDest.uiAddr != 0)
+ {
+ psSGXMemDest->sDevVAddr = psMiscInfo->sDevVAddrDest; /* dest address */
+ }
+ else
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ }
+
+ /* Get physical address of PD for memory read (may need to switch context in microkernel) */
+ if(psMiscInfo->hDevMemContext != IMG_NULL)
+ {
+ SGXGetMMUPDAddrKM( (IMG_HANDLE)psDeviceNode, hDevMemContext, &psSGXMemSrc->sPDDevPAddr);
+
+ /* Single app will always use the same src and dest mem context */
+ psSGXMemDest->sPDDevPAddr = psSGXMemSrc->sPDDevPAddr;
+ }
+ else
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ /* Submit the task to the ukernel */
+ eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "An error occurred in SGXGetMiscInfoUkernel: %d\n",
+ eError));
+ return eError;
+ }
+ psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;
+
+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+ if(*pui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_MEMREAD_FAIL)
+ {
+ return PVRSRV_ERROR_INVALID_MISCINFO;
+ }
+#endif
+ /* Copy SGX features into misc info struct, to return to client */
+ psMiscInfo->uData.sSGXFeatures = *psSGXFeatures;
+ return PVRSRV_OK;
+ }
+#endif /* SUPPORT_SGX_EDM_MEMORY_DEBUG */
+
+#if defined(SUPPORT_SGX_HWPERF)
+ case SGX_MISC_INFO_REQUEST_SET_HWPERF_STATUS:
+ {
+ PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS *psSetHWPerfStatus = &psMiscInfo->uData.sSetHWPerfStatus;
+ const IMG_UINT32 ui32ValidFlags = PVRSRV_SGX_HWPERF_STATUS_RESET_COUNTERS |
+ PVRSRV_SGX_HWPERF_STATUS_GRAPHICS_ON |
+ PVRSRV_SGX_HWPERF_STATUS_PERIODIC_ON |
+ PVRSRV_SGX_HWPERF_STATUS_MK_EXECUTION_ON;
+ SGXMKIF_COMMAND sCommandData = {0};
+
+ /* Check for valid flags */
+ if ((psSetHWPerfStatus->ui32NewHWPerfStatus & ~ui32ValidFlags) != 0)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ #if defined(PDUMP)
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS,
+ "SGX ukernel HWPerf status %u\n",
+ psSetHWPerfStatus->ui32NewHWPerfStatus);
+ #endif /* PDUMP */
+
+ /* Copy the new group selector(s) to the host ctl for the ukernel */
+ #if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS)
+ OSMemCopy(&psDevInfo->psSGXHostCtl->aui32PerfGroup[0],
+ &psSetHWPerfStatus->aui32PerfGroup[0],
+ sizeof(psDevInfo->psSGXHostCtl->aui32PerfGroup));
+ OSMemCopy(&psDevInfo->psSGXHostCtl->aui32PerfBit[0],
+ &psSetHWPerfStatus->aui32PerfBit[0],
+ sizeof(psDevInfo->psSGXHostCtl->aui32PerfBit));
+ psDevInfo->psSGXHostCtl->ui32PerfCounterBitSelect = psSetHWPerfStatus->ui32PerfCounterBitSelect;
+ psDevInfo->psSGXHostCtl->ui32PerfSumMux = psSetHWPerfStatus->ui32PerfSumMux;
+ #if defined(PDUMP)
+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, aui32PerfGroup),
+ sizeof(psDevInfo->psSGXHostCtl->aui32PerfGroup),
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, aui32PerfBit),
+ sizeof(psDevInfo->psSGXHostCtl->aui32PerfBit),
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, ui32PerfCounterBitSelect),
+ sizeof(psDevInfo->psSGXHostCtl->ui32PerfCounterBitSelect),
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, ui32PerfSumMux),
+ sizeof(psDevInfo->psSGXHostCtl->ui32PerfSumMux),
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+ #endif /* PDUMP */
+ #else
+ psDevInfo->psSGXHostCtl->ui32PerfGroup = psSetHWPerfStatus->ui32PerfGroup;
+ #if defined(PDUMP)
+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, ui32PerfGroup),
+ sizeof(psDevInfo->psSGXHostCtl->ui32PerfGroup),
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+ #endif /* PDUMP */
+ #endif /* SGX_FEATURE_EXTENDED_PERF_COUNTERS */
+
+ /* Kick the ukernel to update the hardware state */
+ sCommandData.ui32Data[0] = psSetHWPerfStatus->ui32NewHWPerfStatus;
+ eError = SGXScheduleCCBCommandKM(psDeviceNode,
+ SGXMKIF_CMD_SETHWPERFSTATUS,
+ &sCommandData,
+ KERNEL_ID,
+ 0,
+ hDevMemContext,
+ IMG_FALSE);
+ return eError;
+ }
+#endif /* SUPPORT_SGX_HWPERF */
+
+ case SGX_MISC_INFO_DUMP_DEBUG_INFO:
+ {
+ PVR_LOG(("User requested SGX debug info"));
+
+ /* Dump SGX debug data to the kernel log. */
+ SGXDumpDebugInfo(psDeviceNode->pvDevice, IMG_FALSE);
+
+ return PVRSRV_OK;
+ }
+
+ case SGX_MISC_INFO_DUMP_DEBUG_INFO_FORCE_REGS:
+ {
+ PVR_LOG(("User requested SGX debug info"));
+
+ /* Dump SGX debug data to the kernel log. */
+ SGXDumpDebugInfo(psDeviceNode->pvDevice, IMG_TRUE);
+
+ return PVRSRV_OK;
+ }
+
+#if defined(DEBUG)
+ /* Don't allow user-mode to reboot the device in production drivers */
+ case SGX_MISC_INFO_PANIC:
+ {
+ PVR_LOG(("User requested SGX panic"));
+
+ SGXPanic(psDeviceNode->pvDevice);
+
+ return PVRSRV_OK;
+ }
+#endif
+
+ default:
+ {
+ /* switch statement fell though, so: */
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ }
+}
+
+
+IMG_EXPORT
+PVRSRV_ERROR SGXReadHWPerfCBKM(IMG_HANDLE hDevHandle,
+ IMG_UINT32 ui32ArraySize,
+ PVRSRV_SGX_HWPERF_CB_ENTRY *psClientHWPerfEntry,
+ IMG_UINT32 *pui32DataCount,
+ IMG_UINT32 *pui32ClockSpeed,
+ IMG_UINT32 *pui32HostTimeStamp)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM;
+ IMG_UINT i;
+
+ for (i = 0;
+ psHWPerfCB->ui32Woff != psHWPerfCB->ui32Roff && i < ui32ArraySize;
+ i++)
+ {
+ SGXMKIF_HWPERF_CB_ENTRY *psMKPerfEntry = &psHWPerfCB->psHWPerfCBData[psHWPerfCB->ui32Roff];
+
+ psClientHWPerfEntry[i].ui32FrameNo = psMKPerfEntry->ui32FrameNo;
+ psClientHWPerfEntry[i].ui32PID = psMKPerfEntry->ui32PID;
+ psClientHWPerfEntry[i].ui32RTData = psMKPerfEntry->ui32RTData;
+ psClientHWPerfEntry[i].ui32Type = psMKPerfEntry->ui32Type;
+ psClientHWPerfEntry[i].ui32Ordinal = psMKPerfEntry->ui32Ordinal;
+ psClientHWPerfEntry[i].ui32Info = psMKPerfEntry->ui32Info;
+ psClientHWPerfEntry[i].ui32Clocksx16 = SGXConvertTimeStamp(psDevInfo,
+ psMKPerfEntry->ui32TimeWraps,
+ psMKPerfEntry->ui32Time);
+ OSMemCopy(&psClientHWPerfEntry[i].ui32Counters[0][0],
+ &psMKPerfEntry->ui32Counters[0][0],
+ sizeof(psMKPerfEntry->ui32Counters));
+
+ OSMemCopy(&psClientHWPerfEntry[i].ui32MiscCounters[0][0],
+ &psMKPerfEntry->ui32MiscCounters[0][0],
+ sizeof(psMKPerfEntry->ui32MiscCounters));
+
+ psHWPerfCB->ui32Roff = (psHWPerfCB->ui32Roff + 1) & (SGXMKIF_HWPERF_CB_SIZE - 1);
+ }
+
+ *pui32DataCount = i;
+ *pui32ClockSpeed = psDevInfo->ui32CoreClockSpeed;
+ *pui32HostTimeStamp = OSClockus();
+
+ return eError;
+}
+
+
+/******************************************************************************
+ End of file (sgxinit.c)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/devices/sgx/sgxkick.c b/pvr-source/services4/srvkm/devices/sgx/sgxkick.c
new file mode 100644
index 0000000..584f538
--- /dev/null
+++ b/pvr-source/services4/srvkm/devices/sgx/sgxkick.c
@@ -0,0 +1,899 @@
+/*************************************************************************/ /*!
+@Title Device specific kickTA routines
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h> /* For the macro offsetof() */
+#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"
+#include "ttrace.h"
+
+/*!
+******************************************************************************
+
+ @Function SGXDoKickKM
+
+ @Description
+
+ Really kicks the TA
+
+ @Input hDevHandle - Device handle
+
+ @Return ui32Error - success or failure
+
+******************************************************************************/
+IMG_EXPORT
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK_KM *psCCBKick)
+#else
+PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick)
+#endif
+{
+ 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;
+ IMG_HANDLE hDevMemContext = IMG_NULL;
+#if defined(FIX_HW_BRN_31620)
+ hDevMemContext = psCCBKick->hDevMemContext;
+#endif
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_ENTER, KICK_TOKEN_DOKICK);
+
+ if (!CCB_OFFSET_IS_VALID(SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: Invalid CCB offset"));
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, KICK_TOKEN_DOKICK);
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ /* override QAC warning about stricter alignment */
+ /* PRQA S 3305 1 */
+ psTACmd = CCB_DATA_FROM_OFFSET(SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset);
+
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_CMD_START, KICK_TOKEN_DOKICK);
+
+#if defined(TTRACE)
+ if (psCCBKick->bFirstKickOrResume)
+ {
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK,
+ PVRSRV_TRACE_CLASS_FLAGS,
+ KICK_TOKEN_FIRST_KICK);
+ }
+
+ if (psCCBKick->bLastInScene)
+ {
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK,
+ PVRSRV_TRACE_CLASS_FLAGS,
+ KICK_TOKEN_LAST_KICK);
+ }
+#endif
+ PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_CCB,
+ KICK_TOKEN_CCB_OFFSET, psCCBKick->ui32CCBOffset);
+
+ /* TA/3D dependency */
+ if (psCCBKick->hTA3DSyncInfo)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo;
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_TA3D_SYNC,
+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+ 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;
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_TA_SYNC,
+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+ 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;
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_3D_SYNC,
+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+ 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)
+ {
+ /* Copy status vals over */
+ 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)
+ {
+ /* Copy status vals over */
+ 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
+ }
+ }
+
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+ /* SRC and DST sync dependencies */
+ psTACmd->ui32NumTASrcSyncs = psCCBKick->ui32NumTASrcSyncs;
+ for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i];
+
+ psTACmd->asTASrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ psTACmd->asTASrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+
+ /* Get ui32ReadOpsPending snapshot and copy into the CCB - before incrementing. */
+ psTACmd->asTASrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
+ /* Copy ui32WriteOpsPending snapshot into the CCB. */
+ psTACmd->asTASrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ }
+
+ psTACmd->ui32NumTADstSyncs = psCCBKick->ui32NumTADstSyncs;
+ for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i];
+
+ psTACmd->asTADstSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ psTACmd->asTADstSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+
+ /* Get ui32ReadOpsPending snapshot and copy into the CCB */
+ psTACmd->asTADstSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+ /* Copy ui32WriteOpsPending snapshot into the CCB - before incrementing */
+ psTACmd->asTADstSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
+ }
+
+ psTACmd->ui32Num3DSrcSyncs = psCCBKick->ui32Num3DSrcSyncs;
+ for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i];
+
+ psTACmd->as3DSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ psTACmd->as3DSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+
+ /* Get ui32ReadOpsPending snapshot and copy into the CCB - before incrementing. */
+ psTACmd->as3DSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
+ /* Copy ui32WriteOpsPending snapshot into the CCB. */
+ psTACmd->as3DSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ }
+#else /* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */
+ /* texture dependencies */
+ psTACmd->ui32NumSrcSyncs = psCCBKick->ui32NumSrcSyncs;
+ for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i];
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_SRC_SYNC,
+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+ psTACmd->asSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ psTACmd->asSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+
+ /* Get ui32ReadOpsPending snapshot and copy into the CCB - before incrementing. */
+ psTACmd->asSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++;
+ /* Copy ui32WriteOpsPending snapshot into the CCB. */
+ psTACmd->asSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ }
+#endif/* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */
+
+ 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)->uAllocSize >= (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
+
+ for (i=0; i<ui32NumDstSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i];
+
+ if (psSyncInfo)
+ {
+ psSyncInfo->psSyncData->ui64LastWrite = ui64KickCount;
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_DST_SYNC,
+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+ psHWDeviceSyncList->asSyncData[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+ psHWDeviceSyncList->asSyncData[i].sReadOps2CompleteDevVAddr = psSyncInfo->sReadOps2CompleteDevVAddr;
+
+ psHWDeviceSyncList->asSyncData[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+ psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++;
+ psHWDeviceSyncList->asSyncData[i].ui32ReadOps2PendingVal = psSyncInfo->psSyncData->ui32ReadOps2Pending;
+
+ #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);
+ IMG_UINT32 ui32ROps2Offset = ui32SyncOffset
+ + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOps2PendingVal);
+
+ 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))
+ {
+ /*
+ * Init the ROpsComplete value to 0.
+ */
+ PDUMPCOMMENT("Init RT ROpsComplete\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+ sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
+ 0,
+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+ /*
+ * Init the WOpsComplete value to 0.
+ */
+ 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));
+
+ ui32ModifiedValue = 0;
+ PDUMPCOMMENT("Modify RT %d ROpsPendingVal in HWDevSyncList\r\n", i);
+
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psHWDstSyncListMemInfo,
+ ui32ROpsOffset,
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psHWDstSyncListMemInfo));
+
+ /*
+ * Force the ROps2Complete value to 0.
+ */
+ PDUMPCOMMENT("Modify RT %d ROps2PendingVal in HWDevSyncList\r\n", i);
+ PDUMPMEM(&ui32ModifiedValue,
+ psHWDstSyncListMemInfo,
+ ui32ROps2Offset,
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psHWDstSyncListMemInfo));
+ }
+ #endif /* defined(PDUMP) */
+ }
+ else
+ {
+ psHWDeviceSyncList->asSyncData[i].sWriteOpsCompleteDevVAddr.uiAddr = 0;
+ psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr.uiAddr = 0;
+ psHWDeviceSyncList->asSyncData[i].sReadOps2CompleteDevVAddr.uiAddr = 0;
+
+ psHWDeviceSyncList->asSyncData[i].ui32ReadOpsPendingVal = 0;
+ psHWDeviceSyncList->asSyncData[i].ui32ReadOps2PendingVal = 0;
+ psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal = 0;
+ }
+ }
+ }
+
+ /*
+ NOTE: THIS MUST BE THE LAST THING WRITTEN TO THE TA COMMAND!
+ Set the ready for so the uKernel will process the command.
+ */
+ psTACmd->ui32CtrlFlags |= SGXMKIF_CMDTA_CTRLFLAGS_READY;
+
+#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));
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+ for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++)
+ {
+ IMG_UINT32 ui32ModifiedValue;
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i];
+
+ if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
+ (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
+ {
+ /*
+ * Init the ROpsComplete value to 0.
+ */
+ PDUMPCOMMENT("Init RT TA-SRC ROpsComplete\r\n", i);
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+ sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
+ 0,
+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+ /*
+ * Init the WOpsComplete value to 0.
+ */
+ PDUMPCOMMENT("Init RT TA-SRC 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 TA SrcSync %d ROpsPendingVal\r\n", i);
+
+ PDUMPMEM(&ui32ModifiedValue,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTASrcSyncs) +
+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ PDUMPCOMMENT("Modify TA SrcSync %d WOpPendingVal\r\n", i);
+
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTASrcSyncs) +
+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ }
+
+ for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++)
+ {
+ IMG_UINT32 ui32ModifiedValue;
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i];
+
+ if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
+ (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
+ {
+ /*
+ * Init the ROpsComplete value to 0.
+ */
+ PDUMPCOMMENT("Init RT TA-DST ROpsComplete\r\n", i);
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+ sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
+ 0,
+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+ /*
+ * Init the WOpsComplete value to 0.
+ */
+ PDUMPCOMMENT("Init RT TA-DST 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 TA DstSync %d WOpPendingVal\r\n", i);
+
+ PDUMPMEM(&ui32ModifiedValue,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTADstSyncs) +
+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ PDUMPCOMMENT("Modify TA DstSync %d ROpsPendingVal\r\n", i);
+
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTADstSyncs) +
+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ }
+
+ for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++)
+ {
+ IMG_UINT32 ui32ModifiedValue;
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i];
+
+ if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) &&
+ (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0))
+ {
+ /*
+ * Init the ROpsComplete value to 0.
+ */
+ PDUMPCOMMENT("Init RT 3D-SRC ROpsComplete\r\n", i);
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+ sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
+ 0,
+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+ /*
+ * Init the WOpsComplete value to 0.
+ */
+ PDUMPCOMMENT("Init RT 3D-SRC 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 3D SrcSync %d ROpsPendingVal\r\n", i);
+
+ PDUMPMEM(&ui32ModifiedValue,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, as3DSrcSyncs) +
+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ PDUMPCOMMENT("Modify 3D SrcSync %d WOpPendingVal\r\n", i);
+
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, as3DSrcSyncs) +
+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ }
+#else/* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */
+ 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))
+ {
+ /*
+ * Init the ROpsComplete value to 0.
+ */
+ PDUMPCOMMENT("Init RT ROpsComplete\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
+ sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete),
+ 0,
+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
+ /*
+ * Init the WOpsComplete value to 0.
+ */
+ 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));
+ /*
+ * Init the ROps2Complete value to 0.
+ */
+ PDUMPCOMMENT("Init RT WOpsComplete\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psSyncInfo->psSyncDataMemInfoKM,
+ offsetof(PVRSRV_SYNC_DATA, ui32ReadOps2Complete),
+ sizeof(psSyncInfo->psSyncData->ui32ReadOps2Complete),
+ 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));
+ }
+
+ if (psCCBKick->hTASyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo;
+
+ PDUMPCOMMENT("Modify TA/TQ ROpPendingVal\r\n");
+
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, ui32TATQSyncReadOpsPendingVal),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
+ }
+
+ if (psCCBKick->h3DSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo;
+
+ PDUMPCOMMENT("Modify 3D/TQ ROpPendingVal\r\n");
+
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, ui323DTQSyncReadOpsPendingVal),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
+ }
+
+#endif/* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */
+
+ for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++)
+ {
+#if !defined(SUPPORT_SGX_NEW_STATUS_VALS)
+ 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 + (IMG_UINT32)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)
+ 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 + (IMG_UINT32)offsetof(SGXMKIF_CMDTA_SHARED, sCtl3DStatusInfo[i].ui32StatusValue),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+#endif
+ }
+ }
+#endif /* defined(PDUMP) */
+
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_CMD_END,
+ KICK_TOKEN_DOKICK);
+
+ eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TA, &psCCBKick->sCommand, KERNEL_ID, 0, hDevMemContext, psCCBKick->bLastInScene);
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0)
+ {
+ for (i=0; i < psCCBKick->ui32NumDstSyncObjects; i++)
+ {
+ /* Client will retry, so undo the write ops pending increment done above. */
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i];
+
+ if (psSyncInfo)
+ {
+ psSyncInfo->psSyncData->ui32WriteOpsPending--;
+#if defined(PDUMP)
+ if (PDumpIsCaptureFrameKM())
+ {
+ psSyncInfo->psSyncData->ui32LastOpDumpVal--;
+ }
+#endif
+ }
+ }
+ }
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+ for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i];
+ psSyncInfo->psSyncData->ui32ReadOpsPending--;
+ }
+ for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i];
+ psSyncInfo->psSyncData->ui32WriteOpsPending--;
+ }
+ for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i];
+ psSyncInfo->psSyncData->ui32ReadOpsPending--;
+ }
+#else/* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */
+ for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i];
+ psSyncInfo->psSyncData->ui32ReadOpsPending--;
+ }
+#endif/* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */
+
+ if (psCCBKick->hTA3DSyncInfo)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo;
+ psSyncInfo->psSyncData->ui32ReadOpsPending--;
+ }
+
+ if (psCCBKick->hTASyncInfo)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo;
+ psSyncInfo->psSyncData->ui32ReadOpsPending--;
+ }
+
+ if (psCCBKick->h3DSyncInfo)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo;
+ psSyncInfo->psSyncData->ui32ReadOpsPending--;
+ }
+
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT,
+ KICK_TOKEN_DOKICK);
+ return eError;
+ }
+ else if (PVRSRV_OK != eError)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: SGXScheduleCCBCommandKM failed."));
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT,
+ KICK_TOKEN_DOKICK);
+ return eError;
+ }
+
+
+#if defined(NO_HARDWARE)
+
+
+ /* TA/3D dependency */
+ 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;
+ }
+
+ /* Copy status vals over */
+ 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;
+ /* derive offset into meminfo and write the status value */
+ *(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
+ }
+
+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS)
+ /* SRC and DST dependencies */
+ for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i];
+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
+ }
+ for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i];
+ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ }
+ for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i];
+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
+ }
+#else/* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */
+ /* texture dependencies */
+ for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i];
+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
+ }
+#endif/* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */
+
+ 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;
+
+ for (i=0; i<psCCBKick->ui32NumDstSyncObjects; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i];
+ if (psSyncInfo)
+ psSyncInfo->psSyncData->ui32WriteOpsComplete = psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal+1;
+ }
+ }
+
+ /* Copy status vals over */
+ 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;
+ /* derive offset into meminfo and write the status value */
+ *(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
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT,
+ KICK_TOKEN_DOKICK);
+ return eError;
+}
+
+/******************************************************************************
+ End of file (sgxkick.c)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/devices/sgx/sgxpower.c b/pvr-source/services4/srvkm/devices/sgx/sgxpower.c
new file mode 100644
index 0000000..2acd28d
--- /dev/null
+++ b/pvr-source/services4/srvkm/devices/sgx/sgxpower.c
@@ -0,0 +1,630 @@
+/*************************************************************************/ /*!
+@Title Device specific power routines
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+
+#include "sgxdefs.h"
+#include "services_headers.h"
+#include "sgxapi_km.h"
+#include "sgx_mkif_km.h"
+#include "sgxutils.h"
+#include "pdump_km.h"
+
+int powering_down = 0;
+
+
+#if defined(SUPPORT_HW_RECOVERY)
+static PVRSRV_ERROR SGXAddTimer(PVRSRV_DEVICE_NODE *psDeviceNode,
+ SGX_TIMING_INFORMATION *psSGXTimingInfo,
+ IMG_HANDLE *phTimer)
+{
+ /*
+ Install timer callback for HW recovery at 50 times lower
+ frequency than the microkernel timer.
+ */
+ *phTimer = OSAddTimer(SGXOSTimer, psDeviceNode,
+ 1000 * 50 / psSGXTimingInfo->ui32uKernelFreq);
+ if(*phTimer == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXAddTimer : Failed to register timer callback function"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ return PVRSRV_OK;
+}
+#endif /* SUPPORT_HW_RECOVERY*/
+
+
+/*!
+******************************************************************************
+
+ @Function SGXUpdateTimingInfo
+
+ @Description
+
+ Derives the microkernel timing info from the system-supplied values
+
+ @Input psDeviceNode : SGX Device node
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+static PVRSRV_ERROR SGXUpdateTimingInfo(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)
+ {
+ /*
+ The ukernel timer frequency has changed.
+ */
+ IMG_HANDLE hNewTimer;
+
+ eError = SGXAddTimer(psDeviceNode, psSGXTimingInfo, &hNewTimer);
+ if (eError == PVRSRV_OK)
+ {
+ eError = OSRemoveTimer(psDevInfo->hTimer);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXUpdateTimingInfo: Failed to remove timer"));
+ }
+ psDevInfo->hTimer = hNewTimer;
+ }
+ else
+ {
+ /* Failed to allocate the new timer, leave the old one. */
+ }
+ }
+ }
+ else
+ {
+ eError = SGXAddTimer(psDeviceNode, psSGXTimingInfo, &psDevInfo->hTimer);
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+
+ psDevInfo->psSGXHostCtl->ui32HWRecoverySampleRate =
+ psSGXTimingInfo->ui32uKernelFreq / psSGXTimingInfo->ui32HWRecoveryFreq;
+ }
+#endif /* SUPPORT_HW_RECOVERY*/
+
+ /* Copy the SGX clock speed for use in the kernel */
+ psDevInfo->ui32CoreClockSpeed = psSGXTimingInfo->ui32CoreClockSpeed;
+ psDevInfo->ui32uKernelTimerClock = psSGXTimingInfo->ui32CoreClockSpeed / psSGXTimingInfo->ui32uKernelFreq;
+
+ /* FIXME: no need to duplicate - remove it from psDevInfo */
+ psDevInfo->psSGXHostCtl->ui32uKernelTimerClock = psDevInfo->ui32uKernelTimerClock;
+#if defined(PDUMP)
+ PDUMPCOMMENT("Host Control - Microkernel clock");
+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, ui32uKernelTimerClock),
+ sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+#endif /* PDUMP */
+
+ if (psSGXTimingInfo->bEnableActivePM)
+ {
+ ui32ActivePowManSampleRate =
+ psSGXTimingInfo->ui32uKernelFreq * psSGXTimingInfo->ui32ActivePowManLatencyms / 1000;
+ /*
+ ui32ActivePowerCounter has the value 0 when SGX is not idle.
+ When SGX becomes idle, the value of ui32ActivePowerCounter is changed from 0 to ui32ActivePowManSampleRate.
+ The ukernel timer routine decrements the value of ui32ActivePowerCounter if it is not 0.
+ When the ukernel timer decrements ui32ActivePowerCounter from 1 to 0, the ukernel timer will
+ request power down.
+ Therefore the minimum value of ui32ActivePowManSampleRate is 1.
+ */
+ ui32ActivePowManSampleRate += 1;
+ }
+ else
+ {
+ ui32ActivePowManSampleRate = 0;
+ }
+
+ psDevInfo->psSGXHostCtl->ui32ActivePowManSampleRate = ui32ActivePowManSampleRate;
+#if defined(PDUMP)
+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, ui32ActivePowManSampleRate),
+ sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+#endif /* PDUMP */
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SGXStartTimer
+
+ @Description
+
+ Start the microkernel timer
+
+ @Input psDevInfo : SGX Device Info
+
+ @Return IMG_VOID :
+
+******************************************************************************/
+static IMG_VOID SGXStartTimer(PVRSRV_SGXDEV_INFO *psDevInfo)
+{
+ #if defined(SUPPORT_HW_RECOVERY)
+ PVRSRV_ERROR eError;
+
+ eError = OSEnableTimer(psDevInfo->hTimer);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXStartTimer : Failed to enable host timer"));
+ }
+ #else
+ PVR_UNREFERENCED_PARAMETER(psDevInfo);
+ #endif /* SUPPORT_HW_RECOVERY */
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SGXPollForClockGating
+
+ @Description
+
+ Wait until the SGX core clocks have gated.
+
+ @Input psDevInfo : SGX Device Info
+ @Input ui32Register : Offset of register to poll
+ @Input ui32Register : Value of register to poll for
+ @Input pszComment : Description of poll
+
+ @Return IMG_VOID :
+
+******************************************************************************/
+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)
+ PVR_ASSERT(psDevInfo != IMG_NULL);
+
+ /* PRQA S 0505 1 */ /* QAC does not like assert() */
+ if (PollForValueKM((IMG_UINT32 *)psDevInfo->pvRegsBaseKM + (ui32Register >> 2),
+ 0,
+ ui32RegisterValue,
+ MAX_HW_TIME_US,
+ MAX_HW_TIME_US/WAIT_TRY_COUNT,
+ IMG_FALSE) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXPollForClockGating: %s failed.", pszComment));
+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
+ PVR_DBG_BREAK;
+ }
+ #endif /* NO_HARDWARE */
+
+ PDUMPCOMMENT("%s", pszComment);
+ PDUMPREGPOL(SGX_PDUMPREG_NAME, ui32Register, 0, ui32RegisterValue, PDUMP_POLL_OPERATOR_EQUAL);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SGXPrePowerState
+
+ @Description
+
+ does necessary preparation before power state transition
+
+ @Input hDevHandle : SGX Device Node
+ @Input eNewPowerState : New power state
+ @Input eCurrentPowerState : Current power state
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR SGXPrePowerState (IMG_HANDLE hDevHandle,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState)
+{
+ if ((eNewPowerState != eCurrentPowerState) &&
+ (eNewPowerState != PVRSRV_DEV_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};
+ IMG_UINT32 ui32Core;
+ IMG_UINT32 ui32CoresEnabled;
+
+ #if defined(SUPPORT_HW_RECOVERY)
+ /* Disable timer callback for HW recovery */
+ eError = OSDisableTimer(psDevInfo->hTimer);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Failed to disable timer"));
+ return eError;
+ }
+ #endif /* SUPPORT_HW_RECOVERY */
+
+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF)
+ {
+ /* Request the ukernel to idle SGX and save its state. */
+ ui32PowerCmd = PVRSRV_POWERCMD_POWEROFF;
+ ui32CompleteStatus = PVRSRV_USSE_EDM_POWMAN_POWEROFF_COMPLETE;
+ PDUMPCOMMENT("SGX power off request");
+ }
+ else
+ {
+ /* Request the ukernel to idle SGX. */
+ ui32PowerCmd = PVRSRV_POWERCMD_IDLE;
+ ui32CompleteStatus = PVRSRV_USSE_EDM_POWMAN_IDLE_COMPLETE;
+ PDUMPCOMMENT("SGX idle request");
+ }
+
+ powering_down = 1;
+
+ sCommand.ui32Data[1] = ui32PowerCmd;
+
+ eError = SGXScheduleCCBCommand(psDeviceNode, SGXMKIF_CMD_POWER, &sCommand, KERNEL_ID, 0, IMG_NULL, IMG_FALSE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Failed to submit power down command"));
+ return eError;
+ }
+
+ /* Wait for the ukernel to complete processing. */
+ #if !defined(NO_HARDWARE)
+ if (PollForValueKM(&psDevInfo->psSGXHostCtl->ui32PowerStatus,
+ ui32CompleteStatus,
+ ui32CompleteStatus,
+ MAX_HW_TIME_US,
+ MAX_HW_TIME_US/WAIT_TRY_COUNT,
+ IMG_FALSE) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Wait for SGX ukernel power transition failed."));
+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
+ PVR_DBG_BREAK;
+ }
+ #endif /* NO_HARDWARE */
+
+ psDevInfo->bSGXIdle = IMG_TRUE;
+
+ #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,
+ 0,
+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+ #endif /* PDUMP */
+
+#if defined(SGX_FEATURE_MP)
+ ui32CoresEnabled = ((OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE) & EUR_CR_MASTER_CORE_ENABLE_MASK) >> EUR_CR_MASTER_CORE_ENABLE_SHIFT) + 1;
+#else
+ ui32CoresEnabled = 1;
+#endif
+
+ for (ui32Core = 0; ui32Core < ui32CoresEnabled; ui32Core++)
+ {
+ /* Wait for SGX clock gating. */
+ SGXPollForClockGating(psDevInfo,
+ SGX_MP_CORE_SELECT(psDevInfo->ui32ClkGateStatusReg, ui32Core),
+ psDevInfo->ui32ClkGateStatusMask,
+ "Wait for SGX clock gating");
+ }
+
+ #if defined(SGX_FEATURE_MP)
+ /* Wait for SGX master clock gating. */
+ SGXPollForClockGating(psDevInfo,
+ psDevInfo->ui32MasterClkGateStatusReg,
+ psDevInfo->ui32MasterClkGateStatusMask,
+ "Wait for SGX master clock gating");
+
+ SGXPollForClockGating(psDevInfo,
+ psDevInfo->ui32MasterClkGateStatus2Reg,
+ psDevInfo->ui32MasterClkGateStatus2Mask,
+ "Wait for SGX master clock gating (2)");
+ #endif /* SGX_FEATURE_MP */
+
+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF)
+ {
+ /* Finally, de-initialise some registers. */
+ eError = SGXDeinitialise(psDevInfo);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: SGXDeinitialise failed: %u", eError));
+ return eError;
+ }
+ }
+ }
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SGXPostPowerState
+
+ @Description
+
+ does necessary preparation after power state transition
+
+ @Input hDevHandle : SGX Device Node
+ @Input eNewPowerState : New power state
+ @Input eCurrentPowerState : Current power state
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR SGXPostPowerState (IMG_HANDLE hDevHandle,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState)
+{
+ if ((eNewPowerState != eCurrentPowerState) &&
+ (eCurrentPowerState != PVRSRV_DEV_POWER_STATE_ON))
+ {
+ PVRSRV_ERROR eError;
+ PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl;
+
+ /* Reset the power manager flags. */
+ psSGXHostCtl->ui32PowerStatus = 0;
+ #if defined(PDUMP)
+ PDUMPCOMMENT("Host Control - Reset power status");
+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, ui32PowerStatus),
+ sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));
+ #endif /* PDUMP */
+
+ if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF)
+ {
+ /*
+ Coming up from off, re-initialise SGX.
+ */
+
+ /*
+ Re-generate the timing data required by SGX.
+ */
+ eError = SGXUpdateTimingInfo(psDeviceNode);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXUpdateTimingInfo failed"));
+ return eError;
+ }
+
+ /*
+ Run the SGX init script.
+ */
+ eError = SGXInitialise(psDevInfo, IMG_FALSE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXInitialise failed"));
+ return eError;
+ }
+ powering_down = 0;
+ }
+ else
+ {
+ /*
+ Coming up from idle, restart the ukernel.
+ */
+ SGXMKIF_COMMAND sCommand = {0};
+
+ sCommand.ui32Data[1] = PVRSRV_POWERCMD_RESUME;
+ eError = SGXScheduleCCBCommand(psDeviceNode, SGXMKIF_CMD_POWER, &sCommand, ISR_ID, 0, IMG_NULL, IMG_FALSE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState failed to schedule CCB command: %u", eError));
+ return eError;
+ }
+ }
+
+ SGXStartTimer(psDevInfo);
+ }
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SGXPreClockSpeedChange
+
+ @Description
+
+ Does processing required before an SGX clock speed change.
+
+ @Input hDevHandle : SGX Device Node
+ @Input bIdleDevice : Whether the microkernel needs to be idled
+ @Input eCurrentPowerState : Power state of the device
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR SGXPreClockSpeedChange (IMG_HANDLE hDevHandle,
+ IMG_BOOL bIdleDevice,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+
+ PVR_UNREFERENCED_PARAMETER(psDevInfo);
+
+ if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON)
+ {
+ if (bIdleDevice)
+ {
+ /*
+ * Idle SGX.
+ */
+ PDUMPSUSPEND();
+
+ eError = SGXPrePowerState(hDevHandle, PVRSRV_DEV_POWER_STATE_IDLE,
+ PVRSRV_DEV_POWER_STATE_ON);
+
+ if (eError != PVRSRV_OK)
+ {
+ PDUMPRESUME();
+ return eError;
+ }
+ }
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE,"SGXPreClockSpeedChange: SGX clock speed was %uHz",
+ psDevInfo->ui32CoreClockSpeed));
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SGXPostClockSpeedChange
+
+ @Description
+
+ Does processing required after an SGX clock speed change.
+
+ @Input hDevHandle : SGX Device Node
+ @Input bIdleDevice : Whether the microkernel had been idled previously
+ @Input eCurrentPowerState : Power state of the device
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR SGXPostClockSpeedChange (IMG_HANDLE hDevHandle,
+ IMG_BOOL bIdleDevice,
+ PVRSRV_DEV_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_DEV_POWER_STATE_ON)
+ {
+ PVRSRV_ERROR eError;
+
+ /*
+ Re-generate the timing data required by SGX.
+ */
+ eError = SGXUpdateTimingInfo(psDeviceNode);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXUpdateTimingInfo failed"));
+ return eError;
+ }
+
+ if (bIdleDevice)
+ {
+ /*
+ * Resume SGX.
+ */
+ eError = SGXPostPowerState(hDevHandle, PVRSRV_DEV_POWER_STATE_ON,
+ PVRSRV_DEV_POWER_STATE_IDLE);
+
+ PDUMPRESUME();
+
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+ else
+ {
+ SGXStartTimer(psDevInfo);
+ }
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE,"SGXPostClockSpeedChange: SGX clock speed changed from %uHz to %uHz",
+ ui32OldClockSpeed, psDevInfo->ui32CoreClockSpeed));
+
+ return PVRSRV_OK;
+}
+
+
+/******************************************************************************
+ End of file (sgxpower.c)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/devices/sgx/sgxreset.c b/pvr-source/services4/srvkm/devices/sgx/sgxreset.c
new file mode 100644
index 0000000..dcdefae
--- /dev/null
+++ b/pvr-source/services4/srvkm/devices/sgx/sgxreset.c
@@ -0,0 +1,808 @@
+/*************************************************************************/ /*!
+@Title Device specific reset routines
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "sgxdefs.h"
+#include "sgxmmu.h"
+#include "services_headers.h"
+#include "sgxinfokm.h"
+#include "sgxconfig.h"
+#include "sgxutils.h"
+
+#include "pdump_km.h"
+
+
+/*!
+*******************************************************************************
+
+ @Function SGXInitClocks
+
+ @Description
+ Initialise the SGX clocks
+
+ @Input psDevInfo - device info. structure
+ @Input ui32PDUMPFlags - flags to control PDUMP output
+
+ @Return IMG_VOID
+
+******************************************************************************/
+IMG_VOID SGXInitClocks(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32PDUMPFlags)
+{
+ IMG_UINT32 ui32RegVal;
+
+#if !defined(PDUMP)
+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
+#endif /* PDUMP */
+
+ ui32RegVal = psDevInfo->ui32ClkGateCtl;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_CLKGATECTL, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_CLKGATECTL, ui32RegVal, ui32PDUMPFlags);
+
+#if defined(EUR_CR_CLKGATECTL2)
+ ui32RegVal = psDevInfo->ui32ClkGateCtl2;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_CLKGATECTL2, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_CLKGATECTL2, ui32RegVal, ui32PDUMPFlags);
+#endif
+}
+
+
+/*!
+*******************************************************************************
+
+ @Function SGXResetInitBIFContexts
+
+ @Description
+ Initialise the BIF memory contexts
+
+ @Input psDevInfo - SGX Device Info
+
+ @Return IMG_VOID
+
+******************************************************************************/
+static IMG_VOID SGXResetInitBIFContexts(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32PDUMPFlags)
+{
+ IMG_UINT32 ui32RegVal;
+
+#if !defined(PDUMP)
+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
+#endif /* PDUMP */
+
+ ui32RegVal = 0;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
+
+#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the BIF bank settings\r\n");
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK_SET, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_BANK_SET, ui32RegVal, ui32PDUMPFlags);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_BANK0, ui32RegVal, ui32PDUMPFlags);
+#endif /* SGX_FEATURE_MULTIPLE_MEM_CONTEXTS */
+
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the BIF directory list\r\n");
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal, ui32PDUMPFlags);
+
+#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+ {
+ IMG_UINT32 ui32DirList, ui32DirListReg;
+
+ for (ui32DirList = 1;
+ ui32DirList < SGX_FEATURE_BIF_NUM_DIRLISTS;
+ ui32DirList++)
+ {
+ ui32DirListReg = EUR_CR_BIF_DIR_LIST_BASE1 + 4 * (ui32DirList - 1);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32DirListReg, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, ui32DirListReg, ui32RegVal, ui32PDUMPFlags);
+ }
+ }
+#endif /* SGX_FEATURE_MULTIPLE_MEM_CONTEXTS */
+}
+
+
+/*!
+*******************************************************************************
+
+ @Function SGXResetSetupBIFContexts
+
+ @Description
+ Configure the BIF for the EDM context
+
+ @Input psDevInfo - SGX Device Info
+
+ @Return IMG_VOID
+
+******************************************************************************/
+static IMG_VOID SGXResetSetupBIFContexts(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32PDUMPFlags)
+{
+ IMG_UINT32 ui32RegVal;
+
+#if !defined(PDUMP)
+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
+#endif /* PDUMP */
+
+ #if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+ /* Set up EDM for bank 0 to point at kernel context */
+ ui32RegVal = (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT);
+
+ #if defined(SGX_FEATURE_2D_HARDWARE) && !defined(SGX_FEATURE_PTLA)
+ /* Set up 2D core for bank 0 to point at kernel context */
+ ui32RegVal |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_2D_SHIFT);
+ #endif /* SGX_FEATURE_2D_HARDWARE */
+
+ #if defined(FIX_HW_BRN_23410)
+ /* Set up TA core for bank 0 to point at kernel context to guarantee it is a valid context */
+ ui32RegVal |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_TA_SHIFT);
+ #endif /* FIX_HW_BRN_23410 */
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32RegVal);
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Set up EDM requestor page table in BIF\r\n");
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_BANK0, ui32RegVal, ui32PDUMPFlags);
+ #endif /* defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) */
+
+ {
+ IMG_UINT32 ui32EDMDirListReg;
+
+ /* Set up EDM context with kernel page directory */
+ #if (SGX_BIF_DIR_LIST_INDEX_EDM == 0)
+ ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE0;
+ #else
+ /* Bases 0 and 1 are not necessarily contiguous */
+ ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE1 + 4 * (SGX_BIF_DIR_LIST_INDEX_EDM - 1);
+ #endif /* SGX_BIF_DIR_LIST_INDEX_EDM */
+
+ ui32RegVal = psDevInfo->sKernelPDDevPAddr.uiAddr >> SGX_MMU_PDE_ADDR_ALIGNSHIFT;
+
+#if defined(FIX_HW_BRN_28011)
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal);
+ PDUMPPDREGWITHFLAGS(&psDevInfo->sMMUAttrib, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG);
+#endif
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32EDMDirListReg, ui32RegVal);
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the EDM's directory list base\r\n");
+ PDUMPPDREGWITHFLAGS(&psDevInfo->sMMUAttrib, ui32EDMDirListReg, ui32RegVal, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG);
+ }
+}
+
+
+/*!
+*******************************************************************************
+
+ @Function SGXResetSleep
+
+ @Description
+
+ Sleep for a short time to allow reset register writes to complete.
+ Required because no status registers are available to poll on.
+
+ @Input psDevInfo - SGX Device Info
+ @Input ui32PDUMPFlags - flags to control PDUMP output
+ @Input bPDump - Pdump the sleep
+
+ @Return Nothing
+
+******************************************************************************/
+static IMG_VOID SGXResetSleep(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32PDUMPFlags,
+ IMG_BOOL bPDump)
+{
+#if defined(PDUMP) || defined(EMULATOR)
+ IMG_UINT32 ui32ReadRegister;
+
+ #if defined(SGX_FEATURE_MP)
+ ui32ReadRegister = EUR_CR_MASTER_SOFT_RESET;
+ #else
+ ui32ReadRegister = EUR_CR_SOFT_RESET;
+ #endif /* SGX_FEATURE_MP */
+#endif
+
+#if !defined(PDUMP)
+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
+#endif /* PDUMP */
+
+ /* Sleep for 100 SGX clocks */
+ SGXWaitClocks(psDevInfo, 100);
+ if (bPDump)
+ {
+ PDUMPIDLWITHFLAGS(30, ui32PDUMPFlags);
+#if defined(PDUMP)
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Read back to flush the register writes\r\n");
+ PDumpRegRead(SGX_PDUMPREG_NAME, ui32ReadRegister, ui32PDUMPFlags);
+#endif
+ }
+
+#if defined(EMULATOR)
+ /*
+ Read a register to make sure we wait long enough on the emulator...
+ */
+ OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32ReadRegister);
+#endif
+}
+
+
+#if !defined(SGX_FEATURE_MP)
+/*!
+*******************************************************************************
+
+ @Function SGXResetSoftReset
+
+ @Description
+
+ Write to the SGX soft reset register.
+
+ @Input psDevInfo - SGX Device Info
+ @Input bResetBIF - Include the BIF in the soft reset
+ @Input ui32PDUMPFlags - flags to control PDUMP output
+ @Input bPDump - Pdump the sleep
+
+ @Return Nothing
+
+******************************************************************************/
+static IMG_VOID SGXResetSoftReset(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_BOOL bResetBIF,
+ IMG_UINT32 ui32PDUMPFlags,
+ IMG_BOOL bPDump)
+{
+ IMG_UINT32 ui32SoftResetRegVal;
+
+ ui32SoftResetRegVal =
+ /* add common reset bits: */
+ 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;
+
+/* add conditional reset bits: */
+#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_TCU_L2_RESET_MASK)
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TCU_L2_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(EUR_CR_SOFT_RESET_DCU_L2_RESET_MASK)
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_DCU_L2_RESET_MASK;
+#endif
+#if defined(EUR_CR_SOFT_RESET_DCU_L0L1_RESET_MASK)
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_DCU_L0L1_RESET_MASK;
+#endif
+
+#if !defined(PDUMP)
+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
+#endif /* PDUMP */
+
+ if (bResetBIF)
+ {
+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_BIF_RESET_MASK;
+ }
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32SoftResetRegVal);
+ if (bPDump)
+ {
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_SOFT_RESET, ui32SoftResetRegVal, ui32PDUMPFlags);
+ }
+}
+
+
+/*!
+*******************************************************************************
+
+ @Function SGXResetInvalDC
+
+ @Description
+
+ Invalidate the BIF Directory Cache and wait for the operation to complete.
+
+ @Input psDevInfo - SGX Device Info
+ @Input ui32PDUMPFlags - flags to control PDUMP output
+
+ @Return Nothing
+
+******************************************************************************/
+static IMG_VOID SGXResetInvalDC(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32PDUMPFlags,
+ IMG_BOOL bPDump)
+{
+ IMG_UINT32 ui32RegVal;
+
+ /* Invalidate BIF Directory cache. */
+#if defined(EUR_CR_BIF_CTRL_INVAL)
+ ui32RegVal = EUR_CR_BIF_CTRL_INVAL_ALL_MASK;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL_INVAL, ui32RegVal);
+ if (bPDump)
+ {
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL_INVAL, ui32RegVal, ui32PDUMPFlags);
+ }
+#else
+ ui32RegVal = EUR_CR_BIF_CTRL_INVALDC_MASK;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
+ if (bPDump)
+ {
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
+ }
+
+ ui32RegVal = 0;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
+ if (bPDump)
+ {
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
+ }
+#endif
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, bPDump);
+
+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+ {
+ /*
+ Wait for the DC invalidate to complete - indicated by
+ outstanding reads reaching zero.
+ */
+ 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,
+ MAX_HW_TIME_US/WAIT_TRY_COUNT,
+ IMG_FALSE) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"Wait for DC invalidate failed."));
+ PVR_DBG_BREAK;
+ }
+
+ if (bPDump)
+ {
+ PDUMPREGPOLWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_MEM_REQ_STAT, 0, EUR_CR_BIF_MEM_REQ_STAT_READS_MASK, ui32PDUMPFlags, PDUMP_POLL_OPERATOR_EQUAL);
+ }
+ }
+#endif /* SGX_FEATURE_MULTIPLE_MEM_CONTEXTS */
+}
+#endif /* SGX_FEATURE_MP */
+
+
+/*!
+*******************************************************************************
+
+ @Function SGXReset
+
+ @Description
+
+ Reset chip
+
+ @Input psDevInfo - device info. structure
+ @Input bHardwareRecovery - true if recovering powered hardware,
+ false if powering up
+ @Input ui32PDUMPFlags - flags to control PDUMP output
+
+ @Return IMG_VOID
+
+******************************************************************************/
+IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_BOOL bHardwareRecovery,
+ IMG_UINT32 ui32PDUMPFlags)
+#if !defined(SGX_FEATURE_MP)
+{
+ 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(PDUMP)
+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
+#endif /* PDUMP */
+
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Start of SGX reset sequence\r\n");
+
+#if defined(FIX_HW_BRN_23944)
+ /* Pause the BIF. */
+ ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
+
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT);
+ if (ui32RegVal & ui32BifFaultMask)
+ {
+ /* Page fault needs to be cleared before resetting the BIF. */
+ ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK | EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, 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(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
+
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+ }
+#endif /* defined(FIX_HW_BRN_23944) */
+
+ /* Reset all including BIF */
+ SGXResetSoftReset(psDevInfo, IMG_TRUE, ui32PDUMPFlags, IMG_TRUE);
+
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+ /*
+ Initialise the BIF state.
+ */
+#if defined(SGX_FEATURE_36BIT_MMU)
+ /* enable 36bit addressing mode if the MMU supports it*/
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_36BIT_ADDRESSING, EUR_CR_BIF_36BIT_ADDRESSING_ENABLE_MASK);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_36BIT_ADDRESSING, EUR_CR_BIF_36BIT_ADDRESSING_ENABLE_MASK, ui32PDUMPFlags);
+#endif
+
+ SGXResetInitBIFContexts(psDevInfo, ui32PDUMPFlags);
+
+#if defined(EUR_CR_BIF_MEM_ARB_CONFIG)
+ /*
+ Initialise the memory arbiter to its default state
+ */
+ ui32RegVal = (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, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_MEM_ARB_CONFIG, ui32RegVal, ui32PDUMPFlags);
+#endif /* EUR_CR_BIF_MEM_ARB_CONFIG */
+
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+ #if defined(SGX_BYPASS_SYSTEM_CACHE)
+ /* set the SLC to bypass all accesses */
+ ui32RegVal = MNE_CR_CTRL_BYPASS_ALL_MASK;
+ #else
+ #if defined(FIX_HW_BRN_26620)
+ ui32RegVal = 0;
+ #else
+ /* set the SLC to bypass cache-coherent accesses */
+ ui32RegVal = MNE_CR_CTRL_BYP_CC_MASK;
+ #endif
+ #if defined(FIX_HW_BRN_34028)
+ /* Bypass the MNE for the USEC requester */
+ ui32RegVal |= (8 << MNE_CR_CTRL_BYPASS_SHIFT);
+ #endif
+ #endif /* SGX_BYPASS_SYSTEM_CACHE */
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, MNE_CR_CTRL, ui32RegVal);
+ PDUMPREG(SGX_PDUMPREG_NAME, MNE_CR_CTRL, ui32RegVal);
+#endif /* SGX_FEATURE_SYSTEM_CACHE */
+
+ if (bHardwareRecovery)
+ {
+ /*
+ Set all requestors to the dummy PD which forces all memory
+ accesses to page fault.
+ This enables us to flush out BIF requests from parts of SGX
+ which do not have their own soft reset.
+ Note: sBIFResetPDDevPAddr.uiAddr is a relative address (2GB max)
+ MSB is the bus master flag; 1 == enabled
+ */
+ ui32RegVal = (IMG_UINT32)psDevInfo->sBIFResetPDDevPAddr.uiAddr;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal);
+
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
+
+ /* Bring BIF out of reset. */
+ SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_TRUE);
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
+
+ SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
+
+ /*
+ Check for a page fault from parts of SGX which do not have a reset.
+ */
+ 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;
+ }
+
+ /*
+ There is a page fault, so reset the BIF again, map in the dummy page,
+ bring the BIF up and invalidate the Directory Cache.
+ */
+ 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;
+
+ /* Put the BIF into reset. */
+ SGXResetSoftReset(psDevInfo, IMG_TRUE, ui32PDUMPFlags, IMG_FALSE);
+
+ /* Map in the dummy page. */
+ psDevInfo->pui32BIFResetPD[ui32PDIndex] = (psDevInfo->sBIFResetPTDevPAddr.uiAddr
+ >>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PDE_PAGE_SIZE_4K
+ | SGX_MMU_PDE_VALID;
+ psDevInfo->pui32BIFResetPT[ui32PTIndex] = (psDevInfo->sBIFResetPageDevPAddr.uiAddr
+ >>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
+ | SGX_MMU_PTE_VALID;
+
+ /* Clear outstanding events. */
+ 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);
+
+ /* Bring the BIF out of reset. */
+ SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_FALSE);
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
+
+ /* Invalidate Directory Cache. */
+ SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
+
+ /* Unmap the dummy page and try again. */
+ psDevInfo->pui32BIFResetPD[ui32PDIndex] = 0;
+ psDevInfo->pui32BIFResetPT[ui32PTIndex] = 0;
+ }
+ }
+ else
+ {
+ /* Bring BIF out of reset. */
+ SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_TRUE);
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
+ }
+
+ /*
+ Initialise the BIF memory contexts before bringing the rest of SGX out of reset.
+ */
+ SGXResetSetupBIFContexts(psDevInfo, ui32PDUMPFlags);
+
+#if defined(SGX_FEATURE_2D_HARDWARE) && !defined(SGX_FEATURE_PTLA)
+ /* check that the heap base has the right alignment (1Mb) */
+ #if ((SGX_2D_HEAP_BASE & ~EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK) != 0)
+ #error "SGXReset: SGX_2D_HEAP_BASE doesn't match EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK alignment"
+ #endif
+ /* Set up 2D requestor base */
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_TWOD_REQ_BASE, SGX_2D_HEAP_BASE);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_TWOD_REQ_BASE, SGX_2D_HEAP_BASE, ui32PDUMPFlags);
+#endif
+
+ /* Invalidate BIF Directory cache. */
+ SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+ PVR_DPF((PVR_DBG_MESSAGE,"Soft Reset of SGX"));
+
+ /* Take chip out of reset */
+ ui32RegVal = 0;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_SOFT_RESET, ui32RegVal, ui32PDUMPFlags);
+
+ /* wait a bit */
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "End of SGX reset sequence\r\n");
+}
+
+#else
+
+{
+ IMG_UINT32 ui32RegVal;
+
+ PVR_UNREFERENCED_PARAMETER(bHardwareRecovery);
+
+#if !defined(PDUMP)
+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
+#endif /* PDUMP */
+
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Start of SGX MP reset sequence\r\n");
+
+ /* Put hydra into soft reset */
+ ui32RegVal = EUR_CR_MASTER_SOFT_RESET_BIF_RESET_MASK |
+ EUR_CR_MASTER_SOFT_RESET_IPF_RESET_MASK |
+ EUR_CR_MASTER_SOFT_RESET_DPM_RESET_MASK |
+ EUR_CR_MASTER_SOFT_RESET_VDM_RESET_MASK;
+
+ if (bHardwareRecovery)
+ {
+ ui32RegVal |= EUR_CR_MASTER_SOFT_RESET_MCI_RESET_MASK;
+ }
+
+#if defined(SGX_FEATURE_PTLA)
+ ui32RegVal |= EUR_CR_MASTER_SOFT_RESET_PTLA_RESET_MASK;
+#endif
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+ ui32RegVal |= EUR_CR_MASTER_SOFT_RESET_SLC_RESET_MASK;
+#endif
+
+ /* Hard reset the slave cores */
+ ui32RegVal |= EUR_CR_MASTER_SOFT_RESET_CORE_RESET_MASK(0) |
+ EUR_CR_MASTER_SOFT_RESET_CORE_RESET_MASK(1) |
+ EUR_CR_MASTER_SOFT_RESET_CORE_RESET_MASK(2) |
+ EUR_CR_MASTER_SOFT_RESET_CORE_RESET_MASK(3);
+
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SOFT_RESET, ui32RegVal);
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Soft reset hydra partition, hard reset the cores\r\n");
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SOFT_RESET, ui32RegVal, ui32PDUMPFlags);
+
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+ ui32RegVal = 0;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BIF_CTRL, ui32RegVal);
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the hydra BIF control\r\n");
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
+
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+ #if defined(SGX_BYPASS_SYSTEM_CACHE)
+ ui32RegVal = EUR_CR_MASTER_SLC_CTRL_BYPASS_ALL_MASK;
+ #else
+ ui32RegVal = EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ0_MASK |
+ #if defined(FIX_HW_BRN_30954)
+ EUR_CR_MASTER_SLC_CTRL_DISABLE_REORDERING_MASK |
+ #endif
+ #if defined(PVR_SLC_8KB_ADDRESS_MODE)
+ (4 << EUR_CR_MASTER_SLC_CTRL_ADDR_DECODE_MODE_SHIFT) |
+ #endif
+ #if defined(FIX_HW_BRN_33809)
+ (2 << EUR_CR_MASTER_SLC_CTRL_ADDR_DECODE_MODE_SHIFT) |
+ #endif
+ (0xC << EUR_CR_MASTER_SLC_CTRL_ARB_PAGE_SIZE_SHIFT);
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SLC_CTRL, ui32RegVal);
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the hydra SLC control\r\n");
+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SLC_CTRL, ui32RegVal);
+
+ ui32RegVal = EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_MASK;
+ #if defined(FIX_HW_BRN_31620)
+ ui32RegVal |= EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_MMU_MASK;
+ #endif
+ #if defined(FIX_HW_BRN_31195)
+ ui32RegVal |= EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE0_MASK |
+ EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE1_MASK |
+ EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE2_MASK |
+ EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE3_MASK |
+ EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TA_MASK;
+ #endif
+ #endif /* SGX_BYPASS_SYSTEM_CACHE */
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SLC_CTRL_BYPASS, ui32RegVal);
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the hydra SLC bypass control\r\n");
+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SLC_CTRL_BYPASS, ui32RegVal);
+#endif /* SGX_FEATURE_SYSTEM_CACHE */
+
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+ /* Remove the resets */
+ ui32RegVal = 0;
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SOFT_RESET, ui32RegVal);
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Remove the resets from all of SGX\r\n");
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SOFT_RESET, ui32RegVal, ui32PDUMPFlags);
+
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Turn on the slave cores' clock gating\r\n");
+ SGXInitClocks(psDevInfo, ui32PDUMPFlags);
+
+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
+
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the slave BIFs\r\n");
+
+#if defined(FIX_HW_BRN_31278) || defined(FIX_HW_BRN_31620) || defined(FIX_HW_BRN_31671) || defined(FIX_HW_BRN_32085)
+ #if defined(FIX_HW_BRN_31278) || defined(FIX_HW_BRN_32085)
+ /* disable prefetch */
+ ui32RegVal = (1<<EUR_CR_MASTER_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT);
+ #else
+ ui32RegVal = (1<<EUR_CR_MASTER_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT) | EUR_CR_MASTER_BIF_MMU_CTRL_PREFETCHING_ON_MASK;
+ #endif
+ #if !defined(FIX_HW_BRN_31620) && !defined(FIX_HW_BRN_31671)
+ /* enable the DC TLB */
+ ui32RegVal |= EUR_CR_MASTER_BIF_MMU_CTRL_ENABLE_DC_TLB_MASK;
+ #endif
+
+ /* Master bank */
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BIF_MMU_CTRL, ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_BIF_MMU_CTRL, ui32RegVal, ui32PDUMPFlags);
+
+ #if defined(FIX_HW_BRN_31278) || defined(FIX_HW_BRN_32085)
+ /* disable prefetch */
+ ui32RegVal = (1<<EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT);
+ #else
+ ui32RegVal = (1<<EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT) | EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_MASK;
+ #endif
+ #if !defined(FIX_HW_BRN_31620) && !defined(FIX_HW_BRN_31671)
+ /* enable the DC TLB */
+ ui32RegVal |= EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_MASK;
+ #endif
+
+ /* Per-core */
+ {
+ IMG_UINT32 ui32Core;
+
+ for (ui32Core=0;ui32Core<SGX_FEATURE_MP_CORE_COUNT;ui32Core++)
+ {
+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BIF_MMU_CTRL, ui32Core), ui32RegVal);
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_BIF_MMU_CTRL, ui32Core), ui32RegVal, ui32PDUMPFlags);
+ }
+ }
+#endif
+
+ SGXResetInitBIFContexts(psDevInfo, ui32PDUMPFlags);
+ SGXResetSetupBIFContexts(psDevInfo, ui32PDUMPFlags);
+
+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "End of SGX MP reset sequence\r\n");
+}
+#endif /* SGX_FEATURE_MP */
+
+
+/******************************************************************************
+ End of file (sgxreset.c)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/devices/sgx/sgxtransfer.c b/pvr-source/services4/srvkm/devices/sgx/sgxtransfer.c
new file mode 100644
index 0000000..81f3b07
--- /dev/null
+++ b/pvr-source/services4/srvkm/devices/sgx/sgxtransfer.c
@@ -0,0 +1,814 @@
+/*************************************************************************/ /*!
+@Title Device specific transfer queue routines
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#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 "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"
+#include "ttrace.h"
+
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK_KM *psKick)
+#else
+IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK *psKick)
+#endif
+{
+ 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;
+ IMG_UINT32 loop;
+ IMG_HANDLE hDevMemContext = IMG_NULL;
+ IMG_BOOL abSrcSyncEnable[SGX_MAX_TRANSFER_SYNC_OPS];
+ IMG_UINT32 ui32RealSrcSyncNum = 0;
+ IMG_BOOL abDstSyncEnable[SGX_MAX_TRANSFER_SYNC_OPS];
+ IMG_UINT32 ui32RealDstSyncNum = 0;
+
+
+#if defined(PDUMP)
+ IMG_BOOL bPersistentProcess = IMG_FALSE;
+ /*
+ * For persistent processes, the HW kicks should not go into the
+ * extended init phase; only keep memory transactions from the
+ * window system which are necessary to run the client app.
+ */
+ {
+ PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+ if(psPerProc != IMG_NULL)
+ {
+ bPersistentProcess = psPerProc->bPDumpPersistent;
+ }
+ }
+#endif /* PDUMP */
+#if defined(FIX_HW_BRN_31620)
+ hDevMemContext = psKick->hDevMemContext;
+#endif
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_ENTER, TRANSFER_TOKEN_SUBMIT);
+
+ for (loop = 0; loop < SGX_MAX_TRANSFER_SYNC_OPS; loop++)
+ {
+ abSrcSyncEnable[loop] = IMG_TRUE;
+ abDstSyncEnable[loop] = IMG_TRUE;
+ }
+
+ if (!CCB_OFFSET_IS_VALID(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: Invalid CCB offset"));
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT,
+ TRANSFER_TOKEN_SUBMIT);
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ /* override QAC warning about stricter alignment */
+ /* PRQA S 3305 1 */
+ psSharedTransferCmd = CCB_DATA_FROM_OFFSET(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset);
+
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CMD_START, TRANSFER_TOKEN_SUBMIT);
+ PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CCB,
+ TRANSFER_TOKEN_CCB_OFFSET, psKick->ui32SharedCmdCCBOffset);
+
+ if (psKick->hTASyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_TA_SYNC,
+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+ 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;
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_3D_SYNC,
+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+ 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;
+ }
+
+ /* filter out multiple occurrences of the same sync object from srcs or dests
+ * note : the same sync can still be used to synchronize both src and dst.
+ */
+ for (loop = 0; loop < MIN(SGX_MAX_TRANSFER_SYNC_OPS, psKick->ui32NumSrcSync); loop++)
+ {
+ IMG_UINT32 i;
+
+ PVRSRV_KERNEL_SYNC_INFO * psMySyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop];
+
+ for (i = 0; i < loop; i++)
+ {
+ if (abSrcSyncEnable[i])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i];
+
+ if (psSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr == psMySyncInfo->sWriteOpsCompleteDevVAddr.uiAddr)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "SGXSubmitTransferKM : Same src synchronized multiple times!"));
+ abSrcSyncEnable[loop] = IMG_FALSE;
+ break;
+ }
+ }
+ }
+ if (abSrcSyncEnable[loop])
+ {
+ ui32RealSrcSyncNum++;
+ }
+ }
+ for (loop = 0; loop < MIN(SGX_MAX_TRANSFER_SYNC_OPS, psKick->ui32NumDstSync); loop++)
+ {
+ IMG_UINT32 i;
+
+ PVRSRV_KERNEL_SYNC_INFO * psMySyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop];
+
+ for (i = 0; i < loop; i++)
+ {
+ if (abDstSyncEnable[i])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[i];
+
+ if (psSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr == psMySyncInfo->sWriteOpsCompleteDevVAddr.uiAddr)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "SGXSubmitTransferKM : Same dst synchronized multiple times!"));
+ abDstSyncEnable[loop] = IMG_FALSE;
+ break;
+ }
+ }
+ }
+ if (abDstSyncEnable[loop])
+ {
+ ui32RealDstSyncNum++;
+ }
+ }
+
+ psSharedTransferCmd->ui32NumSrcSyncs = ui32RealSrcSyncNum;
+ psSharedTransferCmd->ui32NumDstSyncs = ui32RealDstSyncNum;
+
+ if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL)
+ {
+ IMG_UINT32 i = 0;
+
+ for (loop = 0; loop < psKick->ui32NumSrcSync; loop++)
+ {
+ if (abSrcSyncEnable[loop])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop];
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_SRC_SYNC,
+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+ psSharedTransferCmd->asSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ psSharedTransferCmd->asSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+
+ psSharedTransferCmd->asSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ psSharedTransferCmd->asSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+ i++;
+ }
+ }
+ PVR_ASSERT(i == ui32RealSrcSyncNum);
+
+ i = 0;
+ for (loop = 0; loop < psKick->ui32NumDstSync; loop++)
+ {
+ if (abDstSyncEnable[loop])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop];
+
+ psSyncInfo->psSyncData->ui64LastWrite = ui64KickCount;
+
+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_DST_SYNC,
+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE);
+
+ psSharedTransferCmd->asDstSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending;
+ psSharedTransferCmd->asDstSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending;
+ psSharedTransferCmd->asDstSyncs[i].ui32ReadOps2PendingVal = psSyncInfo->psSyncData->ui32ReadOps2Pending;
+
+ psSharedTransferCmd->asDstSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ psSharedTransferCmd->asDstSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+ psSharedTransferCmd->asDstSyncs[i].sReadOps2CompleteDevVAddr = psSyncInfo->sReadOps2CompleteDevVAddr;
+ i++;
+ }
+ }
+ PVR_ASSERT(i == ui32RealDstSyncNum);
+
+ /*
+ * We allow source and destination sync objects to be the
+ * same, which is why the read/write pending updates are delayed
+ * until the transfer command has been updated with the current
+ * values from the objects.
+ */
+ for (loop = 0; loop < psKick->ui32NumSrcSync; loop++)
+ {
+ if (abSrcSyncEnable[loop])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop];
+ psSyncInfo->psSyncData->ui32ReadOpsPending++;
+ }
+ }
+ for (loop = 0; loop < psKick->ui32NumDstSync; loop++)
+ {
+ if (abDstSyncEnable[loop])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop];
+ psSyncInfo->psSyncData->ui32WriteOpsPending++;
+ }
+ }
+ }
+
+#if defined(PDUMP)
+ if ((PDumpIsCaptureFrameKM()
+ || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
+ && (bPersistentProcess == IMG_FALSE) )
+ {
+ PDUMPCOMMENT("Shared part of transfer command\r\n");
+ PDUMPMEM(psSharedTransferCmd,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff,
+ sizeof(SGXMKIF_TRANSFERCMD_SHARED),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL)
+ {
+ IMG_UINT32 i = 0;
+
+ for (loop = 0; loop < psKick->ui32NumSrcSync; loop++)
+ {
+ if (abSrcSyncEnable[loop])
+ {
+ psSyncInfo = psKick->ahSrcSyncInfo[loop];
+
+ PDUMPCOMMENT("Tweak src surface write op in transfer cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asSrcSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal)),
+ sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ PDUMPCOMMENT("Tweak src surface read op in transfer cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asSrcSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal)),
+ sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ i++;
+ }
+ }
+
+ i = 0;
+ for (loop = 0; loop < psKick->ui32NumDstSync; loop++)
+ {
+ if (abDstSyncEnable[i])
+ {
+ IMG_UINT32 ui32PDumpReadOp2 = 0;
+ psSyncInfo = psKick->ahDstSyncInfo[loop];
+
+ PDUMPCOMMENT("Tweak dest surface write op in transfer cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal)),
+ sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ PDUMPCOMMENT("Tweak dest surface read op in transfer cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal)),
+ sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ PDUMPCOMMENT("Tweak dest surface read op2 in transfer cmd\r\n");
+ PDUMPMEM(&ui32PDumpReadOp2,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOps2PendingVal)),
+ sizeof(ui32PDumpReadOp2),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ i++;
+ }
+ }
+
+ /*
+ * We allow the first source and destination sync objects to be the
+ * same, which is why the read/write pending updates are delayed
+ * until the transfer command has been updated with the current
+ * values from the objects.
+ */
+ for (loop = 0; loop < (psKick->ui32NumSrcSync); loop++)
+ {
+ if (abSrcSyncEnable[loop])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop];
+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
+ }
+ }
+
+ for (loop = 0; loop < (psKick->ui32NumDstSync); loop++)
+ {
+ if (abDstSyncEnable[loop])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0];
+ psSyncInfo->psSyncData->ui32LastOpDumpVal++;
+ }
+ }
+ }
+
+ if (psKick->hTASyncInfo != IMG_NULL)
+ {
+ psSyncInfo = psKick->hTASyncInfo;
+
+ PDUMPCOMMENT("Tweak TA/TQ surface write op in transfer cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32TASyncWriteOpsPendingVal)),
+ sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ psSyncInfo->psSyncData->ui32LastOpDumpVal++;
+ }
+
+ if (psKick->h3DSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = psKick->h3DSyncInfo;
+
+ PDUMPCOMMENT("Tweak 3D/TQ surface write op in transfer cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui323DSyncWriteOpsPendingVal)),
+ sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ psSyncInfo->psSyncData->ui32LastOpDumpVal++;
+ }
+ }
+#endif
+
+ sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr;
+
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CMD_END,
+ TRANSFER_TOKEN_SUBMIT);
+
+ eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TRANSFER, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags, hDevMemContext, IMG_FALSE);
+
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ /* Client will retry, so undo the sync ops pending increment(s) done above. */
+ if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL)
+ {
+ for (loop = 0; loop < psKick->ui32NumSrcSync; loop++)
+ {
+ if (abSrcSyncEnable[loop])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop];
+ psSyncInfo->psSyncData->ui32ReadOpsPending--;
+#if defined(PDUMP)
+ if (PDumpIsCaptureFrameKM()
+ || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
+ {
+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal--;
+ }
+#endif
+ }
+ }
+ for (loop = 0; loop < psKick->ui32NumDstSync; loop++)
+ {
+ if (abDstSyncEnable[loop])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop];
+ psSyncInfo->psSyncData->ui32WriteOpsPending--;
+#if defined(PDUMP)
+ if (PDumpIsCaptureFrameKM()
+ || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
+ {
+ psSyncInfo->psSyncData->ui32LastOpDumpVal--;
+ }
+#endif
+ }
+ }
+ }
+
+ /* Command needed to be synchronised with the TA? */
+ if (psKick->hTASyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
+ psSyncInfo->psSyncData->ui32WriteOpsPending--;
+ }
+
+ /* Command needed to be synchronised with the 3D? */
+ if (psKick->h3DSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
+ psSyncInfo->psSyncData->ui32WriteOpsPending--;
+ }
+ }
+
+ else if (PVRSRV_OK != eError)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: SGXScheduleCCBCommandKM failed."));
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT,
+ TRANSFER_TOKEN_SUBMIT);
+ return eError;
+ }
+
+
+#if defined(NO_HARDWARE)
+ if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_NOSYNCUPDATE) == 0)
+ {
+ /* Update sync objects pretending that we have done the job*/
+ for (loop = 0; loop < psKick->ui32NumSrcSync; loop++)
+ {
+ if (abSrcSyncEnable[loop])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop];
+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
+ }
+ }
+
+ for (loop = 0; loop < psKick->ui32NumDstSync; loop++)
+ {
+ if (abDstSyncEnable[loop])
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop];
+ 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
+ PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT,
+ TRANSFER_TOKEN_SUBMIT);
+ return eError;
+}
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+#if defined (SUPPORT_SID_INTERFACE)
+IMG_EXPORT PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK_KM *psKick)
+#else
+IMG_EXPORT PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK *psKick)
+#endif
+
+{
+ 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;
+ IMG_HANDLE hDevMemContext = IMG_NULL;
+#if defined(PDUMP)
+ IMG_BOOL bPersistentProcess = IMG_FALSE;
+ /*
+ * For persistent processes, the HW kicks should not go into the
+ * extended init phase; only keep memory transactions from the
+ * window system which are necessary to run the client app.
+ */
+ {
+ PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+ if(psPerProc != IMG_NULL)
+ {
+ bPersistentProcess = psPerProc->bPDumpPersistent;
+ }
+ }
+#endif /* PDUMP */
+#if defined(FIX_HW_BRN_31620)
+ hDevMemContext = psKick->hDevMemContext;
+#endif
+
+ 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;
+ }
+ /* override QAC warning about stricter alignment */
+ /* PRQA S 3305 1 */
+ ps2DCmd = CCB_DATA_FROM_OFFSET(SGXMKIF_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset);
+
+ OSMemSet(ps2DCmd, 0, sizeof(*ps2DCmd));
+
+ /* Command needs to be synchronised with the TA? */
+ 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;
+ }
+
+ /* Command needs to be synchronised with the 3D? */
+ 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;
+ }
+
+ /*
+ * We allow the first source and destination sync objects to be the
+ * same, which is why the read/write pending updates are delayed
+ * until the transfer command has been updated with the current
+ * values from the objects.
+ */
+ 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.ui32ReadOps2PendingVal = psSyncInfo->psSyncData->ui32ReadOps2Pending;
+
+ ps2DCmd->sDstSyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr;
+ ps2DCmd->sDstSyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr;
+ ps2DCmd->sDstSyncData.sReadOps2CompleteDevVAddr = psSyncInfo->sReadOps2CompleteDevVAddr;
+ }
+
+ /* Read/Write ops pending updates, delayed from above */
+ 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))
+ && (bPersistentProcess == IMG_FALSE) )
+ {
+ /* Pdump the command from the per context CCB */
+ 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("Tweak src surface write op in 2D cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sSrcSyncData[i].ui32WriteOpsPendingVal),
+ sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ PDUMPCOMMENT("Tweak src surface read op in 2D cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sSrcSyncData[i].ui32ReadOpsPendingVal),
+ sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ }
+
+ if (psKick->hDstSyncInfo != IMG_NULL)
+ {
+ IMG_UINT32 ui32PDumpReadOp2 = 0;
+ psSyncInfo = psKick->hDstSyncInfo;
+
+ PDUMPCOMMENT("Tweak dest surface write op in 2D cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32WriteOpsPendingVal),
+ sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ PDUMPCOMMENT("Tweak dest surface read op in 2D cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32ReadOpsPendingVal),
+ sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ PDUMPCOMMENT("Tweak dest surface read op2 in 2D cmd\r\n");
+ PDUMPMEM(&ui32PDumpReadOp2,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32ReadOps2PendingVal),
+ sizeof(ui32PDumpReadOp2),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ }
+
+ /* Read/Write ops pending updates, delayed from above */
+ 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[1] = psKick->sHW2DContextDevVAddr.uiAddr;
+
+ eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_2D, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags, hDevMemContext, IMG_FALSE);
+
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ /* Client will retry, so undo the write ops pending increment
+ done above.
+ */
+#if defined(PDUMP)
+ if (PDumpIsCaptureFrameKM())
+ {
+ 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
+
+ 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--;
+ }
+
+ /* Command needed to be synchronised with the TA? */
+ if (psKick->hTASyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo;
+
+ psSyncInfo->psSyncData->ui32WriteOpsPending--;
+ }
+
+ /* Command needed to be synchronised with the 3D? */
+ if (psKick->h3DSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo;
+
+ psSyncInfo->psSyncData->ui32WriteOpsPending--;
+ }
+ }
+
+
+
+
+#if defined(NO_HARDWARE)
+ /* Update sync objects pretending that we have done the job*/
+ for(i = 0; i < psKick->ui32NumSrcSync; i++)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i];
+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending;
+ }
+
+ if (psKick->hDstSyncInfo != IMG_NULL)
+ {
+ 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 /* SGX_FEATURE_2D_HARDWARE */
+#endif /* TRANSFER_QUEUE */
diff --git a/pvr-source/services4/srvkm/devices/sgx/sgxutils.c b/pvr-source/services4/srvkm/devices/sgx/sgxutils.c
new file mode 100644
index 0000000..227675d
--- /dev/null
+++ b/pvr-source/services4/srvkm/devices/sgx/sgxutils.c
@@ -0,0 +1,1912 @@
+/*************************************************************************/ /*!
+@Title Device specific utility routines
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Device specific functions
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+
+#include "sgxdefs.h"
+#include "services_headers.h"
+#include "buffer_manager.h"
+#include "sgx_bridge_km.h"
+#include "sgxapi_km.h"
+#include "sgxinfo.h"
+#include "sgx_mkif_km.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"
+#include "ttrace.h"
+
+#ifdef __linux__
+#include <linux/kernel.h> // sprintf
+#include <linux/string.h> // strncpy, strlen
+#else
+#include <stdio.h>
+#endif
+
+IMG_UINT64 ui64KickCount;
+
+
+#if defined(SYS_CUSTOM_POWERDOWN)
+PVRSRV_ERROR SysPowerDownMISR(PVRSRV_DEVICE_NODE * psDeviceNode, IMG_UINT32 ui32CallerID);
+#endif
+
+
+
+/*!
+******************************************************************************
+
+ @Function SGXPostActivePowerEvent
+
+ @Description
+
+ post power event functionality (e.g. restart)
+
+ @Input psDeviceNode : SGX Device Node
+ @Input ui32CallerID - KERNEL_ID or ISR_ID
+
+ @Return IMG_VOID :
+
+******************************************************************************/
+static IMG_VOID SGXPostActivePowerEvent(PVRSRV_DEVICE_NODE * psDeviceNode,
+ IMG_UINT32 ui32CallerID)
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl;
+
+ /* Update the counter for stats. */
+ psSGXHostCtl->ui32NumActivePowerEvents++;
+
+ if ((psSGXHostCtl->ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE) != 0)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "SGXPostActivePowerEvent: SGX requests immediate restart"));
+
+ /*
+ Events were queued during the active power
+ request, so SGX will need to be restarted.
+ */
+ if (ui32CallerID == ISR_ID)
+ {
+ psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE;
+ }
+ else
+ {
+ SGXScheduleProcessQueuesKM(psDeviceNode);
+ }
+ }
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SGXTestActivePowerEvent
+
+ @Description
+
+ Checks whether the microkernel has generated an active power event. If so,
+ perform the power transition.
+
+ @Input psDeviceNode : SGX Device Node
+ @Input ui32CallerID - KERNEL_ID or ISR_ID
+
+ @Return IMG_VOID :
+
+******************************************************************************/
+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;
+
+ /*
+ * Quickly check (without lock) if there is an IDLE or APM event we should handle.
+ * This check fails most of the time so we don't want to incur lock overhead.
+ * Check the flags in the reverse order that microkernel clears them to prevent
+ * us from seeing an inconsistent state.
+ */
+ if ((((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_IDLE) == 0) &&
+ ((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_IDLE) != 0)) ||
+ (((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) == 0) &&
+ ((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) != 0)))
+ {
+ eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE);
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ return;
+ }
+ else if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXTestActivePowerEvent failed to acquire lock - "
+ "ui32CallerID:%d eError:%u", ui32CallerID, eError));
+ return;
+ }
+
+ /*
+ * Check again (with lock) if IDLE event has been cleared or handled. A race
+ * condition may allow multiple threads to pass the quick check.
+ */
+ if(((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_IDLE) == 0) &&
+ ((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_IDLE) != 0))
+ {
+ psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_IDLE;
+ psDevInfo->bSGXIdle = IMG_TRUE;
+
+ SysSGXIdleEntered();
+ }
+
+ /*
+ * Check again (with lock) if APM event has been cleared or handled. A race
+ * condition may allow multiple threads to pass the quick check.
+ */
+ if (((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) == 0) &&
+ ((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) != 0))
+ {
+ /* Microkernel is idle and is requesting to be powered down. */
+ psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER;
+
+ /* Suspend pdumping. */
+ PDUMPSUSPEND();
+
+#if defined(SYS_CUSTOM_POWERDOWN)
+ /*
+ Some power down code cannot be executed inside an MISR on
+ some platforms that use mutexes inside the power code.
+ */
+ eError = SysPowerDownMISR(psDeviceNode, ui32CallerID);
+#else
+ eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE_OFF);
+#endif
+ if (eError == PVRSRV_OK)
+ {
+ SGXPostActivePowerEvent(psDeviceNode, ui32CallerID);
+ }
+ /* Resume pdumping */
+ PDUMPRESUME();
+ }
+
+ PVRSRVPowerUnlock(ui32CallerID);
+ }
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXTestActivePowerEvent error:%u", eError));
+ }
+}
+
+
+/******************************************************************************
+ FUNCTION : SGXAcquireKernelCCBSlot
+
+ PURPOSE : Attempts to obtain a slot in the Kernel CCB
+
+ PARAMETERS : psCCB - the CCB
+
+ RETURNS : Address of space if available, IMG_NULL otherwise
+******************************************************************************/
+#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];
+ }
+
+ OSSleepms(1);
+ } END_LOOP_UNTIL_TIMEOUT();
+
+ /* Time out on waiting for CCB space */
+ return IMG_NULL;
+}
+
+/*!
+******************************************************************************
+
+ @Function SGXScheduleCCBCommand
+
+ @Description - Submits a CCB command and kicks the ukernel (without
+ power management)
+
+ @Input psDevInfo - pointer to device info
+ @Input eCmdType - see SGXMKIF_CMD_*
+ @Input psCommandData - kernel CCB command
+ @Input ui32CallerID - KERNEL_ID or ISR_ID
+ @Input ui32PDumpFlags
+
+ @Return ui32Error - success or failure
+
+******************************************************************************/
+PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_DEVICE_NODE *psDeviceNode,
+ SGXMKIF_CMD_TYPE eCmdType,
+ SGXMKIF_COMMAND *psCommandData,
+ IMG_UINT32 ui32CallerID,
+ IMG_UINT32 ui32PDumpFlags,
+ IMG_HANDLE hDevMemContext,
+ IMG_BOOL bLastInScene)
+{
+ PVRSRV_SGX_CCB_INFO *psKernelCCB;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ SGXMKIF_COMMAND *psSGXCommand;
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl;
+#if defined(FIX_HW_BRN_31620)
+ IMG_UINT32 ui32CacheMasks[4];
+ IMG_UINT32 i;
+ MMU_CONTEXT *psMMUContext;
+#endif
+#if defined(PDUMP)
+ IMG_VOID *pvDumpCommand;
+ IMG_BOOL bPDumpIsSuspended = PDumpIsSuspended();
+ IMG_BOOL bPersistentProcess = IMG_FALSE;
+#else
+ PVR_UNREFERENCED_PARAMETER(ui32CallerID);
+ PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags);
+#endif
+
+#if defined(FIX_HW_BRN_31620)
+ for(i=0;i<4;i++)
+ {
+ ui32CacheMasks[i] = 0;
+ }
+
+ psMMUContext = psDevInfo->hKernelMMUContext;
+ psDeviceNode->pfnMMUGetCacheFlushRange(psMMUContext, &ui32CacheMasks[0]);
+
+ /* Put the apps memory context in the bottom half */
+ if (hDevMemContext)
+ {
+ BM_CONTEXT *psBMContext = (BM_CONTEXT *) hDevMemContext;
+
+ psMMUContext = psBMContext->psMMUContext;
+ psDeviceNode->pfnMMUGetCacheFlushRange(psMMUContext, &ui32CacheMasks[2]);
+ }
+
+ /* If we have an outstanding flush request then set the cachecontrol bit */
+ if (ui32CacheMasks[0] || ui32CacheMasks[1] || ui32CacheMasks[2] || ui32CacheMasks[3])
+ {
+ psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_PD;
+ }
+#endif
+
+#if defined(FIX_HW_BRN_28889)
+ /*
+ If the data cache and bif cache need invalidating there has been a cleanup
+ request. Therefore, we need to send the invalidate seperately and wait
+ for it to complete.
+ */
+ if ( (eCmdType != SGXMKIF_CMD_PROCESS_QUEUES) &&
+ ((psDevInfo->ui32CacheControl & SGXMKIF_CC_INVAL_DATA) != 0) &&
+ ((psDevInfo->ui32CacheControl & (SGXMKIF_CC_INVAL_BIF_PT | SGXMKIF_CC_INVAL_BIF_PD)) != 0))
+ {
+ #if defined(PDUMP)
+ PVRSRV_KERNEL_MEM_INFO *psSGXHostCtlMemInfo = psDevInfo->psKernelSGXHostCtlMemInfo;
+ #endif
+ SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl;
+ SGXMKIF_COMMAND sCacheCommand = {0};
+
+ eError = SGXScheduleCCBCommand(psDeviceNode,
+ SGXMKIF_CMD_PROCESS_QUEUES,
+ &sCacheCommand,
+ ui32CallerID,
+ ui32PDumpFlags,
+ hDevMemContext,
+ bLastInScene);
+ if (eError != PVRSRV_OK)
+ {
+ goto Exit;
+ }
+
+ /* Wait for the invalidate to happen */
+ #if !defined(NO_HARDWARE)
+ if(PollForValueKM(&psSGXHostCtl->ui32InvalStatus,
+ PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE,
+ PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE,
+ 2 * MAX_HW_TIME_US,
+ MAX_HW_TIME_US/WAIT_TRY_COUNT,
+ IMG_FALSE) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommand: Wait for uKernel to Invalidate BIF cache failed"));
+ PVR_DBG_BREAK;
+ }
+ #endif
+
+ #if defined(PDUMP)
+ /* Pdump the poll as well. */
+ PDUMPCOMMENTWITHFLAGS(0, "Host Control - Poll for BIF cache invalidate request to complete");
+ PDUMPMEMPOL(psSGXHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, ui32InvalStatus),
+ PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE,
+ PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE,
+ PDUMP_POLL_OPERATOR_EQUAL,
+ 0,
+ MAKEUNIQUETAG(psSGXHostCtlMemInfo));
+ #endif /* PDUMP */
+
+ psSGXHostCtl->ui32InvalStatus &= ~(PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE);
+ PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psSGXHostCtlMemInfo));
+ }
+#else
+ PVR_UNREFERENCED_PARAMETER(hDevMemContext);
+#endif
+
+#if defined(FIX_HW_BRN_31620)
+ if ((eCmdType != SGXMKIF_CMD_FLUSHPDCACHE) && (psDevInfo->ui32CacheControl & SGXMKIF_CC_INVAL_BIF_PD))
+ {
+ SGXMKIF_COMMAND sPDECacheCommand = {0};
+ IMG_DEV_PHYADDR sDevPAddr;
+
+ /* Put the kernel info in the top 1/2 of the data */
+ psMMUContext = psDevInfo->hKernelMMUContext;
+
+ psDeviceNode->pfnMMUGetPDPhysAddr(psMMUContext, &sDevPAddr);
+ sPDECacheCommand.ui32Data[0] = sDevPAddr.uiAddr | 1;
+ sPDECacheCommand.ui32Data[1] = ui32CacheMasks[0];
+ sPDECacheCommand.ui32Data[2] = ui32CacheMasks[1];
+
+ /* Put the apps memory context in the bottom half */
+ if (hDevMemContext)
+ {
+ BM_CONTEXT *psBMContext = (BM_CONTEXT *) hDevMemContext;
+
+ psMMUContext = psBMContext->psMMUContext;
+
+ psDeviceNode->pfnMMUGetPDPhysAddr(psMMUContext, &sDevPAddr);
+ /* Or in 1 to the lsb to show we have a valid context */
+ sPDECacheCommand.ui32Data[3] = sDevPAddr.uiAddr | 1;
+ sPDECacheCommand.ui32Data[4] = ui32CacheMasks[2];
+ sPDECacheCommand.ui32Data[5] = ui32CacheMasks[3];
+ }
+
+ /* Only do a kick if there is any update */
+ if (sPDECacheCommand.ui32Data[1] | sPDECacheCommand.ui32Data[2] | sPDECacheCommand.ui32Data[4] |
+ sPDECacheCommand.ui32Data[5])
+ {
+ eError = SGXScheduleCCBCommand(psDeviceNode,
+ SGXMKIF_CMD_FLUSHPDCACHE,
+ &sPDECacheCommand,
+ ui32CallerID,
+ ui32PDumpFlags,
+ hDevMemContext,
+ bLastInScene);
+ if (eError != PVRSRV_OK)
+ {
+ goto Exit;
+ }
+ }
+ }
+#endif
+#if defined(PDUMP)
+ /*
+ * For persistent processes, the HW kicks should not go into the
+ * extended init phase; only keep memory transactions from the
+ * window system which are necessary to run the client app.
+ */
+ {
+ PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
+ if(psPerProc != IMG_NULL)
+ {
+ bPersistentProcess = psPerProc->bPDumpPersistent;
+ }
+ }
+#endif /* PDUMP */
+ psKernelCCB = psDevInfo->psKernelCCBInfo;
+
+ psSGXCommand = SGXAcquireKernelCCBSlot(psKernelCCB);
+
+ /* Wait for CCB space timed out */
+ if(!psSGXCommand)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXScheduleCCBCommand: Wait for CCB space timed out")) ;
+ eError = PVRSRV_ERROR_TIMEOUT;
+ goto Exit;
+ }
+
+ /* embed cache control word */
+ psCommandData->ui32CacheControl = psDevInfo->ui32CacheControl;
+
+#if defined(PDUMP)
+ /* Accumulate any cache invalidates that may have happened */
+ psDevInfo->sPDContext.ui32CacheControl |= psDevInfo->ui32CacheControl;
+#endif
+
+ /* and clear it */
+ psDevInfo->ui32CacheControl = 0;
+
+ /* Copy command data over */
+ *psSGXCommand = *psCommandData;
+
+ if (eCmdType >= SGXMKIF_CMD_MAX)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXScheduleCCBCommand: Unknown command type: %d", eCmdType)) ;
+ eError = PVRSRV_ERROR_INVALID_CCB_COMMAND;
+ goto Exit;
+ }
+
+ if (eCmdType == SGXMKIF_CMD_2D ||
+ eCmdType == SGXMKIF_CMD_TRANSFER ||
+ ((eCmdType == SGXMKIF_CMD_TA) && bLastInScene))
+ {
+ SYS_DATA *psSysData;
+
+ /* CPU cache clean control */
+ SysAcquireData(&psSysData);
+
+ if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH)
+ {
+ OSFlushCPUCacheKM();
+ }
+ else if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN)
+ {
+ OSCleanCPUCacheKM();
+ }
+
+ /* Clear the pending op */
+ psSysData->ePendingCacheOpType = PVRSRV_MISC_INFO_CPUCACHEOP_NONE;
+ }
+
+ PVR_ASSERT(eCmdType < SGXMKIF_CMD_MAX);
+ psSGXCommand->ui32ServiceAddress = psDevInfo->aui32HostKickAddr[eCmdType]; /* PRQA S 3689 */ /* misuse of enums for bounds checking */
+
+#if defined(PDUMP)
+ if ((ui32CallerID != ISR_ID) && (bPDumpIsSuspended == IMG_FALSE) &&
+ (bPersistentProcess == IMG_FALSE) )
+ {
+ /* Poll for space in the CCB. */
+ PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "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,
+ ui32PDumpFlags,
+ MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo));
+
+ PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB command (type == %d)\r\n", eCmdType);
+ 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));
+
+ /* Overwrite cache control with pdump shadow */
+ PDUMPMEM(&psDevInfo->sPDContext.ui32CacheControl,
+ psKernelCCB->psCCBMemInfo,
+ psKernelCCB->ui32CCBDumpWOff * sizeof(SGXMKIF_COMMAND) +
+ offsetof(SGXMKIF_COMMAND, ui32CacheControl),
+ sizeof(IMG_UINT32),
+ ui32PDumpFlags,
+ MAKEUNIQUETAG(psKernelCCB->psCCBMemInfo));
+
+ if (PDumpIsCaptureFrameKM()
+ || ((ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
+ {
+ /* Clear cache invalidate shadow */
+ psDevInfo->sPDContext.ui32CacheControl = 0;
+ }
+ }
+#endif
+
+#if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE)
+ /* Make sure the previous command has been read before send the next one */
+ eError = PollForValueKM (psKernelCCB->pui32ReadOffset,
+ *psKernelCCB->pui32WriteOffset,
+ 0xFF,
+ MAX_HW_TIME_US,
+ MAX_HW_TIME_US/WAIT_TRY_COUNT,
+ IMG_FALSE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXScheduleCCBCommand: Timeout waiting for previous command to be read")) ;
+ eError = PVRSRV_ERROR_TIMEOUT;
+ goto Exit;
+ }
+#endif
+
+ /*
+ Increment the write offset
+ */
+ *psKernelCCB->pui32WriteOffset = (*psKernelCCB->pui32WriteOffset + 1) & 255;
+
+#if defined(PDUMP)
+ if ((ui32CallerID != ISR_ID) && (bPDumpIsSuspended == IMG_FALSE) &&
+ (bPersistentProcess == IMG_FALSE) )
+ {
+ #if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE)
+ PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "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,
+ ui32PDumpFlags,
+ MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo));
+ #endif
+
+ if (PDumpIsCaptureFrameKM()
+ || ((ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))
+ {
+ psKernelCCB->ui32CCBDumpWOff = (psKernelCCB->ui32CCBDumpWOff + 1) & 0xFF;
+ psDevInfo->ui32KernelCCBEventKickerDumpVal = (psDevInfo->ui32KernelCCBEventKickerDumpVal + 1) & 0xFF;
+ }
+
+ PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "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(ui32PDumpFlags, "Kernel CCB event kicker\r\n");
+ PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal,
+ psDevInfo->psKernelCCBEventKickerMemInfo,
+ 0,
+ sizeof(IMG_UINT32),
+ ui32PDumpFlags,
+ MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));
+ PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kick the SGX microkernel\r\n");
+ #if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE)
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), EUR_CR_EVENT_KICK2_NOW_MASK, ui32PDumpFlags);
+ #else
+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), EUR_CR_EVENT_KICK_NOW_MASK, ui32PDumpFlags);
+ #endif
+ }
+#endif
+
+ *psDevInfo->pui32KernelCCBEventKicker = (*psDevInfo->pui32KernelCCBEventKicker + 1) & 0xFF;
+
+ /*
+ * New command submission is considered a proper handling of any pending
+ * IDLE or APM event, so mark them as handled to prevent other host threads
+ * from taking action.
+ */
+ psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_IDLE;
+ psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER;
+
+ OSWriteMemoryBarrier();
+
+ /* Order is importent for post processor! */
+ PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_MKSYNC, PVRSRV_TRACE_CLASS_NONE,
+ MKSYNC_TOKEN_KERNEL_CCB_OFFSET, *psKernelCCB->pui32WriteOffset);
+ PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_MKSYNC, PVRSRV_TRACE_CLASS_NONE,
+ MKSYNC_TOKEN_CORE_CLK, psDevInfo->ui32CoreClockSpeed);
+ PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_MKSYNC, PVRSRV_TRACE_CLASS_NONE,
+ MKSYNC_TOKEN_UKERNEL_CLK, psDevInfo->ui32uKernelTimerClock);
+
+
+#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
+
+ OSMemoryBarrier();
+
+#if defined(NO_HARDWARE)
+ /* Increment read offset */
+ *psKernelCCB->pui32ReadOffset = (*psKernelCCB->pui32ReadOffset + 1) & 255;
+#endif
+
+ ui64KickCount++;
+Exit:
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SGXScheduleCCBCommandKM
+
+ @Description - Submits a CCB command and kicks the ukernel
+
+ @Input psDeviceNode - pointer to SGX device node
+ @Input eCmdType - see SGXMKIF_CMD_*
+ @Input psCommandData - kernel CCB command
+ @Input ui32CallerID - KERNEL_ID or ISR_ID
+ @Input ui32PDumpFlags
+
+ @Return ui32Error - success or failure
+
+******************************************************************************/
+PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE *psDeviceNode,
+ SGXMKIF_CMD_TYPE eCmdType,
+ SGXMKIF_COMMAND *psCommandData,
+ IMG_UINT32 ui32CallerID,
+ IMG_UINT32 ui32PDumpFlags,
+ IMG_HANDLE hDevMemContext,
+ IMG_BOOL bLastInScene)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+
+ eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE);
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ if (ui32CallerID == ISR_ID)
+ {
+ SYS_DATA *psSysData;
+
+ /*
+ ISR failed to acquire lock so it must be held by a kernel thread.
+ Bring up and kick SGX if necessary when the lock is available.
+ */
+ psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE;
+ eError = PVRSRV_OK;
+
+ SysAcquireData(&psSysData);
+ OSScheduleMISR(psSysData);
+ }
+ else
+ {
+ /*
+ Return to srvclient for retry.
+ */
+ }
+
+ return eError;
+ }
+ else if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommandKM failed to acquire lock - "
+ "ui32CallerID:%d eError:%u", ui32CallerID, eError));
+ return eError;
+ }
+
+ /* Note that a power-up has been dumped in the init phase. */
+ PDUMPSUSPEND();
+
+ SysSGXCommandPending(psDevInfo->bSGXIdle);
+ psDevInfo->bSGXIdle = IMG_FALSE;
+
+ /* Ensure that SGX is powered up before kicking the ukernel. */
+ eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE_ON);
+
+ PDUMPRESUME();
+
+ if (eError == PVRSRV_OK)
+ {
+ psDeviceNode->bReProcessDeviceCommandComplete = IMG_FALSE;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommandKM failed to acquire lock - "
+ "ui32CallerID:%d eError:%u", ui32CallerID, eError));
+ return eError;
+ }
+
+ eError = SGXScheduleCCBCommand(psDeviceNode, eCmdType, psCommandData, ui32CallerID, ui32PDumpFlags, hDevMemContext, bLastInScene);
+
+ PVRSRVPowerUnlock(ui32CallerID);
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SGXScheduleProcessQueuesKM
+
+ @Description - Software command complete handler
+
+ @Input psDeviceNode - SGX device node
+
+******************************************************************************/
+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)
+ {
+ /* The ukernel has no work to do so don't waste power. */
+ return PVRSRV_OK;
+ }
+
+ eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_CMD_PROCESS_QUEUES, &sCommand, ISR_ID, 0, IMG_NULL, IMG_FALSE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXScheduleProcessQueuesKM failed to schedule CCB command: %u", eError));
+ return eError;
+ }
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SGXIsDevicePowered
+
+ @Description
+
+ Whether the device is powered, for the purposes of lockup detection.
+
+ @Input psDeviceNode - pointer to device node
+
+ @Return IMG_BOOL : Whether device is powered
+
+******************************************************************************/
+IMG_BOOL SGXIsDevicePowered(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ return PVRSRVIsDevicePowered(psDeviceNode->sDevId.ui32DeviceIndex);
+}
+
+/*!
+*******************************************************************************
+
+ @Function SGXGetInternalDevInfoKM
+
+ @Description
+ Gets device information that is not intended to be passed
+ on beyond the srvclient libs.
+
+ @Input hDevCookie
+
+ @Output psSGXInternalDevInfo
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+IMG_EXPORT
+PVRSRV_ERROR SGXGetInternalDevInfoKM(IMG_HANDLE hDevCookie,
+#if defined (SUPPORT_SID_INTERFACE)
+ SGX_INTERNAL_DEVINFO_KM *psSGXInternalDevInfo)
+#else
+ SGX_INTERNAL_DEVINFO *psSGXInternalDevInfo)
+#endif
+{
+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
+
+ psSGXInternalDevInfo->ui32Flags = psDevInfo->ui32Flags;
+ psSGXInternalDevInfo->bForcePTOff = (IMG_BOOL)psDevInfo->bForcePTOff;
+
+ /* This should be patched up by OS bridge code */
+ psSGXInternalDevInfo->hHostCtlKernelMemInfoHandle =
+ (IMG_HANDLE)psDevInfo->psKernelSGXHostCtlMemInfo;
+
+ return PVRSRV_OK;
+}
+
+
+/*****************************************************************************
+ FUNCTION : SGXCleanupRequest
+
+ PURPOSE : Wait for the microkernel to clean up its references to either a
+ render context or render target.
+
+ PARAMETERS : psDeviceNode - SGX device node
+ psHWDataDevVAddr - Device Address of the resource
+ ui32CleanupType - PVRSRV_CLEANUPCMD_*
+ bForceCleanup - Skips sync polling
+
+ RETURNS : error status
+*****************************************************************************/
+PVRSRV_ERROR SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_DEV_VIRTADDR *psHWDataDevVAddr,
+ IMG_UINT32 ui32CleanupType,
+ IMG_BOOL bForceCleanup)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ PVRSRV_KERNEL_MEM_INFO *psHostCtlMemInfo = psDevInfo->psKernelSGXHostCtlMemInfo;
+ SGXMKIF_HOST_CTL *psHostCtl = psHostCtlMemInfo->pvLinAddrKM;
+
+ SGXMKIF_COMMAND sCommand = {0};
+
+
+ if (bForceCleanup != FORCE_CLEANUP)
+ {
+ sCommand.ui32Data[0] = ui32CleanupType;
+ sCommand.ui32Data[1] = (psHWDataDevVAddr == IMG_NULL) ? 0 : psHWDataDevVAddr->uiAddr;
+ PDUMPCOMMENTWITHFLAGS(0, "Request ukernel resource clean-up, Type %u, Data 0x%X", sCommand.ui32Data[0], sCommand.ui32Data[1]);
+
+ eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_CMD_CLEANUP, &sCommand, KERNEL_ID, 0, IMG_NULL, IMG_FALSE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Failed to submit clean-up command"));
+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
+ PVR_DBG_BREAK;
+ return eError;
+ }
+
+ /* Wait for the uKernel process the cleanup request */
+ #if !defined(NO_HARDWARE)
+ if(PollForValueKM(&psHostCtl->ui32CleanupStatus,
+ PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
+ PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE,
+ 10 * MAX_HW_TIME_US,
+ 1000,
+ IMG_TRUE) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Wait for uKernel to clean up (%u) failed", ui32CleanupType));
+ eError = PVRSRV_ERROR_TIMEOUT;
+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE);
+ PVR_DBG_BREAK;
+ }
+ #endif
+
+ #if defined(PDUMP)
+ /*
+ Pdump the poll as well.
+ Note:
+ We don't expect the cleanup to report busy as the client should have
+ ensured the the resource has been finished with before requesting
+ it's cleanup. This isn't true of the abnormal termination case but
+ we don't expect to PDump that. Unless/until PDump has flow control
+ there isn't anything else we can do.
+ */
+ PDUMPCOMMENTWITHFLAGS(0, "Host Control - Poll for clean-up request to complete");
+ PDUMPMEMPOL(psHostCtlMemInfo,
+ offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus),
+ PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE | PVRSRV_USSE_EDM_CLEANUPCMD_DONE,
+ PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE | PVRSRV_USSE_EDM_CLEANUPCMD_DONE,
+ PDUMP_POLL_OPERATOR_EQUAL,
+ 0,
+ MAKEUNIQUETAG(psHostCtlMemInfo));
+ #endif /* PDUMP */
+
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+
+ if (psHostCtl->ui32CleanupStatus & PVRSRV_USSE_EDM_CLEANUPCMD_BUSY)
+ {
+ /* Only one flag should be set */
+ PVR_ASSERT((psHostCtl->ui32CleanupStatus & PVRSRV_USSE_EDM_CLEANUPCMD_DONE) == 0);
+ eError = PVRSRV_ERROR_RETRY;
+ psHostCtl->ui32CleanupStatus &= ~(PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE | PVRSRV_USSE_EDM_CLEANUPCMD_BUSY);
+ }
+ else
+ {
+ eError = PVRSRV_OK;
+ psHostCtl->ui32CleanupStatus &= ~(PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE | PVRSRV_USSE_EDM_CLEANUPCMD_DONE);
+ }
+
+ PDUMPMEM(IMG_NULL, psHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psHostCtlMemInfo));
+
+ /* Request the cache invalidate */
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+ psDevInfo->ui32CacheControl |= (SGXMKIF_CC_INVAL_BIF_SL | SGXMKIF_CC_INVAL_DATA);
+#else
+ psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_DATA;
+#endif
+ return eError;
+}
+
+
+typedef struct _SGX_HW_RENDER_CONTEXT_CLEANUP_
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ PVRSRV_KERNEL_MEM_INFO *psHWRenderContextMemInfo;
+ IMG_HANDLE hBlockAlloc;
+ PRESMAN_ITEM psResItem;
+ IMG_BOOL bCleanupTimerRunning;
+ IMG_PVOID pvTimeData;
+} SGX_HW_RENDER_CONTEXT_CLEANUP;
+
+
+static PVRSRV_ERROR SGXCleanupHWRenderContextCallback(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bForceCleanup)
+{
+ PVRSRV_ERROR eError;
+ SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup = pvParam;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+
+ eError = SGXCleanupRequest(psCleanup->psDeviceNode,
+ &psCleanup->psHWRenderContextMemInfo->sDevVAddr,
+ PVRSRV_CLEANUPCMD_RC,
+ bForceCleanup);
+
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ if (!psCleanup->bCleanupTimerRunning)
+ {
+ OSTimeCreateWithUSOffset(&psCleanup->pvTimeData, MAX_CLEANUP_TIME_US);
+ psCleanup->bCleanupTimerRunning = IMG_TRUE;
+ }
+ else
+ {
+ if (OSTimeHasTimePassed(psCleanup->pvTimeData))
+ {
+ eError = PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE;
+ psCleanup->bCleanupTimerRunning = IMG_FALSE;
+ OSTimeDestroy(psCleanup->pvTimeData);
+ }
+ }
+ }
+ else
+ {
+ if (psCleanup->bCleanupTimerRunning)
+ {
+ OSTimeDestroy(psCleanup->pvTimeData);
+ }
+ }
+
+ if (eError != PVRSRV_ERROR_RETRY)
+ {
+ /* Free the Device Mem allocated */
+ PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode,
+ psCleanup->psHWRenderContextMemInfo);
+
+ /* Finally, free the cleanup structure itself */
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+ /*not nulling pointer, copy on stack*/
+ }
+
+ return eError;
+}
+
+typedef struct _SGX_HW_TRANSFER_CONTEXT_CLEANUP_
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ PVRSRV_KERNEL_MEM_INFO *psHWTransferContextMemInfo;
+ IMG_HANDLE hBlockAlloc;
+ PRESMAN_ITEM psResItem;
+ IMG_BOOL bCleanupTimerRunning;
+ IMG_PVOID pvTimeData;
+} SGX_HW_TRANSFER_CONTEXT_CLEANUP;
+
+
+static PVRSRV_ERROR SGXCleanupHWTransferContextCallback(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bForceCleanup)
+{
+ PVRSRV_ERROR eError;
+ SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)pvParam;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+
+ eError = SGXCleanupRequest(psCleanup->psDeviceNode,
+ &psCleanup->psHWTransferContextMemInfo->sDevVAddr,
+ PVRSRV_CLEANUPCMD_TC,
+ bForceCleanup);
+
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ if (!psCleanup->bCleanupTimerRunning)
+ {
+ OSTimeCreateWithUSOffset(&psCleanup->pvTimeData, MAX_CLEANUP_TIME_US);
+ psCleanup->bCleanupTimerRunning = IMG_TRUE;
+ }
+ else
+ {
+ if (OSTimeHasTimePassed(psCleanup->pvTimeData))
+ {
+ eError = PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE;
+ psCleanup->bCleanupTimerRunning = IMG_FALSE;
+ OSTimeDestroy(psCleanup->pvTimeData);
+ }
+ }
+ }
+ else
+ {
+ if (psCleanup->bCleanupTimerRunning)
+ {
+ OSTimeDestroy(psCleanup->pvTimeData);
+ }
+ }
+
+ if (eError != PVRSRV_ERROR_RETRY)
+ {
+ /* Free the Device Mem allocated */
+ PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode,
+ psCleanup->psHWTransferContextMemInfo);
+
+ /* Finally, free the cleanup structure itself */
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+ /*not nulling pointer, copy on stack*/
+ }
+
+ return eError;
+}
+
+IMG_EXPORT
+IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE hDeviceNode,
+ IMG_CPU_VIRTADDR *psHWRenderContextCpuVAddr,
+ IMG_UINT32 ui32HWRenderContextSize,
+ IMG_UINT32 ui32OffsetToPDDevPAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_VIRTADDR *psHWRenderContextDevVAddr,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_ERROR eError;
+ IMG_HANDLE hBlockAlloc;
+ SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup;
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)hDeviceNode;
+ DEVICE_MEMORY_INFO *psDevMemoryInfo;
+ DEVICE_MEMORY_HEAP_INFO *psHeapInfo;
+ IMG_HANDLE hDevMemContextInt;
+ MMU_CONTEXT *psMMUContext;
+ IMG_DEV_PHYADDR sPDDevPAddr;
+ int iPtrByte;
+ IMG_UINT8 *pSrc;
+ IMG_UINT8 *pDst;
+ PRESMAN_ITEM psResItem;
+
+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
+ (IMG_VOID **)&psCleanup,
+ &hBlockAlloc,
+ "SGX Hardware Render Context Cleanup");
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't allocate memory for SGX_HW_RENDER_CONTEXT_CLEANUP structure"));
+ goto exit0;
+ }
+
+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+ psHeapInfo = &psDevMemoryInfo->psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID];
+
+ eError = PVRSRVAllocDeviceMemKM(hDeviceNode,
+ psPerProc,
+ psHeapInfo->hDevMemHeap,
+ PVRSRV_MEM_READ | PVRSRV_MEM_WRITE
+ | PVRSRV_MEM_NO_SYNCOBJ | PVRSRV_MEM_EDM_PROTECT
+ | PVRSRV_MEM_CACHE_CONSISTENT,
+ ui32HWRenderContextSize,
+ 32,
+ IMG_NULL,
+ 0,
+ 0,0,0,IMG_NULL, /* No sparse mapping data */
+ &psCleanup->psHWRenderContextMemInfo,
+ "HW Render Context");
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't allocate device memory for HW Render Context"));
+ goto exit1;
+ }
+
+ eError = OSCopyFromUser(psPerProc,
+ psCleanup->psHWRenderContextMemInfo->pvLinAddrKM,
+ psHWRenderContextCpuVAddr,
+ ui32HWRenderContextSize);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't copy user-mode copy of HWContext into device memory"));
+ goto exit2;
+ }
+
+ /* Pass the DevVAddr of the new context back up through the bridge */
+ psHWRenderContextDevVAddr->uiAddr = psCleanup->psHWRenderContextMemInfo->sDevVAddr.uiAddr;
+
+ /* Retrieve the PDDevPAddr */
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Can't lookup DevMem Context"));
+ goto exit2;
+ }
+
+ psMMUContext = BM_GetMMUContextFromMemContext(hDevMemContextInt);
+ sPDDevPAddr = psDeviceNode->pfnMMUGetPDDevPAddr(psMMUContext);
+
+ /*
+ patch-in the Page-Directory Device-Physical address. Note that this is
+ copied-in one byte at a time, as we have no guarantee that the usermode-
+ provided ui32OffsetToPDDevPAddr is a validly-aligned address for the
+ current CPU architecture.
+ */
+ pSrc = (IMG_UINT8 *)&sPDDevPAddr;
+ pDst = (IMG_UINT8 *)psCleanup->psHWRenderContextMemInfo->pvLinAddrKM;
+ pDst += ui32OffsetToPDDevPAddr;
+
+ for (iPtrByte = 0; iPtrByte < sizeof(IMG_DEV_PHYADDR); iPtrByte++)
+ {
+ pDst[iPtrByte] = pSrc[iPtrByte];
+ }
+
+#if defined(PDUMP)
+ /* PDUMP the HW context */
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "HW Render context struct");
+
+ PDUMPMEM(
+ IMG_NULL,
+ psCleanup->psHWRenderContextMemInfo,
+ 0,
+ ui32HWRenderContextSize,
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psCleanup->psHWRenderContextMemInfo));
+
+ /* PDUMP the PDDevPAddr */
+ PDUMPCOMMENT("Page directory address in HW render context");
+ PDUMPPDDEVPADDR(
+ psCleanup->psHWRenderContextMemInfo,
+ ui32OffsetToPDDevPAddr,
+ sPDDevPAddr,
+ MAKEUNIQUETAG(psCleanup->psHWRenderContextMemInfo),
+ PDUMP_PD_UNIQUETAG);
+#endif
+
+ psCleanup->hBlockAlloc = hBlockAlloc;
+ psCleanup->psDeviceNode = psDeviceNode;
+ psCleanup->bCleanupTimerRunning = IMG_FALSE;
+
+ 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"));
+ goto exit2;
+ }
+
+ psCleanup->psResItem = psResItem;
+
+ return (IMG_HANDLE)psCleanup;
+
+/* Error exit paths */
+exit2:
+ PVRSRVFreeDeviceMemKM(hDeviceNode,
+ psCleanup->psHWRenderContextMemInfo);
+exit1:
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+ /*not nulling pointer, out of scope*/
+exit0:
+ return IMG_NULL;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext, IMG_BOOL bForceCleanup)
+{
+ 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, bForceCleanup);
+
+ return eError;
+}
+
+
+IMG_EXPORT
+IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE hDeviceNode,
+ IMG_CPU_VIRTADDR *psHWTransferContextCpuVAddr,
+ IMG_UINT32 ui32HWTransferContextSize,
+ IMG_UINT32 ui32OffsetToPDDevPAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_VIRTADDR *psHWTransferContextDevVAddr,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_ERROR eError;
+ IMG_HANDLE hBlockAlloc;
+ SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup;
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)hDeviceNode;
+ DEVICE_MEMORY_INFO *psDevMemoryInfo;
+ DEVICE_MEMORY_HEAP_INFO *psHeapInfo;
+ IMG_HANDLE hDevMemContextInt;
+ MMU_CONTEXT *psMMUContext;
+ IMG_DEV_PHYADDR sPDDevPAddr;
+ int iPtrByte;
+ IMG_UINT8 *pSrc;
+ IMG_UINT8 *pDst;
+ PRESMAN_ITEM psResItem;
+
+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
+ (IMG_VOID **)&psCleanup,
+ &hBlockAlloc,
+ "SGX Hardware Transfer Context Cleanup");
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't allocate memory for SGX_HW_TRANSFER_CONTEXT_CLEANUP structure"));
+ goto exit0;
+ }
+
+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+ psHeapInfo = &psDevMemoryInfo->psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID];
+
+ eError = PVRSRVAllocDeviceMemKM(hDeviceNode,
+ psPerProc,
+ psHeapInfo->hDevMemHeap,
+ PVRSRV_MEM_READ | PVRSRV_MEM_WRITE
+ | PVRSRV_MEM_NO_SYNCOBJ | PVRSRV_MEM_EDM_PROTECT
+ | PVRSRV_MEM_CACHE_CONSISTENT,
+ ui32HWTransferContextSize,
+ 32,
+ IMG_NULL,
+ 0,
+ 0,0,0,IMG_NULL, /* No sparse mapping data */
+ &psCleanup->psHWTransferContextMemInfo,
+ "HW Render Context");
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't allocate device memory for HW Render Context"));
+ goto exit1;
+ }
+
+ eError = OSCopyFromUser(psPerProc,
+ psCleanup->psHWTransferContextMemInfo->pvLinAddrKM,
+ psHWTransferContextCpuVAddr,
+ ui32HWTransferContextSize);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't copy user-mode copy of HWContext into device memory"));
+ goto exit2;
+ }
+
+ /* Pass the DevVAddr of the new context back up through the bridge */
+ psHWTransferContextDevVAddr->uiAddr = psCleanup->psHWTransferContextMemInfo->sDevVAddr.uiAddr;
+
+ /* Retrieve the PDDevPAddr */
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Can't lookup DevMem Context"));
+ goto exit2;
+ }
+
+ psMMUContext = BM_GetMMUContextFromMemContext(hDevMemContextInt);
+ sPDDevPAddr = psDeviceNode->pfnMMUGetPDDevPAddr(psMMUContext);
+
+ /*
+ patch-in the Page-Directory Device-Physical address. Note that this is
+ copied-in one byte at a time, as we have no guarantee that the usermode-
+ provided ui32OffsetToPDDevPAddr is a validly-aligned address for the
+ current CPU architecture.
+ */
+ pSrc = (IMG_UINT8 *)&sPDDevPAddr;
+ pDst = (IMG_UINT8 *)psCleanup->psHWTransferContextMemInfo->pvLinAddrKM;
+ pDst += ui32OffsetToPDDevPAddr;
+
+ for (iPtrByte = 0; iPtrByte < sizeof(IMG_DEV_PHYADDR); iPtrByte++)
+ {
+ pDst[iPtrByte] = pSrc[iPtrByte];
+ }
+
+#if defined(PDUMP)
+ /* PDUMP the HW Transfer Context */
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "HW Transfer context struct");
+
+ PDUMPMEM(
+ IMG_NULL,
+ psCleanup->psHWTransferContextMemInfo,
+ 0,
+ ui32HWTransferContextSize,
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psCleanup->psHWTransferContextMemInfo));
+
+ /* PDUMP the PDDevPAddr */
+ PDUMPCOMMENT("Page directory address in HW transfer context");
+
+ PDUMPPDDEVPADDR(
+ psCleanup->psHWTransferContextMemInfo,
+ ui32OffsetToPDDevPAddr,
+ sPDDevPAddr,
+ MAKEUNIQUETAG(psCleanup->psHWTransferContextMemInfo),
+ PDUMP_PD_UNIQUETAG);
+#endif
+
+ psCleanup->hBlockAlloc = hBlockAlloc;
+ psCleanup->psDeviceNode = psDeviceNode;
+ psCleanup->bCleanupTimerRunning = IMG_FALSE;
+
+ psResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_HW_TRANSFER_CONTEXT,
+ psCleanup,
+ 0,
+ &SGXCleanupHWTransferContextCallback);
+
+ if (psResItem == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: ResManRegisterRes failed"));
+ goto exit2;
+ }
+
+ psCleanup->psResItem = psResItem;
+
+ return (IMG_HANDLE)psCleanup;
+
+/* Error exit paths */
+exit2:
+ PVRSRVFreeDeviceMemKM(hDeviceNode,
+ psCleanup->psHWTransferContextMemInfo);
+exit1:
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+ /*not nulling pointer, out of scope*/
+
+exit0:
+ return IMG_NULL;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR SGXUnregisterHWTransferContextKM(IMG_HANDLE hHWTransferContext, IMG_BOOL bForceCleanup)
+{
+ 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, bForceCleanup);
+
+ return eError;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR SGXSetTransferContextPriorityKM(
+ IMG_HANDLE hDeviceNode,
+ IMG_HANDLE hHWTransferContext,
+ IMG_UINT32 ui32Priority,
+ IMG_UINT32 ui32OffsetOfPriorityField)
+{
+ SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup;
+ IMG_UINT8 *pSrc;
+ IMG_UINT8 *pDst;
+ int iPtrByte;
+ PVR_UNREFERENCED_PARAMETER(hDeviceNode);
+
+ if (hHWTransferContext != IMG_NULL)
+ {
+ psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)hHWTransferContext;
+
+ if ((ui32OffsetOfPriorityField + sizeof(ui32Priority))
+ >= psCleanup->psHWTransferContextMemInfo->uAllocSize)
+ {
+ PVR_DPF((
+ PVR_DBG_ERROR,
+ "SGXSetTransferContextPriorityKM: invalid context prioirty offset"));
+
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ /*
+ cannot be sure that offset (passed from user-land) is safe to deref
+ as a word-ptr on current CPU arch: copy one byte at a time.
+ */
+ pDst = (IMG_UINT8 *)psCleanup->psHWTransferContextMemInfo->pvLinAddrKM;
+ pDst += ui32OffsetOfPriorityField;
+ pSrc = (IMG_UINT8 *)&ui32Priority;
+
+ for (iPtrByte = 0; iPtrByte < sizeof(ui32Priority); iPtrByte++)
+ {
+ pDst[iPtrByte] = pSrc[iPtrByte];
+ }
+ }
+ return PVRSRV_OK;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR SGXSetRenderContextPriorityKM(
+ IMG_HANDLE hDeviceNode,
+ IMG_HANDLE hHWRenderContext,
+ IMG_UINT32 ui32Priority,
+ IMG_UINT32 ui32OffsetOfPriorityField)
+{
+ SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup;
+ IMG_UINT8 *pSrc;
+ IMG_UINT8 *pDst;
+ int iPtrByte;
+ PVR_UNREFERENCED_PARAMETER(hDeviceNode);
+
+ if (hHWRenderContext != IMG_NULL)
+ {
+ psCleanup = (SGX_HW_RENDER_CONTEXT_CLEANUP *)hHWRenderContext;
+ if ((ui32OffsetOfPriorityField + sizeof(ui32Priority))
+ >= psCleanup->psHWRenderContextMemInfo->uAllocSize)
+ {
+ PVR_DPF((
+ PVR_DBG_ERROR,
+ "SGXSetContextPriorityKM: invalid HWRenderContext prioirty offset"));
+
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ /*
+ cannot be sure that offset (passed from user-land) is safe to deref
+ as a word-ptr on current CPU arch: copy one byte at a time.
+ */
+ pDst = (IMG_UINT8 *)psCleanup->psHWRenderContextMemInfo->pvLinAddrKM;
+ pDst += ui32OffsetOfPriorityField;
+
+ pSrc = (IMG_UINT8 *)&ui32Priority;
+
+ for (iPtrByte = 0; iPtrByte < sizeof(ui32Priority); iPtrByte++)
+ {
+ pDst[iPtrByte] = pSrc[iPtrByte];
+ }
+ }
+ return PVRSRV_OK;
+}
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+typedef struct _SGX_HW_2D_CONTEXT_CLEANUP_
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+ PVRSRV_KERNEL_MEM_INFO *psHW2DContextMemInfo;
+ IMG_HANDLE hBlockAlloc;
+ PRESMAN_ITEM psResItem;
+ IMG_BOOL bCleanupTimerRunning;
+ IMG_PVOID pvTimeData;
+} SGX_HW_2D_CONTEXT_CLEANUP;
+
+static PVRSRV_ERROR SGXCleanupHW2DContextCallback(IMG_PVOID pvParam,
+ IMG_UINT32 ui32Param,
+ IMG_BOOL bForceCleanup)
+{
+ PVRSRV_ERROR eError;
+ SGX_HW_2D_CONTEXT_CLEANUP *psCleanup = (SGX_HW_2D_CONTEXT_CLEANUP *)pvParam;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+
+ /* First, ensure the context is no longer being utilised */
+ eError = SGXCleanupRequest(psCleanup->psDeviceNode,
+ &psCleanup->psHW2DContextMemInfo->sDevVAddr,
+ PVRSRV_CLEANUPCMD_2DC,
+ bForceCleanup);
+
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ if (!psCleanup->bCleanupTimerRunning)
+ {
+ OSTimeCreateWithUSOffset(&psCleanup->pvTimeData, MAX_CLEANUP_TIME_US);
+ psCleanup->bCleanupTimerRunning = IMG_TRUE;
+ }
+ else
+ {
+ if (OSTimeHasTimePassed(psCleanup->pvTimeData))
+ {
+ eError = PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE;
+ psCleanup->bCleanupTimerRunning = IMG_FALSE;
+ OSTimeDestroy(psCleanup->pvTimeData);
+ }
+ }
+ }
+ else
+ {
+ if (psCleanup->bCleanupTimerRunning)
+ {
+ OSTimeDestroy(psCleanup->pvTimeData);
+ }
+ }
+
+ if (eError != PVRSRV_ERROR_RETRY)
+ {
+ /* Free the Device Mem allocated */
+ PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode,
+ psCleanup->psHW2DContextMemInfo);
+
+ /* Finally, free the cleanup structure itself */
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+ /*not nulling pointer, copy on stack*/
+ }
+ return eError;
+}
+
+IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE hDeviceNode,
+ IMG_CPU_VIRTADDR *psHW2DContextCpuVAddr,
+ IMG_UINT32 ui32HW2DContextSize,
+ IMG_UINT32 ui32OffsetToPDDevPAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_VIRTADDR *psHW2DContextDevVAddr,
+ PVRSRV_PER_PROCESS_DATA *psPerProc)
+{
+ PVRSRV_ERROR eError;
+ IMG_HANDLE hBlockAlloc;
+ SGX_HW_2D_CONTEXT_CLEANUP *psCleanup;
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)hDeviceNode;
+ DEVICE_MEMORY_INFO *psDevMemoryInfo;
+ DEVICE_MEMORY_HEAP_INFO *psHeapInfo;
+ IMG_HANDLE hDevMemContextInt;
+ MMU_CONTEXT *psMMUContext;
+ IMG_DEV_PHYADDR sPDDevPAddr;
+ int iPtrByte;
+ IMG_UINT8 *pSrc;
+ IMG_UINT8 *pDst;
+ PRESMAN_ITEM psResItem;
+
+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
+ (IMG_VOID **)&psCleanup,
+ &hBlockAlloc,
+ "SGX Hardware 2D Context Cleanup");
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't allocate memory for SGX_HW_2D_CONTEXT_CLEANUP structure"));
+ goto exit0;
+ }
+
+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+ psHeapInfo = &psDevMemoryInfo->psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID];
+
+ eError = PVRSRVAllocDeviceMemKM(hDeviceNode,
+ psPerProc,
+ psHeapInfo->hDevMemHeap,
+ PVRSRV_MEM_READ | PVRSRV_MEM_WRITE
+ | PVRSRV_MEM_NO_SYNCOBJ | PVRSRV_MEM_EDM_PROTECT
+ | PVRSRV_MEM_CACHE_CONSISTENT,
+ ui32HW2DContextSize,
+ 32,
+ IMG_NULL,
+ 0,
+ 0,0,0,IMG_NULL, /* No sparse mapping data */
+ &psCleanup->psHW2DContextMemInfo,
+ "HW 2D Context");
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't allocate device memory for HW Render Context"));
+ goto exit1;
+ }
+
+ eError = OSCopyFromUser(psPerProc,
+ psCleanup->psHW2DContextMemInfo->pvLinAddrKM,
+ psHW2DContextCpuVAddr,
+ ui32HW2DContextSize);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't copy user-mode copy of HWContext into device memory"));
+ goto exit2;
+ }
+
+ /* Pass the DevVAddr of the new context back up through the bridge */
+ psHW2DContextDevVAddr->uiAddr = psCleanup->psHW2DContextMemInfo->sDevVAddr.uiAddr;
+
+ /* Retrieve the PDDevPAddr */
+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+ &hDevMemContextInt,
+ hDevMemContext,
+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Can't lookup DevMem Context"));
+ goto exit2;
+ }
+
+ psMMUContext = BM_GetMMUContextFromMemContext(hDevMemContextInt);
+ sPDDevPAddr = psDeviceNode->pfnMMUGetPDDevPAddr(psMMUContext);
+
+ /*
+ patch-in the Page-Directory Device-Physical address. Note that this is
+ copied-in one byte at a time, as we have no guarantee that the usermode-
+ provided ui32OffsetToPDDevPAddr is a validly-aligned address for the
+ current CPU architecture.
+ */
+ pSrc = (IMG_UINT8 *)&sPDDevPAddr;
+ pDst = (IMG_UINT8 *)psCleanup->psHW2DContextMemInfo->pvLinAddrKM;
+ pDst += ui32OffsetToPDDevPAddr;
+
+ for (iPtrByte = 0; iPtrByte < sizeof(IMG_DEV_PHYADDR); iPtrByte++)
+ {
+ pDst[iPtrByte] = pSrc[iPtrByte];
+ }
+
+#if defined(PDUMP)
+ /* PDUMP the HW 2D Context */
+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "HW 2D context struct");
+
+ PDUMPMEM(
+ IMG_NULL,
+ psCleanup->psHW2DContextMemInfo,
+ 0,
+ ui32HW2DContextSize,
+ PDUMP_FLAGS_CONTINUOUS,
+ MAKEUNIQUETAG(psCleanup->psHW2DContextMemInfo));
+
+ /* PDUMP the PDDevPAddr */
+ PDUMPCOMMENT("Page directory address in HW 2D transfer context");
+ PDUMPPDDEVPADDR(
+ psCleanup->psHW2DContextMemInfo,
+ ui32OffsetToPDDevPAddr,
+ sPDDevPAddr,
+ MAKEUNIQUETAG(psCleanup->psHW2DContextMemInfo),
+ PDUMP_PD_UNIQUETAG);
+#endif
+
+ psCleanup->hBlockAlloc = hBlockAlloc;
+ psCleanup->psDeviceNode = psDeviceNode;
+ psCleanup->bCleanupTimerRunning = IMG_FALSE;
+
+ psResItem = ResManRegisterRes(psPerProc->hResManContext,
+ RESMAN_TYPE_HW_2D_CONTEXT,
+ psCleanup,
+ 0,
+ &SGXCleanupHW2DContextCallback);
+
+ if (psResItem == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: ResManRegisterRes failed"));
+ goto exit2;
+ }
+
+ psCleanup->psResItem = psResItem;
+
+ return (IMG_HANDLE)psCleanup;
+
+/* Error exit paths */
+exit2:
+ PVRSRVFreeDeviceMemKM(hDeviceNode,
+ psCleanup->psHW2DContextMemInfo);
+exit1:
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
+ sizeof(SGX_HW_2D_CONTEXT_CLEANUP),
+ psCleanup,
+ psCleanup->hBlockAlloc);
+ /*not nulling pointer, out of scope*/
+exit0:
+ return IMG_NULL;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR SGXUnregisterHW2DContextKM(IMG_HANDLE hHW2DContext, IMG_BOOL bForceCleanup)
+{
+ 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, bForceCleanup);
+
+ return eError;
+}
+#endif /* #if defined(SGX_FEATURE_2D_HARDWARE)*/
+
+/*!****************************************************************************
+ @Function SGX2DQuerySyncOpsCompleteKM
+
+ @Input psSyncInfo : Sync object to be queried
+
+ @Return IMG_TRUE - ops complete, IMG_FALSE - ops pending
+
+******************************************************************************/
+#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)
+ );
+}
+
+/*!****************************************************************************
+ @Function SGX2DQueryBlitsCompleteKM
+
+ @Input psDevInfo : SGX device info structure
+
+ @Input psSyncInfo : Sync object to be queried
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+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))
+ {
+ /* Instant success */
+ PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: No wait. Blits complete."));
+ return PVRSRV_OK;
+ }
+
+ /* Not complete yet */
+ if (!bWaitForComplete)
+ {
+ /* Just report not complete */
+ PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: No wait. Ops pending."));
+ return PVRSRV_ERROR_CMD_NOT_PROCESSED;
+ }
+
+ /* Start polling */
+ PVR_DPF((PVR_DBG_MESSAGE, "SGX2DQueryBlitsCompleteKM: Ops pending. Start polling."));
+
+ LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
+ {
+ OSSleepms(1);
+
+ if(SGX2DQuerySyncOpsComplete(psSyncInfo, ui32ReadOpsPending, ui32WriteOpsPending))
+ {
+ /* Success */
+ PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: Wait over. Blits complete."));
+ return PVRSRV_OK;
+ }
+
+ OSSleepms(1);
+ } END_LOOP_UNTIL_TIMEOUT();
+
+ /* Timed out */
+ PVR_DPF((PVR_DBG_ERROR,"SGX2DQueryBlitsCompleteKM: Timed out. Ops pending."));
+
+#if defined(DEBUG)
+ {
+ PVRSRV_SYNC_DATA *psSyncData = psSyncInfo->psSyncData;
+
+ PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Syncinfo: 0x%x, Syncdata: 0x%x",
+ (IMG_UINTPTR_T)psSyncInfo, (IMG_UINTPTR_T)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
+PVRSRV_ERROR SGXFlushHWRenderTargetKM(IMG_HANDLE psDeviceNode,
+ IMG_DEV_VIRTADDR sHWRTDataSetDevVAddr,
+ IMG_BOOL bForceCleanup)
+{
+ PVR_ASSERT(sHWRTDataSetDevVAddr.uiAddr != IMG_NULL);
+
+ return SGXCleanupRequest(psDeviceNode,
+ &sHWRTDataSetDevVAddr,
+ PVRSRV_CLEANUPCMD_RT,
+ bForceCleanup);
+}
+
+
+IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32TimeWraps,
+ IMG_UINT32 ui32Time)
+{
+#if defined(EUR_CR_TIMER)
+ PVR_UNREFERENCED_PARAMETER(psDevInfo);
+ PVR_UNREFERENCED_PARAMETER(ui32TimeWraps);
+ return ui32Time;
+#else
+ 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;
+#endif /* EUR_CR_TIMER */
+}
+
+
+IMG_VOID SGXWaitClocks(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32SGXClocks)
+{
+ /*
+ Round up to the next microsecond.
+ */
+ OSWaitus(1 + (ui32SGXClocks * 1000000 / psDevInfo->ui32CoreClockSpeed));
+}
+
+
+
+/******************************************************************************
+ End of file (sgxutils.c)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/devices/sgx/sgxutils.h b/pvr-source/services4/srvkm/devices/sgx/sgxutils.h
new file mode 100644
index 0000000..fc2ef6f
--- /dev/null
+++ b/pvr-source/services4/srvkm/devices/sgx/sgxutils.h
@@ -0,0 +1,195 @@
+/*************************************************************************/ /*!
+@Title Device specific utility routines declarations
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Inline functions/structures specific to SGX
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "perproc.h"
+#include "sgxinfokm.h"
+
+/* PRQA S 3410 7 */ /* macros require the absence of some brackets */
+#define CCB_OFFSET_IS_VALID(type, psCCBMemInfo, psCCBKick, offset) \
+ ((sizeof(type) <= (psCCBMemInfo)->uAllocSize) && \
+ ((psCCBKick)->offset <= (psCCBMemInfo)->uAllocSize - sizeof(type)))
+
+#define CCB_DATA_FROM_OFFSET(type, psCCBMemInfo, psCCBKick, offset) \
+ ((type *)(((IMG_CHAR *)(psCCBMemInfo)->pvLinAddrKM) + \
+ (psCCBKick)->offset))
+
+extern IMG_UINT64 ui64KickCount;
+
+
+IMG_IMPORT
+IMG_VOID SGXTestActivePowerEvent(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_UINT32 ui32CallerID);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_DEVICE_NODE *psDeviceNode,
+ SGXMKIF_CMD_TYPE eCommandType,
+ SGXMKIF_COMMAND *psCommandData,
+ IMG_UINT32 ui32CallerID,
+ IMG_UINT32 ui32PDumpFlags,
+ IMG_HANDLE hDevMemContext,
+ IMG_BOOL bLastInScene);
+IMG_IMPORT
+PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE *psDeviceNode,
+ SGXMKIF_CMD_TYPE eCommandType,
+ SGXMKIF_COMMAND *psCommandData,
+ IMG_UINT32 ui32CallerID,
+ IMG_UINT32 ui32PDumpFlags,
+ IMG_HANDLE hDevMemContext,
+ IMG_BOOL bLastInScene);
+
+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_CPU_VIRTADDR *psHWRenderContextCpuVAddr,
+ IMG_UINT32 ui32HWRenderContextSize,
+ IMG_UINT32 ui32OffsetToPDDevPAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_VIRTADDR *psHWRenderContextDevVAddr,
+ PVRSRV_PER_PROCESS_DATA *psPerProc);
+
+IMG_IMPORT
+IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE psDeviceNode,
+ IMG_CPU_VIRTADDR *psHWTransferContextCpuVAddr,
+ IMG_UINT32 ui32HWTransferContextSize,
+ IMG_UINT32 ui32OffsetToPDDevPAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_VIRTADDR *psHWTransferContextDevVAddr,
+ PVRSRV_PER_PROCESS_DATA *psPerProc);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXFlushHWRenderTargetKM(IMG_HANDLE psSGXDevInfo,
+ IMG_DEV_VIRTADDR psHWRTDataSetDevVAddr,
+ IMG_BOOL bForceCleanup);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext, IMG_BOOL bForceCleanup);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXUnregisterHWTransferContextKM(IMG_HANDLE hHWTransferContext, IMG_BOOL bForceCleanup);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXSetRenderContextPriorityKM(IMG_HANDLE hDeviceNode,
+ IMG_HANDLE hHWRenderContext,
+ IMG_UINT32 ui32Priority,
+ IMG_UINT32 ui32OffsetOfPriorityField);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXSetTransferContextPriorityKM(IMG_HANDLE hDeviceNode,
+ IMG_HANDLE hHWTransferContext,
+ IMG_UINT32 ui32Priority,
+ IMG_UINT32 ui32OffsetOfPriorityField);
+
+#if defined(SGX_FEATURE_2D_HARDWARE)
+IMG_IMPORT
+IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE psDeviceNode,
+ IMG_CPU_VIRTADDR *psHW2DContextCpuVAddr,
+ IMG_UINT32 ui32HW2DContextSize,
+ IMG_UINT32 ui32OffsetToPDDevPAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_DEV_VIRTADDR *psHW2DContextDevVAddr,
+ PVRSRV_PER_PROCESS_DATA *psPerProc);
+
+IMG_IMPORT
+PVRSRV_ERROR SGXUnregisterHW2DContextKM(IMG_HANDLE hHW2DContext, IMG_BOOL bForceCleanup);
+#endif
+
+IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32TimeWraps,
+ IMG_UINT32 ui32Time);
+
+/*!
+*******************************************************************************
+
+ @Function SGXWaitClocks
+
+ @Description
+
+ Wait for a specified number of SGX clock cycles to elapse.
+
+ @Input psDevInfo - SGX Device Info
+ @Input ui32SGXClocks - number of clock cycles to wait
+
+ @Return IMG_VOID
+
+******************************************************************************/
+IMG_VOID SGXWaitClocks(PVRSRV_SGXDEV_INFO *psDevInfo,
+ IMG_UINT32 ui32SGXClocks);
+
+PVRSRV_ERROR SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_DEV_VIRTADDR *psHWDataDevVAddr,
+ IMG_UINT32 ui32CleanupType,
+ IMG_BOOL bForceCleanup);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVGetSGXRevDataKM(PVRSRV_DEVICE_NODE* psDeviceNode, IMG_UINT32 *pui32SGXCoreRev,
+ IMG_UINT32 *pui32SGXCoreID);
+
+/*!
+******************************************************************************
+
+ @Function SGXContextSuspend
+
+ @Description - Interface to the SGX microkernel to instruct it to suspend or
+ resume processing on a given context. This will interrupt current
+ processing of this context if a task is already running and is
+ interruptable.
+
+ @Input psDeviceNode SGX device node
+ @Input psHWContextDevVAddr SGX virtual address of the context to be suspended
+ or resumed. Can be of type SGXMKIF_HWRENDERCONTEXT,
+ SGXMKIF_HWTRANSFERCONTEXT or SGXMKIF_HW2DCONTEXT
+ @Input bResume IMG_TRUE to put a context into suspend state,
+ IMG_FALSE to resume a previously suspended context
+
+******************************************************************************/
+PVRSRV_ERROR SGXContextSuspend(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_DEV_VIRTADDR *psHWContextDevVAddr,
+ IMG_BOOL bResume);
+
+/******************************************************************************
+ End of file (sgxutils.h)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/env/linux/Kbuild.mk b/pvr-source/services4/srvkm/env/linux/Kbuild.mk
new file mode 100644
index 0000000..25e35e9
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/Kbuild.mk
@@ -0,0 +1,166 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+pvrsrvkm_sgx$(SGXCORE)_$(SGX_CORE_REV)-y += \
+ services4/srvkm/env/linux/osfunc.o \
+ services4/srvkm/env/linux/mutils.o \
+ services4/srvkm/env/linux/mmap.o \
+ services4/srvkm/env/linux/module.o \
+ services4/srvkm/env/linux/pdump.o \
+ services4/srvkm/env/linux/proc.o \
+ services4/srvkm/env/linux/pvr_bridge_k.o \
+ services4/srvkm/env/linux/pvr_debug.o \
+ services4/srvkm/env/linux/mm.o \
+ services4/srvkm/env/linux/mutex.o \
+ services4/srvkm/env/linux/event.o \
+ services4/srvkm/env/linux/osperproc.o \
+ services4/srvkm/env/linux/sysfs.o \
+ services4/srvkm/common/buffer_manager.o \
+ services4/srvkm/common/devicemem.o \
+ services4/srvkm/common/deviceclass.o \
+ services4/srvkm/common/handle.o \
+ services4/srvkm/common/hash.o \
+ services4/srvkm/common/lists.o \
+ services4/srvkm/common/mem.o \
+ services4/srvkm/common/mem_debug.o \
+ services4/srvkm/common/metrics.o \
+ services4/srvkm/common/osfunc_common.o \
+ services4/srvkm/common/pdump_common.o \
+ services4/srvkm/common/perproc.o \
+ services4/srvkm/common/power.o \
+ services4/srvkm/common/pvrsrv.o \
+ services4/srvkm/common/queue.o \
+ services4/srvkm/common/ra.o \
+ services4/srvkm/common/refcount.o \
+ services4/srvkm/common/resman.o \
+ services4/srvkm/bridged/bridged_support.o \
+ services4/srvkm/bridged/bridged_pvr_bridge.o \
+ services4/system/$(PVR_SYSTEM)/sysconfig.o \
+ services4/system/$(PVR_SYSTEM)/sysutils.o
+
+pvrsrvkm_sgx$(SGXCORE)_$(SGX_CORE_REV)-$(CONFIG_ION_OMAP) += \
+ services4/srvkm/env/linux/ion.o
+pvrsrvkm_sgx$(SGXCORE)_$(SGX_CORE_REV)-$(CONFIG_GCBV) += \
+ services4/srvkm/env/linux/gc_bvmapping.o
+
+ifeq ($(SUPPORT_ION),1)
+pvrsrvkm-y += \
+ services4/srvkm/env/linux/ion.o
+endif
+
+ifeq ($(TTRACE),1)
+pvrsrvkm-y += \
+ services4/srvkm/common/ttrace.o
+endif
+
+ifneq ($(W),1)
+CFLAGS_osfunc.o := -Werror
+CFLAGS_mutils.o := -Werror
+CFLAGS_mmap.o := -Werror
+CFLAGS_module.o := -Werror
+CFLAGS_pdump.o := -Werror
+CFLAGS_proc.o := -Werror
+CFLAGS_pvr_bridge_k.o := -Werror
+CFLAGS_pvr_debug.o := -Werror
+CFLAGS_mm.o := -Werror
+CFLAGS_mutex.o := -Werror
+CFLAGS_event.o := -Werror
+CFLAGS_osperproc.o := -Werror
+CFLAGS_buffer_manager.o := -Werror
+CFLAGS_devicemem.o := -Werror
+CFLAGS_deviceclass.o := -Werror
+CFLAGS_handle.o := -Werror
+CFLAGS_hash.o := -Werror
+CFLAGS_metrics.o := -Werror
+CFLAGS_pvrsrv.o := -Werror
+CFLAGS_queue.o := -Werror
+CFLAGS_ra.o := -Werror
+CFLAGS_resman.o := -Werror
+CFLAGS_power.o := -Werror
+CFLAGS_mem.o := -Werror
+CFLAGS_pdump_common.o := -Werror
+CFLAGS_bridged_support.o := -Werror
+CFLAGS_bridged_pvr_bridge.o := -Werror
+CFLAGS_perproc.o := -Werror
+CFLAGS_lists.o := -Werror
+CFLAGS_mem_debug.o := -Werror
+CFLAGS_osfunc_common.o := -Werror
+CFLAGS_refcount.o := -Werror
+endif
+
+# SUPPORT_SGX==1 only
+
+pvrsrvkm_sgx$(SGXCORE)_$(SGX_CORE_REV)-y += \
+ services4/srvkm/bridged/sgx/bridged_sgx_bridge.o \
+ services4/srvkm/devices/sgx/sgxinit.o \
+ services4/srvkm/devices/sgx/sgxpower.o \
+ services4/srvkm/devices/sgx/sgxreset.o \
+ services4/srvkm/devices/sgx/sgxutils.o \
+ services4/srvkm/devices/sgx/sgxkick.o \
+ services4/srvkm/devices/sgx/sgxtransfer.o \
+ services4/srvkm/devices/sgx/mmu.o \
+ services4/srvkm/devices/sgx/pb.o
+
+ifneq ($(W),1)
+CFLAGS_bridged_sgx_bridge.o := -Werror
+CFLAGS_sgxinit.o := -Werror
+CFLAGS_sgxpower.o := -Werror
+CFLAGS_sgxreset.o := -Werror
+CFLAGS_sgxutils.o := -Werror
+CFLAGS_sgxkick.o := -Werror
+CFLAGS_sgxtransfer.o := -Werror
+CFLAGS_mmu.o := -Werror
+CFLAGS_pb.o := -Werror
+endif
+
+ifeq ($(SUPPORT_DRI_DRM),1)
+
+pvrsrvkm_sgx$(SGXCORE)_$(SGX_CORE_REV)-y += \
+ services4/srvkm/env/linux/pvr_drm.o
+
+ccflags-y += \
+ -I$(KERNELDIR)/include/drm \
+ -I$(TOP)/services4/include/env/linux \
+
+ifeq ($(PVR_DRI_DRM_NOT_PCI),1)
+ccflags-y += -I$(TOP)/services4/3rdparty/linux_drm
+endif
+
+endif # SUPPORT_DRI_DRM
diff --git a/pvr-source/services4/srvkm/env/linux/Linux.mk b/pvr-source/services4/srvkm/env/linux/Linux.mk
new file mode 100644
index 0000000..7e3d0fb
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/Linux.mk
@@ -0,0 +1,45 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+modules := srvkm
+
+srvkm_type := kernel_module
+srvkm_target := pvrsrvkm_sgx$(SGXCORE)_$(SGX_CORE_REV).ko
+srvkm_makefile := $(THIS_DIR)/Kbuild.mk
diff --git a/pvr-source/services4/srvkm/env/linux/env_data.h b/pvr-source/services4/srvkm/env/linux/env_data.h
new file mode 100644
index 0000000..b838809
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/env_data.h
@@ -0,0 +1,93 @@
+/*************************************************************************/ /*!
+@Title Environmental Data header file
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Linux-specific part of system data.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef _ENV_DATA_
+#define _ENV_DATA_
+
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+
+#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
+#include <linux/workqueue.h>
+#endif
+
+/*
+ * Env data specific to linux - convenient place to put this
+ */
+
+/* Fairly arbitrary sizes - hopefully enough for all bridge calls */
+#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;
+#if defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
+ struct workqueue_struct *psWorkQueue;
+#endif
+#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
+ struct work_struct sMISRWork;
+ IMG_VOID *pvMISRData;
+#else
+ struct tasklet_struct sMISRTasklet;
+#endif
+#if defined (SUPPORT_ION)
+ IMG_HANDLE hIonHeaps;
+ IMG_HANDLE hIonDev;
+#endif
+} ENV_DATA;
+
+#endif /* _ENV_DATA_ */
+/*****************************************************************************
+ End of file (env_data.h)
+*****************************************************************************/
diff --git a/pvr-source/services4/srvkm/env/linux/env_perproc.h b/pvr-source/services4/srvkm/env/linux/env_perproc.h
new file mode 100644
index 0000000..8a37a7f
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/env_perproc.h
@@ -0,0 +1,79 @@
+/*************************************************************************/ /*!
+@Title OS specific per process data interface
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Linux per process data
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef __ENV_PERPROC_H__
+#define __ENV_PERPROC_H__
+
+#include <linux/list.h>
+#include <linux/proc_fs.h>
+
+#include "services.h"
+#include "handle.h"
+
+#define ION_CLIENT_NAME_SIZE 50
+typedef struct _PVRSRV_ENV_PER_PROCESS_DATA_
+{
+ IMG_HANDLE hBlockAlloc;
+ struct proc_dir_entry *psProcDir;
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+ struct list_head sDRMAuthListHead;
+#endif
+#if defined (SUPPORT_ION)
+ struct ion_client *psIONClient;
+ IMG_CHAR azIonClientName[ION_CLIENT_NAME_SIZE];
+#endif
+} 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);
+
+IMG_HANDLE LinuxTerminatingProcessPrivateData(IMG_VOID);
+
+#endif /* __ENV_PERPROC_H__ */
+
+/******************************************************************************
+ End of file (env_perproc.h)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/env/linux/event.c b/pvr-source/services4/srvkm/env/linux/event.c
new file mode 100644
index 0000000..b70a79d
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/event.c
@@ -0,0 +1,414 @@
+/*************************************************************************/ /*!
+@Title Event Object
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#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/spinlock.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"
+#include "event.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;
+
+/*!
+******************************************************************************
+
+ @Function LinuxEventObjectListCreate
+
+ @Description
+
+ Linux wait object list creation
+
+ @Output hOSEventKM : Pointer to the event object list handle
+
+ @Return PVRSRV_ERROR : Error code
+
+******************************************************************************/
+PVRSRV_ERROR LinuxEventObjectListCreate(IMG_HANDLE *phEventObjectList)
+{
+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psEventObjectList;
+
+ if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT_LIST),
+ (IMG_VOID **)&psEventObjectList, IMG_NULL,
+ "Linux Event Object List") != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectCreate: failed to allocate memory for event list"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ INIT_LIST_HEAD(&psEventObjectList->sList);
+
+ rwlock_init(&psEventObjectList->sLock);
+
+ *phEventObjectList = (IMG_HANDLE *) psEventObjectList;
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function LinuxEventObjectListDestroy
+
+ @Description
+
+ Linux wait object list destruction
+
+ @Input hOSEventKM : Event object list handle
+
+ @Return PVRSRV_ERROR : Error code
+
+******************************************************************************/
+PVRSRV_ERROR LinuxEventObjectListDestroy(IMG_HANDLE hEventObjectList)
+{
+
+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST *) hEventObjectList ;
+
+ if(psEventObjectList)
+ {
+ IMG_BOOL bListEmpty;
+
+ read_lock(&psEventObjectList->sLock);
+ bListEmpty = list_empty(&psEventObjectList->sList);
+ read_unlock(&psEventObjectList->sLock);
+
+ if (!bListEmpty)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectListDestroy: Event List is not empty"));
+ return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT;
+ }
+
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT_LIST), psEventObjectList, IMG_NULL);
+ /*not nulling pointer, copy on stack*/
+ }
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function LinuxEventObjectDelete
+
+ @Description
+
+ Linux wait object removal
+
+ @Input hOSEventObjectList : Event object list handle
+ @Input hOSEventObject : Event object handle
+ @Input bResManCallback : Called from the resman
+
+ @Return PVRSRV_ERROR : Error code
+
+******************************************************************************/
+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: %u", psLinuxEventObject->ui32Stats));
+#endif
+ if(ResManFreeResByPtr(psLinuxEventObject->hResItem, CLEANUP_WITH_POLL) != PVRSRV_OK)
+ {
+ return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT;
+ }
+
+ return PVRSRV_OK;
+ }
+ }
+ return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT;
+
+}
+
+/*!
+******************************************************************************
+
+ @Function LinuxEventObjectDeleteCallback
+
+ @Description
+
+ Linux wait object removal
+
+ @Input hOSEventObject : Event object handle
+
+ @Return PVRSRV_ERROR : Error code
+
+******************************************************************************/
+static PVRSRV_ERROR LinuxEventObjectDeleteCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bForceCleanup)
+{
+ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = pvParam;
+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = psLinuxEventObject->psLinuxEventObjectList;
+ unsigned long ulLockFlags;
+
+ PVR_UNREFERENCED_PARAMETER(ui32Param);
+ PVR_UNREFERENCED_PARAMETER(bForceCleanup);
+
+ write_lock_irqsave(&psLinuxEventObjectList->sLock, ulLockFlags);
+ list_del(&psLinuxEventObject->sList);
+ write_unlock_irqrestore(&psLinuxEventObjectList->sLock, ulLockFlags);
+
+#if defined(DEBUG)
+ PVR_DPF((PVR_DBG_MESSAGE, "LinuxEventObjectDeleteCallback: Event object waits: %u", psLinuxEventObject->ui32Stats));
+#endif
+
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT), psLinuxEventObject, IMG_NULL);
+ /*not nulling pointer, copy on stack*/
+
+ return PVRSRV_OK;
+}
+/*!
+******************************************************************************
+
+ @Function LinuxEventObjectAdd
+
+ @Description
+
+ Linux wait object addition
+
+ @Input hOSEventObjectList : Event object list handle
+ @Output phOSEventObject : Pointer to the event object handle
+
+ @Return PVRSRV_ERROR : Error code
+
+******************************************************************************/
+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;
+ unsigned long ulLockFlags;
+
+ 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;
+ }
+
+ /* allocate completion variable */
+ if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT),
+ (IMG_VOID **)&psLinuxEventObject, IMG_NULL,
+ "Linux Event Object") != 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_irqsave(&psLinuxEventObjectList->sLock, ulLockFlags);
+ list_add(&psLinuxEventObject->sList, &psLinuxEventObjectList->sList);
+ write_unlock_irqrestore(&psLinuxEventObjectList->sLock, ulLockFlags);
+
+ *phOSEventObject = psLinuxEventObject;
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function LinuxEventObjectSignal
+
+ @Description
+
+ Linux wait object signaling function
+
+ @Input hOSEventObjectList : Event object list handle
+
+ @Return PVRSRV_ERROR : Error code
+
+******************************************************************************/
+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, *psList;
+
+ psList = &psLinuxEventObjectList->sList;
+
+ /*
+ * We don't take the write lock in interrupt context, so we don't
+ * need to use read_lock_irqsave.
+ */
+ read_lock(&psLinuxEventObjectList->sLock);
+ list_for_each(psListEntry, psList)
+ {
+
+ psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)list_entry(psListEntry, PVRSRV_LINUX_EVENT_OBJECT, sList);
+
+ atomic_inc(&psLinuxEventObject->sTimeStamp);
+ wake_up_interruptible(&psLinuxEventObject->sWait);
+ }
+ read_unlock(&psLinuxEventObjectList->sLock);
+
+ return PVRSRV_OK;
+
+}
+
+/*!
+******************************************************************************
+
+ @Function LinuxEventObjectWait
+
+ @Description
+
+ Linux wait object routine
+
+ @Input hOSEventObject : Event object handle
+
+ @Input ui32MSTimeout : Time out value in msec
+
+ @Return PVRSRV_ERROR : Error code
+
+******************************************************************************/
+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 = (IMG_UINT32)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/pvr-source/services4/srvkm/env/linux/event.h b/pvr-source/services4/srvkm/env/linux/event.h
new file mode 100644
index 0000000..5c1451c
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/event.h
@@ -0,0 +1,48 @@
+/*************************************************************************/ /*!
+@Title Event Object
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+
+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/pvr-source/services4/srvkm/env/linux/gc_bvmapping.c b/pvr-source/services4/srvkm/env/linux/gc_bvmapping.c
new file mode 100644
index 0000000..6c5d17a
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/gc_bvmapping.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2011 Texas Instruments, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/bltsville.h>
+#include <linux/bvinternal.h>
+#include <linux/gcbv-iface.h>
+
+#include "gc_bvmapping.h"
+#include "services_headers.h"
+
+void gc_bvmap_meminfo(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+ int i;
+ IMG_CPU_PHYADDR phy_addr;
+ unsigned long *page_addrs;
+ struct bvbuffdesc *buffdesc;
+ struct bvphysdesc *physdesc;
+ int num_pages;
+ struct bventry bv_entry;
+ enum bverror bv_error;
+
+ gcbv_init(&bv_entry);
+ if (!bv_entry.bv_map) {
+ psMemInfo->bvmap_handle = NULL;
+ return;
+ }
+
+ num_pages = (psMemInfo->uAllocSize +
+ PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+ page_addrs = kzalloc(sizeof(*page_addrs) * num_pages, GFP_KERNEL);
+ if (!page_addrs) {
+ printk(KERN_ERR "%s: Out of memory\n", __func__);
+ return;
+ }
+
+ physdesc = kzalloc(sizeof(*physdesc), GFP_KERNEL);
+ buffdesc = kzalloc(sizeof(*buffdesc), GFP_KERNEL);
+ if (!buffdesc || !physdesc) {
+ printk(KERN_ERR "%s: Out of memory\n", __func__);
+ kfree(page_addrs);
+ kfree(physdesc);
+ kfree(buffdesc);
+ return;
+ }
+
+ for (i = 0; i < num_pages; i++) {
+ phy_addr = OSMemHandleToCpuPAddr(
+ psMemInfo->sMemBlk.hOSMemHandle, i << PAGE_SHIFT);
+ page_addrs[i] = (u32)phy_addr.uiAddr;
+ }
+
+ buffdesc->structsize = sizeof(*buffdesc);
+ buffdesc->map = NULL;
+ buffdesc->length = psMemInfo->uAllocSize;
+ buffdesc->auxtype = BVAT_PHYSDESC;
+ buffdesc->auxptr = physdesc;
+ physdesc->structsize = sizeof(*physdesc);
+ physdesc->pagesize = PAGE_SIZE;
+ physdesc->pagearray = page_addrs;
+ physdesc->pagecount = num_pages;
+
+ /*
+ * For ion allocated buffers let's verify how many planes this
+ * meminfo consist of
+ */
+ if(psMemInfo->ui32Flags & PVRSRV_MEM_ION) {
+ IMG_UINT32 num_addr_offsets = 0;
+ OSGetMemMultiPlaneInfo(psMemInfo->sMemBlk.hOSMemHandle,
+ NULL, &num_addr_offsets);
+
+ /*
+ * Account for this meminfo plane offset (relative to the base
+ * address) if necessary
+ */
+ if(num_addr_offsets > 0)
+ physdesc->pageoffset = psMemInfo->planeOffsets[0];
+
+ /*
+ * In BV there is no way to specify multiple offsets, check
+ * all planes have the same offset and report any discrepancy
+ */
+ for (i = 1; i < num_addr_offsets; i++) {
+ IMG_UINT32 plane_offset =
+ psMemInfo->planeOffsets[i] % PAGE_SIZE;
+ if (psMemInfo->planeOffsets[0] != plane_offset) {
+ printk(KERN_WARNING "%s: meminfo %p offset 0 %d"
+ " != offset %d %d, coalignment is "
+ "missing\n", __func__, psMemInfo,
+ psMemInfo->planeOffsets[0],
+ i, plane_offset);
+ }
+ }
+ }
+
+ bv_error = bv_entry.bv_map(buffdesc);
+ if (bv_error) {
+ printk(KERN_ERR "%s: Failed to map meminfo %p, bverror %d\n",
+ __func__, psMemInfo, bv_error);
+ psMemInfo->bvmap_handle = NULL;
+ } else
+ psMemInfo->bvmap_handle = buffdesc;
+
+}
+
+void gc_bvunmap_meminfo(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+ struct bvbuffdesc *buffdesc;
+ struct bvphysdesc *physdesc;
+ struct bventry bv_entry;
+ enum bverror bv_error;
+
+ gcbv_init(&bv_entry);
+ if (!bv_entry.bv_map || !psMemInfo || !psMemInfo->bvmap_handle)
+ return;
+
+ buffdesc = psMemInfo->bvmap_handle;
+ physdesc = (struct bvphysdesc*) buffdesc->auxptr;
+ bv_error = bv_entry.bv_unmap(buffdesc);
+ if (bv_error) {
+ printk(KERN_ERR "%s: Failed to unmap bvhandle %p from meminfo "
+ "%p, bverror %d\n", __func__, buffdesc, psMemInfo,
+ bv_error);
+ }
+
+ kfree(physdesc->pagearray);
+ kfree(physdesc);
+ kfree(psMemInfo->bvmap_handle);
+ psMemInfo->bvmap_handle = NULL;
+}
+
+IMG_VOID *gc_meminfo_to_hndl(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
+{
+ return psMemInfo->bvmap_handle;
+}
diff --git a/pvr-source/services4/srvkm/env/linux/gc_bvmapping.h b/pvr-source/services4/srvkm/env/linux/gc_bvmapping.h
new file mode 100644
index 0000000..6a3a2b1
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/gc_bvmapping.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 Texas Instruments, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef GC_BVMAPPING_H
+#define GC_BVMAPPING_H
+
+#include "services_headers.h"
+
+void gc_bvunmap_meminfo(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
+
+void gc_bvmap_meminfo(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
+
+IMG_VOID *gc_meminfo_to_hndl(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
+
+#endif
diff --git a/pvr-source/services4/srvkm/env/linux/ion.c b/pvr-source/services4/srvkm/env/linux/ion.c
new file mode 100644
index 0000000..3e772bc
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/ion.c
@@ -0,0 +1,363 @@
+/*************************************************************************/ /*!
+@Title Ion driver inter-operability code.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "ion.h"
+
+#include "services.h"
+#include "servicesint.h"
+#include "mutex.h"
+#include "lock.h"
+#include "mm.h"
+#include "handle.h"
+#include "perproc.h"
+#include "env_perproc.h"
+#include "private_data.h"
+#include "pvr_debug.h"
+
+#include <linux/module.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+
+#if defined (CONFIG_ION_OMAP)
+#define MAX_HANDLES_PER_FD 2
+extern struct ion_client *gpsIONClient;
+
+int PVRSRVExportFDToIONHandles(int fd, struct ion_client **client,
+ struct ion_handle **handles,
+ unsigned int *num_handles)
+{
+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+ LinuxMemArea *psLinuxMemArea;
+ PVRSRV_ERROR eError;
+ struct file *psFile;
+ int i;
+ unsigned int ui32NumHandles = *num_handles;
+ int ret = -EINVAL;
+
+ /* Take the bridge mutex so the handle won't be freed underneath us */
+ LinuxLockMutex(&gPVRSRVLock);
+
+ psFile = fget(fd);
+ if(!psFile)
+ goto err_unlock;
+
+ psPrivateData = psFile->private_data;
+ if(!psPrivateData)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: struct file* has no private_data; "
+ "invalid export handle", __func__));
+ goto err_fput;
+ }
+
+ eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+ (IMG_PVOID *)&psKernelMemInfo,
+ psPrivateData->hKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to look up MEM_INFO handle",
+ __func__));
+ goto err_fput;
+ }
+
+ psLinuxMemArea = (LinuxMemArea *)psKernelMemInfo->sMemBlk.hOSMemHandle;
+ BUG_ON(psLinuxMemArea == IMG_NULL);
+
+ if(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_ION)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Valid handle, but not an ION buffer",
+ __func__));
+ goto err_fput;
+ }
+
+ /* Client is requesting fewer handles then we have */
+ if(ui32NumHandles < psLinuxMemArea->uData.sIONTilerAlloc.ui32NumValidPlanes) {
+
+ PVR_DPF((PVR_DBG_ERROR, "%s: Client requested %u handles, but we have %u",
+ __func__,
+ ui32NumHandles,
+ psLinuxMemArea->uData.sIONTilerAlloc.ui32NumValidPlanes));
+
+ /* Clear client handles */
+ for (i = 0; i < ui32NumHandles; i++)
+ handles[i] = NULL;
+
+ /* Return number of handles to client */
+ *num_handles = psLinuxMemArea->uData.sIONTilerAlloc.ui32NumValidPlanes;
+ goto err_fput;
+ }
+
+ for (i = 0; (i < psLinuxMemArea->uData.sIONTilerAlloc.ui32NumValidPlanes) && (i < MAX_HANDLES_PER_FD); i++)
+ handles[i] = psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[i];
+
+ *num_handles = i;
+
+ if(client)
+ *client = gpsIONClient;
+
+ ret = 0;
+
+err_fput:
+ fput(psFile);
+err_unlock:
+ /* Allow PVRSRV clients to communicate with srvkm again */
+ LinuxUnLockMutex(&gPVRSRVLock);
+
+ return ret;
+}
+
+struct ion_handle *
+PVRSRVExportFDToIONHandle(int fd, struct ion_client **client)
+{
+ unsigned int num_handles = 1;
+ struct ion_handle *psHandle = IMG_NULL;
+ PVRSRVExportFDToIONHandles(fd, client, &psHandle, &num_handles);
+ return psHandle;
+}
+
+EXPORT_SYMBOL(PVRSRVExportFDToIONHandles);
+EXPORT_SYMBOL(PVRSRVExportFDToIONHandle);
+#endif
+
+#if defined (SUPPORT_ION)
+#include "syscommon.h"
+#include "env_data.h"
+#include "../drivers/gpu/ion/ion_priv.h"
+#include "linux/kernel.h"
+
+struct ion_heap **apsIonHeaps;
+struct ion_device *psIonDev;
+
+static struct ion_platform_data generic_config = {
+ .nr = 2,
+ .heaps = {
+ {
+ .type = ION_HEAP_TYPE_SYSTEM_CONTIG,
+ .name = "System contig",
+ .id = ION_HEAP_TYPE_SYSTEM_CONTIG,
+ },
+ {
+ .type = ION_HEAP_TYPE_SYSTEM,
+ .name = "System",
+ .id = ION_HEAP_TYPE_SYSTEM,
+ }
+ }
+};
+
+PVRSRV_ERROR IonInit(IMG_VOID)
+{
+ int uiHeapCount = generic_config.nr;
+ int uiError;
+ int i;
+
+ apsIonHeaps = kzalloc(sizeof(struct ion_heap *) * uiHeapCount, GFP_KERNEL);
+ /* Create the ion devicenode */
+ psIonDev = ion_device_create(NULL);
+ if (IS_ERR_OR_NULL(psIonDev)) {
+ kfree(apsIonHeaps);
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ /* Register all the heaps */
+ for (i = 0; i < generic_config.nr; i++)
+ {
+ struct ion_platform_heap *psPlatHeapData = &generic_config.heaps[i];
+
+ apsIonHeaps[i] = ion_heap_create(psPlatHeapData);
+ if (IS_ERR_OR_NULL(apsIonHeaps[i]))
+ {
+ uiError = PTR_ERR(apsIonHeaps[i]);
+ goto failHeapCreate;
+ }
+ ion_device_add_heap(psIonDev, apsIonHeaps[i]);
+ }
+
+ return PVRSRV_OK;
+failHeapCreate:
+ for (i = 0; i < uiHeapCount; i++) {
+ if (apsIonHeaps[i])
+ {
+ ion_heap_destroy(apsIonHeaps[i]);
+ }
+ }
+ kfree(apsIonHeaps);
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+}
+
+IMG_VOID IonDeinit(IMG_VOID)
+{
+ int uiHeapCount = generic_config.nr;
+ int i;
+
+ for (i = 0; i < uiHeapCount; i++) {
+ if (apsIonHeaps[i])
+ {
+ ion_heap_destroy(apsIonHeaps[i]);
+ }
+ }
+ kfree(apsIonHeaps);
+ ion_device_destroy(psIonDev);
+}
+
+typedef struct _ION_IMPORT_DATA_
+{
+ struct ion_client *psIonClient;
+ struct ion_handle *psIonHandle;
+ IMG_PVOID pvKernAddr;
+} ION_IMPORT_DATA;
+
+PVRSRV_ERROR IonImportBufferAndAquirePhysAddr(IMG_HANDLE hIonDev,
+ IMG_HANDLE hIonFD,
+ IMG_UINT32 *pui32PageCount,
+ IMG_SYS_PHYADDR **ppasSysPhysAddr,
+ IMG_PVOID *ppvKernAddr,
+ IMG_HANDLE *phPriv)
+{
+ struct ion_client *psIonClient = hIonDev;
+ struct ion_handle *psIonHandle;
+ struct scatterlist *psScatterList;
+ struct scatterlist *psTemp;
+ IMG_SYS_PHYADDR *pasSysPhysAddr = NULL;
+ ION_IMPORT_DATA *psImportData;
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32PageCount = 0;
+ IMG_UINT32 i;
+ IMG_PVOID pvKernAddr;
+ int fd = (int) hIonFD;
+
+ psImportData = kmalloc(sizeof(ION_IMPORT_DATA), GFP_KERNEL);
+ if (psImportData == NULL)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ /* Get the buffer handle */
+ psIonHandle = ion_import_fd(psIonClient, fd);
+ if (psIonHandle == IMG_NULL)
+ {
+ eError = PVRSRV_ERROR_BAD_MAPPING;
+ goto exitFailImport;
+ }
+
+ /* Create data for free callback */
+ psImportData->psIonClient = psIonClient;
+ psImportData->psIonHandle = psIonHandle;
+
+ psScatterList = ion_map_dma(psIonClient, psIonHandle);
+ if (psScatterList == NULL)
+ {
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ goto exitFailMap;
+ }
+
+ /*
+ We do a two pass process, 1st workout how many pages there
+ are, 2nd fill in the data.
+ */
+ for (i=0;i<2;i++)
+ {
+ psTemp = psScatterList;
+ if (i == 1)
+ {
+ pasSysPhysAddr = kmalloc(sizeof(IMG_SYS_PHYADDR) * ui32PageCount, GFP_KERNEL);
+ if (pasSysPhysAddr == NULL)
+ {
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto exitFailAlloc;
+ }
+ ui32PageCount = 0; /* Reset the page count a we use if for the index */
+ }
+
+ while(psTemp)
+ {
+ IMG_UINT32 j;
+
+ for (j=0;j<psTemp->length;j+=PAGE_SIZE)
+ {
+ if (i == 1)
+ {
+ /* Pass 2: Get the page data */
+ pasSysPhysAddr[ui32PageCount].uiAddr = sg_phys(psTemp);
+ }
+ ui32PageCount++;
+ }
+ psTemp = sg_next(psTemp);
+ }
+ }
+
+ pvKernAddr = ion_map_kernel(psIonClient, psIonHandle);
+ if (IS_ERR(pvKernAddr))
+ {
+ pvKernAddr = IMG_NULL;
+ }
+
+ psImportData->pvKernAddr = pvKernAddr;
+
+ *ppvKernAddr = pvKernAddr;
+ *pui32PageCount = ui32PageCount;
+ *ppasSysPhysAddr = pasSysPhysAddr;
+ *phPriv = psImportData;
+ return PVRSRV_OK;
+
+exitFailAlloc:
+ ion_unmap_dma(psIonClient, psIonHandle);
+exitFailMap:
+ ion_free(psIonClient, psIonHandle);
+exitFailImport:
+ kfree(psImportData);
+ return eError;
+}
+
+
+IMG_VOID IonUnimportBufferAndReleasePhysAddr(IMG_HANDLE hPriv)
+{
+ ION_IMPORT_DATA *psImportData = hPriv;
+
+ ion_unmap_dma(psImportData->psIonClient, psImportData->psIonHandle);
+ if (psImportData->pvKernAddr)
+ {
+ ion_unmap_kernel(psImportData->psIonClient, psImportData->psIonHandle);
+ }
+ ion_free(psImportData->psIonClient, psImportData->psIonHandle);
+ kfree(psImportData);
+}
+#endif
diff --git a/pvr-source/services4/srvkm/env/linux/ion.h b/pvr-source/services4/srvkm/env/linux/ion.h
new file mode 100644
index 0000000..1cf385d
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/ion.h
@@ -0,0 +1,74 @@
+/*************************************************************************/ /*!
+@Title Ion driver inter-operability code.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __IMG_LINUX_ION_H__
+#define __IMG_LINUX_ION_H__
+
+#include <linux/ion.h>
+#if defined (CONFIG_ION_OMAP)
+#include <linux/omap_ion.h>
+#endif
+#if defined (SUPPORT_ION)
+#include "img_types.h"
+#include "servicesext.h"
+#endif
+
+int PVRSRVExportFDToIONHandles(int fd, struct ion_client **client,
+ struct ion_handle **handles,
+ unsigned int *num_handles);
+
+struct ion_handle *PVRSRVExportFDToIONHandle(int fd,
+ struct ion_client **client);
+
+#if defined (SUPPORT_ION)
+PVRSRV_ERROR IonInit(IMG_VOID);
+IMG_VOID IonDeinit(IMG_VOID);
+
+PVRSRV_ERROR IonImportBufferAndAquirePhysAddr(IMG_HANDLE hIonDev,
+ IMG_HANDLE hIonFD,
+ IMG_UINT32 *pui32PageCount,
+ IMG_SYS_PHYADDR **ppasSysPhysAddr,
+ IMG_PVOID *ppvKernAddr,
+ IMG_HANDLE *phPriv);
+
+IMG_VOID IonUnimportBufferAndReleasePhysAddr(IMG_HANDLE hPriv);
+#endif
+#endif /* __IMG_LINUX_ION_H__ */
diff --git a/pvr-source/services4/srvkm/env/linux/linkage.h b/pvr-source/services4/srvkm/env/linux/linkage.h
new file mode 100644
index 0000000..55cd4f0
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/linkage.h
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@Title Linux specific Services code internal interfaces
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Interfaces between various parts of the Linux specific
+ Services code, that don't have any other obvious
+ header file to go into.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef __LINKAGE_H__
+#define __LINKAGE_H__
+
+#if !defined(SUPPORT_DRI_DRM)
+long PVRSRV_BridgeDispatchKM(struct file *file, unsigned int cmd, unsigned long arg);
+#endif
+
+IMG_VOID PVRDPFInit(IMG_VOID);
+PVRSRV_ERROR PVROSFuncInit(IMG_VOID);
+IMG_VOID PVROSFuncDeInit(IMG_VOID);
+
+#ifdef DEBUG
+
+IMG_INT PVRDebugProcSetLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data);
+void ProcSeqShowDebugLevel(struct seq_file *sfile,void* el);
+
+#ifdef PVR_MANUAL_POWER_CONTROL
+IMG_INT PVRProcSetPowerLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data);
+
+void ProcSeqShowPowerLevel(struct seq_file *sfile,void* el);
+
+#endif /* PVR_MANUAL_POWER_CONTROL */
+
+#endif /* DEBUG */
+
+#endif /* __LINKAGE_H__ */
+/*****************************************************************************
+ End of file (linkage.h)
+*****************************************************************************/
diff --git a/pvr-source/services4/srvkm/env/linux/lock.h b/pvr-source/services4/srvkm/env/linux/lock.h
new file mode 100644
index 0000000..11adcaa
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/lock.h
@@ -0,0 +1,56 @@
+/*************************************************************************/ /*!
+@Title Main driver lock
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description The main driver lock, held in most places in
+ the driver.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef __LOCK_H__
+#define __LOCK_H__
+
+/*
+ * Main driver lock, used to ensure driver code is single threaded.
+ * There are some places where this lock must not be taken, such as
+ * in the mmap related deriver entry points.
+ */
+extern PVRSRV_LINUX_MUTEX gPVRSRVLock;
+
+#endif /* __LOCK_H__ */
+/*****************************************************************************
+ End of file (lock.h)
+*****************************************************************************/
diff --git a/pvr-source/services4/srvkm/env/linux/mm.c b/pvr-source/services4/srvkm/env/linux/mm.c
new file mode 100644
index 0000000..0815e46
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/mm.c
@@ -0,0 +1,2945 @@
+/*************************************************************************/ /*!
+@Title Misc memory management utility functions for Linux
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#if !defined(PVR_LINUX_MEM_AREA_POOL_MAX_PAGES)
+#define PVR_LINUX_MEM_AREA_POOL_MAX_PAGES 0
+#endif
+
+#include <linux/kernel.h>
+#include <asm/atomic.h>
+#include <linux/list.h>
+#include <linux/mutex.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>
+
+#if defined(PVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0))
+#include <linux/shrinker.h>
+#endif
+#endif
+
+#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_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ #include "lists.h"
+#endif
+
+/* If there is no explicit definition
+ * for the minimum DMM alignment size,
+ * then set it to "0" and let ION/DMM
+ * set the minimum value. */
+#ifndef CONFIG_TILER_GRANULARITY
+#define CONFIG_TILER_GRANULARITY 0
+#endif
+
+/*
+ * The page pool entry count is an atomic int so that the shrinker function
+ * can return it even when we can't take the lock that protects the page pool
+ * list.
+ */
+static atomic_t g_sPagePoolEntryCount = ATOMIC_INIT(0);
+
+#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_ION,
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ DEBUG_MEM_ALLOC_TYPE_VMAP,
+#endif
+ DEBUG_MEM_ALLOC_TYPE_COUNT
+} DEBUG_MEM_ALLOC_TYPE;
+
+typedef struct _DEBUG_MEM_ALLOC_REC
+{
+ DEBUG_MEM_ALLOC_TYPE eAllocType;
+ IMG_VOID *pvKey; /* Some unique value (private to the eAllocType) */
+ 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;
+ struct _DEBUG_MEM_ALLOC_REC **ppsThis;
+} DEBUG_MEM_ALLOC_REC;
+
+static IMPLEMENT_LIST_ANY_VA_2(DEBUG_MEM_ALLOC_REC, IMG_BOOL, IMG_FALSE)
+static IMPLEMENT_LIST_ANY_VA(DEBUG_MEM_ALLOC_REC)
+static IMPLEMENT_LIST_FOR_EACH(DEBUG_MEM_ALLOC_REC)
+static IMPLEMENT_LIST_INSERT(DEBUG_MEM_ALLOC_REC)
+static IMPLEMENT_LIST_REMOVE(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];
+
+/* vmalloc + kmalloc + alloc_pages + kmem_cache */
+static IMG_UINT32 g_SysRAMWaterMark; /* Doesn't include page pool */
+static IMG_UINT32 g_SysRAMHighWaterMark; /* *DOES* include page pool */
+
+static inline IMG_UINT32
+SysRAMTrueWaterMark(void)
+{
+ return g_SysRAMWaterMark + PAGES_TO_BYTES(atomic_read(&g_sPagePoolEntryCount));
+}
+
+/* ioremap + io */
+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 struct proc_dir_entry *g_SeqFileMemoryRecords;
+static void* ProcSeqNextMemoryRecords(struct seq_file *sfile,void* el,loff_t off);
+static void ProcSeqShowMemoryRecords(struct seq_file *sfile,void* el);
+static void* ProcSeqOff2ElementMemoryRecords(struct seq_file * sfile, loff_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;
+ struct _DEBUG_LINUX_MEM_AREA_REC **ppsThis;
+}DEBUG_LINUX_MEM_AREA_REC;
+
+
+static IMPLEMENT_LIST_ANY_VA(DEBUG_LINUX_MEM_AREA_REC)
+static IMPLEMENT_LIST_FOR_EACH(DEBUG_LINUX_MEM_AREA_REC)
+static IMPLEMENT_LIST_INSERT(DEBUG_LINUX_MEM_AREA_REC)
+static IMPLEMENT_LIST_REMOVE(DEBUG_LINUX_MEM_AREA_REC)
+
+
+
+
+static DEBUG_LINUX_MEM_AREA_REC *g_LinuxMemAreaRecords;
+static IMG_UINT32 g_LinuxMemAreaCount;
+static IMG_UINT32 g_LinuxMemAreaWaterMark;
+static IMG_UINT32 g_LinuxMemAreaHighWaterMark;
+
+
+static struct proc_dir_entry *g_SeqFileMemArea;
+
+static void* ProcSeqNextMemArea(struct seq_file *sfile,void* el,loff_t off);
+static void ProcSeqShowMemArea(struct seq_file *sfile,void* el);
+static void* ProcSeqOff2ElementMemArea(struct seq_file *sfile, loff_t off);
+
+#endif
+
+#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+static PVRSRV_LINUX_MUTEX g_sDebugMutex;
+#endif
+
+#if (defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS))
+static void ProcSeqStartstopDebugMutex(struct seq_file *sfile,IMG_BOOL start);
+#endif
+
+typedef struct
+{
+ /* Linkage for page pool LRU list */
+ struct list_head sPagePoolItem;
+
+ struct page *psPage;
+} LinuxPagePoolEntry;
+
+static LinuxKMemCache *g_PsLinuxMemAreaCache;
+static LinuxKMemCache *g_PsLinuxPagePoolCache;
+
+static LIST_HEAD(g_sPagePoolList);
+static int g_iPagePoolMaxEntries;
+
+#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
+
+
+static inline IMG_BOOL
+AreaIsUncached(IMG_UINT32 ui32AreaFlags)
+{
+ return (ui32AreaFlags & (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_UNCACHED)) != 0;
+}
+
+static inline IMG_BOOL
+CanFreeToPool(LinuxMemArea *psLinuxMemArea)
+{
+ return AreaIsUncached(psLinuxMemArea->ui32AreaFlags) && !psLinuxMemArea->bNeedsCacheInvalidate;
+}
+
+IMG_VOID *
+_KMallocWrapper(IMG_UINT32 ui32ByteSize, gfp_t uFlags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
+{
+ IMG_VOID *pvRet;
+ pvRet = kmalloc(ui32ByteSize, uFlags);
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ if (pvRet)
+ {
+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_KMALLOC,
+ pvRet,
+ pvRet,
+ 0,
+ NULL,
+ ui32ByteSize,
+ pszFileName,
+ ui32Line
+ );
+ }
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(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);
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(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 = OSGetCurrentProcessIDKM();
+ psRecord->ui32Bytes = ui32Bytes;
+ psRecord->pszFileName = pszFileName;
+ psRecord->ui32Line = ui32Line;
+
+ List_DEBUG_MEM_ALLOC_REC_Insert(&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)
+ {
+ IMG_UINT32 ui32SysRAMTrueWaterMark;
+
+ g_SysRAMWaterMark += ui32Bytes;
+ ui32SysRAMTrueWaterMark = SysRAMTrueWaterMark();
+
+ if (ui32SysRAMTrueWaterMark > g_SysRAMHighWaterMark)
+ {
+ g_SysRAMHighWaterMark = ui32SysRAMTrueWaterMark;
+ }
+ }
+ 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_BOOL DebugMemAllocRecordRemove_AnyVaCb(DEBUG_MEM_ALLOC_REC *psCurrentRecord, va_list va)
+{
+ DEBUG_MEM_ALLOC_TYPE eAllocType;
+ IMG_VOID *pvKey;
+
+ eAllocType = va_arg(va, DEBUG_MEM_ALLOC_TYPE);
+ pvKey = va_arg(va, IMG_VOID*);
+
+ if (psCurrentRecord->eAllocType == eAllocType
+ && psCurrentRecord->pvKey == pvKey)
+ {
+ eAllocType = psCurrentRecord->eAllocType;
+ g_WaterMarkData[eAllocType] -= psCurrentRecord->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 -= psCurrentRecord->ui32Bytes;
+ }
+ else if (eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP
+ || eAllocType == DEBUG_MEM_ALLOC_TYPE_IO)
+ {
+ g_IOMemWaterMark -= psCurrentRecord->ui32Bytes;
+ }
+
+ List_DEBUG_MEM_ALLOC_REC_Remove(psCurrentRecord);
+ kfree(psCurrentRecord);
+
+ return IMG_TRUE;
+ }
+ else
+ {
+ return IMG_FALSE;
+ }
+}
+
+
+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);
+
+ /* Locate the corresponding allocation entry */
+ if (!List_DEBUG_MEM_ALLOC_REC_IMG_BOOL_Any_va(g_MemoryRecords,
+ DebugMemAllocRecordRemove_AnyVaCb,
+ eAllocType,
+ pvKey))
+ {
+ 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));
+ }
+
+ LinuxUnLockMutex(&g_sDebugMutex);
+}
+
+
+static IMG_CHAR *
+DebugMemAllocRecordTypeToString(DEBUG_MEM_ALLOC_TYPE eAllocType)
+{
+ IMG_CHAR *apszDebugMemoryRecordTypes[] = {
+ "KMALLOC",
+ "VMALLOC",
+ "ALLOC_PAGES",
+ "IOREMAP",
+ "IO",
+ "KMEM_CACHE_ALLOC",
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ "VMAP"
+#endif
+ };
+ return apszDebugMemoryRecordTypes[eAllocType];
+}
+#endif
+
+
+static IMG_BOOL
+AllocFlagsToPGProt(pgprot_t *pPGProtFlags, IMG_UINT32 ui32AllocFlags)
+{
+ pgprot_t PGProtFlags;
+
+ 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,
+ "%s: Unknown mapping flags=0x%08x",
+ __FUNCTION__, ui32AllocFlags));
+ dump_stack();
+ return IMG_FALSE;
+ }
+
+ *pPGProtFlags = PGProtFlags;
+
+ return IMG_TRUE;
+}
+
+IMG_VOID *
+_VMallocWrapper(IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32AllocFlags,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32Line)
+{
+ pgprot_t PGProtFlags;
+ IMG_VOID *pvRet;
+
+ if (!AllocFlagsToPGProt(&PGProtFlags, ui32AllocFlags))
+ {
+ return NULL;
+ }
+
+ /* Allocate virtually contiguous pages */
+ 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
+ );
+ }
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(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);
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+ vfree(pvCpuVAddr);
+}
+
+
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+static IMG_VOID *
+_VMapWrapper(struct page **ppsPageList, IMG_UINT32 ui32NumPages, IMG_UINT32 ui32AllocFlags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
+{
+ pgprot_t PGProtFlags;
+ IMG_VOID *pvRet;
+
+ if (!AllocFlagsToPGProt(&PGProtFlags, ui32AllocFlags))
+ {
+ return NULL;
+ }
+
+ pvRet = vmap(ppsPageList, ui32NumPages, GFP_KERNEL | __GFP_HIGHMEM, PGProtFlags);
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ if (pvRet)
+ {
+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_VMAP,
+ pvRet,
+ pvRet,
+ 0,
+ NULL,
+ PAGES_TO_BYTES(ui32NumPages),
+ pszFileName,
+ ui32Line
+ );
+ }
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+
+ return pvRet;
+}
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define VMapWrapper(ppsPageList, ui32Bytes, ui32AllocFlags) _VMapWrapper(ppsPageList, ui32Bytes, ui32AllocFlags, __FILE__, __LINE__)
+#else
+#define VMapWrapper(ppsPageList, ui32Bytes, ui32AllocFlags) _VMapWrapper(ppsPageList, ui32Bytes, ui32AllocFlags, NULL, 0)
+#endif
+
+
+static IMG_VOID
+_VUnmapWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
+{
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_VMAP, pvCpuVAddr, pszFileName, ui32Line);
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+ vunmap(pvCpuVAddr);
+}
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define VUnmapWrapper(pvCpuVAddr) _VUnmapWrapper(pvCpuVAddr, __FILE__, __LINE__)
+#else
+#define VUnmapWrapper(pvCpuVAddr) _VUnmapWrapper(pvCpuVAddr, NULL, 0)
+#endif
+
+#endif /* defined(PVR_LINUX_MEM_AREA_USE_VMAP) */
+
+
+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);
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+
+ kmem_cache_free(psCache, pvObject);
+}
+
+
+const IMG_CHAR *
+KMemCacheNameWrapper(LinuxKMemCache *psCache)
+{
+ PVR_UNREFERENCED_PARAMETER(psCache);
+
+ /* In this case kmem_cache_t is an incomplete typedef,
+ * so we can't even de-reference to get the name member. It is also a GPL export symbol */
+ return "";
+}
+
+
+static LinuxPagePoolEntry *
+LinuxPagePoolEntryAlloc(IMG_VOID)
+{
+ return KMemCacheAllocWrapper(g_PsLinuxPagePoolCache, GFP_KERNEL);
+}
+
+static IMG_VOID
+LinuxPagePoolEntryFree(LinuxPagePoolEntry *psPagePoolEntry)
+{
+ KMemCacheFreeWrapper(g_PsLinuxPagePoolCache, psPagePoolEntry);
+}
+
+
+static struct page *
+AllocPageFromLinux(void)
+{
+ struct page *psPage;
+
+ psPage = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, 0);
+ if (!psPage)
+ {
+ return NULL;
+
+ }
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
+ /* Reserve those pages to allow them to be re-mapped to user space */
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
+ SetPageReserved(psPage);
+#else
+ mem_map_reserve(psPage);
+#endif
+#endif
+ return psPage;
+}
+
+
+static IMG_VOID
+FreePageToLinux(struct page *psPage)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0))
+ ClearPageReserved(psPage);
+#else
+ mem_map_reserve(psPage);
+#endif
+#endif
+ __free_pages(psPage, 0);
+}
+
+
+#if (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0)
+static DEFINE_MUTEX(g_sPagePoolMutex);
+
+static inline void
+PagePoolLock(void)
+{
+ mutex_lock(&g_sPagePoolMutex);
+}
+
+static inline void
+PagePoolUnlock(void)
+{
+ mutex_unlock(&g_sPagePoolMutex);
+}
+
+static inline int
+PagePoolTrylock(void)
+{
+ return mutex_trylock(&g_sPagePoolMutex);
+}
+
+#else /* (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0) */
+static inline void
+PagePoolLock(void)
+{
+}
+
+static inline void
+PagePoolUnlock(void)
+{
+}
+
+static inline int
+PagePoolTrylock(void)
+{
+ return 1;
+}
+#endif /* (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0) */
+
+
+static inline void
+AddEntryToPool(LinuxPagePoolEntry *psPagePoolEntry)
+{
+ list_add_tail(&psPagePoolEntry->sPagePoolItem, &g_sPagePoolList);
+ atomic_inc(&g_sPagePoolEntryCount);
+}
+
+static inline void
+RemoveEntryFromPool(LinuxPagePoolEntry *psPagePoolEntry)
+{
+ list_del(&psPagePoolEntry->sPagePoolItem);
+ atomic_dec(&g_sPagePoolEntryCount);
+}
+
+static inline LinuxPagePoolEntry *
+RemoveFirstEntryFromPool(void)
+{
+ LinuxPagePoolEntry *psPagePoolEntry;
+
+ if (list_empty(&g_sPagePoolList))
+ {
+ PVR_ASSERT(atomic_read(&g_sPagePoolEntryCount) == 0);
+
+ return NULL;
+ }
+
+ PVR_ASSERT(atomic_read(&g_sPagePoolEntryCount) > 0);
+
+ psPagePoolEntry = list_first_entry(&g_sPagePoolList, LinuxPagePoolEntry, sPagePoolItem);
+
+ RemoveEntryFromPool(psPagePoolEntry);
+
+ return psPagePoolEntry;
+}
+
+static struct page *
+AllocPage(IMG_UINT32 ui32AreaFlags, IMG_BOOL *pbFromPagePool)
+{
+ struct page *psPage = NULL;
+
+ /*
+ * Only uncached allocations can come from the page pool.
+ * The page pool is currently used to reduce the cost of
+ * invalidating the CPU cache when uncached memory is allocated.
+ */
+ if (AreaIsUncached(ui32AreaFlags) && atomic_read(&g_sPagePoolEntryCount) != 0)
+ {
+ LinuxPagePoolEntry *psPagePoolEntry;
+
+ PagePoolLock();
+ psPagePoolEntry = RemoveFirstEntryFromPool();
+ PagePoolUnlock();
+
+ /* List may have changed since we checked the counter */
+ if (psPagePoolEntry)
+ {
+ psPage = psPagePoolEntry->psPage;
+ LinuxPagePoolEntryFree(psPagePoolEntry);
+ *pbFromPagePool = IMG_TRUE;
+ }
+ }
+
+ if (!psPage)
+ {
+ psPage = AllocPageFromLinux();
+ if (psPage)
+ {
+ *pbFromPagePool = IMG_FALSE;
+ }
+ }
+
+ return psPage;
+
+}
+
+static IMG_VOID
+FreePage(IMG_BOOL bToPagePool, struct page *psPage)
+{
+ /* Only uncached allocations can be freed to the page pool */
+ if (bToPagePool && atomic_read(&g_sPagePoolEntryCount) < g_iPagePoolMaxEntries)
+ {
+ LinuxPagePoolEntry *psPagePoolEntry = LinuxPagePoolEntryAlloc();
+ if (psPagePoolEntry)
+ {
+ psPagePoolEntry->psPage = psPage;
+
+ PagePoolLock();
+ AddEntryToPool(psPagePoolEntry);
+ PagePoolUnlock();
+
+ return;
+ }
+ }
+
+ FreePageToLinux(psPage);
+}
+
+static IMG_VOID
+FreePagePool(IMG_VOID)
+{
+ LinuxPagePoolEntry *psPagePoolEntry, *psTempPoolEntry;
+
+ PagePoolLock();
+
+#if (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0)
+ PVR_DPF((PVR_DBG_MESSAGE,"%s: Freeing %d pages from pool", __FUNCTION__, atomic_read(&g_sPagePoolEntryCount)));
+#else
+ PVR_ASSERT(atomic_read(&g_sPagePoolEntryCount) == 0);
+ PVR_ASSERT(list_empty(&g_sPagePoolList));
+#endif
+
+ list_for_each_entry_safe(psPagePoolEntry, psTempPoolEntry, &g_sPagePoolList, sPagePoolItem)
+ {
+ RemoveEntryFromPool(psPagePoolEntry);
+
+ FreePageToLinux(psPagePoolEntry->psPage);
+ LinuxPagePoolEntryFree(psPagePoolEntry);
+ }
+
+ PVR_ASSERT(atomic_read(&g_sPagePoolEntryCount) == 0);
+
+ PagePoolUnlock();
+}
+
+#if defined(PVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK)
+#if defined(PVRSRV_NEED_PVR_ASSERT)
+static struct shrinker g_sShrinker;
+#endif
+
+static int
+ShrinkPagePool(struct shrinker *psShrinker, struct shrink_control *psShrinkControl)
+{
+ unsigned long uNumToScan = psShrinkControl->nr_to_scan;
+
+ PVR_ASSERT(psShrinker == &g_sShrinker);
+ (void)psShrinker;
+
+ if (uNumToScan != 0)
+ {
+ LinuxPagePoolEntry *psPagePoolEntry, *psTempPoolEntry;
+
+ PVR_DPF((PVR_DBG_MESSAGE,"%s: Number to scan: %ld", __FUNCTION__, uNumToScan));
+ PVR_DPF((PVR_DBG_MESSAGE,"%s: Pages in pool before scan: %d", __FUNCTION__, atomic_read(&g_sPagePoolEntryCount)));
+
+ if (!PagePoolTrylock())
+ {
+ PVR_TRACE(("%s: Couldn't get page pool lock", __FUNCTION__));
+ return -1;
+ }
+
+ list_for_each_entry_safe(psPagePoolEntry, psTempPoolEntry, &g_sPagePoolList, sPagePoolItem)
+ {
+ RemoveEntryFromPool(psPagePoolEntry);
+
+ FreePageToLinux(psPagePoolEntry->psPage);
+ LinuxPagePoolEntryFree(psPagePoolEntry);
+
+ if (--uNumToScan == 0)
+ {
+ break;
+ }
+ }
+
+ if (list_empty(&g_sPagePoolList))
+ {
+ PVR_ASSERT(atomic_read(&g_sPagePoolEntryCount) == 0);
+ }
+
+ PagePoolUnlock();
+
+ PVR_DPF((PVR_DBG_MESSAGE,"%s: Pages in pool after scan: %d", __FUNCTION__, atomic_read(&g_sPagePoolEntryCount)));
+ }
+
+ return atomic_read(&g_sPagePoolEntryCount);
+}
+#endif
+
+static IMG_BOOL
+AllocPages(IMG_UINT32 ui32AreaFlags, struct page ***pppsPageList, IMG_HANDLE *phBlockPageList, IMG_UINT32 ui32NumPages, IMG_BOOL *pbFromPagePool)
+{
+ struct page **ppsPageList;
+ IMG_HANDLE hBlockPageList;
+ IMG_INT32 i; /* Must be signed; see "for" loop conditions */
+ PVRSRV_ERROR eError;
+ IMG_BOOL bFromPagePool = IMG_FALSE;
+
+ eError = OSAllocMem(0, sizeof(*ppsPageList) * ui32NumPages, (IMG_VOID **)&ppsPageList, &hBlockPageList,
+ "Array of pages");
+ if (eError != PVRSRV_OK)
+ {
+ goto failed_page_list_alloc;
+ }
+
+ *pbFromPagePool = IMG_TRUE;
+ for(i = 0; i < (IMG_INT32)ui32NumPages; i++)
+ {
+ ppsPageList[i] = AllocPage(ui32AreaFlags, &bFromPagePool);
+ if (!ppsPageList[i])
+ {
+ goto failed_alloc_pages;
+ }
+ *pbFromPagePool &= bFromPagePool;
+ }
+
+ *pppsPageList = ppsPageList;
+ *phBlockPageList = hBlockPageList;
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES,
+ ppsPageList,
+ 0,
+ 0,
+ NULL,
+ PAGES_TO_BYTES(ui32NumPages),
+ "unknown",
+ 0
+ );
+#endif
+
+ return IMG_TRUE;
+
+failed_alloc_pages:
+ for(i--; i >= 0; i--)
+ {
+ FreePage(*pbFromPagePool, ppsPageList[i]);
+ }
+ (IMG_VOID) OSFreeMem(0, sizeof(*ppsPageList) * ui32NumPages, ppsPageList, hBlockPageList);
+
+failed_page_list_alloc:
+ return IMG_FALSE;
+}
+
+
+static IMG_VOID
+FreePages(IMG_BOOL bToPagePool, struct page **ppsPageList, IMG_HANDLE hBlockPageList, IMG_UINT32 ui32NumPages)
+{
+ IMG_INT32 i;
+
+ for(i = 0; i < (IMG_INT32)ui32NumPages; i++)
+ {
+ FreePage(bToPagePool, ppsPageList[i]);
+ }
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, ppsPageList, __FILE__, __LINE__);
+#endif
+
+ (IMG_VOID) OSFreeMem(0, sizeof(*ppsPageList) * ui32NumPages, ppsPageList, hBlockPageList);
+}
+
+
+LinuxMemArea *
+NewVMallocLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags)
+{
+ LinuxMemArea *psLinuxMemArea = NULL;
+ IMG_VOID *pvCpuVAddr;
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ IMG_UINT32 ui32NumPages = 0;
+ struct page **ppsPageList = NULL;
+ IMG_HANDLE hBlockPageList;
+#endif
+ IMG_BOOL bFromPagePool = IMG_FALSE;
+
+ psLinuxMemArea = LinuxMemAreaStructAlloc();
+ if (!psLinuxMemArea)
+ {
+ goto failed;
+ }
+
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ ui32NumPages = RANGE_TO_PAGES(ui32Bytes);
+
+ if (!AllocPages(ui32AreaFlags, &ppsPageList, &hBlockPageList, ui32NumPages, &bFromPagePool))
+ {
+ goto failed;
+ }
+
+ pvCpuVAddr = VMapWrapper(ppsPageList, ui32NumPages, ui32AreaFlags);
+#else /* defined(PVR_LINUX_MEM_AREA_USE_VMAP) */
+ pvCpuVAddr = VMallocWrapper(ui32Bytes, ui32AreaFlags);
+ if (!pvCpuVAddr)
+ {
+ goto failed;
+ }
+/* PG_reserved was deprecated in linux-2.6.15 */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
+ /* Reserve those pages to allow them to be re-mapped to user space */
+ ReservePages(pvCpuVAddr, ui32Bytes);
+#endif
+#endif /* defined(PVR_LINUX_MEM_AREA_USE_VMAP) */
+
+ psLinuxMemArea->eAreaType = LINUX_MEM_AREA_VMALLOC;
+ psLinuxMemArea->uData.sVmalloc.pvVmallocAddress = pvCpuVAddr;
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ psLinuxMemArea->uData.sVmalloc.ppsPageList = ppsPageList;
+ psLinuxMemArea->uData.sVmalloc.hBlockPageList = hBlockPageList;
+#endif
+ psLinuxMemArea->ui32ByteSize = ui32Bytes;
+ psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
+ INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
+#endif
+
+ /* This works around a problem where Linux will not invalidate
+ * the cache for physical memory it frees that is direct mapped.
+ *
+ * As a result, cache entries remain that may be subsequently flushed
+ * to these physical pages after they have been allocated for another
+ * purpose. For a subsequent cached use of this memory, that is not a
+ * problem, but if we are allocating uncached or write-combined memory,
+ * and bypassing the cache, it can cause subsequent uncached writes to
+ * the memory to be replaced with junk from the cache.
+ *
+ * If the pages are from our page cache, no cache invalidate is needed.
+ *
+ * This just handles the __vmalloc() case (when we have a kernel virtual
+ * address range). The alloc_pages() path is handled in mmap.c.
+ */
+ if (AreaIsUncached(ui32AreaFlags) && !bFromPagePool)
+ {
+ OSInvalidateCPUCacheRangeKM(psLinuxMemArea, 0, pvCpuVAddr, ui32Bytes);
+ }
+
+ return psLinuxMemArea;
+
+failed:
+ PVR_DPF((PVR_DBG_ERROR, "%s: failed!", __FUNCTION__));
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ if (ppsPageList)
+ {
+ FreePages(bFromPagePool, ppsPageList, hBlockPageList, ui32NumPages);
+ }
+#endif
+ if (psLinuxMemArea)
+ {
+ LinuxMemAreaStructFree(psLinuxMemArea);
+ }
+
+ return NULL;
+}
+
+
+IMG_VOID
+FreeVMallocLinuxMemArea(LinuxMemArea *psLinuxMemArea)
+{
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ IMG_UINT32 ui32NumPages;
+ struct page **ppsPageList;
+ IMG_HANDLE hBlockPageList;
+#endif
+
+ 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
+
+ PVR_DPF((PVR_DBG_MESSAGE,"%s: pvCpuVAddr: %p",
+ __FUNCTION__, psLinuxMemArea->uData.sVmalloc.pvVmallocAddress));
+
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ VUnmapWrapper(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress);
+
+ ui32NumPages = RANGE_TO_PAGES(psLinuxMemArea->ui32ByteSize);
+ ppsPageList = psLinuxMemArea->uData.sVmalloc.ppsPageList;
+ hBlockPageList = psLinuxMemArea->uData.sVmalloc.hBlockPageList;
+
+ FreePages(CanFreeToPool(psLinuxMemArea), ppsPageList, hBlockPageList, ui32NumPages);
+#else
+/* PG_reserved was deprecated in linux-2.6.15 */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
+ UnreservePages(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress,
+ psLinuxMemArea->ui32ByteSize);
+#endif
+
+ VFreeWrapper(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress);
+#endif /* defined(PVR_LINUX_MEM_AREA_USE_VMAP) */
+
+ LinuxMemAreaStructFree(psLinuxMemArea);
+}
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
+/* Reserve pages of memory in order that they're not automatically
+ deallocated after the last user reference dies. */
+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
+ }
+}
+
+
+/* Un-reserve pages of memory in order that they can be freed. */
+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 /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)) */
+
+
+IMG_VOID *
+_IORemapWrapper(IMG_CPU_PHYADDR BasePAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32MappingFlags,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32Line)
+{
+ IMG_VOID *pvIORemapCookie;
+
+ 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
+ );
+ }
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(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);
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(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;
+ 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);
+}
+
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+/*
+ * Avoid using remap_pfn_range on RAM, if possible. On x86 systems, with
+ * PAT enabled, remap_pfn_range checks the page attributes requested by
+ * remap_pfn_range against those of the direct kernel mapping for those
+ * pages (if any). This is rather annoying if the pages have been obtained
+ * with alloc_pages, where we just ask for raw pages; we don't care about
+ * the direct mapping. This latter issue arises when device memory is
+ * exported from one process to another. Services implements this
+ * using memory wrapping, which ends up creating an external KV memory area.
+ */
+static IMG_BOOL
+TreatExternalPagesAsContiguous(IMG_SYS_PHYADDR *psSysPhysAddr, IMG_UINT32 ui32Bytes, IMG_BOOL bPhysContig)
+{
+ IMG_UINT32 ui32;
+ IMG_UINT32 ui32AddrChk;
+ IMG_UINT32 ui32NumPages = RANGE_TO_PAGES(ui32Bytes);
+
+ /*
+ * If bPhysContig is IMG_TRUE, we must assume psSysPhysAddr points
+ * to the address of the first page, not an array of page addresses.
+ */
+ for (ui32 = 0, ui32AddrChk = psSysPhysAddr[0].uiAddr;
+ ui32 < ui32NumPages;
+ ui32++, ui32AddrChk = (bPhysContig) ? (ui32AddrChk + PAGE_SIZE) : psSysPhysAddr[ui32].uiAddr)
+ {
+ if (!pfn_valid(PHYS_TO_PFN(ui32AddrChk)))
+ {
+ break;
+ }
+ }
+ if (ui32 == ui32NumPages)
+ {
+ return IMG_FALSE;
+ }
+
+ if (!bPhysContig)
+ {
+ for (ui32 = 0, ui32AddrChk = psSysPhysAddr[0].uiAddr;
+ ui32 < ui32NumPages;
+ ui32++, ui32AddrChk += PAGE_SIZE)
+ {
+ if (psSysPhysAddr[ui32].uiAddr != ui32AddrChk)
+ {
+ return IMG_FALSE;
+ }
+ }
+ }
+
+ return IMG_TRUE;
+}
+#endif
+
+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 =
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ (bPhysContig || TreatExternalPagesAsContiguous(pBasePAddr, ui32Bytes, bPhysContig))
+ ? IMG_TRUE : IMG_FALSE;
+#else
+ bPhysContig;
+#endif
+ if (psLinuxMemArea->uData.sExternalKV.bPhysContig)
+ {
+ psLinuxMemArea->uData.sExternalKV.uPhysAddr.SysPhysAddr = *pBasePAddr;
+ }
+ else
+ {
+ psLinuxMemArea->uData.sExternalKV.uPhysAddr.pSysPhysAddr = pBasePAddr;
+ }
+ psLinuxMemArea->ui32ByteSize = ui32Bytes;
+ psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
+ 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;
+ }
+
+ /* Nothing to activly do. We just keep a record of the physical range. */
+ psLinuxMemArea->eAreaType = LINUX_MEM_AREA_IO;
+ psLinuxMemArea->uData.sIO.CPUPhysAddr.uiAddr = BasePAddr.uiAddr;
+ psLinuxMemArea->ui32ByteSize = ui32Bytes;
+ psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
+ 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
+
+ /* Nothing more to do than free the LinuxMemArea struct */
+
+ LinuxMemAreaStructFree(psLinuxMemArea);
+}
+
+
+LinuxMemArea *
+NewAllocPagesLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags)
+{
+ LinuxMemArea *psLinuxMemArea;
+ IMG_UINT32 ui32NumPages;
+ struct page **ppsPageList;
+ IMG_HANDLE hBlockPageList;
+ IMG_BOOL bFromPagePool;
+
+ psLinuxMemArea = LinuxMemAreaStructAlloc();
+ if (!psLinuxMemArea)
+ {
+ goto failed_area_alloc;
+ }
+
+ ui32NumPages = RANGE_TO_PAGES(ui32Bytes);
+
+ if (!AllocPages(ui32AreaFlags, &ppsPageList, &hBlockPageList, ui32NumPages, &bFromPagePool))
+ {
+ goto failed_alloc_pages;
+ }
+
+ psLinuxMemArea->eAreaType = LINUX_MEM_AREA_ALLOC_PAGES;
+ psLinuxMemArea->uData.sPageList.ppsPageList = ppsPageList;
+ psLinuxMemArea->uData.sPageList.hBlockPageList = hBlockPageList;
+ psLinuxMemArea->ui32ByteSize = ui32Bytes;
+ psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
+ INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
+
+ /* We defer the cache flush to the first user mapping of this memory */
+ psLinuxMemArea->bNeedsCacheInvalidate = AreaIsUncached(ui32AreaFlags) && !bFromPagePool;
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
+#endif
+
+ return psLinuxMemArea;
+
+failed_alloc_pages:
+ LinuxMemAreaStructFree(psLinuxMemArea);
+failed_area_alloc:
+ PVR_DPF((PVR_DBG_ERROR, "%s: failed", __FUNCTION__));
+
+ return NULL;
+}
+
+
+IMG_VOID
+FreeAllocPagesLinuxMemArea(LinuxMemArea *psLinuxMemArea)
+{
+ IMG_UINT32 ui32NumPages;
+ struct page **ppsPageList;
+ IMG_HANDLE hBlockPageList;
+
+ PVR_ASSERT(psLinuxMemArea);
+ PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_ALLOC_PAGES);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
+#endif
+
+ ui32NumPages = RANGE_TO_PAGES(psLinuxMemArea->ui32ByteSize);
+ ppsPageList = psLinuxMemArea->uData.sPageList.ppsPageList;
+ hBlockPageList = psLinuxMemArea->uData.sPageList.hBlockPageList;
+
+ FreePages(CanFreeToPool(psLinuxMemArea), ppsPageList, hBlockPageList, ui32NumPages);
+
+ LinuxMemAreaStructFree(psLinuxMemArea);
+}
+
+#if defined(CONFIG_ION_OMAP)
+
+#include "env_perproc.h"
+
+#include <linux/ion.h>
+#include <linux/omap_ion.h>
+#include <linux/scatterlist.h>
+
+extern struct ion_client *gpsIONClient;
+
+LinuxMemArea *
+NewIONLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags,
+ IMG_PVOID pvPrivData, IMG_UINT32 ui32PrivDataLength)
+{
+ const IMG_UINT32 ui32AllocDataLen =
+ offsetof(struct omap_ion_tiler_alloc_data, handle);
+ struct omap_ion_tiler_alloc_data asAllocData[PVRSRV_MAX_NUMBER_OF_MM_BUFFER_PLANES];
+ u32 *pu32PageAddrs[PVRSRV_MAX_NUMBER_OF_MM_BUFFER_PLANES] = { NULL, NULL, NULL};
+ IMG_UINT32 i, j, ui32NumHandlesPerFd;
+ IMG_BYTE *pbPrivData = pvPrivData;
+ IMG_CPU_PHYADDR *pCPUPhysAddrs;
+ IMG_UINT32 iNumPages[PVRSRV_MAX_NUMBER_OF_MM_BUFFER_PLANES] = { 0, 0, 0};
+ LinuxMemArea *psLinuxMemArea;
+ IMG_UINT32 ui32ProcID;
+ IMG_UINT32 ui32TotalPagesSizeInBytes = 0, ui32TotalPages = 0;
+
+ psLinuxMemArea = LinuxMemAreaStructAlloc();
+ if (!psLinuxMemArea)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate LinuxMemArea struct", __func__));
+ goto err_out;
+ }
+
+ /* Depending on the UM config, userspace might give us info for
+ * one, two or three ION allocations. Divide the total size of data we
+ * were given by this ui32AllocDataLen, and check it's 1 or 2.
+ * Otherwise abort.
+ */
+ BUG_ON(ui32PrivDataLength != ui32AllocDataLen &&
+ ui32PrivDataLength != ui32AllocDataLen * 2 &&
+ ui32PrivDataLength != ui32AllocDataLen * 3);
+ /* This is bad !- change this logic to pass in the size or
+ * use uniformed API */
+ ui32NumHandlesPerFd = ui32PrivDataLength / ui32AllocDataLen;
+
+ ui32ProcID = OSGetCurrentProcessIDKM();
+
+ memset(asAllocData, 0x00, sizeof(asAllocData));
+
+ /* We do not care about what the first (Y) buffer offset would be,
+ * but we do care for the UV buffers to be co-aligned with Y
+ * This for SGX to find the UV offset solely based on the height
+ * and stride of the YUV buffer.This is very important for OMAP4470
+ * and later chipsets, where SGX version is 544. 544 and later use
+ * non-shader based YUV to RGB conversion unit that require
+ * contiguous GPU virtual space */
+ for(i = 0; i < ui32NumHandlesPerFd; i++)
+ {
+ memcpy(&asAllocData[i], &pbPrivData[i * ui32AllocDataLen], ui32AllocDataLen);
+ asAllocData[i].token = ui32ProcID;
+
+#ifndef SGX_DISABLE_DMM_OFFSET_BUFFER_ALLOCATIONS
+ if(i == 0)
+ {
+ /* Tiler API says:
+ * Allocate first buffer with the required alignment
+ * and an offset of 0 ... */
+ asAllocData[i].out_align = CONFIG_TILER_GRANULARITY;
+ asAllocData[i].offset = 0;
+ }
+ else
+ { /* .. Then for the second buffer, use the offset from the first
+ * buffer with alignment of PAGE_SIZE */
+ asAllocData[i].out_align = PAGE_SIZE;
+ asAllocData[i].offset = asAllocData[0].offset;
+ }
+#else
+ asAllocData[i].offset = 0;
+ asAllocData[i].out_align = PAGE_SIZE;
+#endif
+
+ if(asAllocData[i].fmt == TILER_PIXEL_FMT_PAGE)
+ {
+ /* 1D DMM Buffers */
+ struct scatterlist *sg, *sglist;
+ IMG_UINT32 ui32Num1dPages;
+
+ asAllocData[i].handle = ion_alloc (gpsIONClient,
+ ui32Bytes,
+ PAGE_SIZE, (1 << OMAP_ION_HEAP_SYSTEM));
+
+ if (asAllocData[i].handle == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate via ion_alloc",
+ __func__));
+ goto err_free;
+ }
+
+ sglist = ion_map_dma (gpsIONClient, asAllocData[i].handle);
+ if (sglist == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to compute pages",
+ __func__));
+ goto err_free;
+ }
+
+ ui32Num1dPages = (ui32Bytes >> PAGE_SHIFT);
+ pu32PageAddrs[i] = kmalloc (sizeof(u32) * ui32Num1dPages, GFP_KERNEL);
+ if (pu32PageAddrs[i] == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate page array",
+ __func__));
+ goto err_free;
+ }
+
+ for_each_sg (sglist, sg, ui32Num1dPages, j)
+ {
+ pu32PageAddrs[i][j] = sg_phys (sg);
+ }
+
+ iNumPages[i] = ui32Num1dPages;
+ }
+ else /* 2D DMM Buffers */
+ {
+ if (omap_ion_tiler_alloc(gpsIONClient, &asAllocData[i]) < 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate via ion_tiler",
+ __func__));
+ goto err_free;
+ }
+
+ if (omap_tiler_pages(gpsIONClient, asAllocData[i].handle, &iNumPages[i],
+ &pu32PageAddrs[i]) < 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to compute tiler pages",
+ __func__));
+ goto err_free;
+ }
+ }
+ }
+
+ /* Basic sanity check on plane co-alignment */
+ if((ui32NumHandlesPerFd > 1) &&
+ (asAllocData[0].offset != asAllocData[1].offset))
+ {
+ pr_err("%s: Y and UV offsets do not match for tiler handles "
+ "%p,%p: %d != %d \n "
+ "Expect issues with SGX544xx and later chipsets\n",
+ __func__, asAllocData[0].handle, asAllocData[1].handle,
+ (int)asAllocData[0].offset, (int)asAllocData[1].offset);
+ }
+
+ /* Assume the user-allocator has already done the tiler math and that the
+ * number of tiler pages allocated matches any other allocation type.
+ */
+ for(i = 0; i < ui32NumHandlesPerFd; i++)
+ {
+ ui32TotalPages += iNumPages[i];
+ }
+
+ BUG_ON(ui32Bytes != (ui32TotalPages * PAGE_SIZE));
+ BUG_ON(sizeof(IMG_CPU_PHYADDR) != sizeof(int));
+
+ /* Glue the page lists together */
+ pCPUPhysAddrs = vmalloc(sizeof(IMG_CPU_PHYADDR) * ui32TotalPages);
+ if (!pCPUPhysAddrs)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate page list", __func__));
+ goto err_free;
+ }
+
+ j = 0;
+ for(i = 0; i < ui32NumHandlesPerFd; i++)
+ {
+ IMG_UINT32 ui32PageIndx;
+ for(ui32PageIndx = 0; ui32PageIndx < iNumPages[i]; ui32PageIndx++)
+ {
+ pCPUPhysAddrs[j++].uiAddr = pu32PageAddrs[i][ui32PageIndx];
+ }
+
+ psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[i] =
+ asAllocData[i].handle;
+ psLinuxMemArea->uData.sIONTilerAlloc.planeOffsets[i] =
+ ui32TotalPagesSizeInBytes + asAllocData[i].offset;
+ /* Add the number of pages this plane consists of */
+ ui32TotalPagesSizeInBytes += (iNumPages[i] * PAGE_SIZE);
+ }
+
+ psLinuxMemArea->eAreaType = LINUX_MEM_AREA_ION;
+ psLinuxMemArea->uData.sIONTilerAlloc.pCPUPhysAddrs = pCPUPhysAddrs;
+ psLinuxMemArea->uData.sIONTilerAlloc.ui32NumValidPlanes =
+ ui32NumHandlesPerFd;
+ psLinuxMemArea->ui32ByteSize = ui32TotalPagesSizeInBytes;
+ psLinuxMemArea->ui32AreaFlags = ui32AreaFlags;
+ INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList);
+
+ /* We defer the cache flush to the first user mapping of this memory */
+ psLinuxMemArea->bNeedsCacheInvalidate = AreaIsUncached(ui32AreaFlags);
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_ION,
+ asAllocData[0].handle,
+ 0,
+ 0,
+ NULL,
+ PAGE_ALIGN(ui32Bytes),
+ "unknown",
+ 0
+ );
+#endif
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags);
+#endif
+
+err_out:
+ return psLinuxMemArea;
+
+err_free:
+ LinuxMemAreaStructFree(psLinuxMemArea);
+ psLinuxMemArea = IMG_NULL;
+ goto err_out;
+}
+
+IMG_INT32
+GetIONLinuxMemAreaInfo(LinuxMemArea *psLinuxMemArea, IMG_UINT32* pui32AddressOffsets,
+ IMG_UINT32* ui32NumAddrOffsets)
+{
+ IMG_UINT32 i;
+
+ if(!ui32NumAddrOffsets)
+ return -1;
+
+ if(*ui32NumAddrOffsets < psLinuxMemArea->uData.sIONTilerAlloc.ui32NumValidPlanes)
+ {
+ *ui32NumAddrOffsets = psLinuxMemArea->uData.sIONTilerAlloc.ui32NumValidPlanes;
+ return -1;
+ }
+
+ if(!pui32AddressOffsets)
+ return -1;
+
+ for(i = 0; i < psLinuxMemArea->uData.sIONTilerAlloc.ui32NumValidPlanes; i++)
+ {
+ if(psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[i])
+ pui32AddressOffsets[i] =
+ psLinuxMemArea->uData.sIONTilerAlloc.planeOffsets[i];
+ }
+
+ *ui32NumAddrOffsets = psLinuxMemArea->uData.sIONTilerAlloc.ui32NumValidPlanes;
+
+ return psLinuxMemArea->ui32ByteSize;
+}
+
+IMG_VOID
+FreeIONLinuxMemArea(LinuxMemArea *psLinuxMemArea)
+{
+ IMG_UINT32 i;
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
+#endif
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ION,
+ psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[0],
+ __FILE__, __LINE__);
+#endif
+
+ for(i = 0; i < psLinuxMemArea->uData.sIONTilerAlloc.ui32NumValidPlanes; i++)
+ {
+ if (!psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[i])
+ break;
+ ion_free(gpsIONClient, psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[i]);
+ psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[i] = IMG_NULL;
+ }
+
+ /* free copy of page list, originals are freed by ion_free */
+ vfree(psLinuxMemArea->uData.sIONTilerAlloc.pCPUPhysAddrs);
+ psLinuxMemArea->uData.sIONTilerAlloc.pCPUPhysAddrs = IMG_NULL;
+
+ LinuxMemAreaStructFree(psLinuxMemArea);
+}
+
+#endif /* defined(CONFIG_ION_OMAP) */
+
+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.ppsPageList[ui32PageIndex];
+
+ case LINUX_MEM_AREA_VMALLOC:
+ pui8Addr = psLinuxMemArea->uData.sVmalloc.pvVmallocAddress;
+ pui8Addr += ui32ByteOffset;
+ return vmalloc_to_page(pui8Addr);
+
+ case LINUX_MEM_AREA_SUB_ALLOC:
+ /* PRQA S 3670 3 */ /* ignore recursive warning */
+ 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",
+ __FUNCTION__, 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 /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22) */
+ );
+}
+
+
+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_zalloc(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
+ );
+#else
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(ui32Line);
+#endif
+
+ return pvRet;
+}
+
+
+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->bNeedsCacheInvalidate = psParentLinuxMemArea->bNeedsCacheInvalidate;
+ 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;
+}
+
+
+static IMG_VOID
+FreeSubLinuxMemArea(LinuxMemArea *psLinuxMemArea)
+{
+ PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC);
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ DebugLinuxMemAreaRecordRemove(psLinuxMemArea);
+#endif
+
+ /* Nothing more to do than free the LinuxMemArea structure */
+
+ LinuxMemAreaStructFree(psLinuxMemArea);
+}
+
+
+static LinuxMemArea *
+LinuxMemAreaStructAlloc(IMG_VOID)
+{
+/* debug */
+#if 0
+ LinuxMemArea *psLinuxMemArea;
+ psLinuxMemArea = kmem_cache_alloc(g_PsLinuxMemAreaCache, GFP_KERNEL);
+ printk(KERN_ERR "%s: psLinuxMemArea=%p\n", __FUNCTION__, psLinuxMemArea);
+ dump_stack();
+ return psLinuxMemArea;
+#else
+ return KMemCacheAllocWrapper(g_PsLinuxMemAreaCache, GFP_KERNEL);
+#endif
+}
+
+
+static IMG_VOID
+LinuxMemAreaStructFree(LinuxMemArea *psLinuxMemArea)
+{
+ KMemCacheFreeWrapper(g_PsLinuxMemAreaCache, psLinuxMemArea);
+ /* debug */
+ //printk(KERN_ERR "%s(%p)\n", __FUNCTION__, 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;
+ case LINUX_MEM_AREA_ION:
+ FreeIONLinuxMemArea(psLinuxMemArea);
+ break;
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "%s: Unknown are type (%d)\n",
+ __FUNCTION__, psLinuxMemArea->eAreaType));
+ break;
+ }
+}
+
+
+#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++;
+
+ /* Create a new memory allocation record */
+ psNewRecord = kmalloc(sizeof(DEBUG_LINUX_MEM_AREA_REC), GFP_KERNEL);
+ if (psNewRecord)
+ {
+ /* Record the allocation */
+ psNewRecord->psLinuxMemArea = psLinuxMemArea;
+ psNewRecord->ui32Flags = ui32Flags;
+ psNewRecord->pid = OSGetCurrentProcessIDKM();
+
+ List_DEBUG_LINUX_MEM_AREA_REC_Insert(&g_LinuxMemAreaRecords, psNewRecord);
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: failed to allocate linux memory area record.",
+ __FUNCTION__));
+ }
+
+ /* Sanity check the flags */
+ pi8FlagsString = HAPFlagsToString(ui32Flags);
+ if (strstr(pi8FlagsString, "UNKNOWN"))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Unexpected flags (0x%08x) associated with psLinuxMemArea @ %p",
+ __FUNCTION__,
+ ui32Flags,
+ psLinuxMemArea));
+ //dump_stack();
+ }
+
+ LinuxUnLockMutex(&g_sDebugMutex);
+}
+
+
+
+static IMG_VOID* MatchLinuxMemArea_AnyVaCb(DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord,
+ va_list va)
+{
+ LinuxMemArea *psLinuxMemArea;
+
+ psLinuxMemArea = va_arg(va, LinuxMemArea*);
+ if (psCurrentRecord->psLinuxMemArea == psLinuxMemArea)
+ {
+ return psCurrentRecord;
+ }
+ else
+ {
+ return IMG_NULL;
+ }
+}
+
+
+static DEBUG_LINUX_MEM_AREA_REC *
+DebugLinuxMemAreaRecordFind(LinuxMemArea *psLinuxMemArea)
+{
+ DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord;
+
+ LinuxLockMutex(&g_sDebugMutex);
+ psCurrentRecord = List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
+ MatchLinuxMemArea_AnyVaCb,
+ psLinuxMemArea);
+
+/*exit_unlock:*/
+ LinuxUnLockMutex(&g_sDebugMutex);
+
+ return psCurrentRecord;
+}
+
+
+static IMG_VOID
+DebugLinuxMemAreaRecordRemove(LinuxMemArea *psLinuxMemArea)
+{
+ DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord;
+
+ LinuxLockMutex(&g_sDebugMutex);
+
+ if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
+ {
+ g_LinuxMemAreaWaterMark -= psLinuxMemArea->ui32ByteSize;
+ }
+ g_LinuxMemAreaCount--;
+
+ /* Locate the corresponding allocation entry */
+ psCurrentRecord = List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
+ MatchLinuxMemArea_AnyVaCb,
+ psLinuxMemArea);
+ if (psCurrentRecord)
+ {
+ /* Unlink the allocation record */
+ List_DEBUG_LINUX_MEM_AREA_REC_Remove(psCurrentRecord);
+ kfree(psCurrentRecord);
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: couldn't find an entry for psLinuxMemArea=%p\n",
+ __FUNCTION__, psLinuxMemArea));
+ }
+
+ 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); /* PRQA S 3670 */ /* ignore recursive warning */
+ 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_ION:
+ {
+ IMG_UINT32 ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset);
+ CpuPAddr = psLinuxMemArea->uData.sIONTilerAlloc.pCPUPhysAddrs[ui32PageIndex];
+ CpuPAddr.uiAddr += ADDR_TO_PAGE_OFFSET(ui32ByteOffset);
+ break;
+ }
+ case LINUX_MEM_AREA_ALLOC_PAGES:
+ {
+ struct page *page;
+ IMG_UINT32 ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset);
+ page = psLinuxMemArea->uData.sPageList.ppsPageList[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);
+ break;
+ }
+ }
+
+ 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_ION:
+ case LINUX_MEM_AREA_VMALLOC:
+ case LINUX_MEM_AREA_ALLOC_PAGES:
+ return IMG_FALSE;
+
+ case LINUX_MEM_AREA_SUB_ALLOC:
+ /* PRQA S 3670 1 */ /* ignore recursive warning */
+ 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)
+{
+ /* Note we explicitly check the types instead of e.g.
+ * using the type to index an array of strings so
+ * we remain orthogonal to enum changes */
+ 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";
+ case LINUX_MEM_AREA_ION:
+ return "LINUX_MEM_AREA_ION";
+ default:
+ PVR_ASSERT(0);
+ }
+
+ return "";
+}
+
+
+#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+static void ProcSeqStartstopDebugMutex(struct seq_file *sfile, IMG_BOOL start)
+{
+ if (start)
+ {
+ LinuxLockMutex(&g_sDebugMutex);
+ }
+ else
+ {
+ LinuxUnLockMutex(&g_sDebugMutex);
+ }
+}
+#endif /* defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) */
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+
+static IMG_VOID* DecOffMemAreaRec_AnyVaCb(DEBUG_LINUX_MEM_AREA_REC *psNode, va_list va)
+{
+ off_t *pOff = va_arg(va, off_t*);
+ if (--(*pOff))
+ {
+ return IMG_NULL;
+ }
+ else
+ {
+ return psNode;
+ }
+}
+
+/* seq_file version of generating output, for reference check proc.c:CreateProcReadEntrySeq */
+static void* ProcSeqNextMemArea(struct seq_file *sfile,void* el,loff_t off)
+{
+ DEBUG_LINUX_MEM_AREA_REC *psRecord;
+ psRecord = (DEBUG_LINUX_MEM_AREA_REC*)
+ List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
+ DecOffMemAreaRec_AnyVaCb,
+ &off);
+ return (void*)psRecord;
+}
+
+static void* ProcSeqOff2ElementMemArea(struct seq_file * sfile, loff_t off)
+{
+ DEBUG_LINUX_MEM_AREA_REC *psRecord;
+ if (!off)
+ {
+ return PVR_PROC_SEQ_START_TOKEN;
+ }
+
+ psRecord = (DEBUG_LINUX_MEM_AREA_REC*)
+ List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords,
+ DecOffMemAreaRec_AnyVaCb,
+ &off);
+ return (void*)psRecord;
+}
+
+
+static void ProcSeqShowMemArea(struct seq_file *sfile,void* el)
+{
+ DEBUG_LINUX_MEM_AREA_REC *psRecord = (DEBUG_LINUX_MEM_AREA_REC*)el;
+ if (el == PVR_PROC_SEQ_START_TOKEN)
+ {
+
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+ seq_printf(sfile,
+ "Number of Linux Memory Areas: %u\n"
+ "At the current water mark these areas correspond to %u bytes (excluding SUB areas)\n"
+ "At the highest water mark these areas corresponded to %u 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
+ seq_printf(sfile,
+ "<mem_areas_header>\n"
+ "\t<count>%u</count>\n"
+ "\t<watermark key=\"mar0\" description=\"current\" bytes=\"%u\"/>\n" /* (excluding SUB areas) */
+ "\t<watermark key=\"mar1\" description=\"high\" bytes=\"%u\"/>\n" /* (excluding SUB areas) */
+ "</mem_areas_header>\n",
+ g_LinuxMemAreaCount,
+ g_LinuxMemAreaWaterMark,
+ g_LinuxMemAreaHighWaterMark
+ );
+#endif
+ return;
+ }
+
+ seq_printf(sfile,
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+ "%8p %-24s %8p %08x %-8d %-5u %08x=(%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>%08x</cpu_physical>\n"
+ "\t<bytes>%d</bytes>\n"
+ "\t<pid>%u</pid>\n"
+ "\t<flags>%08x</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)
+ );
+
+}
+
+#endif /* DEBUG_LINUX_MEM_AREAS */
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+
+static IMG_VOID* DecOffMemAllocRec_AnyVaCb(DEBUG_MEM_ALLOC_REC *psNode, va_list va)
+{
+ off_t *pOff = va_arg(va, off_t*);
+ if (--(*pOff))
+ {
+ return IMG_NULL;
+ }
+ else
+ {
+ return psNode;
+ }
+}
+
+
+/* seq_file version of generating output, for reference check proc.c:CreateProcReadEntrySeq */
+static void* ProcSeqNextMemoryRecords(struct seq_file *sfile,void* el,loff_t off)
+{
+ DEBUG_MEM_ALLOC_REC *psRecord;
+ psRecord = (DEBUG_MEM_ALLOC_REC*)
+ List_DEBUG_MEM_ALLOC_REC_Any_va(g_MemoryRecords,
+ DecOffMemAllocRec_AnyVaCb,
+ &off);
+#if defined(DEBUG_LINUX_XML_PROC_FILES)
+ if (!psRecord)
+ {
+ seq_printf(sfile, "</meminfo>\n");
+ }
+#endif
+
+ return (void*)psRecord;
+}
+
+static void* ProcSeqOff2ElementMemoryRecords(struct seq_file *sfile, loff_t off)
+{
+ DEBUG_MEM_ALLOC_REC *psRecord;
+ if (!off)
+ {
+ return PVR_PROC_SEQ_START_TOKEN;
+ }
+
+ psRecord = (DEBUG_MEM_ALLOC_REC*)
+ List_DEBUG_MEM_ALLOC_REC_Any_va(g_MemoryRecords,
+ DecOffMemAllocRec_AnyVaCb,
+ &off);
+
+#if defined(DEBUG_LINUX_XML_PROC_FILES)
+ if (!psRecord)
+ {
+ seq_printf(sfile, "</meminfo>\n");
+ }
+#endif
+
+ return (void*)psRecord;
+}
+
+static void ProcSeqShowMemoryRecords(struct seq_file *sfile,void* el)
+{
+ DEBUG_MEM_ALLOC_REC *psRecord = (DEBUG_MEM_ALLOC_REC*)el;
+ if (el == PVR_PROC_SEQ_START_TOKEN)
+ {
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+ /* NOTE: If you update this code, please also update the XML varient below
+ * too! */
+
+ seq_printf(sfile, "%-60s: %d bytes\n",
+ "Current Water Mark of bytes allocated via kmalloc",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
+ seq_printf(sfile, "%-60s: %d bytes\n",
+ "Highest Water Mark of bytes allocated via kmalloc",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
+ seq_printf(sfile, "%-60s: %d bytes\n",
+ "Current Water Mark of bytes allocated via vmalloc",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
+ seq_printf(sfile, "%-60s: %d bytes\n",
+ "Highest Water Mark of bytes allocated via vmalloc",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
+ seq_printf(sfile, "%-60s: %d bytes\n",
+ "Current Water Mark of bytes allocated via alloc_pages",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
+ seq_printf(sfile, "%-60s: %d bytes\n",
+ "Highest Water Mark of bytes allocated via alloc_pages",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
+ seq_printf(sfile, "%-60s: %d bytes\n",
+ "Current Water Mark of bytes allocated via ioremap",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
+ seq_printf(sfile, "%-60s: %d bytes\n",
+ "Highest Water Mark of bytes allocated via ioremap",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
+ seq_printf(sfile, "%-60s: %d bytes\n",
+ "Current Water Mark of bytes reserved for \"IO\" memory areas",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
+ seq_printf(sfile, "%-60s: %d bytes\n",
+ "Highest Water Mark of bytes allocated for \"IO\" memory areas",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
+ seq_printf(sfile, "%-60s: %d bytes\n",
+ "Current Water Mark of bytes allocated via kmem_cache_alloc",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
+ seq_printf(sfile, "%-60s: %d bytes\n",
+ "Highest Water Mark of bytes allocated via kmem_cache_alloc",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ seq_printf(sfile, "%-60s: %d bytes\n",
+ "Current Water Mark of bytes mapped via vmap",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMAP]);
+ seq_printf(sfile, "%-60s: %d bytes\n",
+ "Highest Water Mark of bytes mapped via vmap",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMAP]);
+#endif
+#if (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0)
+ seq_printf(sfile, "%-60s: %d pages\n",
+ "Number of pages in page pool",
+ atomic_read(&g_sPagePoolEntryCount));
+#endif
+ seq_printf( sfile, "\n");
+ seq_printf(sfile, "%-60s: %d bytes\n",
+ "The Current Water Mark for memory allocated from system RAM",
+ SysRAMTrueWaterMark());
+ seq_printf(sfile, "%-60s: %d bytes\n",
+ "The Highest Water Mark for memory allocated from system RAM",
+ g_SysRAMHighWaterMark);
+ seq_printf(sfile, "%-60s: %d bytes\n",
+ "The Current Water Mark for memory allocated from IO memory",
+ g_IOMemWaterMark);
+ seq_printf(sfile, "%-60s: %d bytes\n",
+ "The Highest Water Mark for memory allocated from IO memory",
+ g_IOMemHighWaterMark);
+
+ seq_printf( sfile, "\n");
+
+ seq_printf(sfile, "Details for all known allocations:\n"
+ "%-16s %-8s %-8s %-10s %-5s %-10s %s\n",
+ "Type",
+ "CpuVAddr",
+ "CpuPAddr",
+ "Bytes",
+ "PID",
+ "PrivateData",
+ "Filename:Line");
+
+#else /* DEBUG_LINUX_XML_PROC_FILES */
+
+ /* Note: If you want to update the description property of a watermark
+ * ensure that the key property remains unchanged so that watermark data
+ * logged over time from different driver revisions may remain comparable
+ */
+ seq_printf(sfile, "<meminfo>\n<meminfo_header>\n");
+ seq_printf(sfile,
+ "<watermark key=\"mr0\" description=\"kmalloc_current\" bytes=\"%d\"/>\n",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
+ seq_printf(sfile,
+ "<watermark key=\"mr1\" description=\"kmalloc_high\" bytes=\"%d\"/>\n",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
+ seq_printf(sfile,
+ "<watermark key=\"mr2\" description=\"vmalloc_current\" bytes=\"%d\"/>\n",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
+ seq_printf(sfile,
+ "<watermark key=\"mr3\" description=\"vmalloc_high\" bytes=\"%d\"/>\n",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
+ seq_printf(sfile,
+ "<watermark key=\"mr4\" description=\"alloc_pages_current\" bytes=\"%d\"/>\n",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
+ seq_printf(sfile,
+ "<watermark key=\"mr5\" description=\"alloc_pages_high\" bytes=\"%d\"/>\n",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
+ seq_printf(sfile,
+ "<watermark key=\"mr6\" description=\"ioremap_current\" bytes=\"%d\"/>\n",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
+ seq_printf(sfile,
+ "<watermark key=\"mr7\" description=\"ioremap_high\" bytes=\"%d\"/>\n",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
+ seq_printf(sfile,
+ "<watermark key=\"mr8\" description=\"io_current\" bytes=\"%d\"/>\n",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
+ seq_printf(sfile,
+ "<watermark key=\"mr9\" description=\"io_high\" bytes=\"%d\"/>\n",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
+ seq_printf(sfile,
+ "<watermark key=\"mr10\" description=\"kmem_cache_current\" bytes=\"%d\"/>\n",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
+ seq_printf(sfile,
+ "<watermark key=\"mr11\" description=\"kmem_cache_high\" bytes=\"%d\"/>\n",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ seq_printf(sfile,
+ "<watermark key=\"mr12\" description=\"vmap_current\" bytes=\"%d\"/>\n",
+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMAP]);
+ seq_printf(sfile,
+ "<watermark key=\"mr13\" description=\"vmap_high\" bytes=\"%d\"/>\n",
+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMAP]);
+#endif
+ seq_printf(sfile,
+ "<watermark key=\"mr14\" description=\"system_ram_current\" bytes=\"%d\"/>\n",
+ SysRAMTrueWaterMark());
+ seq_printf(sfile,
+ "<watermark key=\"mr15\" description=\"system_ram_high\" bytes=\"%d\"/>\n",
+ g_SysRAMHighWaterMark);
+ seq_printf(sfile,
+ "<watermark key=\"mr16\" description=\"system_io_current\" bytes=\"%d\"/>\n",
+ g_IOMemWaterMark);
+ seq_printf(sfile,
+ "<watermark key=\"mr17\" description=\"system_io_high\" bytes=\"%d\"/>\n",
+ g_IOMemHighWaterMark);
+
+#if (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0)
+ seq_printf(sfile,
+ "<watermark key=\"mr18\" description=\"page_pool_current\" bytes=\"%d\"/>\n",
+ PAGES_TO_BYTES(atomic_read(&g_sPagePoolEntryCount)));
+#endif
+ seq_printf(sfile, "</meminfo_header>\n");
+
+#endif /* DEBUG_LINUX_XML_PROC_FILES */
+ return;
+ }
+
+ if (psRecord->eAllocType != DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE)
+ {
+ seq_printf(sfile,
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+ "%-16s %-8p %08x %-10d %-5d %-10s %s:%d\n",
+#else
+ "<allocation>\n"
+ "\t<type>%s</type>\n"
+ "\t<cpu_virtual>%-8p</cpu_virtual>\n"
+ "\t<cpu_physical>%08x</cpu_physical>\n"
+ "\t<bytes>%d</bytes>\n"
+ "\t<pid>%d</pid>\n"
+ "\t<private>%s</private>\n"
+ "\t<filename>%s</filename>\n"
+ "\t<line>%d</line>\n"
+ "</allocation>\n",
+#endif
+ DebugMemAllocRecordTypeToString(psRecord->eAllocType),
+ psRecord->pvCpuVAddr,
+ psRecord->ulCpuPAddr,
+ psRecord->ui32Bytes,
+ psRecord->pid,
+ "NULL",
+ psRecord->pszFileName,
+ psRecord->ui32Line);
+ }
+ else
+ {
+ seq_printf(sfile,
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+ "%-16s %-8p %08x %-10d %-5d %-10s %s:%d\n",
+#else
+ "<allocation>\n"
+ "\t<type>%s</type>\n"
+ "\t<cpu_virtual>%-8p</cpu_virtual>\n"
+ "\t<cpu_physical>%08x</cpu_physical>\n"
+ "\t<bytes>%d</bytes>\n"
+ "\t<pid>%d</pid>\n"
+ "\t<private>%s</private>\n"
+ "\t<filename>%s</filename>\n"
+ "\t<line>%d</line>\n"
+ "</allocation>\n",
+#endif
+ DebugMemAllocRecordTypeToString(psRecord->eAllocType),
+ psRecord->pvCpuVAddr,
+ psRecord->ulCpuPAddr,
+ psRecord->ui32Bytes,
+ psRecord->pid,
+ KMemCacheNameWrapper(psRecord->pvPrivateData),
+ psRecord->pszFileName,
+ psRecord->ui32Line);
+ }
+}
+
+#endif /* defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) */
+
+
+#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MMAP_AREAS)
+/* This could be moved somewhere more general */
+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"
+ };
+
+ /* FIXME create an enum for the cache type that we can
+ * cast and select so we get compiler warnings when
+ * when this code isn't complete due to new flags */
+ 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)));
+ }
+
+ /* FIXME create an enum for the map type that we can
+ * cast and select so we get compiler warnings when
+ * when this code isn't complete due to new flags */
+ 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
+
+#if defined(DEBUG_LINUX_MEM_AREAS)
+static IMG_VOID LinuxMMCleanup_MemAreas_ForEachCb(DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord)
+{
+ LinuxMemArea *psLinuxMemArea;
+
+ psLinuxMemArea = psCurrentRecord->psLinuxMemArea;
+ PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: Cleaning up Linux memory area (%p), type=%s, size=%d bytes",
+ __FUNCTION__,
+ psCurrentRecord->psLinuxMemArea,
+ LinuxMemAreaTypeToString(psCurrentRecord->psLinuxMemArea->eAreaType),
+ psCurrentRecord->psLinuxMemArea->ui32ByteSize));
+ /* Note this will also remove psCurrentRecord from g_LinuxMemAreaRecords
+ * but that's ok since we have already got a pointer to the next area. */
+ LinuxMemAreaDeepFree(psLinuxMemArea);
+}
+#endif
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+static IMG_VOID LinuxMMCleanup_MemRecords_ForEachVa(DEBUG_MEM_ALLOC_REC *psCurrentRecord)
+
+{
+
+/* It's a bug if anything remains allocated at this point. We
+ * report an error, and simply brute force free anything we find. */
+ PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: Cleaning up memory: "
+ "type=%s "
+ "CpuVAddr=%p "
+ "CpuPAddr=0x%08x, "
+ "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:
+ /* Nothing needed except to free the record */
+ 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;
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ case DEBUG_MEM_ALLOC_TYPE_VMAP:
+ VUnmapWrapper(psCurrentRecord->pvCpuVAddr);
+ break;
+#endif
+ default:
+ PVR_ASSERT(0);
+ }
+}
+#endif
+
+
+#if defined(PVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK)
+static struct shrinker g_sShrinker =
+{
+ .shrink = ShrinkPagePool,
+ .seeks = DEFAULT_SEEKS
+};
+
+static IMG_BOOL g_bShrinkerRegistered;
+#endif
+
+IMG_VOID
+LinuxMMCleanup(IMG_VOID)
+{
+#if defined(DEBUG_LINUX_MEM_AREAS)
+ {
+ if (g_LinuxMemAreaCount)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: There are %d LinuxMemArea allocation unfreed (%d bytes)",
+ __FUNCTION__, g_LinuxMemAreaCount, g_LinuxMemAreaWaterMark));
+ }
+
+ List_DEBUG_LINUX_MEM_AREA_REC_ForEach(g_LinuxMemAreaRecords, LinuxMMCleanup_MemAreas_ForEachCb);
+
+ if (g_SeqFileMemArea)
+ {
+ RemoveProcEntrySeq(g_SeqFileMemArea);
+ }
+ }
+#endif
+
+#if defined(PVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK)
+ if (g_bShrinkerRegistered)
+ {
+ unregister_shrinker(&g_sShrinker);
+ }
+#endif
+
+ /*
+ * The page pool must be freed after any remaining mem areas, but before
+ * the remaining memory resources.
+ */
+ FreePagePool();
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ {
+
+ /*
+ * It's a bug if anything remains allocated at this point. We
+ * report an error, and simply brute force free anything we find.
+ */
+ List_DEBUG_MEM_ALLOC_REC_ForEach(g_MemoryRecords, LinuxMMCleanup_MemRecords_ForEachVa);
+
+ if (g_SeqFileMemoryRecords)
+ {
+ RemoveProcEntrySeq(g_SeqFileMemoryRecords);
+ }
+ }
+#endif
+
+ if (g_PsLinuxMemAreaCache)
+ {
+ KMemCacheDestroyWrapper(g_PsLinuxMemAreaCache);
+ }
+
+ if (g_PsLinuxPagePoolCache)
+ {
+ KMemCacheDestroyWrapper(g_PsLinuxPagePoolCache);
+ }
+}
+
+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)
+ {
+ g_SeqFileMemArea = CreateProcReadEntrySeq(
+ "mem_areas",
+ NULL,
+ ProcSeqNextMemArea,
+ ProcSeqShowMemArea,
+ ProcSeqOff2ElementMemArea,
+ ProcSeqStartstopDebugMutex
+ );
+ if (!g_SeqFileMemArea)
+ {
+ goto failed;
+ }
+ }
+#endif
+
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ {
+ g_SeqFileMemoryRecords = CreateProcReadEntrySeq(
+ "meminfo",
+ NULL,
+ ProcSeqNextMemoryRecords,
+ ProcSeqShowMemoryRecords,
+ ProcSeqOff2ElementMemoryRecords,
+ ProcSeqStartstopDebugMutex
+ );
+ if (!g_SeqFileMemoryRecords)
+ {
+ goto failed;
+ }
+ }
+#endif
+
+ g_PsLinuxMemAreaCache = KMemCacheCreateWrapper("img-mm", sizeof(LinuxMemArea), 0, 0);
+ if (!g_PsLinuxMemAreaCache)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"%s: failed to allocate mem area kmem_cache", __FUNCTION__));
+ goto failed;
+ }
+
+#if (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0)
+ g_iPagePoolMaxEntries = PVR_LINUX_MEM_AREA_POOL_MAX_PAGES;
+ if (g_iPagePoolMaxEntries <= 0 || g_iPagePoolMaxEntries > INT_MAX/2)
+ {
+ g_iPagePoolMaxEntries = INT_MAX/2;
+ PVR_TRACE(("%s: No limit set for page pool size", __FUNCTION__));
+ }
+ else
+ {
+ PVR_TRACE(("%s: Maximum page pool size: %d", __FUNCTION__, g_iPagePoolMaxEntries));
+ }
+
+ g_PsLinuxPagePoolCache = KMemCacheCreateWrapper("img-mm-pool", sizeof(LinuxPagePoolEntry), 0, 0);
+ if (!g_PsLinuxPagePoolCache)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"%s: failed to allocate page pool kmem_cache", __FUNCTION__));
+ goto failed;
+ }
+#endif
+
+#if defined(PVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK)
+ register_shrinker(&g_sShrinker);
+ g_bShrinkerRegistered = IMG_TRUE;
+#endif
+
+ return PVRSRV_OK;
+
+failed:
+ LinuxMMCleanup();
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+}
+
diff --git a/pvr-source/services4/srvkm/env/linux/mm.h b/pvr-source/services4/srvkm/env/linux/mm.h
new file mode 100644
index 0000000..5c01322
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/mm.h
@@ -0,0 +1,751 @@
+/*************************************************************************/ /*!
+@Title Linux Memory Management.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares various memory management utility functions
+ for Linux.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef __IMG_LINUX_MM_H__
+#define __IMG_LINUX_MM_H__
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#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))
+
+#define PAGES_TO_BYTES(pages) ((pages) << PAGE_SHIFT)
+
+#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_ION,
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ LINUX_MEM_AREA_VMAP,
+#endif
+ LINUX_MEM_AREA_TYPE_COUNT
+}LINUX_MEM_AREA_TYPE;
+
+typedef struct _LinuxMemArea LinuxMemArea;
+
+
+/* FIXME - describe this structure. */
+struct _LinuxMemArea {
+ LINUX_MEM_AREA_TYPE eAreaType;
+ union _uData
+ {
+ struct _sIORemap
+ {
+ /* Note: The memory this represents is _not_ implicitly
+ * page aligned, neither is its size */
+ IMG_CPU_PHYADDR CPUPhysAddr;
+ IMG_VOID *pvIORemapCookie;
+ }sIORemap;
+ struct _sExternalKV
+ {
+ /* Note: The memory this represents is _not_ implicitly
+ * page aligned, neither is its size */
+ IMG_BOOL bPhysContig;
+ union {
+ /*
+ * SYSPhysAddr is valid if bPhysContig is true, else
+ * pSysPhysAddr is valid
+ */
+ IMG_SYS_PHYADDR SysPhysAddr;
+ IMG_SYS_PHYADDR *pSysPhysAddr;
+ } uPhysAddr;
+ IMG_VOID *pvExternalKV;
+ }sExternalKV;
+ struct _sIO
+ {
+ /* Note: The memory this represents is _not_ implicitly
+ * page aligned, neither is its size */
+ IMG_CPU_PHYADDR CPUPhysAddr;
+ }sIO;
+ struct _sVmalloc
+ {
+ /* Note the memory this represents _is_ implicitly
+ * page aligned _and_ so is its size */
+ IMG_VOID *pvVmallocAddress;
+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP)
+ struct page **ppsPageList;
+ IMG_HANDLE hBlockPageList;
+#endif
+ }sVmalloc;
+ struct _sPageList
+ {
+ /* Note the memory this represents _is_ implicitly
+ * page aligned _and_ so is its size */
+ struct page **ppsPageList;
+ IMG_HANDLE hBlockPageList;
+ }sPageList;
+ struct _sIONTilerAlloc
+ {
+ /* Note the memory this represents _is_ implicitly
+ * page aligned _and_ so is its size */
+ IMG_CPU_PHYADDR *pCPUPhysAddrs;
+ IMG_UINT32 ui32NumValidPlanes;
+ struct ion_handle *psIONHandle[PVRSRV_MAX_NUMBER_OF_MM_BUFFER_PLANES];
+ IMG_UINT32 planeOffsets[PVRSRV_MAX_NUMBER_OF_MM_BUFFER_PLANES];
+ }sIONTilerAlloc;
+ struct _sSubAlloc
+ {
+ /* Note: The memory this represents is _not_ implicitly
+ * page aligned, neither is its size */
+ LinuxMemArea *psParentLinuxMemArea;
+ IMG_UINT32 ui32ByteOffset;
+ }sSubAlloc;
+ }uData;
+
+ IMG_UINT32 ui32ByteSize; /* Size of memory area */
+
+ IMG_UINT32 ui32AreaFlags; /* Flags passed at creation time */
+
+ IMG_BOOL bMMapRegistered; /* Registered with mmap code */
+
+ IMG_BOOL bNeedsCacheInvalidate; /* Cache should be invalidated on first map? */
+
+ IMG_HANDLE hBMHandle; /* Handle back to BM for this allocation */
+
+ /* List entry for global list of areas registered for mmap */
+ struct list_head sMMapItem;
+
+ /*
+ * Head of list of all mmap offset structures associated with this
+ * memory area.
+ */
+ 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
+
+
+/*!
+ *******************************************************************************
+ * @Function LinuxMMInit
+ *
+ * @Description
+ *
+ * Initialise linux memory management code.
+ * This should be called during services initialisation.
+ *
+ * @Return none
+******************************************************************************/
+PVRSRV_ERROR LinuxMMInit(IMG_VOID);
+
+
+/*!
+ *******************************************************************************
+ *
+ * @Function LinuxMMCleanup
+ *
+ * @Description
+ *
+ * Cleanup state for the linux memory management code.
+ * This should be called at services cleanup.
+ *
+ * @Return none
+******************************************************************************/
+IMG_VOID LinuxMMCleanup(IMG_VOID);
+
+
+/*!
+ *******************************************************************************
+ * @brief Wrappers for kmalloc/kfree with optional /proc/pvr/km tracking
+ * They can also be used as more concise replacements for OSAllocMem
+ * in Linux specific code.
+ *
+ * @param ui32ByteSize
+ *
+ * @return
+ ******************************************************************************/
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+#define KMallocWrapper(ui32ByteSize, uFlags) _KMallocWrapper(ui32ByteSize, uFlags, __FILE__, __LINE__)
+#else
+#define KMallocWrapper(ui32ByteSize, uFlags) _KMallocWrapper(ui32ByteSize, uFlags, NULL, 0)
+#endif
+IMG_VOID *_KMallocWrapper(IMG_UINT32 ui32ByteSize, gfp_t uFlags, IMG_CHAR *szFileName, IMG_UINT32 ui32Line);
+
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param pvCpuVAddr
+ *
+ * @return
+ ******************************************************************************/
+#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);
+
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param ui32Bytes
+ * @param ui32AllocFlags
+ *
+ * @return
+ ******************************************************************************/
+#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);
+
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param pvCpuVAddr
+ *
+ * @return
+ ******************************************************************************/
+#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);
+
+
+/*!
+ *******************************************************************************
+ * @brief Allocates virtually contiguous pages
+ *
+ * @param ui32Bytes number of bytes to reserve
+ * @param ui32AreaFlags Heap caching and mapping Flags
+ *
+ * @return Page-aligned address of virtual allocation or NULL on error
+ ******************************************************************************/
+LinuxMemArea *NewVMallocLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags);
+
+
+/*!
+ *******************************************************************************
+ * @brief Deallocates virtually contiguous pages
+ *
+ * @param LinuxMemArea from NewVMallocLinuxMemArea
+ *
+ ******************************************************************************/
+IMG_VOID FreeVMallocLinuxMemArea(LinuxMemArea *psLinuxMemArea);
+
+
+/*!
+ *******************************************************************************
+ * @brief Reserve physical IO memory and create a CPU virtual mapping for it
+ *
+ * @param BasePAddr
+ * @param ui32Bytes
+ * @param ui32MappingFlags
+ *
+ * @return
+ ******************************************************************************/
+#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);
+
+
+/*!
+ *******************************************************************************
+ * @brief Reserve physical IO memory and create a CPU virtual mapping for it
+ *
+ * @param BasePAddr
+ * @param ui32Bytes
+ * @param ui32AreaFlags Heap caching and mapping Flags
+ *
+ * @return
+ ******************************************************************************/
+LinuxMemArea *NewIORemapLinuxMemArea(IMG_CPU_PHYADDR BasePAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags);
+
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param psLinuxMemArea
+ *
+ * @return
+ ********************************************************************************/
+IMG_VOID FreeIORemapLinuxMemArea(LinuxMemArea *psLinuxMemArea);
+
+/*!
+ *******************************************************************************
+ * @brief Register physical memory which already has a CPU virtual mapping
+ *
+ * @param pBasePAddr
+ * @param pvCPUVAddr
+ * @param bPhysContig
+ * @param ui32Bytes
+ * @param ui32AreaFlags Heap caching and mapping Flags
+ *
+ * @return
+ ******************************************************************************/
+LinuxMemArea *NewExternalKVLinuxMemArea(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCPUVAddr, IMG_UINT32 ui32Bytes, IMG_BOOL bPhysContig, IMG_UINT32 ui32AreaFlags);
+
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param psLinuxMemArea
+ *
+ * @return
+ ******************************************************************************/
+IMG_VOID FreeExternalKVLinuxMemArea(LinuxMemArea *psLinuxMemArea);
+
+
+/*!
+ ******************************************************************************
+ * @brief Unmaps an IO memory mapping created using IORemap
+ *
+ * @param pvIORemapCookie
+ *
+ * @return
+ ******************************************************************************/
+#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);
+
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param psLinuxMemArea
+ * @param ui32ByteOffset
+ *
+ * @return
+ ******************************************************************************/
+struct page *LinuxMemAreaOffsetToPage(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset);
+
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param pszName
+ * @param Size
+ * @param Align
+ * @param ui32Flags
+ *
+ * @return
+ ******************************************************************************/
+LinuxKMemCache *KMemCacheCreateWrapper(IMG_CHAR *pszName, size_t Size, size_t Align, IMG_UINT32 ui32Flags);
+
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param psCache
+ *
+ * @return
+ ******************************************************************************/
+IMG_VOID KMemCacheDestroyWrapper(LinuxKMemCache *psCache);
+
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param psCache
+ * @param Flags
+ *
+ * @return
+ ******************************************************************************/
+#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
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param psCache
+ * @param pvObject
+ *
+ * @return
+ ******************************************************************************/
+#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);
+
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param psCache
+ *
+ * @return
+ ******************************************************************************/
+const IMG_CHAR *KMemCacheNameWrapper(LinuxKMemCache *psCache);
+
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param BasePAddr
+ * @param ui32Bytes
+ * @param ui32AreaFlags Heap caching and mapping Flags
+ *
+ * @return
+ ******************************************************************************/
+LinuxMemArea *NewIOLinuxMemArea(IMG_CPU_PHYADDR BasePAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags);
+
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param psLinuxMemArea
+ *
+ * @return
+ ******************************************************************************/
+IMG_VOID FreeIOLinuxMemArea(LinuxMemArea *psLinuxMemArea);
+
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param ui32Bytes
+ * @param ui32AreaFlags E.g Heap caching and mapping Flags
+ *
+ * @return
+ ******************************************************************************/
+LinuxMemArea *NewAllocPagesLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags);
+
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param psLinuxMemArea
+ *
+ * @return
+ ******************************************************************************/
+IMG_VOID FreeAllocPagesLinuxMemArea(LinuxMemArea *psLinuxMemArea);
+
+
+#if defined(CONFIG_ION_OMAP)
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param ui32Bytes
+ * @param ui32AreaFlags E.g Heap caching and mapping Flags
+ *
+ * @return
+ ******************************************************************************/
+LinuxMemArea *
+NewIONLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags,
+ IMG_PVOID pvPrivData, IMG_UINT32 ui32PrivDataLength);
+
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param psLinuxMemArea
+ *
+ * @return
+ ******************************************************************************/
+IMG_VOID FreeIONLinuxMemArea(LinuxMemArea *psLinuxMemArea);
+
+IMG_INT32
+GetIONLinuxMemAreaInfo(LinuxMemArea *psLinuxMemArea, IMG_UINT32* ui32AddressOffsets,
+ IMG_UINT32* ui32NumAddr);
+
+#else /* defined(CONFIG_ION_OMAP) */
+
+static inline LinuxMemArea *
+NewIONLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags,
+ IMG_PVOID pvPrivData, IMG_UINT32 ui32PrivDataLength)
+{
+ PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+ PVR_UNREFERENCED_PARAMETER(ui32AreaFlags);
+ PVR_UNREFERENCED_PARAMETER(pvPrivData);
+ PVR_UNREFERENCED_PARAMETER(ui32PrivDataLength);
+ BUG();
+ return IMG_NULL;
+}
+
+static inline IMG_VOID FreeIONLinuxMemArea(LinuxMemArea *psLinuxMemArea)
+{
+ PVR_UNREFERENCED_PARAMETER(psLinuxMemArea);
+ BUG();
+}
+
+static inline IMG_INT32
+GetIONLinuxMemAreaInfo(LinuxMemArea *psLinuxMemArea, IMG_UINT32* ui32AddressOffsets,
+ IMG_UINT32* ui32NumAddr);
+{
+ PVR_UNREFERENCED_PARAMETER(psLinuxMemArea);
+ PVR_UNREFERENCED_PARAMETER(ui32AddressOffsets);
+ PVR_UNREFERENCED_PARAMETER(ui32NumAddr);
+ BUG();
+ return -1;
+}
+
+#endif /* defined(CONFIG_ION_OMAP) */
+
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param psParentLinuxMemArea
+ * @param ui32ByteOffset
+ * @param ui32Bytes
+ *
+ * @return
+ ******************************************************************************/
+LinuxMemArea *NewSubLinuxMemArea(LinuxMemArea *psParentLinuxMemArea,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_UINT32 ui32Bytes);
+
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param psLinuxMemArea
+ *
+ * @return
+ ******************************************************************************/
+IMG_VOID LinuxMemAreaDeepFree(LinuxMemArea *psLinuxMemArea);
+
+
+/*!
+ *******************************************************************************
+ * @brief For debug builds, LinuxMemAreas are tracked in /proc
+ *
+ * @param psLinuxMemArea
+ *
+ ******************************************************************************/
+#if defined(LINUX_MEM_AREAS_DEBUG)
+IMG_VOID LinuxMemAreaRegister(LinuxMemArea *psLinuxMemArea);
+#else
+#define LinuxMemAreaRegister(X)
+#endif
+
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param psLinuxMemArea
+ *
+ * @return
+ ******************************************************************************/
+IMG_VOID *LinuxMemAreaToCpuVAddr(LinuxMemArea *psLinuxMemArea);
+
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param psLinuxMemArea
+ * @param ui32ByteOffset
+ *
+ * @return
+ ******************************************************************************/
+IMG_CPU_PHYADDR LinuxMemAreaToCpuPAddr(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset);
+
+
+#define LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32ByteOffset) PHYS_TO_PFN(LinuxMemAreaToCpuPAddr(psLinuxMemArea, ui32ByteOffset).uiAddr)
+
+/*!
+ *******************************************************************************
+ * @brief Indicate whether a LinuxMemArea is physically contiguous
+ *
+ * @param psLinuxMemArea
+ *
+ * @return IMG_TRUE if the physical address range is contiguous, else IMG_FALSE
+ ******************************************************************************/
+IMG_BOOL LinuxMemAreaPhysIsContig(LinuxMemArea *psLinuxMemArea);
+
+/*!
+ *******************************************************************************
+ * @brief Return the real underlying LinuxMemArea
+ *
+ * @param psLinuxMemArea
+ *
+ * @return The real underlying LinuxMemArea
+ ******************************************************************************/
+static inline LinuxMemArea *
+LinuxMemAreaRoot(LinuxMemArea *psLinuxMemArea)
+{
+ if(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC)
+ {
+ return psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea;
+ }
+ else
+ {
+ return psLinuxMemArea;
+ }
+}
+
+
+/*!
+ *******************************************************************************
+ * @brief Return type of real underlying LinuxMemArea
+ *
+ * @param psLinuxMemArea
+ *
+ * @return The areas eAreaType or for SUB areas; return the parents eAreaType.
+ ******************************************************************************/
+static inline LINUX_MEM_AREA_TYPE
+LinuxMemAreaRootType(LinuxMemArea *psLinuxMemArea)
+{
+ return LinuxMemAreaRoot(psLinuxMemArea)->eAreaType;
+}
+
+
+/*!
+ *******************************************************************************
+ * @brief Converts the enum type of a LinuxMemArea to a const string
+ *
+ * @param eMemAreaType
+ *
+ * @return const string representation of type
+ ******************************************************************************/
+const IMG_CHAR *LinuxMemAreaTypeToString(LINUX_MEM_AREA_TYPE eMemAreaType);
+
+
+/*!
+ *******************************************************************************
+ * @brief
+ *
+ * @param ui32Flags
+ *
+ * @return
+ ******************************************************************************/
+#if defined(DEBUG) || defined(DEBUG_LINUX_MEM_AREAS)
+const IMG_CHAR *HAPFlagsToString(IMG_UINT32 ui32Flags);
+#endif
+
+#endif /* __IMG_LINUX_MM_H__ */
+
diff --git a/pvr-source/services4/srvkm/env/linux/mmap.c b/pvr-source/services4/srvkm/env/linux/mmap.c
new file mode 100644
index 0000000..1a485c4
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/mmap.c
@@ -0,0 +1,1656 @@
+/*************************************************************************/ /*!
+@Title Linux mmap interface
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#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>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
+#include <linux/highmem.h>
+#endif
+#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
+#if defined(SUPPORT_DRI_DRM)
+#include <drm/drmP.h>
+#endif
+
+#include "services_headers.h"
+
+#include "pvrmmap.h"
+#include "mutils.h"
+#include "mmap.h"
+#include "mm.h"
+#include "proc.h"
+#include "mutex.h"
+#include "handle.h"
+#include "perproc.h"
+#include "env_perproc.h"
+#include "bridged_support.h"
+#if defined(SUPPORT_DRI_DRM)
+#include "pvr_drm.h"
+#endif
+
+#if !defined(PVR_SECURE_HANDLES) && !defined (SUPPORT_SID_INTERFACE)
+#error "The mmap code requires PVR_SECURE_HANDLES"
+#endif
+
+/* WARNING:
+ * The mmap code has its own mutex, to prevent a possible deadlock,
+ * when using gPVRSRVLock.
+ * The Linux kernel takes the mm->mmap_sem before calling the mmap
+ * entry points (PVRMMap, MMapVOpen, MMapVClose), but the ioctl
+ * entry point may take mm->mmap_sem during fault handling, or
+ * before calling get_user_pages. If gPVRSRVLock was used in the
+ * mmap entry points, a deadlock could result, due to the ioctl
+ * and mmap code taking the two locks in different orders.
+ * As a corollary to this, the mmap entry points must not call
+ * any driver code that relies on gPVRSRVLock is held.
+ */
+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
+
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+static struct proc_dir_entry *g_ProcMMap;
+#endif /* defined(DEBUG_LINUX_MMAP_AREAS) */
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+/*
+ * Now that we are using mmap2 in srvclient, almost (*) the full 32
+ * bit offset is available. The range of values is divided into two.
+ * The first part of the range, from FIRST_PHYSICAL_PFN to
+ * LAST_PHYSICAL_PFN, is for raw page mappings (VM_PFNMAP). The
+ * resulting 43 bit (*) physical address range should be enough for
+ * the current range of processors we support.
+ *
+ * NB: (*) -- the above figures assume 4KB page size. The offset
+ * argument to mmap2() is in units of 4,096 bytes regardless of page
+ * size. Thus, we lose (PAGE_SHIFT-12) bits of resolution on other
+ * architectures.
+ *
+ * The second part of the range, from FIRST_SPECIAL_PFN to LAST_SPECIAL_PFN,
+ * is used for all other mappings. These other mappings will always
+ * consist of pages with associated page structures, and need not
+ * represent a contiguous range of physical addresses.
+ *
+ */
+#define MMAP2_PGOFF_RESOLUTION (32-PAGE_SHIFT+12)
+#define RESERVED_PGOFF_BITS 1
+#define MAX_MMAP_HANDLE ((1UL<<(MMAP2_PGOFF_RESOLUTION-RESERVED_PGOFF_BITS))-1)
+
+#define FIRST_PHYSICAL_PFN 0
+#define LAST_PHYSICAL_PFN (FIRST_PHYSICAL_PFN + MAX_MMAP_HANDLE)
+#define FIRST_SPECIAL_PFN (LAST_PHYSICAL_PFN + 1)
+#define LAST_SPECIAL_PFN (FIRST_SPECIAL_PFN + MAX_MMAP_HANDLE)
+
+#else /* !defined(PVR_MAKE_ALL_PFNS_SPECIAL) */
+
+#if PAGE_SHIFT != 12
+#error This build variant has not yet been made non-4KB page-size aware
+#endif
+
+/*
+ * Since we no longer have to worry about clashes with the mmap
+ * offsets used for pure PFN mappings (VM_PFNMAP), there is greater
+ * freedom in choosing the mmap handles. This is useful if the
+ * mmap offset space has to be shared with another driver component.
+ */
+
+#if defined(PVR_MMAP_OFFSET_BASE)
+#define FIRST_SPECIAL_PFN PVR_MMAP_OFFSET_BASE
+#else
+#define FIRST_SPECIAL_PFN 0x80000000UL
+#endif
+
+#if defined(PVR_NUM_MMAP_HANDLES)
+#define MAX_MMAP_HANDLE PVR_NUM_MMAP_HANDLES
+#else
+#define MAX_MMAP_HANDLE 0x7fffffffUL
+#endif
+
+#endif /* !defined(PVR_MAKE_ALL_PFNS_SPECIAL) */
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+static inline IMG_BOOL
+PFNIsPhysical(IMG_UINT32 pfn)
+{
+ /* Unsigned, no need to compare >=0 */
+ return (/*(pfn >= FIRST_PHYSICAL_PFN) &&*/ (pfn <= LAST_PHYSICAL_PFN)) ? IMG_TRUE : IMG_FALSE;
+}
+
+static inline IMG_BOOL
+PFNIsSpecial(IMG_UINT32 pfn)
+{
+ /* Unsigned, no need to compare <=MAX_UINT */
+ return ((pfn >= FIRST_SPECIAL_PFN) /*&& (pfn <= LAST_SPECIAL_PFN)*/) ? IMG_TRUE : IMG_FALSE;
+}
+#endif
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+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);
+}
+#endif
+
+static inline IMG_UINT32
+#if defined (SUPPORT_SID_INTERFACE)
+HandleToMMapOffset(IMG_SID hHandle)
+#else
+HandleToMMapOffset(IMG_HANDLE hHandle)
+#endif
+{
+ IMG_UINT32 ulHandle = (IMG_UINT32)hHandle;
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ if (PFNIsSpecial(ulHandle))
+ {
+ PVR_ASSERT(PFNIsSpecial(ulHandle));
+ return 0;
+ }
+#endif
+ return ulHandle + FIRST_SPECIAL_PFN;
+}
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+/*
+ * Determine whether physical or special mappings will be used for
+ * a given memory area. At present, this decision is made on
+ * whether the mapping represents a contiguous range of physical
+ * addresses, which is a requirement for raw page mappings (VM_PFNMAP).
+ * In the VMA structure for such a mapping, vm_pgoff is the PFN
+ * (page frame number, the physical address divided by the page size)
+ * of the first page in the VMA. The second page is assumed to have
+ * PFN (vm_pgoff + 1), the third (vm_pgoff + 2) and so on.
+ */
+static inline IMG_BOOL
+LinuxMemAreaUsesPhysicalMap(LinuxMemArea *psLinuxMemArea)
+{
+ return LinuxMemAreaPhysIsContig(psLinuxMemArea);
+}
+#endif
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+static inline IMG_UINT32
+GetCurrentThreadID(IMG_VOID)
+{
+ /*
+ * The PID is the thread ID, as each thread is a
+ * seperate process.
+ */
+ return (IMG_UINT32)current->pid;
+}
+#endif
+
+/*
+ * Create an offset structure, which is used to hold per-process
+ * mmap data.
+ */
+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
+
+#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS)
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "%s(%s, psLinuxMemArea: 0x%p, ui32AllocFlags: 0x%8x)",
+ __FUNCTION__, pszName, psLinuxMemArea, psLinuxMemArea->ui32AreaFlags));
+#endif
+
+ 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->ui32RealByteSize = ui32RealByteSize;
+
+ /*
+ * We store the TID in case two threads within a process
+ * generate the same offset structure, and both end up on the
+ * list of structures waiting to be mapped, at the same time.
+ * This could happen if two sub areas within the same page are
+ * being mapped at the same time.
+ * The TID allows the mmap entry point to distinguish which
+ * mapping is being done by which thread.
+ */
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ psOffsetStruct->ui32TID = GetCurrentThreadID();
+#endif
+ psOffsetStruct->ui32PID = OSGetCurrentProcessIDKM();
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+ /* Extra entries to support proc filesystem debug info */
+ psOffsetStruct->pszName = pszName;
+#endif
+
+ list_add_tail(&psOffsetStruct->sAreaItem, &psLinuxMemArea->sMMapOffsetStructList);
+
+ return psOffsetStruct;
+}
+
+
+static IMG_VOID
+DestroyOffsetStruct(PKV_OFFSET_STRUCT psOffsetStruct)
+{
+#ifdef DEBUG
+ IMG_CPU_PHYADDR CpuPAddr;
+ CpuPAddr = LinuxMemAreaToCpuPAddr(psOffsetStruct->psLinuxMemArea, 0);
+#endif
+
+ list_del(&psOffsetStruct->sAreaItem);
+
+ if (psOffsetStruct->bOnMMapList)
+ {
+ list_del(&psOffsetStruct->sMMapItem);
+ }
+
+#ifdef DEBUG
+ PVR_DPF((PVR_DBG_MESSAGE, "%s: Table entry: "
+ "psLinuxMemArea=%p, CpuPAddr=0x%08X", __FUNCTION__,
+ psOffsetStruct->psLinuxMemArea,
+ CpuPAddr.uiAddr));
+#endif
+
+ KMemCacheFreeWrapper(g_psMemmapCache, psOffsetStruct);
+}
+
+
+/*
+ * There are no alignment constraints for mapping requests made by user
+ * mode Services. For this, and potentially other reasons, the
+ * mapping created for a users request may look different to the
+ * original request in terms of size and alignment.
+ *
+ * This function determines an offset that the user can add to the mapping
+ * that is _actually_ created which will point to the memory they are
+ * _really_ interested in.
+ *
+ */
+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);
+}
+
+
+/*!
+ *******************************************************************************
+
+ @Function PVRMMapOSMemHandleToMMapData
+
+ @Description
+
+ Determine various parameters needed to mmap a memory area, and to
+ locate the memory within the mapped area.
+
+ @input psPerProc : Per-process data.
+ @input hMHandle : Memory handle.
+ @input pui32MMapOffset : pointer to location for returned mmap offset.
+ @input pui32ByteOffset : pointer to location for returned byte offset.
+ @input pui32RealByteSize : pointer to location for returned real byte size.
+ @input pui32UserVaddr : pointer to location for returned user mode address.
+
+ @output pui32MMapOffset : points to mmap offset to be used in mmap2 sys call.
+ @output pui32ByteOffset : points to byte offset of start of memory
+ within mapped area returned by mmap2.
+ @output pui32RealByteSize : points to size of area to be mapped.
+ @output pui32UserVAddr : points to user mode address of start of
+ mapping, or 0 if it hasn't been mapped yet.
+
+ @Return PVRSRV_ERROR : PVRSRV_OK, or error code.
+
+ ******************************************************************************/
+PVRSRV_ERROR
+PVRMMapOSMemHandleToMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMHandle,
+#else
+ IMG_HANDLE hMHandle,
+#endif
+ IMG_UINT32 *pui32MMapOffset,
+ IMG_UINT32 *pui32ByteOffset,
+ IMG_UINT32 *pui32RealByteSize,
+ IMG_UINT32 *pui32UserVAddr)
+{
+ LinuxMemArea *psLinuxMemArea;
+ PKV_OFFSET_STRUCT psOffsetStruct;
+ IMG_HANDLE hOSMemHandle;
+ PVRSRV_ERROR eError;
+
+ LinuxLockMutex(&g_sMMapMutex);
+
+ PVR_ASSERT(PVRSRVGetMaxHandle(psPerProc->psHandleBase) <= MAX_MMAP_HANDLE);
+
+ eError = PVRSRVLookupOSMemHandle(psPerProc->psHandleBase, &hOSMemHandle, hMHandle);
+ if (eError != PVRSRV_OK)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DPF((PVR_DBG_ERROR, "%s: Lookup of handle %x failed", __FUNCTION__, hMHandle));
+#else
+ PVR_DPF((PVR_DBG_ERROR, "%s: Lookup of handle %p failed", __FUNCTION__, hMHandle));
+#endif
+
+ goto exit_unlock;
+ }
+
+ psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+
+ if (psLinuxMemArea && (psLinuxMemArea->eAreaType == LINUX_MEM_AREA_ION))
+ {
+ *pui32RealByteSize = psLinuxMemArea->ui32ByteSize;
+ *pui32ByteOffset = psLinuxMemArea->uData.sIONTilerAlloc.planeOffsets[0];
+ /* The offsets for the subsequent planes must be co-aligned for user
+ * space mapping and sgx 544 and later. I.e.
+ * psLinuxMemArea->uData.sIONTilerAlloc.planeOffsets[n];
+ */
+ }
+ else
+ {
+
+ /* Sparse mappings have to ask the BM for the virtual size */
+ if (psLinuxMemArea->hBMHandle)
+ {
+ *pui32RealByteSize = BM_GetVirtualSize(psLinuxMemArea->hBMHandle);
+ *pui32ByteOffset = 0;
+ }
+ else
+ {
+ DetermineUsersSizeAndByteOffset(psLinuxMemArea,
+ pui32RealByteSize,
+ pui32ByteOffset);
+ }
+ }
+
+ /* Check whether this memory area has already been mapped */
+ list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem)
+ {
+ if (psPerProc->ui32PID == psOffsetStruct->ui32PID)
+ {
+ if (!psLinuxMemArea->hBMHandle)
+ {
+ PVR_ASSERT(*pui32RealByteSize == psOffsetStruct->ui32RealByteSize);
+ }
+ /*
+ * User mode locking is required to stop two threads racing to
+ * map the same memory area. The lock should prevent a
+ * second thread retrieving mmap data for a given handle,
+ * before the first thread has done the mmap.
+ * Without locking, both threads may attempt the mmap,
+ * and one of them will fail.
+ */
+ *pui32MMapOffset = psOffsetStruct->ui32MMapOffset;
+ *pui32UserVAddr = psOffsetStruct->ui32UserVAddr;
+ PVRSRVOffsetStructIncRef(psOffsetStruct);
+
+ eError = PVRSRV_OK;
+ goto exit_unlock;
+ }
+ }
+
+ /* Memory area won't have been mapped yet */
+ *pui32UserVAddr = 0;
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ if (LinuxMemAreaUsesPhysicalMap(psLinuxMemArea))
+ {
+ *pui32MMapOffset = LinuxMemAreaToCpuPFN(psLinuxMemArea, 0);
+ PVR_ASSERT(PFNIsPhysical(*pui32MMapOffset));
+ }
+ else
+#endif
+ {
+ *pui32MMapOffset = HandleToMMapOffset(hMHandle);
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ PVR_ASSERT(PFNIsSpecial(*pui32MMapOffset));
+#endif
+ }
+
+ psOffsetStruct = CreateOffsetStruct(psLinuxMemArea, *pui32MMapOffset, *pui32RealByteSize);
+ if (psOffsetStruct == IMG_NULL)
+ {
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto exit_unlock;
+ }
+
+ /*
+ * Offset structures representing physical mappings are added to
+ * a list, so that they can be located when the memory area is mapped.
+ */
+ list_add_tail(&psOffsetStruct->sMMapItem, &g_sMMapOffsetStructList);
+
+ psOffsetStruct->bOnMMapList = IMG_TRUE;
+
+ PVRSRVOffsetStructIncRef(psOffsetStruct);
+
+ eError = PVRSRV_OK;
+
+ /* Need to scale up the offset to counter the shifting that
+ is done in the mmap2() syscall, as it expects the pgoff
+ argument to be in units of 4,096 bytes irrespective of
+ page size */
+ *pui32MMapOffset = *pui32MMapOffset << (PAGE_SHIFT - 12);
+
+exit_unlock:
+ LinuxUnLockMutex(&g_sMMapMutex);
+
+ return eError;
+}
+
+
+/*!
+ *******************************************************************************
+
+ @Function PVRMMapReleaseMMapData
+
+ @Description
+
+ Release mmap data.
+
+ @input psPerProc : Per-process data.
+ @input hMHandle : Memory handle.
+ @input pbMUnmap : pointer to location for munmap flag.
+ @input pui32UserVAddr : pointer to location for user mode address of mapping.
+ @input pui32ByteSize : pointer to location for size of mapping.
+
+ @Output pbMUnmap : points to flag that indicates whether an munmap is
+ required.
+ @output pui32UserVAddr : points to user mode address to munmap.
+
+ @Return PVRSRV_ERROR : PVRSRV_OK, or error code.
+
+ ******************************************************************************/
+PVRSRV_ERROR
+PVRMMapReleaseMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMHandle,
+#else
+ IMG_HANDLE hMHandle,
+#endif
+ IMG_BOOL *pbMUnmap,
+ IMG_UINT32 *pui32RealByteSize,
+ IMG_UINT32 *pui32UserVAddr)
+{
+ LinuxMemArea *psLinuxMemArea;
+ PKV_OFFSET_STRUCT psOffsetStruct;
+ IMG_HANDLE hOSMemHandle;
+ PVRSRV_ERROR eError;
+ 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)
+ {
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DPF((PVR_DBG_ERROR, "%s: Lookup of handle %x failed", __FUNCTION__, hMHandle));
+#else
+ PVR_DPF((PVR_DBG_ERROR, "%s: Lookup of handle %p failed", __FUNCTION__, hMHandle));
+#endif
+
+ goto exit_unlock;
+ }
+
+ psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+
+ /* Find the offset structure */
+ 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 %p", __FUNCTION__, psOffsetStruct, psLinuxMemArea));
+ eError = PVRSRV_ERROR_STILL_MAPPED;
+ goto exit_unlock;
+ }
+
+ PVRSRVOffsetStructDecRef(psOffsetStruct);
+
+ *pbMUnmap = (IMG_BOOL)((psOffsetStruct->ui32RefCount == 0) && (psOffsetStruct->ui32UserVAddr != 0));
+
+ *pui32UserVAddr = (*pbMUnmap) ? psOffsetStruct->ui32UserVAddr : 0;
+ *pui32RealByteSize = (*pbMUnmap) ? psOffsetStruct->ui32RealByteSize : 0;
+
+ eError = PVRSRV_OK;
+ goto exit_unlock;
+ }
+ }
+
+ /* MMap data not found */
+#if defined (SUPPORT_SID_INTERFACE)
+ PVR_DPF((PVR_DBG_ERROR, "%s: Mapping data not found for handle %x (memory area %p)", __FUNCTION__, hMHandle, psLinuxMemArea));
+#else
+ PVR_DPF((PVR_DBG_ERROR, "%s: Mapping data not found for handle %p (memory area %p)", __FUNCTION__, hMHandle, psLinuxMemArea));
+#endif
+
+ eError = PVRSRV_ERROR_MAPPING_NOT_FOUND;
+
+exit_unlock:
+ LinuxUnLockMutex(&g_sMMapMutex);
+
+ return eError;
+}
+
+static inline PKV_OFFSET_STRUCT
+FindOffsetStructByOffset(IMG_UINT32 ui32Offset, IMG_UINT32 ui32RealByteSize)
+{
+ PKV_OFFSET_STRUCT psOffsetStruct;
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ IMG_UINT32 ui32TID = GetCurrentThreadID();
+#endif
+ IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
+
+ list_for_each_entry(psOffsetStruct, &g_sMMapOffsetStructList, sMMapItem)
+ {
+ if (ui32Offset == psOffsetStruct->ui32MMapOffset && ui32RealByteSize == psOffsetStruct->ui32RealByteSize && psOffsetStruct->ui32PID == ui32PID)
+ {
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ /*
+ * If the offset is physical, make sure the thread IDs match,
+ * as different threads may be mapping different memory areas
+ * with the same offset.
+ */
+ if (!PFNIsPhysical(ui32Offset) || psOffsetStruct->ui32TID == ui32TID)
+#endif
+ {
+ return psOffsetStruct;
+ }
+ }
+ }
+
+ return IMG_NULL;
+}
+
+
+/*
+ * Map a memory area into user space.
+ * Note, the ui32ByteOffset is _not_ implicitly page aligned since
+ * LINUX_MEM_AREA_SUB_ALLOC LinuxMemAreas have no alignment constraints.
+ */
+static IMG_BOOL
+DoMapToUser(LinuxMemArea *psLinuxMemArea,
+ struct vm_area_struct* ps_vma,
+ IMG_UINT32 ui32ByteOffset)
+{
+ IMG_UINT32 ui32ByteSize;
+
+ if ((psLinuxMemArea->hBMHandle) && (ui32ByteOffset != 0))
+ {
+ /* Partial mapping of sparse allocations should never happen */
+ return IMG_FALSE;
+ }
+
+ if (psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC)
+ {
+ return DoMapToUser(LinuxMemAreaRoot(psLinuxMemArea), /* PRQA S 3670 */ /* allow recursion */
+ ps_vma,
+ psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset + ui32ByteOffset);
+ }
+
+ /*
+ * Note that ui32ByteSize may be larger than the size of the memory
+ * area being mapped, as the former is a multiple of the page size.
+ */
+ ui32ByteSize = ps_vma->vm_end - ps_vma->vm_start;
+ PVR_ASSERT(ADDR_TO_PAGE_OFFSET(ui32ByteSize) == 0);
+
+#if defined (__sparc__)
+ /*
+ * For LINUX_MEM_AREA_EXTERNAL_KV, we don't know where the address range
+ * we are being asked to map has come from, that is, whether it is memory
+ * or I/O. For all architectures other than SPARC, there is no distinction.
+ * Since we don't currently support SPARC, we won't worry about it.
+ */
+#error "SPARC not supported"
+#endif
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ if (PFNIsPhysical(ps_vma->vm_pgoff))
+ {
+ IMG_INT result;
+
+ PVR_ASSERT(LinuxMemAreaPhysIsContig(psLinuxMemArea));
+ PVR_ASSERT(LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32ByteOffset) == ps_vma->vm_pgoff);
+ /*
+ * Since the memory is contiguous, we can map the whole range in one
+ * go .
+ */
+
+ PVR_ASSERT(psLinuxMemArea->hBMHandle == IMG_NULL);
+
+ 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));
+ }
+#endif
+
+ {
+ /*
+ * Memory may be non-contiguous, so we map the range page,
+ * by page. Since VM_PFNMAP mappings are assumed to be physically
+ * contiguous, we can't legally use REMAP_PFN_RANGE (that is, we
+ * could, but the resulting VMA may confuse other bits of the kernel
+ * that attempt to interpret it).
+ * The only alternative is to use VM_INSERT_PAGE, which requires
+ * finding the page structure corresponding to each page, or
+ * if mixed maps are supported (VM_MIXEDMAP), vm_insert_mixed.
+ */
+ IMG_UINT32 ulVMAPos;
+ IMG_UINT32 ui32ByteEnd = ui32ByteOffset + ui32ByteSize;
+ IMG_UINT32 ui32PA;
+ IMG_UINT32 ui32AdjustedPA = ui32ByteOffset;
+#if defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ IMG_BOOL bMixedMap = IMG_FALSE;
+#endif
+ /* First pass, validate the page frame numbers */
+ for(ui32PA = ui32ByteOffset; ui32PA < ui32ByteEnd; ui32PA += PAGE_SIZE)
+ {
+ IMG_UINT32 pfn;
+ IMG_BOOL bMapPage = IMG_TRUE;
+
+ if (psLinuxMemArea->hBMHandle)
+ {
+ if (!BM_MapPageAtOffset(psLinuxMemArea->hBMHandle, ui32PA))
+ {
+ bMapPage = IMG_FALSE;
+ }
+ }
+
+ if (bMapPage)
+ {
+ pfn = LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32AdjustedPA);
+ if (!pfn_valid(pfn))
+ {
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ PVR_DPF((PVR_DBG_ERROR,"%s: Error - PFN invalid: 0x%x", __FUNCTION__, pfn));
+ return IMG_FALSE;
+#else
+ bMixedMap = IMG_TRUE;
+#endif
+ }
+ ui32AdjustedPA += PAGE_SIZE;
+ }
+ }
+
+#if defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ if (bMixedMap)
+ {
+ ps_vma->vm_flags |= VM_MIXEDMAP;
+ }
+#endif
+ /* Second pass, get the page structures and insert the pages */
+ ulVMAPos = ps_vma->vm_start;
+ ui32AdjustedPA = ui32ByteOffset;
+ for(ui32PA = ui32ByteOffset; ui32PA < ui32ByteEnd; ui32PA += PAGE_SIZE)
+ {
+ IMG_UINT32 pfn;
+ IMG_INT result;
+ IMG_BOOL bMapPage = IMG_TRUE;
+
+ if (psLinuxMemArea->hBMHandle)
+ {
+ /* We have a sparse allocation, check if this page should be mapped */
+ if (!BM_MapPageAtOffset(psLinuxMemArea->hBMHandle, ui32PA))
+ {
+ bMapPage = IMG_FALSE;
+ }
+ }
+
+ if (bMapPage)
+ {
+ pfn = LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32AdjustedPA);
+
+#if defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ if (bMixedMap)
+ {
+ result = vm_insert_mixed(ps_vma, ulVMAPos, pfn);
+ if(result != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"%s: Error - vm_insert_mixed failed (%d)", __FUNCTION__, result));
+ return IMG_FALSE;
+ }
+ }
+ else
+#endif
+ {
+ struct page *psPage;
+
+ 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;
+ }
+ }
+ ui32AdjustedPA += PAGE_SIZE;
+ }
+ 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);
+ PVR_ASSERT(!psOffsetStruct->bOnMMapList);
+
+ PVRSRVOffsetStructIncMapped(psOffsetStruct);
+
+ if (psOffsetStruct->ui32Mapped > 1)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s: Offset structure 0x%p is being shared across processes (psOffsetStruct->ui32Mapped: %u)", __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 %d, ui32Mapped %d",
+ __FUNCTION__,
+ psOffsetStruct->psLinuxMemArea,
+ LinuxMemAreaToCpuVAddr(psOffsetStruct->psLinuxMemArea),
+ psOffsetStruct->ui32MMapOffset,
+ psOffsetStruct->ui32Mapped));
+#endif
+}
+
+
+/*
+ * Linux mmap open entry point.
+ */
+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 %p, CpuVAddr %p ui32MMapOffset %d, ui32Mapped %d",
+ __FUNCTION__,
+ psOffsetStruct->psLinuxMemArea,
+ LinuxMemAreaToCpuVAddr(psOffsetStruct->psLinuxMemArea),
+ psOffsetStruct->ui32MMapOffset,
+ psOffsetStruct->ui32Mapped));
+#endif
+
+ PVR_ASSERT(!psOffsetStruct->bOnMMapList);
+ PVRSRVOffsetStructDecMapped(psOffsetStruct);
+ if (psOffsetStruct->ui32Mapped == 0)
+ {
+ if (psOffsetStruct->ui32RefCount != 0)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "%s: psOffsetStruct %p has non-zero reference count (ui32RefCount = %u). User mode address of start of mapping: 0x%x", __FUNCTION__, psOffsetStruct, psOffsetStruct->ui32RefCount, psOffsetStruct->ui32UserVAddr));
+ }
+
+ DestroyOffsetStruct(psOffsetStruct);
+ }
+
+ ps_vma->vm_private_data = NULL;
+}
+
+/*
+ * Linux mmap close entry point.
+ */
+static void
+MMapVClose(struct vm_area_struct* ps_vma)
+{
+ LinuxLockMutex(&g_sMMapMutex);
+
+ MMapVCloseNoLock(ps_vma);
+
+ LinuxUnLockMutex(&g_sMMapMutex);
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
+/*
+ * This vma operation is used to read data from mmap regions. It is called
+ * by access_process_vm, which is called to handle PTRACE_PEEKDATA ptrace
+ * requests and reads from /proc/<pid>/mem.
+ */
+static int MMapVAccess(struct vm_area_struct *ps_vma, unsigned long addr,
+ void *buf, int len, int write)
+{
+ PKV_OFFSET_STRUCT psOffsetStruct;
+ LinuxMemArea *psLinuxMemArea;
+ unsigned long ulOffset;
+ int iRetVal = -EINVAL;
+ IMG_VOID *pvKernelAddr;
+
+ LinuxLockMutex(&g_sMMapMutex);
+
+ psOffsetStruct = (PKV_OFFSET_STRUCT)ps_vma->vm_private_data;
+ psLinuxMemArea = psOffsetStruct->psLinuxMemArea;
+ ulOffset = addr - ps_vma->vm_start;
+
+ if (ulOffset+len > psLinuxMemArea->ui32ByteSize)
+ /* Out of range. We shouldn't get here, because the kernel will do
+ the necessary checks before calling access_process_vm. */
+ goto exit_unlock;
+
+ pvKernelAddr = LinuxMemAreaToCpuVAddr(psLinuxMemArea);
+
+ if (pvKernelAddr)
+ {
+ memcpy(buf, pvKernelAddr+ulOffset, len);
+ iRetVal = len;
+ }
+ else
+ {
+ IMG_UINT32 pfn, ui32OffsetInPage;
+ struct page *page;
+
+ pfn = LinuxMemAreaToCpuPFN(psLinuxMemArea, ulOffset);
+
+ if (!pfn_valid(pfn))
+ goto exit_unlock;
+
+ page = pfn_to_page(pfn);
+ ui32OffsetInPage = ADDR_TO_PAGE_OFFSET(ulOffset);
+
+ if (ui32OffsetInPage+len > PAGE_SIZE)
+ /* The region crosses a page boundary */
+ goto exit_unlock;
+
+ pvKernelAddr = kmap(page);
+ memcpy(buf, pvKernelAddr+ui32OffsetInPage, len);
+ kunmap(page);
+
+ iRetVal = len;
+ }
+
+exit_unlock:
+ LinuxUnLockMutex(&g_sMMapMutex);
+ return iRetVal;
+}
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) */
+
+static struct vm_operations_struct MMapIOOps =
+{
+ .open=MMapVOpen,
+ .close=MMapVClose,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
+ .access=MMapVAccess,
+#endif
+};
+
+
+/*!
+ *******************************************************************************
+
+ @Function PVRMMap
+
+ @Description
+
+ Driver mmap entry point.
+
+ @input pFile : unused.
+ @input ps_vma : pointer to linux memory area descriptor.
+
+ @Return 0, or Linux error code.
+
+ ******************************************************************************/
+int
+PVRMMap(struct file* pFile, struct vm_area_struct* ps_vma)
+{
+ LinuxMemArea *psFlushMemArea = IMG_NULL;
+ PKV_OFFSET_STRUCT psOffsetStruct;
+ IMG_UINT32 ui32ByteSize;
+ IMG_VOID *pvBase = IMG_NULL;
+ int iRetVal = 0;
+ IMG_UINT32 ui32ByteOffset = 0; /* Keep compiler happy */
+ IMG_UINT32 ui32FlushSize = 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 %d(0x%08x)",
+ __FUNCTION__,
+ ps_vma->vm_pgoff,
+ ui32ByteSize, ui32ByteSize));
+
+ psOffsetStruct = FindOffsetStructByOffset(ps_vma->vm_pgoff, ui32ByteSize);
+
+ if (psOffsetStruct == IMG_NULL)
+ {
+#if defined(SUPPORT_DRI_DRM)
+ LinuxUnLockMutex(&g_sMMapMutex);
+
+#if !defined(SUPPORT_DRI_DRM_EXT)
+ /* Pass unknown requests onto the DRM module */
+ return drm_mmap(pFile, ps_vma);
+#else
+ /*
+ * Indicate to caller that the request is not for us.
+ * Do not return this error elsewhere in this function, as the
+ * caller may use it as a clue as to whether the mmap request
+ * should be passed on to another component (e.g. drm_mmap).
+ */
+ return -ENOENT;
+#endif
+#else
+ PVR_UNREFERENCED_PARAMETER(pFile);
+
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Attempted to mmap unregistered area at vm_pgoff 0x%lx",
+ __FUNCTION__, ps_vma->vm_pgoff));
+ iRetVal = -EINVAL;
+#endif
+ goto unlock_and_return;
+ }
+
+ list_del(&psOffsetStruct->sMMapItem);
+ psOffsetStruct->bOnMMapList = IMG_FALSE;
+
+ /* Only support shared writeable mappings */
+ if (((ps_vma->vm_flags & VM_WRITE) != 0) &&
+ ((ps_vma->vm_flags & VM_SHARED) == 0))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Cannot mmap non-shareable writable areas", __FUNCTION__));
+ iRetVal = -EINVAL;
+ goto unlock_and_return;
+ }
+
+ 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;
+
+ /*
+ * Disable mremap because our nopage handler assumes all
+ * page requests have already been validated.
+ */
+ ps_vma->vm_flags |= VM_DONTEXPAND;
+
+ /* Don't allow mapping to be inherited across a process fork */
+ 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:
+ /* This is the default, do nothing. */
+ 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;
+ }
+
+#if defined(SGX544) && defined(SGX_FEATURE_MP)
+ /* In OMAP5, the A15 no longer masks an issue with the interconnect.
+ writecombined access to the Tiler 2D memory will encounter errors due to
+ interconect bus accesses. This will result in a SIGBUS error with a
+ "non-line fetch abort". The workaround is to use a shared device
+ access. */
+ if (psOffsetStruct->psLinuxMemArea->eAreaType == LINUX_MEM_AREA_ION)
+ ps_vma->vm_page_prot = __pgprot_modify(ps_vma->vm_page_prot,
+ L_PTE_MT_MASK, L_PTE_MT_DEV_SHARED);
+#endif
+
+ /* Install open and close handlers for ref-counting */
+ 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;
+
+ /* Invalidate for the ION memory is performed during the mapping */
+ if(psOffsetStruct->psLinuxMemArea->eAreaType == LINUX_MEM_AREA_ION)
+ psOffsetStruct->psLinuxMemArea->bNeedsCacheInvalidate = IMG_FALSE;
+
+ /* Compute the flush region (if necessary) inside the mmap mutex */
+ if(psOffsetStruct->psLinuxMemArea->bNeedsCacheInvalidate)
+ {
+ psFlushMemArea = psOffsetStruct->psLinuxMemArea;
+
+ /* Sparse mappings have to ask the BM for the virtual size */
+ if (psFlushMemArea->hBMHandle)
+ {
+ pvBase = (IMG_VOID *)ps_vma->vm_start;
+ ui32ByteOffset = 0;
+ ui32FlushSize = BM_GetVirtualSize(psFlushMemArea->hBMHandle);
+ }
+ else
+ {
+ IMG_UINT32 ui32DummyByteSize;
+
+ DetermineUsersSizeAndByteOffset(psFlushMemArea,
+ &ui32DummyByteSize,
+ &ui32ByteOffset);
+
+ pvBase = (IMG_VOID *)ps_vma->vm_start + ui32ByteOffset;
+ ui32FlushSize = psFlushMemArea->ui32ByteSize;
+ }
+
+ psFlushMemArea->bNeedsCacheInvalidate = IMG_FALSE;
+ }
+
+ /* Call the open routine to increment the usage count */
+ 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);
+
+ if(psFlushMemArea)
+ {
+ OSInvalidateCPUCacheRangeKM(psFlushMemArea, ui32ByteOffset, pvBase,
+ ui32FlushSize);
+ }
+
+ return iRetVal;
+}
+
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+
+/*
+ * Lock MMap regions list (called on page start/stop while reading /proc/mmap)
+
+ * sfile : seq_file that handles /proc file
+ * start : TRUE if it's start, FALSE if it's stop
+ *
+*/
+static void ProcSeqStartstopMMapRegistations(struct seq_file *sfile,IMG_BOOL start)
+{
+ if(start)
+ {
+ LinuxLockMutex(&g_sMMapMutex);
+ }
+ else
+ {
+ LinuxUnLockMutex(&g_sMMapMutex);
+ }
+}
+
+
+/*
+ * Convert offset (index from KVOffsetTable) to element
+ * (called when reading /proc/mmap file)
+
+ * sfile : seq_file that handles /proc file
+ * off : index into the KVOffsetTable from which to print
+ *
+ * returns void* : Pointer to element that will be dumped
+ *
+*/
+static void* ProcSeqOff2ElementMMapRegistrations(struct seq_file *sfile, loff_t off)
+{
+ LinuxMemArea *psLinuxMemArea;
+ if(!off)
+ {
+ return PVR_PROC_SEQ_START_TOKEN;
+ }
+
+ list_for_each_entry(psLinuxMemArea, &g_sMMapAreaList, sMMapItem)
+ {
+ PKV_OFFSET_STRUCT psOffsetStruct;
+
+ list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem)
+ {
+ off--;
+ if (off == 0)
+ {
+ PVR_ASSERT(psOffsetStruct->psLinuxMemArea == psLinuxMemArea);
+ return (void*)psOffsetStruct;
+ }
+ }
+ }
+ return (void*)0;
+}
+
+/*
+ * Gets next MMap element to show. (called when reading /proc/mmap file)
+
+ * sfile : seq_file that handles /proc file
+ * el : actual element
+ * off : index into the KVOffsetTable from which to print
+ *
+ * returns void* : Pointer to element to show (0 ends iteration)
+*/
+static void* ProcSeqNextMMapRegistrations(struct seq_file *sfile,void* el,loff_t off)
+{
+ return ProcSeqOff2ElementMMapRegistrations(sfile,off);
+}
+
+
+/*
+ * Show MMap element (called when reading /proc/mmap file)
+
+ * sfile : seq_file that handles /proc file
+ * el : actual element
+ *
+*/
+static void ProcSeqShowMMapRegistrations(struct seq_file *sfile, void *el)
+{
+ KV_OFFSET_STRUCT *psOffsetStruct = (KV_OFFSET_STRUCT*)el;
+ LinuxMemArea *psLinuxMemArea;
+ IMG_UINT32 ui32RealByteSize;
+ IMG_UINT32 ui32ByteOffset;
+
+ if(el == PVR_PROC_SEQ_START_TOKEN)
+ {
+ seq_printf( sfile,
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+ "Allocations registered for mmap: %u\n"
+ "In total these areas correspond to %u bytes\n"
+ "psLinuxMemArea "
+ "UserVAddr "
+ "KernelVAddr "
+ "CpuPAddr "
+ "MMapOffset "
+ "ByteLength "
+ "LinuxMemType "
+ "Pid Name Flags\n",
+#else
+ "<mmap_header>\n"
+ "\t<count>%u</count>\n"
+ "\t<bytes>%u</bytes>\n"
+ "</mmap_header>\n",
+#endif
+ g_ui32RegisteredAreas,
+ g_ui32TotalByteSize
+ );
+ return;
+ }
+
+ psLinuxMemArea = psOffsetStruct->psLinuxMemArea;
+
+ DetermineUsersSizeAndByteOffset(psLinuxMemArea,
+ &ui32RealByteSize,
+ &ui32ByteOffset);
+
+ seq_printf( sfile,
+#if !defined(DEBUG_LINUX_XML_PROC_FILES)
+ "%-8p %08x %-8p %08x %08x %-8d %-24s %-5u %-8s %08x(%s)\n",
+#else
+ "<mmap_record>\n"
+ "\t<pointer>%-8p</pointer>\n"
+ "\t<user_virtual>%-8x</user_virtual>\n"
+ "\t<kernel_virtual>%-8p</kernel_virtual>\n"
+ "\t<cpu_physical>%08x</cpu_physical>\n"
+ "\t<mmap_offset>%08x</mmap_offset>\n"
+ "\t<bytes>%-8d</bytes>\n"
+ "\t<linux_mem_area_type>%-24s</linux_mem_area_type>\n"
+ "\t<pid>%-5u</pid>\n"
+ "\t<name>%-8s</name>\n"
+ "\t<flags>%08x</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));
+}
+
+#endif
+
+
+/*!
+ *******************************************************************************
+
+ @Function PVRMMapRegisterArea
+
+ @Description
+
+ Register a memory area with the mmap code.
+
+ @input psLinuxMemArea : pointer to memory area.
+
+ @Return PVRSRV_OK, or PVRSRV_ERROR.
+
+ ******************************************************************************/
+PVRSRV_ERROR
+PVRMMapRegisterArea(LinuxMemArea *psLinuxMemArea)
+{
+ PVRSRV_ERROR eError;
+#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS)
+ const IMG_CHAR *pszName = LinuxMemAreaTypeToString(LinuxMemAreaRootType(psLinuxMemArea));
+#endif
+
+ LinuxLockMutex(&g_sMMapMutex);
+
+#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS)
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "%s(%s, psLinuxMemArea 0x%p, ui32AllocFlags 0x%8x)",
+ __FUNCTION__, pszName, psLinuxMemArea, psLinuxMemArea->ui32AreaFlags));
+#endif
+
+ PVR_ASSERT(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC || LinuxMemAreaRoot(psLinuxMemArea)->eAreaType != LINUX_MEM_AREA_SUB_ALLOC);
+
+ /* Check this mem area hasn't already been registered */
+ 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++;
+ /*
+ * Sub memory areas are excluded from g_ui32TotalByteSize so that we
+ * don't count memory twice, once for the parent and again for sub
+ * allocationis.
+ */
+ if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC)
+ {
+ g_ui32TotalByteSize += psLinuxMemArea->ui32ByteSize;
+ }
+#endif
+
+ eError = PVRSRV_OK;
+
+exit_unlock:
+ LinuxUnLockMutex(&g_sMMapMutex);
+
+ return eError;
+}
+
+
+/*!
+ *******************************************************************************
+
+ @Function PVRMMapRemoveRegisterArea
+
+ @Description
+
+ Unregister a memory area with the mmap code.
+
+ @input psLinuxMemArea : pointer to memory area.
+
+ @Return PVRSRV_OK, or PVRSRV_ERROR.
+
+ ******************************************************************************/
+PVRSRV_ERROR
+PVRMMapRemoveRegisteredArea(LinuxMemArea *psLinuxMemArea)
+{
+ PVRSRV_ERROR eError;
+ 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 %u", __FUNCTION__, psOffsetStruct, psLinuxMemArea, psOffsetStruct->ui32Mapped));
+ dump_stack();
+ PVRSRVDumpRefCountCCB();
+ eError = PVRSRV_ERROR_STILL_MAPPED;
+ goto exit_unlock;
+ }
+ else
+ {
+ /*
+ * An offset structure is created when a call is made to get
+ * the mmap data for a physical mapping. If the data is never
+ * used for mmap, we will be left with an umapped offset
+ * structure.
+ */
+ 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;
+}
+
+
+/*!
+ *******************************************************************************
+
+ @Function LinuxMMapPerProcessConnect
+
+ @Description
+
+ Per-process mmap initialisation code.
+
+ @input psEnvPerProc : pointer to OS specific per-process data.
+
+ @Return PVRSRV_OK, or PVRSRV_ERROR.
+
+ ******************************************************************************/
+PVRSRV_ERROR
+LinuxMMapPerProcessConnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc)
+{
+ PVR_UNREFERENCED_PARAMETER(psEnvPerProc);
+
+ return PVRSRV_OK;
+}
+
+/*!
+ *******************************************************************************
+
+ @Function LinuxMMapPerProcessDisconnect
+
+ @Description
+
+ Per-process mmap deinitialisation code.
+
+ @input psEnvPerProc : pointer to OS specific per-process data.
+
+ ******************************************************************************/
+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);
+}
+
+
+/*!
+ *******************************************************************************
+
+ @Function LinuxMMapPerProcessHandleOptions
+
+ @Description
+
+ Set secure handle options required by mmap code.
+
+ @input psHandleBase : pointer to handle base.
+
+ @Return PVRSRV_OK, or PVRSRV_ERROR.
+
+ ******************************************************************************/
+PVRSRV_ERROR LinuxMMapPerProcessHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase)
+{
+ PVRSRV_ERROR eError;
+
+ 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;
+}
+
+
+/*!
+ *******************************************************************************
+
+ @Function PVRMMapInit
+
+ @Description
+
+ MMap initialisation code
+
+ ******************************************************************************/
+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)
+ g_ProcMMap = CreateProcReadEntrySeq("mmap", NULL,
+ ProcSeqNextMMapRegistrations,
+ ProcSeqShowMMapRegistrations,
+ ProcSeqOff2ElementMMapRegistrations,
+ ProcSeqStartstopMMapRegistations
+ );
+#endif /* defined(DEBUG_LINUX_MMAP_AREAS) */
+ return;
+
+error:
+ PVRMMapCleanup();
+ return;
+}
+
+
+/*!
+ *******************************************************************************
+
+ @Function PVRMMapCleanup
+
+ @Description
+
+ Mmap deinitialisation code
+
+ ******************************************************************************/
+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)));
+
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+ RemoveProcEntrySeq(g_ProcMMap);
+#endif /* defined(DEBUG_LINUX_MMAP_AREAS) */
+
+ if(g_psMemmapCache)
+ {
+ KMemCacheDestroyWrapper(g_psMemmapCache);
+ g_psMemmapCache = NULL;
+ }
+}
diff --git a/pvr-source/services4/srvkm/env/linux/mmap.h b/pvr-source/services4/srvkm/env/linux/mmap.h
new file mode 100644
index 0000000..7140c13
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/mmap.h
@@ -0,0 +1,240 @@
+/*************************************************************************/ /*!
+@Title Linux mmap interface declaration
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__MMAP_H__)
+#define __MMAP_H__
+
+#include <linux/mm.h>
+#include <linux/list.h>
+
+#if defined(VM_MIXEDMAP)
+/*
+ * Mixed maps allow us to avoid using raw PFN mappings (VM_PFNMAP) for
+ * pages without pages structures ("struct page"), giving us more
+ * freedom in choosing the mmap offset for mappings. Mixed maps also
+ * allow both the mmap and the wrap code to be simplified somewhat.
+ */
+#define PVR_MAKE_ALL_PFNS_SPECIAL
+#endif
+
+#include "perproc.h"
+#include "mm.h"
+
+/*
+ * This structure represents the relationship between an mmap2 file
+ * offset and a LinuxMemArea for a given process.
+ */
+typedef struct KV_OFFSET_STRUCT_TAG
+{
+ /*
+ * Mapping count. Incremented when the mapping is created, and
+ * if the mapping is inherited across a process fork.
+ */
+ IMG_UINT32 ui32Mapped;
+
+ /*
+ * Offset to be passed to mmap2 to map the associated memory area
+ * into user space. The offset may represent the page frame number
+ * of the first page in the area (if the area is physically
+ * contiguous), or it may represent the secure handle associated
+ * with the area.
+ */
+ IMG_UINT32 ui32MMapOffset;
+
+ IMG_UINT32 ui32RealByteSize;
+
+ /* Memory area associated with this offset structure */
+ LinuxMemArea *psLinuxMemArea;
+
+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL)
+ /* ID of the thread that owns this structure */
+ IMG_UINT32 ui32TID;
+#endif
+
+ /* ID of the process that owns this structure */
+ IMG_UINT32 ui32PID;
+
+ /*
+ * For offsets that represent actual page frame numbers, this structure
+ * is temporarily put on a list so that it can be found from the
+ * driver mmap entry point. This flag indicates the structure is
+ * on the list.
+ */
+ IMG_BOOL bOnMMapList;
+
+ /* Reference count for this structure */
+ IMG_UINT32 ui32RefCount;
+
+ /*
+ * User mode address of start of mapping. This is not necessarily the
+ * first user mode address of the memory area.
+ */
+ IMG_UINT32 ui32UserVAddr;
+
+ /* Extra entries to support proc filesystem debug info */
+#if defined(DEBUG_LINUX_MMAP_AREAS)
+ const IMG_CHAR *pszName;
+#endif
+
+ /* List entry field for MMap list */
+ struct list_head sMMapItem;
+
+ /* List entry field for per-memory area list */
+ struct list_head sAreaItem;
+}KV_OFFSET_STRUCT, *PKV_OFFSET_STRUCT;
+
+
+
+/*!
+ *******************************************************************************
+ * @Function Mmap initialisation code
+ ******************************************************************************/
+IMG_VOID PVRMMapInit(IMG_VOID);
+
+
+/*!
+ *******************************************************************************
+ * @Function Mmap de-initialisation code
+ ******************************************************************************/
+IMG_VOID PVRMMapCleanup(IMG_VOID);
+
+
+/*!
+ *******************************************************************************
+ * @Function Registers a memory area with the mmap code
+ *
+ * @Input psLinuxMemArea
+ *
+ * @Return PVRSRV_ERROR status
+ ******************************************************************************/
+PVRSRV_ERROR PVRMMapRegisterArea(LinuxMemArea *psLinuxMemArea);
+
+
+/*!
+ *******************************************************************************
+ * @Function Unregisters a memory area from the mmap code
+ *
+ * @Input psLinuxMemArea
+ *
+ * @Return PVRSRV_ERROR status
+ ******************************************************************************/
+PVRSRV_ERROR PVRMMapRemoveRegisteredArea(LinuxMemArea *psLinuxMemArea);
+
+
+/*!
+ ******************************************************************************
+ * @Function When a userspace services client, requests to map a memory
+ * area to userspace, this function validates the request and
+ * returns the details that the client must use when calling mmap(2).
+ *
+ * @Input psPerProc Per process data.
+ * @Input hMHandle Handle associated with the memory to map.
+ * This is a (secure) handle to the OS specific
+ * memory handle structure (hOSMemHandle), or
+ * a handle to a structure that contains the
+ * memory handle.
+ * @Output pui32MMapOffset The page aligned offset that the client must
+ * pass to the mmap2 system call.
+ * @Output pui32ByteOffset The real mapping that will be created for the
+ * services client may have a different
+ * size/alignment from it request. This offset
+ * is returned to the client and should be added
+ * to virtual address returned from mmap2 to get
+ * the first address corresponding to its request.
+ * @Output pui32RealByteOffset The size that the mapping will really be,
+ * that the client must also pass to mmap/munmap.
+ *
+ * @Output pui32UserVAddr Pointer to returned user mode address of
+ * mapping.
+ * @Return PVRSRV_ERROR
+ ******************************************************************************/
+PVRSRV_ERROR PVRMMapOSMemHandleToMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMHandle,
+#else
+ IMG_HANDLE hMHandle,
+#endif
+ IMG_UINT32 *pui32MMapOffset,
+ IMG_UINT32 *pui32ByteOffset,
+ IMG_UINT32 *pui32RealByteSize,
+ IMG_UINT32 *pui32UserVAddr);
+
+/*!
+ *******************************************************************************
+
+ @Function Release mmap data.
+
+ @Input psPerProc Per-process data.
+ @Input hMHandle Memory handle.
+
+ @Output pbMUnmap Flag that indicates whether an munmap is
+ required.
+ @Output pui32RealByteSize Location for size of mapping.
+ @Output pui32UserVAddr User mode address to munmap.
+
+ @Return PVRSRV_ERROR
+ ******************************************************************************/
+PVRSRV_ERROR
+PVRMMapReleaseMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hMHandle,
+#else
+ IMG_HANDLE hMHandle,
+#endif
+ IMG_BOOL *pbMUnmap,
+ IMG_UINT32 *pui32RealByteSize,
+ IMG_UINT32 *pui32UserVAddr);
+
+/*!
+ *******************************************************************************
+ * @Function driver mmap entry point
+ *
+ * @Input pFile : user file structure
+ *
+ * @Input ps_vma : vm area structure
+ *
+ * @Return 0 for success, -errno for failure.
+ ******************************************************************************/
+int PVRMMap(struct file* pFile, struct vm_area_struct* ps_vma);
+
+
+#endif /* __MMAP_H__ */
+
diff --git a/pvr-source/services4/srvkm/env/linux/module.c b/pvr-source/services4/srvkm/env/linux/module.c
new file mode 100644
index 0000000..487069d
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/module.c
@@ -0,0 +1,1214 @@
+/*************************************************************************/ /*!
+@Title Linux module setup
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#if defined(SUPPORT_DRI_DRM) && !defined(SUPPORT_DRI_DRM_PLUGIN)
+#define PVR_MOD_STATIC
+#else
+ /*
+ * For LDM drivers, define PVR_LDM_MODULE to indicate generic LDM
+ * support is required, besides indicating the exact support
+ * required (e.g. platform, or PCI device).
+ */
+ #if defined(LDM_PLATFORM)
+ #define PVR_LDM_PLATFORM_MODULE
+ #define PVR_LDM_DEVICE_CLASS
+ #define PVR_LDM_MODULE
+ #else
+ #if defined(LDM_PCI)
+ #define PVR_LDM_DEVICE_CLASS
+ #define PVR_LDM_PCI_MODULE
+ #define PVR_LDM_MODULE
+ #else
+ #if defined(SYS_SHARES_WITH_3PKM)
+ #define PVR_LDM_DEVICE_CLASS
+ #endif
+ #endif
+ #endif
+#define PVR_MOD_STATIC static
+#endif
+
+#if defined(PVR_LDM_PLATFORM_PRE_REGISTERED)
+#if !defined(NO_HARDWARE)
+#define PVR_USE_PRE_REGISTERED_PLATFORM_DEV
+#endif
+#endif
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+
+#if defined(SUPPORT_DRI_DRM)
+#include <drm/drmP.h>
+#if defined(PVR_SECURE_DRM_AUTH_EXPORT)
+#include "env_perproc.h"
+#endif
+#endif
+
+#if defined(PVR_LDM_PLATFORM_MODULE)
+#include <linux/platform_device.h>
+#endif /* PVR_LDM_PLATFORM_MODULE */
+
+#if defined(PVR_LDM_PCI_MODULE)
+#include <linux/pci.h>
+#endif /* PVR_LDM_PCI_MODULE */
+
+#if defined(PVR_LDM_DEVICE_CLASS)
+#include <linux/device.h>
+#endif /* PVR_LDM_DEVICE_CLASS */
+
+#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"
+#include "buffer_manager.h"
+
+#if defined(SUPPORT_DRI_DRM)
+#include "pvr_drm.h"
+#endif
+/*
+ * DRVNAME is the name we use to register our driver.
+ * DEVNAME is the name we use to register actual device nodes.
+ */
+#if defined(PVR_LDM_MODULE)
+#define DRVNAME PVR_LDM_DRIVER_REGISTRATION_NAME
+#endif
+#define DEVNAME PVRSRV_MODNAME
+
+#if defined(SUPPORT_DRI_DRM)
+#define PRIVATE_DATA(pFile) ((pFile)->driver_priv)
+#else
+#define PRIVATE_DATA(pFile) ((pFile)->private_data)
+#endif
+
+/*
+ * This is all module configuration stuff required by the linux kernel.
+ */
+MODULE_SUPPORTED_DEVICE(DEVNAME);
+
+#if defined(PVRSRV_NEED_PVR_DPF)
+#include <linux/moduleparam.h>
+extern IMG_UINT32 gPVRDebugLevel;
+module_param(gPVRDebugLevel, uint, 0644);
+MODULE_PARM_DESC(gPVRDebugLevel, "Sets the level of debug output (default 0x7)");
+#endif /* defined(PVRSRV_NEED_PVR_DPF) */
+
+#if defined(CONFIG_ION_OMAP)
+#include <linux/ion.h>
+#include <linux/omap_ion.h>
+#include "ion.h"
+extern void omap_ion_register_pvr_export(void *);
+extern struct ion_device *omap_ion_device;
+struct ion_client *gpsIONClient;
+EXPORT_SYMBOL(gpsIONClient);
+#endif /* defined(CONFIG_ION_OMAP) */
+
+/* PRQA S 3207 2 */ /* ignore 'not used' warning */
+EXPORT_SYMBOL(PVRGetDisplayClassJTable);
+EXPORT_SYMBOL(PVRGetBufferClassJTable);
+
+#if defined(PVR_LDM_DEVICE_CLASS) && !defined(SUPPORT_DRI_DRM)
+/*
+ * Device class used for /sys entries (and udev device node creation)
+ */
+static struct class *psPvrClass;
+#endif
+
+#if !defined(SUPPORT_DRI_DRM)
+/*
+ * This is the major number we use for all nodes in /dev.
+ */
+static int AssignedMajorNumber;
+
+/*
+ * These are the operations that will be associated with the device node
+ * we create.
+ *
+ * With gcc -W, specifying only the non-null members produces "missing
+ * initializer" warnings.
+*/
+static int PVRSRVOpen(struct inode* pInode, struct file* pFile);
+static int PVRSRVRelease(struct inode* pInode, struct file* pFile);
+
+static struct file_operations pvrsrv_fops =
+{
+ .owner=THIS_MODULE,
+ .unlocked_ioctl = PVRSRV_BridgeDispatchKM,
+ .open=PVRSRVOpen,
+ .release=PVRSRVRelease,
+ .mmap=PVRMMap,
+};
+#endif
+
+PVRSRV_LINUX_MUTEX gPVRSRVLock;
+
+/* PID of process being released */
+IMG_UINT32 gui32ReleasePID;
+
+#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
+static IMG_UINT32 gPVRPowerLevel;
+#endif
+
+#if defined(PVR_LDM_MODULE)
+
+#if defined(PVR_LDM_PLATFORM_MODULE)
+#define LDM_DEV struct platform_device
+#define LDM_DRV struct platform_driver
+#endif /*PVR_LDM_PLATFORM_MODULE */
+
+#if defined(PVR_LDM_PCI_MODULE)
+#define LDM_DEV struct pci_dev
+#define LDM_DRV struct pci_driver
+#endif /* PVR_LDM_PCI_MODULE */
+/*
+ * This is the driver interface we support.
+ */
+#if defined(PVR_LDM_PLATFORM_MODULE)
+static int PVRSRVDriverRemove(LDM_DEV *device);
+static int PVRSRVDriverProbe(LDM_DEV *device);
+#endif
+#if defined(PVR_LDM_PCI_MODULE)
+static void PVRSRVDriverRemove(LDM_DEV *device);
+static int PVRSRVDriverProbe(LDM_DEV *device, const struct pci_device_id *id);
+#endif
+static int PVRSRVDriverSuspend(LDM_DEV *device, pm_message_t state);
+static void PVRSRVDriverShutdown(LDM_DEV *device);
+static int PVRSRVDriverResume(LDM_DEV *device);
+
+#if defined(PVR_LDM_PCI_MODULE)
+/* This structure is used by the Linux module code */
+struct pci_device_id powervr_id_table[] __devinitdata = {
+ {PCI_DEVICE(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID)},
+#if defined (SYS_SGX_DEV1_DEVICE_ID)
+ {PCI_DEVICE(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV1_DEVICE_ID)},
+#endif
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, powervr_id_table);
+#endif
+
+#if defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+static struct platform_device_id powervr_id_table[] __devinitdata = {
+ {SYS_SGX_DEV_NAME, 0},
+ {}
+};
+#endif
+
+static LDM_DRV powervr_driver = {
+#if defined(PVR_LDM_PLATFORM_MODULE)
+ .driver = {
+ .name = DRVNAME,
+ },
+#endif
+#if defined(PVR_LDM_PCI_MODULE)
+ .name = DRVNAME,
+#endif
+#if defined(PVR_LDM_PCI_MODULE) || defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+ .id_table = powervr_id_table,
+#endif
+ .probe = PVRSRVDriverProbe,
+#if defined(PVR_LDM_PLATFORM_MODULE)
+ .remove = PVRSRVDriverRemove,
+#endif
+#if defined(PVR_LDM_PCI_MODULE)
+ .remove = __devexit_p(PVRSRVDriverRemove),
+#endif
+ .suspend = PVRSRVDriverSuspend,
+ .resume = PVRSRVDriverResume,
+ .shutdown = PVRSRVDriverShutdown,
+};
+
+LDM_DEV *gpsPVRLDMDev;
+
+#if defined(MODULE) && defined(PVR_LDM_PLATFORM_MODULE) && \
+ !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+static void PVRSRVDeviceRelease(struct device unref__ *pDevice)
+{
+}
+
+static struct platform_device powervr_device = {
+ .name = DEVNAME,
+ .id = -1,
+ .dev = {
+ .release = PVRSRVDeviceRelease
+ }
+};
+#endif
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVDriverProbe
+
+ @Description
+
+ See whether a given device is really one we can drive. The platform bus
+ handler has already established that we should be able to service this device
+ because of the name match. We probably don't need to do anything else.
+
+ @input pDevice - the device for which a probe is requested
+
+ @Return 0 for success or <0 for an error.
+
+*****************************************************************************/
+#if defined(PVR_LDM_PLATFORM_MODULE)
+static int PVRSRVDriverProbe(LDM_DEV *pDevice)
+#endif
+#if defined(PVR_LDM_PCI_MODULE)
+static int __devinit PVRSRVDriverProbe(LDM_DEV *pDevice, const struct pci_device_id *id)
+#endif
+{
+ SYS_DATA *psSysData;
+
+ PVR_TRACE(("PVRSRVDriverProbe(pDevice=%p)", pDevice));
+
+#if 0 /* INTEGRATION_POINT */
+ /* Some systems require device-specific system initialisation.
+ * E.g. this lets the OS track a device's dependencies on various
+ * system hardware.
+ *
+ * Note: some systems use this to enable HW that SysAcquireData
+ * will depend on, therefore it must be called first.
+ */
+ if (PerDeviceSysInitialise((IMG_PVOID)pDevice) != PVRSRV_OK)
+ {
+ return -EINVAL;
+ }
+#endif
+ /* SysInitialise only designed to be called once.
+ */
+ psSysData = SysAcquireDataNoCheck();
+ if (psSysData == IMG_NULL)
+ {
+ gpsPVRLDMDev = pDevice;
+ if (SysInitialise() != PVRSRV_OK)
+ {
+ return -ENODEV;
+ }
+ }
+
+#if defined(CONFIG_ION_OMAP)
+ gpsIONClient = ion_client_create(omap_ion_device,
+ 1 << ION_HEAP_TYPE_CARVEOUT |
+ 1 << OMAP_ION_HEAP_TYPE_TILER |
+ 1 << ION_HEAP_TYPE_SYSTEM,
+ "pvr");
+ if (IS_ERR_OR_NULL(gpsIONClient))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVDriverProbe: Couldn't create ion client"));
+ return PTR_ERR(gpsIONClient);
+ }
+ omap_ion_register_pvr_export(&PVRSRVExportFDToIONHandles);
+#endif /* defined(CONFIG_ION_OMAP) */
+
+ return 0;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVDriverRemove
+
+ @Description
+
+ This call is the opposite of the probe call: it is called when the device is
+ being removed from the driver's control. See the file $KERNELDIR/drivers/
+ base/bus.c:device_release_driver() for the call to this function.
+
+ This is the correct place to clean up anything our driver did while it was
+ asoociated with the device.
+
+ @input pDevice - the device for which driver detachment is happening
+
+ @Return 0 for success or <0 for an error.
+
+*****************************************************************************/
+#if defined (PVR_LDM_PLATFORM_MODULE)
+static int PVRSRVDriverRemove(LDM_DEV *pDevice)
+#endif
+#if defined(PVR_LDM_PCI_MODULE)
+static void __devexit PVRSRVDriverRemove(LDM_DEV *pDevice)
+#endif
+{
+ SYS_DATA *psSysData;
+
+ PVR_TRACE(("PVRSRVDriverRemove(pDevice=%p)", pDevice));
+
+#if defined(CONFIG_ION_OMAP)
+ ion_client_destroy(gpsIONClient);
+ gpsIONClient = IMG_NULL;
+#endif
+
+ SysAcquireData(&psSysData);
+
+#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
+ if (gPVRPowerLevel != 0)
+ {
+ if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK)
+ {
+ gPVRPowerLevel = 0;
+ }
+ }
+#endif
+ (void) SysDeinitialise(psSysData);
+
+ gpsPVRLDMDev = IMG_NULL;
+
+#if 0 /* INTEGRATION_POINT */
+ /* See previous integration point for details. */
+ if (PerDeviceSysDeInitialise((IMG_PVOID)pDevice) != PVRSRV_OK)
+ {
+ return -EINVAL;
+ }
+#endif
+
+#if defined (PVR_LDM_PLATFORM_MODULE)
+ return 0;
+#endif
+#if defined (PVR_LDM_PCI_MODULE)
+ return;
+#endif
+}
+#endif /* defined(PVR_LDM_MODULE) */
+
+
+#if defined(PVR_LDM_MODULE) || defined(SUPPORT_DRI_DRM)
+static PVRSRV_LINUX_MUTEX gsPMMutex;
+static IMG_BOOL bDriverIsSuspended;
+static IMG_BOOL bDriverIsShutdown;
+#endif
+
+#if defined(PVR_LDM_MODULE) || defined(PVR_DRI_DRM_PLATFORM_DEV)
+/*!
+******************************************************************************
+
+ @Function PVRSRVDriverShutdown
+
+ @Description
+
+ Suspend device operation for system shutdown. This is called as part of the
+ system halt/reboot process. The driver is put into a quiescent state by
+ setting the power state to D3.
+
+ @input pDevice - the device for which shutdown is requested
+
+ @Return nothing
+
+*****************************************************************************/
+#if defined(SUPPORT_DRI_DRM) && !defined(PVR_DRI_DRM_PLATFORM_DEV) && \
+ !defined(SUPPORT_DRI_DRM_PLUGIN)
+void PVRSRVDriverShutdown(struct drm_device *pDevice)
+#else
+PVR_MOD_STATIC void PVRSRVDriverShutdown(LDM_DEV *pDevice)
+#endif
+{
+ PVR_TRACE(("PVRSRVDriverShutdown(pDevice=%p)", pDevice));
+
+ LinuxLockMutex(&gsPMMutex);
+
+ if (!bDriverIsShutdown && !bDriverIsSuspended)
+ {
+ /*
+ * Take the bridge mutex, and never release it, to stop
+ * processes trying to use the driver after it has been
+ * shutdown.
+ */
+ LinuxLockMutex(&gPVRSRVLock);
+
+ (void) PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3);
+ }
+
+ bDriverIsShutdown = IMG_TRUE;
+
+ /* The bridge mutex is held on exit */
+ LinuxUnLockMutex(&gsPMMutex);
+}
+
+#endif /* defined(PVR_LDM_MODULE) || defined(PVR_DRI_DRM_PLATFORM_DEV) */
+
+
+#if defined(PVR_LDM_MODULE) || defined(SUPPORT_DRI_DRM)
+/*!
+******************************************************************************
+
+ @Function PVRSRVDriverSuspend
+
+ @Description
+
+ For 2.6 kernels:
+ Suspend device operation. We always get three calls to this regardless of
+ the state (D1-D3) chosen. The order is SUSPEND_DISABLE, SUSPEND_SAVE_STATE
+ then SUSPEND_POWER_DOWN. We take action as soon as we get the disable call,
+ the other states not being handled by us yet.
+
+ For MontaVista 2.4 kernels:
+ This call gets made once only when someone does something like
+
+ # echo -e -n "suspend powerdown 0" >/sys.devices/legacy/pvrsrv0/power
+
+ The 3rd, numeric parameter (0) in the above has no relevence and is not
+ passed into us. The state parameter is always zero and the level parameter
+ is always SUSPEND_POWER_DOWN. Vive la difference!
+
+ @input pDevice - the device for which resume is requested
+
+ @Return 0 for success or <0 for an error.
+
+*****************************************************************************/
+#if defined(SUPPORT_DRI_DRM) && !defined(PVR_DRI_DRM_PLATFORM_DEV) && \
+ !defined(SUPPORT_DRI_DRM_PLUGIN)
+#if defined(SUPPORT_DRM_MODESET)
+int PVRSRVDriverSuspend(struct pci_dev *pDevice, pm_message_t state)
+#else
+int PVRSRVDriverSuspend(struct drm_device *pDevice, pm_message_t state)
+#endif
+#else
+PVR_MOD_STATIC int PVRSRVDriverSuspend(LDM_DEV *pDevice, pm_message_t state)
+#endif
+{
+ int res = 0;
+#if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM))
+ PVR_TRACE(( "PVRSRVDriverSuspend(pDevice=%p)", pDevice));
+
+ LinuxLockMutex(&gsPMMutex);
+
+ if (!bDriverIsSuspended && !bDriverIsShutdown)
+ {
+ LinuxLockMutex(&gPVRSRVLock);
+
+ if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3) == PVRSRV_OK)
+ {
+ /* The bridge mutex will be held until we resume */
+ bDriverIsSuspended = IMG_TRUE;
+ }
+ else
+ {
+ LinuxUnLockMutex(&gPVRSRVLock);
+ res = -EINVAL;
+ }
+ }
+
+ LinuxUnLockMutex(&gsPMMutex);
+#endif
+ return res;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVDriverResume
+
+ @Description
+
+ Resume device operation following a lull due to earlier suspension. It is
+ implicit we're returning to D0 (fully operational) state. We always get three
+ calls to this using level thus: RESUME_POWER_ON, RESUME_RESTORE_STATE then
+ RESUME_ENABLE. On 2.6 kernels We don't do anything until we get the enable
+ call; on the MontaVista set-up we only ever get the RESUME_POWER_ON call.
+
+ @input pDevice - the device for which resume is requested
+
+ @Return 0 for success or <0 for an error.
+
+*****************************************************************************/
+#if defined(SUPPORT_DRI_DRM) && !defined(PVR_DRI_DRM_PLATFORM_DEV) && \
+ !defined(SUPPORT_DRI_DRM_PLUGIN)
+#if defined(SUPPORT_DRM_MODESET)
+int PVRSRVDriverResume(struct pci_dev *pDevice)
+#else
+int PVRSRVDriverResume(struct drm_device *pDevice)
+#endif
+#else
+PVR_MOD_STATIC int PVRSRVDriverResume(LDM_DEV *pDevice)
+#endif
+{
+ int res = 0;
+#if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM))
+ PVR_TRACE(("PVRSRVDriverResume(pDevice=%p)", pDevice));
+
+ LinuxLockMutex(&gsPMMutex);
+
+ if (bDriverIsSuspended && !bDriverIsShutdown)
+ {
+ if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK)
+ {
+ bDriverIsSuspended = IMG_FALSE;
+ LinuxUnLockMutex(&gPVRSRVLock);
+ }
+ else
+ {
+ /* The bridge mutex is not released on failure */
+ res = -EINVAL;
+ }
+ }
+
+ LinuxUnLockMutex(&gsPMMutex);
+#endif
+ return res;
+}
+#endif /* defined(PVR_LDM_MODULE) || defined(SUPPORT_DRI_DRM) */
+
+
+#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM)
+/*
+ * If PVR_LDM_PCI_MODULE is defined (and PVR_MANUAL_POWER_CONTROL is *NOT* defined),
+ * the device can be suspended and resumed without suspending/resuming the
+ * system, by writing values into the power/state sysfs file for the device.
+ * To suspend:
+ * echo -n 2 > power/state
+ * To Resume:
+ * echo -n 0 > power/state
+ *
+ * The problem with this approach is that the device is usually left
+ * powered up; it is the responsibility of the bus driver to remove
+ * the power.
+ *
+ * Defining PVR_MANUAL_POWER_CONTROL is intended to make it easier to
+ * debug power management issues, especially when power is really removed
+ * from the device. It is easier to debug the driver if it is not being
+ * suspended/resumed with the rest of the system.
+ *
+ * When PVR_MANUAL_POWER_CONTROL is defined, the following proc entry is
+ * created:
+ * /proc/pvr/power_control
+ * The driver suspend/resume entry points defined below no longer suspend or
+ * resume the device. To suspend the device, type the following:
+ * echo 2 > /proc/pvr/power_control
+ * To resume the device, type:
+ * echo 0 > /proc/pvr/power_control
+ *
+ * The following example shows how to suspend/resume the device independently
+ * of the rest of the system.
+ * Suspend the device:
+ * echo 2 > /proc/pvr/power_control
+ * Suspend the system. Then you should be able to suspend and resume
+ * as normal. To resume the device type the following:
+ * echo 0 > /proc/pvr/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_SYS_POWER_STATE_D3) != PVRSRV_OK)
+ {
+ return -EINVAL;
+ }
+ }
+ else
+ {
+ if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) != PVRSRV_OK)
+ {
+ return -EINVAL;
+ }
+ }
+
+ gPVRPowerLevel = PVRPowerLevel;
+ }
+ }
+ return (count);
+}
+
+void ProcSeqShowPowerLevel(struct seq_file *sfile,void* el)
+{
+ seq_printf(sfile, "%lu\n", gPVRPowerLevel);
+}
+
+#endif
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVOpen
+
+ @Description
+
+ Release access the PVR services node - called when a file is closed, whether
+ at exit or using close(2) system call.
+
+ @input pInode - the inode for the file being openeded
+
+ @input pFile - the file handle data for the actual file being opened
+
+ @Return 0 for success or <0 for an error.
+
+*****************************************************************************/
+#if defined(SUPPORT_DRI_DRM)
+int PVRSRVOpen(struct drm_device unref__ *dev, struct drm_file *pFile)
+#else
+static int PVRSRVOpen(struct inode unref__ * pInode, struct file *pFile)
+#endif
+{
+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
+ IMG_HANDLE hBlockAlloc;
+ int iRet = -ENOMEM;
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32PID;
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+ PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
+#endif
+
+ LinuxLockMutex(&gPVRSRVLock);
+
+ ui32PID = OSGetCurrentProcessIDKM();
+
+ if (PVRSRVProcessConnect(ui32PID, 0) != PVRSRV_OK)
+ goto err_unlock;
+
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+ psEnvPerProc = PVRSRVPerProcessPrivateData(ui32PID);
+ if (psEnvPerProc == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: No per-process private data", __FUNCTION__));
+ goto err_unlock;
+ }
+#endif
+
+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_FILE_PRIVATE_DATA),
+ (IMG_PVOID *)&psPrivateData,
+ &hBlockAlloc,
+ "File Private Data");
+
+ if(eError != PVRSRV_OK)
+ goto err_unlock;
+
+#if defined (SUPPORT_SID_INTERFACE)
+ psPrivateData->hKernelMemInfo = 0;
+#else
+ psPrivateData->hKernelMemInfo = NULL;
+#endif
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+ psPrivateData->psDRMFile = pFile;
+
+ list_add_tail(&psPrivateData->sDRMAuthListItem, &psEnvPerProc->sDRMAuthListHead);
+#endif
+ psPrivateData->ui32OpenPID = ui32PID;
+ psPrivateData->hBlockAlloc = hBlockAlloc;
+ PRIVATE_DATA(pFile) = psPrivateData;
+ iRet = 0;
+err_unlock:
+ LinuxUnLockMutex(&gPVRSRVLock);
+ return iRet;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVRelease
+
+ @Description
+
+ Release access the PVR services node - called when a file is closed, whether
+ at exit or using close(2) system call.
+
+ @input pInode - the inode for the file being released
+
+ @input pFile - the file handle data for the actual file being released
+
+ @Return 0 for success or <0 for an error.
+
+*****************************************************************************/
+#if defined(SUPPORT_DRI_DRM)
+void PVRSRVRelease(void *pvPrivData)
+#else
+static int PVRSRVRelease(struct inode unref__ * pInode, struct file *pFile)
+#endif
+{
+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
+ int err = 0;
+
+ LinuxLockMutex(&gPVRSRVLock);
+
+#if defined(SUPPORT_DRI_DRM)
+ psPrivateData = (PVRSRV_FILE_PRIVATE_DATA *)pvPrivData;
+#else
+ psPrivateData = PRIVATE_DATA(pFile);
+#endif
+ if (psPrivateData != IMG_NULL)
+ {
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+ list_del(&psPrivateData->sDRMAuthListItem);
+#endif
+
+ if(psPrivateData->hKernelMemInfo)
+ {
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+
+ /* Look up the meminfo we just exported */
+ if(PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+ (IMG_PVOID *)&psKernelMemInfo,
+ psPrivateData->hKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to look up export handle", __FUNCTION__));
+ err = -EFAULT;
+ goto err_unlock;
+ }
+
+ /* Tell the XProc about the export if required */
+ if (psKernelMemInfo->sShareMemWorkaround.bInUse)
+ {
+ BM_XProcIndexRelease(psKernelMemInfo->sShareMemWorkaround.ui32ShareIndex);
+ }
+
+ /* This drops the psMemInfo refcount bumped on export */
+ if(FreeMemCallBackCommon(psKernelMemInfo, 0,
+ PVRSRV_FREE_CALLBACK_ORIGIN_EXTERNAL) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: FreeMemCallBackCommon failed", __FUNCTION__));
+ err = -EFAULT;
+ goto err_unlock;
+ }
+ }
+
+ /* Usually this is the same as OSGetCurrentProcessIDKM(),
+ * but not necessarily (e.g. fork(), child closes last..)
+ */
+ gui32ReleasePID = psPrivateData->ui32OpenPID;
+ PVRSRVProcessDisconnect(psPrivateData->ui32OpenPID);
+ gui32ReleasePID = 0;
+
+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_FILE_PRIVATE_DATA),
+ psPrivateData, psPrivateData->hBlockAlloc);
+
+#if !defined(SUPPORT_DRI_DRM)
+ PRIVATE_DATA(pFile) = IMG_NULL; /*nulling shared pointer*/
+#endif
+ }
+
+err_unlock:
+ LinuxUnLockMutex(&gPVRSRVLock);
+#if defined(SUPPORT_DRI_DRM)
+ return;
+#else
+ return err;
+#endif
+}
+
+
+/*!
+******************************************************************************
+
+ @Function PVRCore_Init
+
+ @Description
+
+ Insert the driver into the kernel.
+
+ The device major number is allocated by the kernel dynamically. This means
+ that the device node (nominally /dev/pvrsrv) will need to be re-made at boot
+ time if the number changes between subsequent loads of the module. While the
+ number often stays constant between loads this is not guaranteed. The node
+ is made as root on the shell with:
+
+ mknod /dev/pvrsrv c nnn 0
+
+ where nnn is the major number found in /proc/devices for DEVNAME and also
+ reported by the PVR_DPF() - look at the boot log using dmesg' to see this).
+
+ Currently the auto-generated script /etc/init.d/rc.pvr handles creation of
+ the device. In other environments the device may be created either through
+ devfs or sysfs.
+
+ Readable proc-filesystem entries under /proc/pvr are created with
+ CreateProcEntries(). These can be read at runtime to get information about
+ the device (eg. 'cat /proc/pvr/vm')
+
+ __init places the function in a special memory section that the kernel frees
+ once the function has been run. Refer also to module_init() macro call below.
+
+ @input none
+
+ @Return none
+
+*****************************************************************************/
+#if defined(SUPPORT_DRI_DRM)
+int PVRCore_Init(void)
+#else
+static int __init PVRCore_Init(void)
+#endif
+{
+ int error;
+#if !defined(PVR_LDM_MODULE)
+ PVRSRV_ERROR eError;
+#endif
+#if !defined(SUPPORT_DRI_DRM) && defined(PVR_LDM_DEVICE_CLASS)
+ struct device *psDev;
+#endif
+
+#if !defined(SUPPORT_DRI_DRM)
+ /*
+ * Must come before attempting to print anything via Services.
+ * For DRM, the initialisation will already have been done.
+ */
+ PVRDPFInit();
+#endif
+ PVR_TRACE(("PVRCore_Init"));
+
+#if defined(PVR_LDM_MODULE) || defined(SUPPORT_DRI_DRM)
+ LinuxInitMutex(&gsPMMutex);
+#endif
+ LinuxInitMutex(&gPVRSRVLock);
+
+ if (CreateProcEntries ())
+ {
+ error = -ENOMEM;
+ return error;
+ }
+
+ if (PVROSFuncInit() != PVRSRV_OK)
+ {
+ error = -ENOMEM;
+ goto init_failed;
+ }
+
+ PVRLinuxMUtilsInit();
+
+ if(LinuxMMInit() != PVRSRV_OK)
+ {
+ error = -ENOMEM;
+ goto init_failed;
+ }
+
+ LinuxBridgeInit();
+
+ PVRMMapInit();
+
+#if defined(PVR_LDM_MODULE)
+
+#if defined(PVR_LDM_PLATFORM_MODULE) || defined(SUPPORT_DRI_DRM_PLUGIN)
+ 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 defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+ 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
+#endif /* PVR_LDM_PLATFORM_MODULE */
+
+#if defined(PVR_LDM_PCI_MODULE)
+ 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 /* PVR_LDM_PCI_MODULE */
+#endif /* defined(PVR_LDM_MODULE) */
+
+#if !defined(PVR_LDM_MODULE)
+ /*
+ * Drivers using LDM, will call SysInitialise in the probe/attach code
+ */
+ 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 /* !defined(PVR_LDM_MODULE) */
+
+#if !defined(SUPPORT_DRI_DRM)
+ 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 sys_deinit;
+ }
+
+ PVR_TRACE(("PVRCore_Init: major device %d", AssignedMajorNumber));
+
+#if defined(PVR_LDM_DEVICE_CLASS)
+ /*
+ * This code (using GPL symbols) facilitates automatic device
+ * node creation on platforms with udev (or similar).
+ */
+ 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 /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) */
+ 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 /* defined(PVR_LDM_DEVICE_CLASS) */
+#endif /* !defined(SUPPORT_DRI_DRM) */
+
+ return 0;
+
+#if !defined(SUPPORT_DRI_DRM)
+#if defined(PVR_LDM_DEVICE_CLASS)
+destroy_class:
+ class_destroy(psPvrClass);
+unregister_device:
+ unregister_chrdev((IMG_UINT)AssignedMajorNumber, DEVNAME);
+#endif
+sys_deinit:
+#endif
+#if defined(PVR_LDM_MODULE)
+#if defined(PVR_LDM_PCI_MODULE)
+ pci_unregister_driver(&powervr_driver);
+#endif
+
+#if defined (PVR_LDM_PLATFORM_MODULE)
+#if defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+ platform_device_unregister(&powervr_device);
+#endif
+ platform_driver_unregister(&powervr_driver);
+#endif
+
+#else /* defined(PVR_LDM_MODULE) */
+ /* LDM drivers call SysDeinitialise during PVRSRVDriverRemove */
+ {
+ SYS_DATA *psSysData;
+
+ psSysData = SysAcquireDataNoCheck();
+ if (psSysData != IMG_NULL)
+ {
+ (void) SysDeinitialise(psSysData);
+ }
+ }
+#endif /* defined(PVR_LDM_MODULE) */
+init_failed:
+ PVRMMapCleanup();
+ LinuxMMCleanup();
+ LinuxBridgeDeInit();
+ PVROSFuncDeInit();
+ RemoveProcEntries();
+
+ return error;
+
+} /*PVRCore_Init*/
+
+
+/*!
+*****************************************************************************
+
+ @Function PVRCore_Cleanup
+
+ @Description
+
+ Remove the driver from the kernel.
+
+ There's no way we can get out of being unloaded other than panicking; we
+ just do everything and plough on regardless of error.
+
+ __exit places the function in a special memory section that the kernel frees
+ once the function has been run. Refer also to module_exit() macro call below.
+
+ Note that the for LDM on MontaVista kernels, the positioning of the driver
+ de-registration is the opposite way around than would be suggested by the
+ registration case or the 2,6 kernel case. This is the correct way to do it
+ and the kernel panics if you change it. You have been warned.
+
+ @input none
+
+ @Return none
+
+*****************************************************************************/
+#if defined(SUPPORT_DRI_DRM)
+void PVRCore_Cleanup(void)
+#else
+static void __exit PVRCore_Cleanup(void)
+#endif
+{
+#if !defined(PVR_LDM_MODULE)
+ SYS_DATA *psSysData;
+#endif
+ PVR_TRACE(("PVRCore_Cleanup"));
+
+#if !defined(PVR_LDM_MODULE)
+ SysAcquireData(&psSysData);
+#endif
+
+#if !defined(SUPPORT_DRI_DRM)
+
+#if defined(PVR_LDM_DEVICE_CLASS)
+ device_destroy(psPvrClass, MKDEV(AssignedMajorNumber, 0));
+ class_destroy(psPvrClass);
+#endif
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
+ if (
+#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22)) */
+ unregister_chrdev((IMG_UINT)AssignedMajorNumber, DEVNAME)
+#if !(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
+ ;
+#else /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22)) */
+ )
+ {
+ PVR_DPF((PVR_DBG_ERROR," can't unregister device major %d", AssignedMajorNumber));
+ }
+#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22)) */
+#endif /* !defined(SUPPORT_DRI_DRM) */
+
+#if defined(PVR_LDM_MODULE)
+
+#if defined(PVR_LDM_PCI_MODULE)
+ pci_unregister_driver(&powervr_driver);
+#endif
+
+#if defined (PVR_LDM_PLATFORM_MODULE)
+#if defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
+ platform_device_unregister(&powervr_device);
+#endif
+ platform_driver_unregister(&powervr_driver);
+#endif
+
+#else /* defined(PVR_LDM_MODULE) */
+#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
+ if (gPVRPowerLevel != 0)
+ {
+ if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK)
+ {
+ gPVRPowerLevel = 0;
+ }
+ }
+#endif
+ /* LDM drivers call SysDeinitialise during PVRSRVDriverRemove */
+ (void) SysDeinitialise(psSysData);
+#endif /* defined(PVR_LDM_MODULE) */
+
+ PVRMMapCleanup();
+
+ LinuxMMCleanup();
+
+ LinuxBridgeDeInit();
+
+ PVROSFuncDeInit();
+
+ RemoveProcEntries();
+
+ PVR_TRACE(("PVRCore_Cleanup: unloading"));
+}
+
+/*
+ * These macro calls define the initialisation and removal functions of the
+ * driver. Although they are prefixed `module_', they apply when compiling
+ * statically as well; in both cases they define the function the kernel will
+ * run to start/stop the driver.
+*/
+#if !defined(SUPPORT_DRI_DRM)
+module_init(PVRCore_Init);
+module_exit(PVRCore_Cleanup);
+#endif
diff --git a/pvr-source/services4/srvkm/env/linux/mutex.c b/pvr-source/services4/srvkm/env/linux/mutex.c
new file mode 100644
index 0000000..2cd666f
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/mutex.c
@@ -0,0 +1,153 @@
+/*************************************************************************/ /*!
+@Title Linux mutex interface
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#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_MUTEX_INTERRUPTIBLE_ERROR;
+ }
+ 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)) ? IMG_TRUE : IMG_FALSE;
+}
+
+
+#else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) */
+
+
+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)
+ {
+ /* The process was sent a signal while waiting for the semaphore
+ * (e.g. a kill signal from userspace)
+ */
+ return PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR;
+ }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 /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) */
+
diff --git a/pvr-source/services4/srvkm/env/linux/mutex.h b/pvr-source/services4/srvkm/env/linux/mutex.h
new file mode 100644
index 0000000..c590da1
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/mutex.h
@@ -0,0 +1,90 @@
+/*************************************************************************/ /*!
+@Title Linux mutex interface
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+
+#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 /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) */
+
+
+typedef struct {
+ struct semaphore sSemaphore;
+ /* since Linux's struct semaphore is intended to be
+ * opaque we don't poke inside for the count and
+ * instead we track it outselves. (So we can implement
+ * LinuxIsLockedMutex)
+ */
+ 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 /* __INCLUDED_LINUX_MUTEX_H_ */
+
diff --git a/pvr-source/services4/srvkm/env/linux/mutils.c b/pvr-source/services4/srvkm/env/linux/mutils.c
new file mode 100644
index 0000000..8e57476
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/mutils.c
@@ -0,0 +1,166 @@
+/*************************************************************************/ /*!
+@Title Linux memory interface support functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#include "img_defs.h"
+#include "pvr_debug.h"
+#include "mutils.h"
+
+#if defined(SUPPORT_LINUX_X86_PAT)
+#define PAT_LINUX_X86_WC 1
+
+#define PAT_X86_ENTRY_BITS 8
+
+#define PAT_X86_BIT_PWT 1U
+#define PAT_X86_BIT_PCD 2U
+#define PAT_X86_BIT_PAT 4U
+#define PAT_X86_BIT_MASK (PAT_X86_BIT_PAT | PAT_X86_BIT_PCD | PAT_X86_BIT_PWT)
+
+static IMG_BOOL g_write_combining_available = IMG_FALSE;
+
+#define PROT_TO_PAT_INDEX(v, B) ((v & _PAGE_ ## B) ? PAT_X86_BIT_ ## B : 0)
+
+static inline IMG_UINT
+pvr_pat_index(pgprotval_t prot_val)
+{
+ IMG_UINT ret = 0;
+ pgprotval_t val = prot_val & _PAGE_CACHE_MASK;
+
+ ret |= PROT_TO_PAT_INDEX(val, PAT);
+ ret |= PROT_TO_PAT_INDEX(val, PCD);
+ ret |= PROT_TO_PAT_INDEX(val, PWT);
+
+ return ret;
+}
+
+static inline IMG_UINT
+pvr_pat_entry(u64 pat, IMG_UINT index)
+{
+ return (IMG_UINT)(pat >> (index * PAT_X86_ENTRY_BITS)) & PAT_X86_BIT_MASK;
+}
+
+static IMG_VOID
+PVRLinuxX86PATProbe(IMG_VOID)
+{
+ /*
+ * cpu_has_pat indicates whether PAT support is available on the CPU,
+ * but doesn't indicate if it has been enabled.
+ */
+ if (cpu_has_pat) /* PRQA S 3335 */ /* ignore 'no function declared' */
+ {
+ u64 pat;
+ IMG_UINT pat_index;
+ IMG_UINT pat_entry;
+
+ PVR_TRACE(("%s: PAT available", __FUNCTION__));
+ /*
+ * There is no Linux API for finding out if write combining
+ * is avaialable through the PAT, so we take the direct
+ * approach, and see if the PAT MSR contains a write combining
+ * entry.
+ */
+ rdmsrl(MSR_IA32_CR_PAT, pat);
+ PVR_TRACE(("%s: Top 32 bits of PAT: 0x%.8x", __FUNCTION__, (IMG_UINT)(pat >> 32)));
+ PVR_TRACE(("%s: Bottom 32 bits of PAT: 0x%.8x", __FUNCTION__, (IMG_UINT)(pat)));
+
+ pat_index = pvr_pat_index(_PAGE_CACHE_WC);
+ PVR_TRACE(("%s: PAT index for write combining: %u", __FUNCTION__, pat_index));
+
+ pat_entry = pvr_pat_entry(pat, pat_index);
+ PVR_TRACE(("%s: PAT entry for write combining: 0x%.2x (should be 0x%.2x)", __FUNCTION__, pat_entry, PAT_LINUX_X86_WC));
+
+#if defined(SUPPORT_LINUX_X86_WRITECOMBINE)
+ g_write_combining_available = (IMG_BOOL)(pat_entry == PAT_LINUX_X86_WC);
+#endif
+ }
+#if defined(DEBUG)
+#if defined(SUPPORT_LINUX_X86_WRITECOMBINE)
+ if (g_write_combining_available)
+ {
+ PVR_TRACE(("%s: Write combining available via PAT", __FUNCTION__));
+ }
+ else
+ {
+ PVR_TRACE(("%s: Write combining not available", __FUNCTION__));
+ }
+#else /* defined(SUPPORT_LINUX_X86_WRITECOMBINE) */
+ PVR_TRACE(("%s: Write combining disabled in driver build", __FUNCTION__));
+#endif /* defined(SUPPORT_LINUX_X86_WRITECOMBINE) */
+#endif /* DEBUG */
+}
+
+pgprot_t
+pvr_pgprot_writecombine(pgprot_t prot)
+{
+ /*
+ * It would be worth checking from time to time to see if a
+ * pgprot_writecombine function (or similar) is introduced on Linux for
+ * x86 processors. If so, this function, and PVRLinuxX86PATProbe can be
+ * removed, and a macro used to select between pgprot_writecombine and
+ * pgprot_noncached, dpending on the value for of
+ * SUPPORT_LINUX_X86_WRITECOMBINE.
+ */
+ /* PRQA S 0481,0482 2 */ /* scalar expressions */
+ return (g_write_combining_available) ?
+ __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_MASK) | _PAGE_CACHE_WC) : pgprot_noncached(prot);
+}
+#endif /* defined(SUPPORT_LINUX_X86_PAT) */
+
+IMG_VOID
+PVRLinuxMUtilsInit(IMG_VOID)
+{
+#if defined(SUPPORT_LINUX_X86_PAT)
+ PVRLinuxX86PATProbe();
+#endif
+}
+
diff --git a/pvr-source/services4/srvkm/env/linux/mutils.h b/pvr-source/services4/srvkm/env/linux/mutils.h
new file mode 100644
index 0000000..891598c
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/mutils.h
@@ -0,0 +1,119 @@
+/*************************************************************************/ /*!
+@Title Memory management support utils
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares various memory management support functions
+ for Linux.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef __IMG_LINUX_MUTILS_H__
+#define __IMG_LINUX_MUTILS_H__
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#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__) || defined(__mips__)
+ #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 /* __IMG_LINUX_MUTILS_H__ */
+
diff --git a/pvr-source/services4/srvkm/env/linux/osfunc.c b/pvr-source/services4/srvkm/env/linux/osfunc.c
new file mode 100644
index 0000000..ac03185
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/osfunc.c
@@ -0,0 +1,4714 @@
+/*************************************************************************/ /*!
+@Title Environment related functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <asm/io.h>
+#include <asm/page.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
+#include <asm/system.h>
+#endif
+#include <asm/cacheflush.h>
+#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>
+#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || \
+ defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE) || \
+ defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || \
+ defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE) || \
+ defined(PVR_LINUX_USING_WORKQUEUES)
+#include <linux/workqueue.h>
+#endif
+
+#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"
+#include "linkage.h"
+#include "pvr_uaccess.h"
+#include "lock.h"
+#include <syslocal.h>
+
+#if defined (SUPPORT_ION)
+#include "ion.h"
+#endif
+
+#if defined (CONFIG_X86_PAE)
+#error Physical Address Extension not supported with the driver
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
+#define ON_EACH_CPU(func, info, wait) on_each_cpu(func, info, wait)
+#else
+#define ON_EACH_CPU(func, info, wait) on_each_cpu(func, info, 0, wait)
+#endif
+
+#if defined(PVR_LINUX_USING_WORKQUEUES) && !defined(CONFIG_PREEMPT)
+/*
+ * Services spins at certain points waiting for events (e.g. swap
+ * chain destrucion). If those events rely on workqueues running,
+ * it needs to be possible to preempt the waiting thread.
+ * Removing the need for CONFIG_PREEMPT will require adding preemption
+ * points at various points in Services.
+ */
+#error "A preemptible Linux kernel is required when using workqueues"
+#endif
+
+#if defined(EMULATOR)
+#define EVENT_OBJECT_TIMEOUT_MS (2000)
+#else
+#define EVENT_OBJECT_TIMEOUT_MS (100)
+#endif /* EMULATOR */
+
+#if !defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID *ppvCpuVAddr, IMG_HANDLE *phBlockAlloc)
+#else
+PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID *ppvCpuVAddr, IMG_HANDLE *phBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line)
+#endif
+{
+ PVR_UNREFERENCED_PARAMETER(ui32Flags);
+ PVR_UNREFERENCED_PARAMETER(phBlockAlloc);
+
+ if (ui32Size > PAGE_SIZE)
+ {
+ /* Try to allocate the memory using vmalloc */
+#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_OK;
+ }
+ }
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ *ppvCpuVAddr = _KMallocWrapper(ui32Size, GFP_KERNEL | __GFP_NOWARN, pszFilename, ui32Line);
+#else
+ *ppvCpuVAddr = KMallocWrapper(ui32Size, GFP_KERNEL | __GFP_NOWARN);
+#endif
+ if (!*ppvCpuVAddr)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ return PVRSRV_OK;
+}
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,24))
+
+static inline int is_vmalloc_addr(const void *pvCpuVAddr)
+{
+ unsigned long lAddr = (unsigned long)pvCpuVAddr;
+ return lAddr >= VMALLOC_START && lAddr < VMALLOC_END;
+}
+
+#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,24)) */
+
+#if !defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID pvCpuVAddr, IMG_HANDLE hBlockAlloc)
+#else
+PVRSRV_ERROR OSFreeMem_Impl(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);
+ PVR_UNREFERENCED_PARAMETER(hBlockAlloc);
+
+ if (is_vmalloc_addr(pvCpuVAddr))
+ {
+#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_Impl(IMG_UINT32 ui32AllocFlags,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32PageSize,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_HANDLE hBMHandle,
+ IMG_VOID **ppvCpuVAddr,
+ IMG_HANDLE *phOSMemHandle)
+{
+ LinuxMemArea *psLinuxMemArea;
+
+ PVR_UNREFERENCED_PARAMETER(ui32PageSize);
+
+#if 0
+ /* For debug: force all OSAllocPages allocations to have a kernel
+ * virtual address */
+ if(ui32AllocFlags & PVRSRV_HAP_SINGLE_PROCESS)
+ {
+ ui32AllocFlags &= ~PVRSRV_HAP_SINGLE_PROCESS;
+ ui32AllocFlags |= PVRSRV_HAP_MULTI_PROCESS;
+ }
+#endif
+
+ if(ui32AllocFlags & PVRSRV_MEM_ION)
+ {
+ /* We'll only see HAP_SINGLE_PROCESS with MEM_ION */
+ BUG_ON((ui32AllocFlags & PVRSRV_HAP_MAPTYPE_MASK) != PVRSRV_HAP_SINGLE_PROCESS);
+
+ psLinuxMemArea = NewIONLinuxMemArea(ui32Size, ui32AllocFlags,
+ pvPrivData, ui32PrivDataLength);
+ if(!psLinuxMemArea)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ PVRMMapRegisterArea(psLinuxMemArea);
+ goto ExitSkipSwitch;
+ }
+
+ 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:
+ {
+ /* Currently PVRSRV_HAP_SINGLE_PROCESS implies that we dont need a
+ * kernel virtual mapping, but will need a user space virtual mapping */
+
+ psLinuxMemArea = NewAllocPagesLinuxMemArea(ui32Size, ui32AllocFlags);
+ if(!psLinuxMemArea)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ PVRMMapRegisterArea(psLinuxMemArea);
+ break;
+ }
+
+ case PVRSRV_HAP_MULTI_PROCESS:
+ {
+ /* Currently PVRSRV_HAP_MULTI_PROCESS implies that we need a kernel
+ * virtual mapping and potentially multiple user space virtual
+ * mappings: Note: these eat into our limited kernel virtual
+ * address space. */
+
+#if defined(VIVT_CACHE) || defined(__sh__)
+ /* ARM9 caches are tagged with virtual pages, not physical. As we are going to
+ * share this memory in different address spaces, we don't want it to be cached.
+ * ARM11 has physical tagging, so we can cache this memory without fear of virtual
+ * address aliasing in the TLB, as long as the kernel supports cache colouring for
+ * VIPT architectures. */
+ 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;
+ }
+
+ /*
+ In case of sparse mapping we need to handle back to the BM as it
+ knows the mapping info
+ */
+ if (ui32AllocFlags & PVRSRV_MEM_SPARSE)
+ {
+ psLinuxMemArea->hBMHandle = hBMHandle;
+ }
+
+ExitSkipSwitch:
+ *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;
+ PVRSRV_ERROR eError;
+
+ 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:
+ eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSFreePages(ui32AllocFlags=0x%08X, ui32Bytes=%d, "
+ "pvCpuVAddr=%p, hOSMemHandle=%p) FAILED!",
+ ui32AllocFlags, ui32Bytes, pvCpuVAddr, hOSMemHandle));
+ return eError;
+ }
+ 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;
+}
+
+IMG_INT32
+OSGetMemMultiPlaneInfo(IMG_HANDLE hOSMemHandle, IMG_UINT32* pui32AddressOffsets,
+ IMG_UINT32* ui32NumAddrOffsets)
+{
+ LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+
+ if(!ui32NumAddrOffsets)
+ return -1;
+
+ if(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_ION)
+ return GetIONLinuxMemAreaInfo(psLinuxMemArea, pui32AddressOffsets, ui32NumAddrOffsets);
+
+ if(!pui32AddressOffsets)
+ return -1;
+
+ *pui32AddressOffsets = 0;
+ *ui32NumAddrOffsets = 1;
+
+ return psLinuxMemArea->ui32ByteSize;
+}
+
+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;
+
+ /* KERNEL_ONLY areas are never mmapable. */
+ 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_BOOL OSMemHandleIsPhysContig(IMG_VOID *hOSMemHandle)
+{
+ LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+
+ PVR_ASSERT(psLinuxMemArea);
+
+ if(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_EXTERNAL_KV)
+ return psLinuxMemArea->uData.sExternalKV.bPhysContig;
+
+ return IMG_FALSE;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSMemCopy
+
+ @Description Copies memory around
+
+ @Input pvDst - pointer to dst
+ @Output pvSrc - pointer to src
+ @Input ui32Size - bytes to copy
+
+ @Return none
+
+******************************************************************************/
+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
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSMemSet
+
+ @Description Function that does the same as the C memset() functions
+
+ @Modified *pvDest : pointer to start of buffer to be set
+
+ @Input ui8Value: value to set each byte to
+
+ @Input ui32Size : number of bytes to set
+
+ @Return IMG_VOID
+
+******************************************************************************/
+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
+}
+
+
+/*!
+******************************************************************************
+ @Function OSStringCopy
+ @Description strcpy
+******************************************************************************/
+IMG_CHAR *OSStringCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc)
+{
+ return (strcpy(pszDest, pszSrc));
+}
+
+/*!
+******************************************************************************
+ @Function OSSNPrintf
+ @Description snprintf
+******************************************************************************/
+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;
+}
+
+/*!
+******************************************************************************
+
+ @Function OSBreakResourceLock
+
+ @Description unlocks an OS dependant resource
+
+ @Input phResource - pointer to OS dependent resource structure
+ @Input ui32ID - Lock value to look for
+
+ @Return
+
+******************************************************************************/
+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"));
+ }
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSCreateResource
+
+ @Description creates a OS dependant resource object
+
+ @Input phResource - pointer to OS dependent resource
+
+ @Return error status
+
+******************************************************************************/
+PVRSRV_ERROR OSCreateResource(PVRSRV_RESOURCE *psResource)
+{
+ psResource->ui32ID = 0;
+ psResource->ui32Lock = 0;
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSDestroyResource
+
+ @Description destroys an OS dependant resource object
+
+ @Input phResource - pointer to OS dependent resource
+
+ @Return error status
+
+******************************************************************************/
+PVRSRV_ERROR OSDestroyResource (PVRSRV_RESOURCE *psResource)
+{
+ OSBreakResourceLock (psResource, psResource->ui32ID);
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSInitEnvData
+
+ @Description Allocates space for env specific data
+
+ @Input ppvEnvSpecificData - pointer to pointer in which to return
+ allocated data.
+ @Input ui32MMUMode - MMU mode.
+
+ @Return nothing
+
+******************************************************************************/
+PVRSRV_ERROR OSInitEnvData(IMG_PVOID *ppvEnvSpecificData)
+{
+ ENV_DATA *psEnvData;
+ PVRSRV_ERROR eError;
+
+ /* allocate env specific data */
+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), (IMG_VOID **)&psEnvData, IMG_NULL,
+ "Environment Data");
+ if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, PVRSRV_MAX_BRIDGE_IN_SIZE + PVRSRV_MAX_BRIDGE_OUT_SIZE,
+ &psEnvData->pvBridgeData, IMG_NULL,
+ "Bridge Data");
+ if (eError != PVRSRV_OK)
+ {
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), psEnvData, IMG_NULL);
+ /*not nulling pointer, out of scope*/
+ return eError;
+ }
+
+
+ /* ISR installation flags */
+ psEnvData->bMISRInstalled = IMG_FALSE;
+ psEnvData->bLISRInstalled = IMG_FALSE;
+
+ /* copy structure back */
+ *ppvEnvSpecificData = psEnvData;
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSDeInitEnvData
+
+ @Description frees env specific data memory
+
+ @Input pvEnvSpecificData - pointer to private structure
+
+ @Return PVRSRV_OK on success else PVRSRV_ERROR_OUT_OF_MEMORY
+
+******************************************************************************/
+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, PVRSRV_MAX_BRIDGE_IN_SIZE + PVRSRV_MAX_BRIDGE_OUT_SIZE, psEnvData->pvBridgeData, IMG_NULL);
+ psEnvData->pvBridgeData = IMG_NULL;
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), pvEnvSpecificData, IMG_NULL);
+ /*not nulling pointer, copy on stack*/
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSReleaseThreadQuanta
+
+ @Description
+ Releases thread quanta
+
+ @Return nothing
+
+******************************************************************************/
+IMG_VOID OSReleaseThreadQuanta(IMG_VOID)
+{
+ schedule();
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSClockus
+
+ @Description
+ This function returns the clock in microseconds
+
+ @Input void
+
+ @Return - clock (us)
+
+******************************************************************************/
+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_VOID OSSleepms(IMG_UINT32 ui32Timems)
+{
+ msleep(ui32Timems);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSFuncHighResTimerCreate
+
+ @Description
+ This function creates a high res timer who's handle is returned
+
+ @Input nothing
+
+ @Return handle
+
+******************************************************************************/
+IMG_HANDLE OSFuncHighResTimerCreate(IMG_VOID)
+{
+ /* We don't need a handle, but we must return non-NULL */
+ return (IMG_HANDLE) 1;
+}
+
+/*!
+******************************************************************************
+
+ @Function OSFuncHighResTimerGetus
+
+ @Description
+ This function returns the current timestamp in us
+
+ @Input nothing
+
+ @Return handle
+
+******************************************************************************/
+IMG_UINT32 OSFuncHighResTimerGetus(IMG_HANDLE hTimer)
+{
+ return (IMG_UINT32) jiffies_to_usecs(jiffies);
+}
+
+/*!
+******************************************************************************
+
+ @Function OSFuncHighResTimerDestroy
+
+ @Description
+ This function will destroy the high res timer
+
+ @Input nothing
+
+ @Return handle
+
+******************************************************************************/
+IMG_VOID OSFuncHighResTimerDestroy(IMG_HANDLE hTimer)
+{
+ PVR_UNREFERENCED_PARAMETER(hTimer);
+}
+
+/*!
+******************************************************************************
+
+ @Function OSGetCurrentProcessIDKM
+
+ @Description Returns handle for current process
+
+ @Return ID of current process
+
+*****************************************************************************/
+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
+}
+
+
+int OSGetProcCmdline(IMG_UINT32 ui32PID, char * buffer, int buff_size)
+{
+ int res = 0;
+ unsigned int len;
+ struct task_struct *task = pid_task(find_vpid(ui32PID), PIDTYPE_PID);
+ struct mm_struct *mm = task ? get_task_mm(task) : IMG_NULL;
+ if (!mm)
+ goto out;
+ if (!mm->arg_end)
+ goto out_mm; /* Shh! No looking before we're done */
+
+ len = mm->arg_end - mm->arg_start;
+
+ if (len > buff_size)
+ len = buff_size;
+
+ res = pvr_access_process_vm(task, mm->arg_start, buffer, len, 0);
+
+ // If the nul at the end of args has been overwritten, then
+ // assume application is using setproctitle(3).
+ if (res > 0 && buffer[res-1] != '\0' && len < buff_size) {
+ len = strnlen(buffer, res);
+ if (len < res) {
+ res = len;
+ } else {
+ len = mm->env_end - mm->env_start;
+ if (len > buff_size - res)
+ len = buff_size - res;
+ res += pvr_access_process_vm(task, mm->env_start, buffer+res, len, 0);
+ res = strnlen(buffer, res);
+ }
+ }
+out_mm:
+ mmput(mm);
+out:
+ return res;
+}
+
+const char* OSGetPathBaseName(char * buffer, int buff_size)
+{
+ const char *base_name = buffer;
+ while (1)
+ {
+ const char *next = strnchr(base_name, buff_size, '/');
+ if (!next)
+ break;
+
+ buff_size -= (next - base_name -1);
+ base_name = (next + 1);
+
+ }
+ return base_name;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSGetPageSize
+
+ @Description gets page size
+
+ @Return page size
+
+******************************************************************************/
+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))
+/*!
+******************************************************************************
+
+ @Function DeviceISRWrapper
+
+ @Description wrapper for Device ISR function to conform to ISR OS interface
+
+ @Return
+
+******************************************************************************/
+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)
+ {
+ OSScheduleMISR((IMG_VOID *)psDeviceNode->psSysData);
+ }
+
+out:
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+ return bStatus ? IRQ_HANDLED : IRQ_NONE;
+#endif
+}
+
+
+
+/*!
+******************************************************************************
+
+ @Function SystemISRWrapper
+
+ @Description wrapper for System ISR function to conform to ISR OS interface
+
+ @Input Interrupt - NT interrupt object.
+ @Input Context - Context parameter
+
+ @Return
+
+******************************************************************************/
+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)
+ {
+ OSScheduleMISR((IMG_VOID *)psSysData);
+ }
+
+out:
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+ return bStatus ? IRQ_HANDLED : IRQ_NONE;
+#endif
+}
+/*!
+******************************************************************************
+
+ @Function OSInstallDeviceLISR
+
+ @Description Installs a Device ISR
+
+ @Input pvSysData
+ @Input ui32Irq - IRQ number
+ @Input pszISRName - ISR name
+ @Input pvDeviceNode - device node contains ISR function and data argument
+
+ @Return error status
+
+******************************************************************************/
+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 %p", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
+ return PVRSRV_ERROR_ISR_ALREADY_INSTALLED;
+ }
+
+ PVR_TRACE(("Installing device LISR %s on IRQ %d with cookie %p", 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_UNABLE_TO_INSTALL_ISR;
+ }
+
+ psEnvData->ui32IRQ = ui32Irq;
+ psEnvData->pvISRCookie = pvDeviceNode;
+ psEnvData->bLISRInstalled = IMG_TRUE;
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function OSUninstallDeviceLISR
+
+ @Description Uninstalls a Device ISR
+
+ @Input pvSysData - sysdata
+
+ @Return error status
+
+******************************************************************************/
+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_ISR_NOT_INSTALLED;
+ }
+
+ PVR_TRACE(("Uninstalling device LISR on IRQ %d with cookie %p", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
+
+ free_irq(psEnvData->ui32IRQ, psEnvData->pvISRCookie);
+
+ psEnvData->bLISRInstalled = IMG_FALSE;
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSInstallSystemLISR
+
+ @Description Installs a System ISR
+
+ @Input psSysData
+ @Input ui32Irq - IRQ number
+
+ @Return error status
+
+******************************************************************************/
+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 %p", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
+ return PVRSRV_ERROR_ISR_ALREADY_INSTALLED;
+ }
+
+ PVR_TRACE(("Installing system LISR on IRQ %d with cookie %p", ui32Irq, pvSysData));
+
+ if(request_irq(ui32Irq, SystemISRWrapper,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
+ SA_SHIRQ
+#else
+ IRQF_SHARED
+#endif
+ , PVRSRV_MODNAME, pvSysData))
+ {
+ PVR_DPF((PVR_DBG_ERROR,"OSInstallSystemLISR: Couldn't install system LISR on IRQ %d", ui32Irq));
+
+ return PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR;
+ }
+
+ psEnvData->ui32IRQ = ui32Irq;
+ psEnvData->pvISRCookie = pvSysData;
+ psEnvData->bLISRInstalled = IMG_TRUE;
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSUninstallSystemLISR
+
+ @Description Uninstalls a System ISR
+
+ @Input psSysData
+
+ @Return error status
+
+******************************************************************************/
+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_ISR_NOT_INSTALLED;
+ }
+
+ PVR_TRACE(("Uninstalling system LISR on IRQ %d with cookie %p", psEnvData->ui32IRQ, psEnvData->pvISRCookie));
+
+ free_irq(psEnvData->ui32IRQ, psEnvData->pvISRCookie);
+
+ psEnvData->bLISRInstalled = IMG_FALSE;
+
+ return PVRSRV_OK;
+}
+
+#if defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
+/*!
+******************************************************************************
+
+ @Function MISRWrapper
+
+ @Description OS dependent MISR wrapper
+
+ @Input psSysData
+
+ @Return error status
+
+******************************************************************************/
+static void MISRWrapper(
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+ void *data
+#else
+ struct work_struct *data
+#endif
+)
+{
+ ENV_DATA *psEnvData = container_of(data, ENV_DATA, sMISRWork);
+ SYS_DATA *psSysData = (SYS_DATA *)psEnvData->pvMISRData;
+
+ PVRSRVMISR(psSysData);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSInstallMISR
+
+ @Description Installs an OS dependent MISR
+
+ @Input psSysData
+
+ @Return error status
+
+******************************************************************************/
+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_ISR_ALREADY_INSTALLED;
+ }
+
+ PVR_TRACE(("Installing MISR with cookie %p", pvSysData));
+
+ psEnvData->psWorkQueue = create_singlethread_workqueue("pvr_workqueue");
+
+ if (psEnvData->psWorkQueue == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: create_singlethreaded_workqueue failed"));
+ return PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD;
+ }
+
+ INIT_WORK(&psEnvData->sMISRWork, MISRWrapper
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+ , (void *)&psEnvData->sMISRWork
+#endif
+ );
+
+ psEnvData->pvMISRData = pvSysData;
+ psEnvData->bMISRInstalled = IMG_TRUE;
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSUninstallMISR
+
+ @Description Uninstalls an OS dependent MISR
+
+ @Input psSysData
+
+ @Return error status
+
+******************************************************************************/
+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_ISR_NOT_INSTALLED;
+ }
+
+ PVR_TRACE(("Uninstalling MISR"));
+
+ destroy_workqueue(psEnvData->psWorkQueue);
+
+ psEnvData->bMISRInstalled = IMG_FALSE;
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSScheduleMISR
+
+ @Description Schedules an OS dependent MISR
+
+ @Input pvSysData
+
+ @Return error status
+
+******************************************************************************/
+PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData)
+{
+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+ ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData;
+
+ if (psEnvData->bMISRInstalled)
+ {
+ queue_work(psEnvData->psWorkQueue, &psEnvData->sMISRWork);
+ }
+
+ return PVRSRV_OK;
+}
+#else /* defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE) */
+#if defined(PVR_LINUX_MISR_USING_WORKQUEUE)
+/*!
+******************************************************************************
+
+ @Function MISRWrapper
+
+ @Description OS dependent MISR wrapper
+
+ @Input psSysData
+
+ @Return error status
+
+******************************************************************************/
+static void MISRWrapper(
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+ void *data
+#else
+ struct work_struct *data
+#endif
+)
+{
+ ENV_DATA *psEnvData = container_of(data, ENV_DATA, sMISRWork);
+ SYS_DATA *psSysData = (SYS_DATA *)psEnvData->pvMISRData;
+
+ PVRSRVMISR(psSysData);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSInstallMISR
+
+ @Description Installs an OS dependent MISR
+
+ @Input psSysData
+
+ @Return error status
+
+******************************************************************************/
+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_ISR_ALREADY_INSTALLED;
+ }
+
+ PVR_TRACE(("Installing MISR with cookie %p", pvSysData));
+
+ INIT_WORK(&psEnvData->sMISRWork, MISRWrapper
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+ , (void *)&psEnvData->sMISRWork
+#endif
+ );
+
+ psEnvData->pvMISRData = pvSysData;
+ psEnvData->bMISRInstalled = IMG_TRUE;
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSUninstallMISR
+
+ @Description Uninstalls an OS dependent MISR
+
+ @Input psSysData
+
+ @Return error status
+
+******************************************************************************/
+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_ISR_NOT_INSTALLED;
+ }
+
+ PVR_TRACE(("Uninstalling MISR"));
+
+ flush_scheduled_work();
+
+ psEnvData->bMISRInstalled = IMG_FALSE;
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSScheduleMISR
+
+ @Description Schedules an OS dependent MISR
+
+ @Input pvSysData
+
+ @Return error status
+
+******************************************************************************/
+PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData)
+{
+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData;
+ ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData;
+
+ if (psEnvData->bMISRInstalled)
+ {
+ schedule_work(&psEnvData->sMISRWork);
+ }
+
+ return PVRSRV_OK;
+}
+
+#else /* #if defined(PVR_LINUX_MISR_USING_WORKQUEUE) */
+
+
+/*!
+******************************************************************************
+
+ @Function MISRWrapper
+
+ @Description OS dependent MISR wrapper
+
+ @Input psSysData
+
+ @Return error status
+
+******************************************************************************/
+static void MISRWrapper(unsigned long data)
+{
+ SYS_DATA *psSysData;
+
+ psSysData = (SYS_DATA *)data;
+
+ PVRSRVMISR(psSysData);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSInstallMISR
+
+ @Description Installs an OS dependent MISR
+
+ @Input psSysData
+
+ @Return error status
+
+******************************************************************************/
+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_ISR_ALREADY_INSTALLED;
+ }
+
+ PVR_TRACE(("Installing MISR with cookie %p", pvSysData));
+
+ tasklet_init(&psEnvData->sMISRTasklet, MISRWrapper, (unsigned long)pvSysData);
+
+ psEnvData->bMISRInstalled = IMG_TRUE;
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSUninstallMISR
+
+ @Description Uninstalls an OS dependent MISR
+
+ @Input psSysData
+
+ @Return error status
+
+******************************************************************************/
+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_ISR_NOT_INSTALLED;
+ }
+
+ PVR_TRACE(("Uninstalling MISR"));
+
+ tasklet_kill(&psEnvData->sMISRTasklet);
+
+ psEnvData->bMISRInstalled = IMG_FALSE;
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function OSScheduleMISR
+
+ @Description Schedules an OS dependent MISR
+
+ @Input pvSysData
+
+ @Return error status
+
+******************************************************************************/
+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 defined(PVR_LINUX_MISR_USING_WORKQUEUE) */
+#endif /* #if defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE) */
+
+#endif /* #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) */
+
+IMG_VOID OSPanic(IMG_VOID)
+{
+ BUG();
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
+#define OS_TAS(p) xchg((p), 1)
+#else
+#define OS_TAS(p) tas(p)
+#endif
+/*!
+******************************************************************************
+
+ @Function OSLockResource
+
+ @Description locks an OS dependant Resource
+
+ @Input phResource - pointer to OS dependent Resource
+ @Input bBlock - do we want to block?
+
+ @Return error status
+
+******************************************************************************/
+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_UNABLE_TO_LOCK_RESOURCE;
+
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSUnlockResource
+
+ @Description unlocks an OS dependant resource
+
+ @Input phResource - pointer to OS dependent resource structure
+
+ @Return
+
+******************************************************************************/
+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;
+ smp_mb();
+ *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_INVALID_LOCK_ID;
+ }
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR,"OSUnlockResource: Resource %p is not locked", psResource));
+ eError = PVRSRV_ERROR_RESOURCE_NOT_LOCKED;
+ }
+
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSIsResourceLocked
+
+ @Description tests if resource is locked
+
+ @Input phResource - pointer to OS dependent resource structure
+
+ @Return error status
+
+******************************************************************************/
+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;
+}
+
+
+#if !defined(SYS_CUSTOM_POWERLOCK_WRAP)
+PVRSRV_ERROR OSPowerLockWrap(IMG_BOOL bTryLock)
+{
+ PVR_UNREFERENCED_PARAMETER(bTryLock);
+
+ return PVRSRV_OK;
+}
+
+IMG_VOID OSPowerLockUnwrap (IMG_VOID)
+{
+}
+#endif /* SYS_CUSTOM_POWERLOCK_WRAP */
+
+
+IMG_CPU_PHYADDR OSMapLinToCPUPhys(IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvLinAddr)
+{
+ IMG_CPU_PHYADDR CpuPAddr;
+ LinuxMemArea *psLinuxMemArea;
+ IMG_UINTPTR_T uiByteOffset;
+ IMG_UINT32 ui32ByteOffset;
+
+ PVR_ASSERT(hOSMemHandle != IMG_NULL);
+
+ psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+
+ uiByteOffset = (IMG_UINTPTR_T)pvLinAddr - (IMG_UINTPTR_T)LinuxMemAreaToCpuVAddr(psLinuxMemArea);
+ ui32ByteOffset = (IMG_UINT32)uiByteOffset;
+
+ CpuPAddr = LinuxMemAreaToCpuPAddr(hOSMemHandle, ui32ByteOffset);
+
+ return CpuPAddr;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSMapPhysToLin
+
+ @Description Maps the physical memory into linear addr range
+
+ @Input BasePAddr : physical cpu address
+
+ @Input ui32Bytes - bytes to map
+
+ @Input ui32CacheType - cache type
+
+ @Return : Linear addr of mapping on success, else NULL
+
+ ******************************************************************************/
+IMG_VOID *
+OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32MappingFlags,
+ IMG_HANDLE *phOSMemHandle)
+{
+ if(ui32MappingFlags & PVRSRV_HAP_KERNEL_ONLY)
+ {
+ /*
+ * Provide some backwards compatibility, until all callers
+ * have been updated to pass a non-null OSMemHandle pointer.
+ * Such callers must not call OSMapLinToCPUPhys.
+ */
+ if(phOSMemHandle == IMG_NULL)
+ {
+ IMG_VOID *pvIORemapCookie;
+ pvIORemapCookie = IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags);
+ if(pvIORemapCookie == IMG_NULL)
+ {
+ return IMG_NULL;
+ }
+ return pvIORemapCookie;
+ }
+ else
+ {
+ LinuxMemArea *psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
+
+ if(psLinuxMemArea == IMG_NULL)
+ {
+ return IMG_NULL;
+ }
+
+ *phOSMemHandle = (IMG_HANDLE)psLinuxMemArea;
+ return LinuxMemAreaToCpuVAddr(psLinuxMemArea);
+ }
+ }
+
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSMapPhysToLin should only be used with PVRSRV_HAP_KERNEL_ONLY "
+ " (Use OSReservePhys otherwise)"));
+
+ return IMG_NULL;
+}
+
+/*!
+******************************************************************************
+ @Function OSUnMapPhysToLin
+ @Description Unmaps memory that was mapped with OSMapPhysToLin
+ @Return TRUE on success, else FALSE
+******************************************************************************/
+IMG_BOOL
+OSUnMapPhysToLin(IMG_VOID *pvLinAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32MappingFlags, IMG_HANDLE hOSMemHandle)
+{
+ PVR_UNREFERENCED_PARAMETER(ui32Bytes);
+
+ if(ui32MappingFlags & PVRSRV_HAP_KERNEL_ONLY)
+ {
+ if (hOSMemHandle == IMG_NULL)
+ {
+ IOUnmapWrapper(pvLinAddr);
+ }
+ else
+ {
+ LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+
+ PVR_ASSERT(LinuxMemAreaToCpuVAddr(psLinuxMemArea) == pvLinAddr);
+
+ FreeIORemapLinuxMemArea(psLinuxMemArea);
+ }
+
+ return IMG_TRUE;
+ }
+
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSUnMapPhysToLin should only be used with PVRSRV_HAP_KERNEL_ONLY "
+ " (Use OSUnReservePhys otherwise)"));
+ return IMG_FALSE;
+}
+
+/*!
+******************************************************************************
+ @Function RegisterExternalMem
+ @Description Registers external memory for user mode mapping
+ @Return TRUE on success, else FALSE, MemHandle out
+******************************************************************************/
+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_BAD_MAPPING;
+ }
+ break;
+ }
+ case PVRSRV_HAP_SINGLE_PROCESS:
+ {
+ psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags);
+
+ if(!psLinuxMemArea)
+ {
+ return PVRSRV_ERROR_BAD_MAPPING;
+ }
+ PVRMMapRegisterArea(psLinuxMemArea);
+ break;
+ }
+ case PVRSRV_HAP_MULTI_PROCESS:
+ {
+ /* Currently PVRSRV_HAP_MULTI_PROCESS implies that we need a kernel
+ * virtual mapping and potentially multiple user space virtual mappings.
+ * Beware that the kernel virtual address space is a limited resource.
+ */
+#if defined(VIVT_CACHE) || defined(__sh__)
+ /*
+ * ARM9 caches are tagged with virtual pages, not physical. As we are going to
+ * share this memory in different address spaces, we don't want it to be cached.
+ * ARM11 has physical tagging, so we can cache this memory without fear of virtual
+ * address aliasing in the TLB, as long as the kernel supports cache colouring for
+ * VIPT architectures.
+ */
+ ui32MappingFlags &= ~PVRSRV_HAP_CACHED;
+#endif
+ psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags);
+
+ if(!psLinuxMemArea)
+ {
+ return PVRSRV_ERROR_BAD_MAPPING;
+ }
+ PVRMMapRegisterArea(psLinuxMemArea);
+ break;
+ }
+ default:
+ PVR_DPF((PVR_DBG_ERROR,"OSRegisterMem : invalid flags 0x%x\n", ui32MappingFlags));
+ *phOSMemHandle = (IMG_HANDLE)0;
+ return PVRSRV_ERROR_INVALID_FLAGS;
+ }
+
+ *phOSMemHandle = (IMG_HANDLE)psLinuxMemArea;
+
+ LinuxMemAreaRegister(psLinuxMemArea);
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+ @Function OSRegisterMem
+ @Description Registers external memory for user mode mapping
+ @Output phOSMemHandle - handle to registered memory
+ @Return TRUE on success, else FALSE
+******************************************************************************/
+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);
+}
+
+
+/*!
+******************************************************************************
+ @Function OSUnRegisterMem
+ @Description UnRegisters external memory for user mode mapping
+ @Return TRUE on success, else FALSE
+******************************************************************************/
+PVRSRV_ERROR
+OSUnRegisterMem (IMG_VOID *pvCpuVAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32MappingFlags,
+ IMG_HANDLE hOSMemHandle)
+{
+ LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+ PVRSRV_ERROR eError;
+
+ 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:
+ {
+ eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s(%p, %d, 0x%08X, %p) FAILED!",
+ __FUNCTION__, pvCpuVAddr, ui32Bytes,
+ ui32MappingFlags, hOSMemHandle));
+ return eError;
+ }
+ 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);
+}
+
+/*!
+******************************************************************************
+ @Function OSReservePhys
+ @Description Registers physical memory for user mode mapping
+ @Output ppvCpuVAddr
+ @Output phOsMemHandle handle to registered memory
+ @Return TRUE on success, else FALSE
+******************************************************************************/
+PVRSRV_ERROR
+OSReservePhys(IMG_CPU_PHYADDR BasePAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32MappingFlags,
+ IMG_HANDLE hBMHandle,
+ IMG_VOID **ppvCpuVAddr,
+ IMG_HANDLE *phOSMemHandle)
+{
+ LinuxMemArea *psLinuxMemArea;
+
+#if 0
+ /* For debug: force all OSReservePhys reservations to have a kernel
+ * virtual address */
+ 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:
+ {
+ /* Currently PVRSRV_HAP_KERNEL_ONLY implies that a kernel virtual
+ * mapping is required for the allocation and no user virtual
+ * mappings are allowed: Note these eat into our limited kernel
+ * virtual address space */
+ psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
+ if(!psLinuxMemArea)
+ {
+ return PVRSRV_ERROR_BAD_MAPPING;
+ }
+ break;
+ }
+ case PVRSRV_HAP_SINGLE_PROCESS:
+ {
+ /* Currently this implies that we dont need a kernel virtual
+ * mapping, but will need a user space virtual mapping */
+ psLinuxMemArea = NewIOLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
+ if(!psLinuxMemArea)
+ {
+ return PVRSRV_ERROR_BAD_MAPPING;
+ }
+ PVRMMapRegisterArea(psLinuxMemArea);
+ break;
+ }
+ case PVRSRV_HAP_MULTI_PROCESS:
+ {
+ /* Currently PVRSRV_HAP_MULTI_PROCESS implies that we need a kernel
+ * virtual mapping and potentially multiple user space virtual mappings.
+ * Beware that the kernel virtual address space is a limited resource.
+ */
+#if defined(VIVT_CACHE) || defined(__sh__)
+ /*
+ * ARM9 caches are tagged with virtual pages, not physical. As we are going to
+ * share this memory in different address spaces, we don't want it to be cached.
+ * ARM11 has physical tagging, so we can cache this memory without fear of virtual
+ * address aliasing in the TLB, as long as the kernel supports cache colouring for
+ * VIPT architectures.
+ */
+ ui32MappingFlags &= ~PVRSRV_HAP_CACHED;
+#endif
+ psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags);
+ if(!psLinuxMemArea)
+ {
+ return PVRSRV_ERROR_BAD_MAPPING;
+ }
+ 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_INVALID_FLAGS;
+ }
+
+ /*
+ In case of sparse mapping we need to handle back to the BM as it
+ knows the mapping info
+ */
+ if (ui32MappingFlags & PVRSRV_MEM_SPARSE)
+ {
+ PVR_ASSERT(hBMHandle != IMG_NULL);
+ psLinuxMemArea->hBMHandle = hBMHandle;
+ }
+
+ *phOSMemHandle = (IMG_HANDLE)psLinuxMemArea;
+ *ppvCpuVAddr = LinuxMemAreaToCpuVAddr(psLinuxMemArea);
+
+ LinuxMemAreaRegister(psLinuxMemArea);
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+ @Function OSUnReservePhys
+ @Description UnRegisters physical memory for user mode mapping
+ @Return TRUE on success, else FALSE
+******************************************************************************/
+PVRSRV_ERROR
+OSUnReservePhys(IMG_VOID *pvCpuVAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32MappingFlags,
+ IMG_HANDLE hOSMemHandle)
+{
+ LinuxMemArea *psLinuxMemArea;
+ PVRSRV_ERROR eError;
+
+ 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:
+ {
+ eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s(%p, %d, 0x%08X, %p) FAILED!",
+ __FUNCTION__, pvCpuVAddr, ui32Bytes,
+ ui32MappingFlags, hOSMemHandle));
+ return eError;
+ }
+ break;
+ }
+ default:
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSUnMapPhysToLin : invalid flags 0x%x", ui32MappingFlags));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ }
+
+ LinuxMemAreaDeepFree(psLinuxMemArea);
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+ @Function OSBaseAllocContigMemory
+ @Description Allocate a block of contiguous virtual non-paged memory.
+ @Input ui32Size - number of bytes to allocate
+ @Output ppvLinAddr - pointer to variable that will receive the linear address of buffer
+ @Return PVRSRV_OK if allocation successed else returns PVRSRV_ERROR_OUT_OF_MEMORY
+ **************************************************************************/
+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
+/*
+ * On Linux, the returned virtual address should be used for CPU access,
+ * and not be remapped into the CPU virtual address using ioremap. The fact
+ * that the RAM is being managed by the kernel, and already has a virtual
+ * address, seems to lead to problems when the attributes of the memory are
+ * changed in the ioremap call (such as from cached to non-cached).
+ */
+ IMG_VOID *pvKernLinAddr;
+
+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ pvKernLinAddr = _KMallocWrapper(ui32Size, GFP_KERNEL, __FILE__, __LINE__);
+#else
+ pvKernLinAddr = KMallocWrapper(ui32Size, GFP_KERNEL);
+#endif
+ if (!pvKernLinAddr)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ *pvLinAddr = pvKernLinAddr;
+
+ psPhysAddr->uiAddr = virt_to_phys(pvKernLinAddr);
+
+ return PVRSRV_OK;
+#endif /* !defined(NO_HARDWARE) */
+}
+
+
+/*!
+******************************************************************************
+ @Function OSBaseFreeContigMemory
+ @Description Frees memory allocated with OSBaseAllocContigMemory
+ @Input LinAddr - pointer to buffer allocated with OSBaseAllocContigMemory
+ **************************************************************************/
+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;
+}
+
+/*!
+******************************************************************************
+
+ @Function OSWriteHWReg
+
+ @Description
+
+ register access function
+
+ @input pvLinRegBaseAddr : lin addr of register block base
+
+ @input ui32Offset :
+
+ @input ui32Value :
+
+ @Return none
+
+******************************************************************************/
+
+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))
+
+/*!
+******************************************************************************
+
+ @Function OSPCISetDev
+
+ @Description
+
+ Set a PCI device for subsequent use.
+
+ @input pvPCICookie : Pointer to OS specific PCI structure/cookie
+
+ @input eFlags : Flags
+
+ @Return Pointer to PCI device handle
+
+******************************************************************************/
+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,
+ "PCI Device") != 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) /* PRQA S 3358 */ /* misuse of enums */
+ {
+ pci_set_master(psPVRPCI->psPCIDev);
+ }
+
+ if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_MSI) /* PRQA S 3358 */ /* misuse of enums */
+ {
+#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; /* PRQA S 1474,3358,4130 */ /* misuse of enums */
+ }
+#else
+ PVR_DPF((PVR_DBG_WARNING, "OSPCISetDev: MSI support not enabled in the kernel"));
+#endif
+ }
+
+ /* Initialise the PCI resource tracking array */
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
+ {
+ psPVRPCI->abPCIResourceInUse[i] = IMG_FALSE;
+ }
+
+ return (PVRSRV_PCI_DEV_HANDLE)psPVRPCI;
+}
+
+/*!
+******************************************************************************
+
+ @Function OSPCIAcquireDev
+
+ @Description
+
+ Acquire a PCI device for subsequent use.
+
+ @input ui16VendorID : Vendor PCI ID
+
+ @input ui16VendorID : Device PCI ID
+
+ @input eFlags : Flags
+
+ @Return PVESRV_ERROR
+
+******************************************************************************/
+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);
+}
+
+/*!
+******************************************************************************
+
+ @Function OSPCIIRQ
+
+ @Description
+
+ Get the interrupt number for the device.
+
+ @input hPVRPCI : PCI device handle
+
+ @input pui32IRQ : Pointer to where the interrupt number should be returned
+
+ @Return PVESRV_ERROR
+
+******************************************************************************/
+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;
+}
+
+/* Functions supported by OSPCIAddrRangeFunc */
+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
+};
+
+/*!
+******************************************************************************
+
+ @Function OSPCIAddrRangeFunc
+
+ @Description
+
+ Internal support function for various address range related functions
+
+ @input eFunc : Function to perform
+
+ @input hPVRPCI : PCI device handle
+
+ @input ui32Index : Address range index
+
+ @Return function dependent
+
+******************************************************************************/
+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, PVRSRV_MODNAME);
+ 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;
+}
+
+/*!
+******************************************************************************
+
+ @Function OSPCIAddrRangeLen
+
+ @Description
+
+ Returns length of a given address range length
+
+ @input hPVRPCI : PCI device handle
+
+ @input ui32Index : Address range index
+
+ @Return Length of address range, or 0 if no such range
+
+******************************************************************************/
+IMG_UINT32 OSPCIAddrRangeLen(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
+{
+ return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_LEN, hPVRPCI, ui32Index);
+}
+
+/*!
+******************************************************************************
+
+ @Function OSPCIAddrRangeStart
+
+ @Description
+
+ Returns the start of a given address range
+
+ @input hPVRPCI : PCI device handle
+
+ @input ui32Index : Address range index
+
+ @Return Start of address range, or 0 if no such range
+
+******************************************************************************/
+IMG_UINT32 OSPCIAddrRangeStart(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
+{
+ return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_START, hPVRPCI, ui32Index);
+}
+
+/*!
+******************************************************************************
+
+ @Function OSPCIAddrRangeEnd
+
+ @Description
+
+ Returns the end of a given address range
+
+ @input hPVRPCI : PCI device handle"ayy
+
+ @input ui32Index : Address range index
+
+ @Return End of address range, or 0 if no such range
+
+******************************************************************************/
+IMG_UINT32 OSPCIAddrRangeEnd(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
+{
+ return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_END, hPVRPCI, ui32Index);
+}
+
+/*!
+******************************************************************************
+
+ @Function OSPCIRequestAddrRange
+
+ @Description
+
+ Request a given address range index for subsequent use
+
+ @input hPVRPCI : PCI device handle
+
+ @input ui32Index : Address range index
+
+ @Return PVESRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR OSPCIRequestAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI,
+ IMG_UINT32 ui32Index)
+{
+ return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_REQUEST, hPVRPCI, ui32Index) == 0 ? PVRSRV_ERROR_PCI_CALL_FAILED : PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function OSPCIReleaseAddrRange
+
+ @Description
+
+ Release a given address range that is no longer being used
+
+ @input hPVRPCI : PCI device handle
+
+ @input ui32Index : Address range index
+
+ @Return PVESRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR OSPCIReleaseAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index)
+{
+ return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_RELEASE, hPVRPCI, ui32Index) == 0 ? PVRSRV_ERROR_PCI_CALL_FAILED : PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function OSPCIReleaseDev
+
+ @Description
+
+ Release a PCI device that is no longer being used
+
+ @input hPVRPCI : PCI device handle
+
+ @Return PVESRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR OSPCIReleaseDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI)
+{
+ PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
+ int i;
+
+ PVR_TRACE(("OSPCIReleaseDev"));
+
+ /* Release all PCI regions that are currently in use */
+ 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) /* PRQA S 3358 */ /* misuse of enums */
+ {
+ pci_disable_msi(psPVRPCI->psPCIDev);
+ }
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
+ if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER) /* PRQA S 3358 */ /* misuse of enums */
+ {
+ pci_clear_master(psPVRPCI->psPCIDev);
+ }
+#endif
+ pci_disable_device(psPVRPCI->psPCIDev);
+
+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psPVRPCI), (IMG_VOID *)psPVRPCI, IMG_NULL);
+ /*not nulling pointer, copy on stack*/
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function OSPCISuspendDev
+
+ @Description
+
+ Prepare PCI device to be turned off by power management
+
+ @input hPVRPCI : PCI device handle
+
+ @Return PVESRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR OSPCISuspendDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI)
+{
+ PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI;
+ int i;
+ int err;
+
+ PVR_TRACE(("OSPCISuspendDev"));
+
+ /* Release all PCI regions that are currently in use */
+ 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_PCI_CALL_FAILED;
+ }
+
+ 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;
+}
+
+/*!
+******************************************************************************
+
+ @Function OSPCIResumeDev
+
+ @Description
+
+ Prepare a PCI device to be resumed by power management
+
+ @input hPVRPCI : PCI device handle
+
+ @input pvPCICookie : Pointer to OS specific PCI structure/cookie
+
+ @input eFlags : Flags
+
+ @Return PVESRV_ERROR
+
+******************************************************************************/
+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_UNKNOWN_POWER_STATE;
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_set_power_state failed (%d)", err));
+ return PVRSRV_ERROR_UNKNOWN_POWER_STATE;
+ }
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
+ pci_restore_state(psPVRPCI->psPCIDev);
+#else
+ err = pci_restore_state(psPVRPCI->psPCIDev);
+ if (err != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_restore_state failed (%d)", err));
+ return PVRSRV_ERROR_PCI_CALL_FAILED;
+ }
+#endif
+
+ err = pci_enable_device(psPVRPCI->psPCIDev);
+ if (err != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: Couldn't enable device (%d)", err));
+ return PVRSRV_ERROR_PCI_CALL_FAILED;
+ }
+
+ if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER) /* PRQA S 3358 */ /* misuse of enums */
+ pci_set_master(psPVRPCI->psPCIDev);
+
+ /* Restore the PCI resource tracking array */
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
+ {
+ if (psPVRPCI->abPCIResourceInUse[i])
+ {
+ err = pci_request_region(psPVRPCI->psPCIDev, i, PVRSRV_MODNAME);
+ if (err != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_request_region_failed (region %d, error %d)", i, err));
+ }
+ }
+
+ }
+
+ return PVRSRV_OK;
+}
+
+#endif /* #if defined(CONFIG_PCI) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)) */
+
+#define OS_MAX_TIMERS 8
+
+/* Timer callback strucure used by OSAddTimer */
+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;
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+ struct work_struct sWork;
+#endif
+}TIMER_CALLBACK_DATA;
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+static struct workqueue_struct *psTimerWorkQueue;
+#endif
+
+static TIMER_CALLBACK_DATA sTimers[OS_MAX_TIMERS];
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+DEFINE_MUTEX(sTimerStructLock);
+#else
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39))
+/* The lock is used to control access to sTimers */
+/* PRQA S 0671,0685 1 */ /* C99 macro not understood by QAC */
+static spinlock_t sTimerStructLock = SPIN_LOCK_UNLOCKED;
+#else
+static DEFINE_SPINLOCK(sTimerStructLock);
+#endif
+#endif
+
+static void OSTimerCallbackBody(TIMER_CALLBACK_DATA *psTimerCBData)
+{
+ if (!psTimerCBData->bActive)
+ return;
+
+ /* call timer callback */
+ psTimerCBData->pfnTimerFunc(psTimerCBData->pvData);
+
+ /* reset timer */
+ mod_timer(&psTimerCBData->sTimer, psTimerCBData->ui32Delay + jiffies);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSTimerCallbackWrapper
+
+ @Description
+
+ OS specific timer callback wrapper function
+
+ @Input ui32Data : timer callback data
+
+ @Return NONE
+
+******************************************************************************/
+static IMG_VOID OSTimerCallbackWrapper(IMG_UINT32 ui32Data)
+{
+ TIMER_CALLBACK_DATA *psTimerCBData = (TIMER_CALLBACK_DATA*)ui32Data;
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+ int res;
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+ res = queue_work(psTimerWorkQueue, &psTimerCBData->sWork);
+#else
+ res = schedule_work(&psTimerCBData->sWork);
+#endif
+ if (res == 0)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "OSTimerCallbackWrapper: work already queued"));
+ }
+#else
+ OSTimerCallbackBody(psTimerCBData);
+#endif
+}
+
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+static void OSTimerWorkQueueCallBack(struct work_struct *psWork)
+{
+ TIMER_CALLBACK_DATA *psTimerCBData = container_of(psWork, TIMER_CALLBACK_DATA, sWork);
+
+ OSTimerCallbackBody(psTimerCBData);
+}
+#endif
+
+/*!
+******************************************************************************
+
+ @Function OSAddTimer
+
+ @Description
+
+ OS specific function to install a timer callback
+
+ @Input pfnTimerFunc : timer callback
+
+ @Input *pvData :callback data
+
+ @Input ui32MsTimeout: callback period
+
+ @Return IMG_HANDLE : valid handle success, NULL failure
+
+******************************************************************************/
+IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, IMG_VOID *pvData, IMG_UINT32 ui32MsTimeout)
+{
+ TIMER_CALLBACK_DATA *psTimerCBData;
+ IMG_UINT32 ui32i;
+#if !(defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE))
+ unsigned long ulLockFlags;
+#endif
+
+ /* check callback */
+ if(!pfnTimerFunc)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSAddTimer: passed invalid callback"));
+ return IMG_NULL;
+ }
+
+ /* Allocate timer callback data structure */
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+ mutex_lock(&sTimerStructLock);
+#else
+ spin_lock_irqsave(&sTimerStructLock, ulLockFlags);
+#endif
+ for (ui32i = 0; ui32i < OS_MAX_TIMERS; ui32i++)
+ {
+ psTimerCBData = &sTimers[ui32i];
+ if (!psTimerCBData->bInUse)
+ {
+ psTimerCBData->bInUse = IMG_TRUE;
+ break;
+ }
+ }
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+ mutex_unlock(&sTimerStructLock);
+#else
+ spin_unlock_irqrestore(&sTimerStructLock, ulLockFlags);
+#endif
+ 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;
+
+ /*
+ HZ = ticks per second
+ ui32MsTimeout = required ms delay
+ ticks = (Hz * ui32MsTimeout) / 1000
+ */
+ psTimerCBData->ui32Delay = ((HZ * ui32MsTimeout) < 1000)
+ ? 1
+ : ((HZ * ui32MsTimeout) / 1000);
+ /* initialise object */
+ init_timer(&psTimerCBData->sTimer);
+
+ /* setup timer object */
+ /* PRQA S 0307,0563 1 */ /* ignore warning about inconpartible ptr casting */
+ psTimerCBData->sTimer.function = (IMG_VOID *)OSTimerCallbackWrapper;
+ psTimerCBData->sTimer.data = (IMG_UINT32)psTimerCBData;
+
+ 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];
+}
+
+/*!
+******************************************************************************
+
+ @Function OSRemoveTimer
+
+ @Description
+
+ OS specific function to remove a timer callback
+
+ @Input hTimer : timer handle
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR OSRemoveTimer (IMG_HANDLE hTimer)
+{
+ TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
+
+ PVR_ASSERT(psTimerCBData->bInUse);
+ PVR_ASSERT(!psTimerCBData->bActive);
+
+ /* free timer callback data struct */
+ psTimerCBData->bInUse = IMG_FALSE;
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSEnableTimer
+
+ @Description
+
+ OS specific function to enable a timer callback
+
+ @Input hTimer : timer handle
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR OSEnableTimer (IMG_HANDLE hTimer)
+{
+ TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
+
+ PVR_ASSERT(psTimerCBData->bInUse);
+ PVR_ASSERT(!psTimerCBData->bActive);
+
+ /* Start timer arming */
+ psTimerCBData->bActive = IMG_TRUE;
+
+ /* set the expire time */
+ psTimerCBData->sTimer.expires = psTimerCBData->ui32Delay + jiffies;
+
+ /* Add the timer to the list */
+ add_timer(&psTimerCBData->sTimer);
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSDisableTimer
+
+ @Description
+
+ OS specific function to disable a timer callback
+
+ @Input hTimer : timer handle
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR OSDisableTimer (IMG_HANDLE hTimer)
+{
+ TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
+
+ PVR_ASSERT(psTimerCBData->bInUse);
+ PVR_ASSERT(psTimerCBData->bActive);
+
+ /* Stop timer from arming */
+ psTimerCBData->bActive = IMG_FALSE;
+ smp_mb();
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+ flush_workqueue(psTimerWorkQueue);
+#endif
+#if defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+ flush_scheduled_work();
+#endif
+
+ /* remove timer */
+ del_timer_sync(&psTimerCBData->sTimer);
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+ /*
+ * This second flush is to catch the case where the timer ran
+ * before we managed to delete it, in which case, it will have
+ * queued more work for the workqueue. Since the bActive flag
+ * has been cleared, this second flush won't result in the
+ * timer being rearmed.
+ */
+ flush_workqueue(psTimerWorkQueue);
+#endif
+#if defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+ flush_scheduled_work();
+#endif
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSEventObjectCreateKM
+
+ @Description
+
+ OS specific function to create an event object
+
+ @Input pszName : Globally unique event object name (if null name must be autogenerated)
+
+ @Output psEventObject : OS event object info structure
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR OSEventObjectCreateKM(const IMG_CHAR *pszName, PVRSRV_EVENTOBJECT_KM *psEventObject)
+#else
+PVRSRV_ERROR OSEventObjectCreateKM(const IMG_CHAR *pszName, PVRSRV_EVENTOBJECT *psEventObject)
+#endif
+{
+
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ if(psEventObject)
+ {
+ if(pszName)
+ {
+ /* copy over the event object name */
+ strncpy(psEventObject->szName, pszName, EVENTOBJNAME_MAXLENGTH);
+ }
+ else
+ {
+ /* autogenerate a name */
+ static IMG_UINT16 ui16NameIndex = 0;
+#if defined (SUPPORT_SID_INTERFACE)
+ snprintf(psEventObject->szName, EVENTOBJNAME_MAXLENGTH, "PVRSRV_EVENTOBJECT_KM_%d", ui16NameIndex++);
+#else
+ snprintf(psEventObject->szName, EVENTOBJNAME_MAXLENGTH, "PVRSRV_EVENTOBJECT_%d", ui16NameIndex++);
+#endif
+ }
+
+ if(LinuxEventObjectListCreate(&psEventObject->hOSEventKM) != PVRSRV_OK)
+ {
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectCreateKM: psEventObject is not a valid pointer"));
+ eError = PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT;
+ }
+
+ return eError;
+
+}
+
+
+/*!
+******************************************************************************
+
+ @Function OSEventObjectDestroyKM
+
+ @Description
+
+ OS specific function to destroy an event object
+
+ @Input psEventObject : OS event object info structure
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR OSEventObjectDestroyKM(PVRSRV_EVENTOBJECT_KM *psEventObject)
+#else
+PVRSRV_ERROR OSEventObjectDestroyKM(PVRSRV_EVENTOBJECT *psEventObject)
+#endif
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ if(psEventObject)
+ {
+ if(psEventObject->hOSEventKM)
+ {
+ LinuxEventObjectListDestroy(psEventObject->hOSEventKM);
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroyKM: hOSEventKM is not a valid pointer"));
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroyKM: psEventObject is not a valid pointer"));
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function OSEventObjectWaitKM
+
+ @Description
+
+ OS specific function to wait for an event object. Called from client
+
+ @Input hOSEventKM : OS and kernel specific handle to event object
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR OSEventObjectWaitKM(IMG_HANDLE hOSEventKM)
+{
+ PVRSRV_ERROR eError;
+
+ if(hOSEventKM)
+ {
+ eError = LinuxEventObjectWait(hOSEventKM, EVENT_OBJECT_TIMEOUT_MS);
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectWaitKM: hOSEventKM is not a valid handle"));
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function OSEventObjectOpenKM
+
+ @Description
+
+ OS specific function to open an event object. Called from client
+
+ @Input psEventObject : Pointer to an event object
+ @Output phOSEvent : OS and kernel specific handle to event object
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR OSEventObjectOpenKM(PVRSRV_EVENTOBJECT_KM *psEventObject,
+#else
+PVRSRV_ERROR OSEventObjectOpenKM(PVRSRV_EVENTOBJECT *psEventObject,
+#endif
+ 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, "OSEventObjectCreateKM: psEventObject is not a valid pointer"));
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function OSEventObjectCloseKM
+
+ @Description
+
+ OS specific function to close an event object. Called from client
+
+ @Input psEventObject : Pointer to an event object
+ @OInput hOSEventKM : OS and kernel specific handle to event object
+
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR OSEventObjectCloseKM(PVRSRV_EVENTOBJECT_KM *psEventObject,
+#else
+PVRSRV_ERROR OSEventObjectCloseKM(PVRSRV_EVENTOBJECT *psEventObject,
+#endif
+ 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, "OSEventObjectDestroyKM: psEventObject is not a valid pointer"));
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return eError;
+
+}
+
+/*!
+******************************************************************************
+
+ @Function OSEventObjectSignalKM
+
+ @Description
+
+ OS specific function to 'signal' an event object. Called from L/MISR
+
+ @Input hOSEventKM : OS and kernel specific handle to event object
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR OSEventObjectSignalKM(IMG_HANDLE hOSEventKM)
+{
+ PVRSRV_ERROR eError;
+
+ if(hOSEventKM)
+ {
+ eError = LinuxEventObjectSignal(hOSEventKM);
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectSignalKM: hOSEventKM is not a valid handle"));
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function OSProcHasPrivSrvInit
+
+ @Description
+
+ Does the process have sufficient privileges to initialise services?
+
+ @Input none
+
+ @Return IMG_BOOL :
+
+******************************************************************************/
+IMG_BOOL OSProcHasPrivSrvInit(IMG_VOID)
+{
+ return (capable(CAP_SYS_MODULE) != 0) ? IMG_TRUE : IMG_FALSE;
+}
+
+/*!
+******************************************************************************
+
+ @Function OSCopyToUser
+
+ @Description
+
+ Copy a block of data into user space
+
+ @Input pvSrc
+
+ @Output pvDest
+
+ @Input ui32Bytes
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR OSCopyToUser(IMG_PVOID pvProcess,
+ IMG_VOID *pvDest,
+ IMG_VOID *pvSrc,
+ IMG_UINT32 ui32Bytes)
+{
+ PVR_UNREFERENCED_PARAMETER(pvProcess);
+
+ if(pvr_copy_to_user(pvDest, pvSrc, ui32Bytes)==0)
+ return PVRSRV_OK;
+ else
+ return PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY;
+}
+
+/*!
+******************************************************************************
+
+ @Function OSCopyFromUser
+
+ @Description
+
+ Copy a block of data from the user space
+
+ @Output pvDest
+
+ @Input pvSrc
+
+ @Input ui32Bytes
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR OSCopyFromUser( IMG_PVOID pvProcess,
+ IMG_VOID *pvDest,
+ IMG_VOID *pvSrc,
+ IMG_UINT32 ui32Bytes)
+{
+ PVR_UNREFERENCED_PARAMETER(pvProcess);
+
+ if(pvr_copy_from_user(pvDest, pvSrc, ui32Bytes)==0)
+ return PVRSRV_OK;
+ else
+ return PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY;
+}
+
+/*!
+******************************************************************************
+
+ @Function OSAccessOK
+
+ @Description
+
+ Checks if a user space pointer is valide
+
+ @Input eVerification
+
+ @Input pvUserPtr
+
+ @Input ui32Bytes
+
+ @Return IMG_BOOL :
+
+******************************************************************************/
+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_NULL = 0,
+ WRAP_TYPE_GET_USER_PAGES,
+ WRAP_TYPE_FIND_VMA
+} eWrapMemType;
+
+typedef struct _sWrapMemInfo_
+{
+ eWrapMemType eType;
+ IMG_INT iNumPages;
+ IMG_INT iNumPagesMapped;
+ struct page **ppsPages;
+ IMG_SYS_PHYADDR *psPhysAddr;
+ IMG_INT iPageOffset;
+#if defined(DEBUG)
+ IMG_UINT32 ulStartAddr;
+ IMG_UINT32 ulBeyondEndAddr;
+ struct vm_area_struct *psVMArea;
+#endif
+} sWrapMemInfo;
+
+
+/*!
+******************************************************************************
+
+ @Function *CPUVAddrToPFN
+
+ @Description
+
+ Find the PFN associated with a given CPU virtual address, and return
+ the associated page structure, if it exists.
+ The page in question must be present (i.e. no fault handling required),
+ and must be writable. A get_page is done on the returned page structure.
+
+ @Input psVMArea - pointer to VM area structure
+ ulCPUVAddr - CPU virtual address
+ pulPFN - Pointer to returned PFN.
+ ppsPAge - Pointer to returned page structure pointer.
+
+ @Output *pulPFN - Set to PFN
+ *ppsPage - Pointer to the page structure if present, else NULL.
+ @Return IMG_TRUE if PFN lookup was succesful.
+
+******************************************************************************/
+static IMG_BOOL CPUVAddrToPFN(struct vm_area_struct *psVMArea, IMG_UINT32 ulCPUVAddr, IMG_UINT32 *pulPFN, struct page **ppsPage)
+{
+#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;
+ spinlock_t *psPTLock;
+ IMG_BOOL bRet = IMG_FALSE;
+
+ *pulPFN = 0;
+ *ppsPage = NULL;
+
+ psPGD = pgd_offset(psMM, ulCPUVAddr);
+ if (pgd_none(*psPGD) || pgd_bad(*psPGD))
+ return bRet;
+
+ psPUD = pud_offset(psPGD, ulCPUVAddr);
+ if (pud_none(*psPUD) || pud_bad(*psPUD))
+ return bRet;
+
+ psPMD = pmd_offset(psPUD, ulCPUVAddr);
+ if (pmd_none(*psPMD) || pmd_bad(*psPMD))
+ return bRet;
+
+ psPTE = (pte_t *)pte_offset_map_lock(psMM, psPMD, ulCPUVAddr, &psPTLock);
+
+ if ((pte_none(*psPTE) == 0) && (pte_present(*psPTE) != 0) && (pte_write(*psPTE) != 0))
+ {
+ *pulPFN = pte_pfn(*psPTE);
+ bRet = IMG_TRUE;
+
+ if (pfn_valid(*pulPFN))
+ {
+ *ppsPage = pfn_to_page(*pulPFN);
+
+ get_page(*ppsPage);
+ }
+ }
+
+ pte_unmap_unlock(psPTE, psPTLock);
+
+ return bRet;
+#else
+ return IMG_FALSE;
+#endif
+}
+
+/*!
+******************************************************************************
+
+ @Function OSReleasePhysPageAddr
+
+ @Description
+
+ Release wrapped memory.
+
+ @Input hOSWrapMem : Driver cookie
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR OSReleasePhysPageAddr(IMG_HANDLE hOSWrapMem)
+{
+ sWrapMemInfo *psInfo = (sWrapMemInfo *)hOSWrapMem;
+ IMG_INT i;
+
+ if (psInfo == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_WARNING,
+ "OSReleasePhysPageAddr: called with null wrap handle"));
+ return PVRSRV_OK;
+ }
+
+ switch (psInfo->eType)
+ {
+ case WRAP_TYPE_NULL:
+ {
+ PVR_DPF((PVR_DBG_WARNING,
+ "OSReleasePhysPageAddr: called with wrap type WRAP_TYPE_NULL"));
+ break;
+ }
+ case WRAP_TYPE_GET_USER_PAGES:
+ {
+ for (i = 0; i < psInfo->iNumPagesMapped; i++)
+ {
+ struct page *psPage = psInfo->ppsPages[i];
+
+ PVR_ASSERT(psPage != NULL);
+
+ /*
+ * If the number of pages mapped is not the same as
+ * the number of pages in the address range, then
+ * get_user_pages must have failed, so we are cleaning
+ * up after failure, and the pages can't be dirty.
+ */
+ if (psInfo->iNumPagesMapped == psInfo->iNumPages)
+ {
+ if (!PageReserved(psPage))
+ {
+ SetPageDirty(psPage);
+ }
+ }
+ page_cache_release(psPage);
+ }
+ break;
+ }
+ case WRAP_TYPE_FIND_VMA:
+ {
+ for (i = 0; i < psInfo->iNumPages; i++)
+ {
+ if (psInfo->ppsPages[i] != IMG_NULL)
+ {
+ put_page(psInfo->ppsPages[i]);
+ }
+ }
+ break;
+ }
+ default:
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSReleasePhysPageAddr: Unknown wrap type (%d)", psInfo->eType));
+ return PVRSRV_ERROR_INVALID_WRAP_TYPE;
+ }
+ }
+
+ if (psInfo->ppsPages != IMG_NULL)
+ {
+ kfree(psInfo->ppsPages);
+ }
+
+ if (psInfo->psPhysAddr != IMG_NULL)
+ {
+ kfree(psInfo->psPhysAddr);
+ }
+
+ kfree(psInfo);
+
+ return PVRSRV_OK;
+}
+
+#if defined(CONFIG_TI_TILER) || defined(CONFIG_DRM_OMAP_DMM_TILER)
+
+static IMG_UINT32 CPUAddrToTilerPhy(IMG_UINT32 uiAddr)
+{
+ IMG_UINT32 ui32PhysAddr = 0;
+ pte_t *ptep, pte;
+ pgd_t *pgd;
+ pmd_t *pmd;
+ pud_t *pud;
+
+ pgd = pgd_offset(current->mm, uiAddr);
+ if (pgd_none(*pgd) || pgd_bad(*pgd))
+ goto err_out;
+
+ pud = pud_offset(pgd, uiAddr);
+ if (pud_none(*pud) || pud_bad(*pud))
+ goto err_out;
+
+ pmd = pmd_offset(pud, uiAddr);
+ if (pmd_none(*pmd) || pmd_bad(*pmd))
+ goto err_out;
+
+ ptep = pte_offset_map(pmd, uiAddr);
+ if (!ptep)
+ goto err_out;
+
+ pte = *ptep;
+ if (!pte_present(pte))
+ goto err_out;
+
+ ui32PhysAddr = (pte & PAGE_MASK) | (~PAGE_MASK & uiAddr);
+
+ /* If the physAddr is not in the TILER physical range
+ * then we don't proceed.
+ */
+ if (ui32PhysAddr < 0x60000000 && ui32PhysAddr > 0x7fffffff)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CPUAddrToTilerPhy: Not in tiler range"));
+ ui32PhysAddr = 0;
+ goto err_out;
+ }
+
+err_out:
+ return ui32PhysAddr;
+}
+
+#endif /* defined(CONFIG_TI_TILER) || defined(CONFIG_DRM_OMAP_DMM_TILER) */
+
+/*!
+******************************************************************************
+
+ @Function OSAcquirePhysPageAddr
+
+ @Description
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+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 i;
+ struct vm_area_struct *psVMArea;
+ sWrapMemInfo *psInfo = NULL;
+ IMG_BOOL bHavePageStructs = IMG_FALSE;
+ IMG_BOOL bHaveNoPageStructs = IMG_FALSE;
+ IMG_BOOL bMMapSemHeld = IMG_FALSE;
+ PVRSRV_ERROR eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+
+ /* Align start and end addresses to page boundaries */
+ ulStartAddr = ulStartAddrOrig & PAGE_MASK;
+ ulBeyondEndAddr = PAGE_ALIGN(ulBeyondEndAddrOrig);
+ ulAddrRange = ulBeyondEndAddr - ulStartAddr;
+
+ /*
+ * Check for address range calculation overflow, and attempts to wrap
+ * zero bytes.
+ */
+ if (ulBeyondEndAddr <= ulStartAddr)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Invalid address range (start %x, length %x)",
+ ulStartAddrOrig, ulAddrRangeOrig));
+ goto error;
+ }
+
+ /* Allocate information structure */
+ psInfo = kmalloc(sizeof(*psInfo), GFP_KERNEL);
+ if (psInfo == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Couldn't allocate information structure"));
+ goto error;
+ }
+ 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);
+
+ /* Allocate physical address array */
+ 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;
+ }
+ memset(psInfo->psPhysAddr, 0, (size_t)psInfo->iNumPages * sizeof(*psInfo->psPhysAddr));
+
+ /* Allocate page array */
+ 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;
+ }
+ memset(psInfo->ppsPages, 0, (size_t)psInfo->iNumPages * sizeof(*psInfo->ppsPages));
+
+ /* Default error code from now on */
+ eError = PVRSRV_ERROR_BAD_MAPPING;
+
+ /* Set the mapping type to aid clean up */
+ psInfo->eType = WRAP_TYPE_GET_USER_PAGES;
+
+ /* Lock down user memory */
+ down_read(&current->mm->mmap_sem);
+ bMMapSemHeld = IMG_TRUE;
+
+ /* Get page list */
+ psInfo->iNumPagesMapped = get_user_pages(current, current->mm, ulStartAddr, psInfo->iNumPages, 1, 0, psInfo->ppsPages, NULL);
+
+ if (psInfo->iNumPagesMapped >= 0)
+ {
+ /* See if we got all the pages we wanted */
+ if (psInfo->iNumPagesMapped != psInfo->iNumPages)
+ {
+ PVR_TRACE(("OSAcquirePhysPageAddr: Couldn't map all the pages needed (wanted: %d, got %d)", psInfo->iNumPages, psInfo->iNumPagesMapped));
+
+ goto error;
+ }
+
+ /* Build list of physical page addresses */
+ for (i = 0; i < psInfo->iNumPages; i++)
+ {
+ IMG_CPU_PHYADDR CPUPhysAddr;
+ IMG_UINT32 ulPFN;
+
+ ulPFN = page_to_pfn(psInfo->ppsPages[i]);
+ CPUPhysAddr.uiAddr = ulPFN << PAGE_SHIFT;
+ if ((CPUPhysAddr.uiAddr >> PAGE_SHIFT) != ulPFN)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Page frame number out of range (%x)", ulPFN));
+
+ goto error;
+ }
+ psInfo->psPhysAddr[i] = SysCpuPAddrToSysPAddr(CPUPhysAddr);
+ psSysPAddr[i] = psInfo->psPhysAddr[i];
+
+ }
+
+ goto exit;
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE, "OSAcquirePhysPageAddr: get_user_pages failed (%d), using CPU page table", psInfo->iNumPagesMapped));
+
+ /* Reset some fields */
+ psInfo->eType = WRAP_TYPE_NULL;
+ psInfo->iNumPagesMapped = 0;
+ memset(psInfo->ppsPages, 0, (size_t)psInfo->iNumPages * sizeof(*psInfo->ppsPages));
+
+ /*
+ * get_user_pages didn't work. If this is due to the address range
+ * representing memory mapped I/O, then we'll look for the pages
+ * in the appropriate memory region of the process.
+ */
+
+ /* Set the mapping type to aid clean up */
+ psInfo->eType = WRAP_TYPE_FIND_VMA;
+
+ psVMArea = find_vma(current->mm, ulStartAddrOrig);
+ if (psVMArea == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Couldn't find memory region containing start address %x", ulStartAddrOrig));
+
+ goto error;
+ }
+#if defined(DEBUG)
+ psInfo->psVMArea = psVMArea;
+#endif
+
+ /*
+ * find_vma locates a region with an end point past a given
+ * virtual address. So check the address is actually in the region.
+ */
+ if (ulStartAddrOrig < psVMArea->vm_start)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Start address %x is outside of the region returned by find_vma", ulStartAddrOrig));
+ goto error;
+ }
+
+ /* Now check the end address is in range */
+ if (ulBeyondEndAddrOrig > psVMArea->vm_end)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: End address %x is outside of the region returned by find_vma", ulBeyondEndAddrOrig));
+ goto error;
+ }
+
+ /* Does the region represent memory mapped I/O? */
+ 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;
+ }
+
+ /* We require read and write access */
+ 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;
+ }
+
+ for (ulAddr = ulStartAddrOrig, i = 0; ulAddr < ulBeyondEndAddrOrig; ulAddr += PAGE_SIZE, i++)
+ {
+ IMG_CPU_PHYADDR CPUPhysAddr;
+ IMG_UINT32 ulPFN = 0;
+
+ PVR_ASSERT(i < psInfo->iNumPages);
+
+ if (!CPUVAddrToPFN(psVMArea, ulAddr, &ulPFN, &psInfo->ppsPages[i]))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Invalid CPU virtual address"));
+
+ goto error;
+ }
+ if (psInfo->ppsPages[i] == NULL)
+ {
+#if defined(CONFIG_TI_TILER) || defined(CONFIG_DRM_OMAP_DMM_TILER)
+ /* This could be tiler memory.*/
+ IMG_UINT32 ui32TilerAddr = CPUAddrToTilerPhy(ulAddr);
+ if (ui32TilerAddr)
+ {
+ bHavePageStructs = IMG_TRUE;
+ psInfo->iNumPagesMapped++;
+ psInfo->psPhysAddr[i].uiAddr = ui32TilerAddr;
+ psSysPAddr[i].uiAddr = ui32TilerAddr;
+ continue;
+ }
+#endif /* defined(CONFIG_TI_TILER) || defined(CONFIG_DRM_OMAP_DMM_TILER) */
+
+ bHaveNoPageStructs = IMG_TRUE;
+ }
+ else
+ {
+ bHavePageStructs = IMG_TRUE;
+
+ psInfo->iNumPagesMapped++;
+
+ PVR_ASSERT(ulPFN == page_to_pfn(psInfo->ppsPages[i]));
+ }
+
+ CPUPhysAddr.uiAddr = ulPFN << PAGE_SHIFT;
+ if ((CPUPhysAddr.uiAddr >> PAGE_SHIFT) != ulPFN)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Page frame number out of range (%x)", ulPFN));
+
+ goto error;
+ }
+
+ psInfo->psPhysAddr[i] = SysCpuPAddrToSysPAddr(CPUPhysAddr);
+ psSysPAddr[i] = psInfo->psPhysAddr[i];
+ }
+ PVR_ASSERT(i == psInfo->iNumPages);
+
+#if defined(VM_MIXEDMAP)
+ if ((psVMArea->vm_flags & VM_MIXEDMAP) != 0)
+ {
+ goto exit;
+ }
+#endif
+
+ if (bHavePageStructs && bHaveNoPageStructs)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Region is VM_MIXEDMAP, but isn't marked as such"));
+ goto error;
+ }
+
+ if (!bHaveNoPageStructs)
+ {
+ /* The ideal case; every page has a page structure */
+ goto exit;
+ }
+
+#if defined(VM_PFNMAP)
+ if ((psVMArea->vm_flags & VM_PFNMAP) == 0)
+#endif
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "OSAcquirePhysPageAddr: Region is VM_PFNMAP, but isn't marked as such"));
+ goto error;
+ }
+
+exit:
+ PVR_ASSERT(bMMapSemHeld);
+ up_read(&current->mm->mmap_sem);
+
+ /* Return the cookie */
+ *phOSWrapMem = (IMG_HANDLE)psInfo;
+
+ if (bHaveNoPageStructs)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "OSAcquirePhysPageAddr: Region contains pages which can't be locked down (no page structures)"));
+ }
+
+ PVR_ASSERT(psInfo->eType != 0);
+
+ return PVRSRV_OK;
+
+error:
+ if (bMMapSemHeld)
+ {
+ up_read(&current->mm->mmap_sem);
+ }
+ OSReleasePhysPageAddr((IMG_HANDLE)psInfo);
+
+ PVR_ASSERT(eError != PVRSRV_OK);
+
+ return eError;
+}
+
+typedef void (*InnerCacheOp_t)(const void *pvStart, const void *pvEnd);
+
+#if defined(__arm__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39))
+typedef void (*OuterCacheOp_t)(phys_addr_t uStart, phys_addr_t uEnd);
+#else
+typedef void (*OuterCacheOp_t)(unsigned long ulStart, unsigned long ulEnd);
+#endif
+
+#if defined(CONFIG_OUTER_CACHE)
+
+typedef IMG_BOOL (*MemAreaToPhys_t)(LinuxMemArea *psLinuxMemArea,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32PageNumOffset,
+ IMG_UINT32 ui32PageNum,
+ unsigned long *pulStart);
+
+static IMG_BOOL VMallocAreaToPhys(LinuxMemArea *psLinuxMemArea,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32PageNumOffset,
+ IMG_UINT32 ui32PageNum,
+ unsigned long *pulStart)
+{
+ *pulStart = vmalloc_to_pfn(pvRangeAddrStart + ui32PageNum * PAGE_SIZE) << PAGE_SHIFT;
+ return IMG_TRUE;
+}
+
+static IMG_BOOL ExternalKVAreaToPhys(LinuxMemArea *psLinuxMemArea,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32PageNumOffset,
+ IMG_UINT32 ui32PageNum,
+ unsigned long *pulStart)
+{
+ IMG_SYS_PHYADDR SysPAddr;
+ IMG_CPU_PHYADDR CpuPAddr;
+ SysPAddr = psLinuxMemArea->uData.sExternalKV.uPhysAddr.pSysPhysAddr[ui32PageNumOffset + ui32PageNum];
+ CpuPAddr = SysSysPAddrToCpuPAddr(SysPAddr);
+ *pulStart = CpuPAddr.uiAddr;
+ return IMG_TRUE;
+}
+
+static IMG_BOOL AllocPagesAreaToPhys(LinuxMemArea *psLinuxMemArea,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32PageNumOffset,
+ IMG_UINT32 ui32PageNum,
+ unsigned long *pulStart)
+{
+ struct page *pPage;
+
+ pPage = psLinuxMemArea->uData.sPageList.ppsPageList[ui32PageNumOffset + ui32PageNum];
+ *pulStart = page_to_pfn(pPage) << PAGE_SHIFT;
+ return IMG_TRUE;
+}
+
+static IMG_BOOL AllocPagesSparseAreaToPhys(LinuxMemArea *psLinuxMemArea,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32PageNumOffset,
+ IMG_UINT32 ui32PageNum,
+ unsigned long *pulStart)
+{
+ IMG_UINT32 ui32VirtOffset = (ui32PageNumOffset + ui32PageNum) << PAGE_SHIFT;
+ IMG_UINT32 ui32PhysOffset;
+ struct page *pPage;
+
+ if (BM_VirtOffsetToPhysical(psLinuxMemArea->hBMHandle, ui32VirtOffset, &ui32PhysOffset))
+ {
+ PVR_ASSERT(ui32PhysOffset <= ui32VirtOffset);
+ pPage = psLinuxMemArea->uData.sPageList.ppsPageList[ui32PhysOffset >> PAGE_SHIFT];
+ *pulStart = page_to_pfn(pPage) << PAGE_SHIFT;
+ return IMG_TRUE;
+ }
+
+ return IMG_FALSE;
+}
+
+
+static IMG_BOOL IONAreaToPhys(LinuxMemArea *psLinuxMemArea,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32PageNumOffset,
+ IMG_UINT32 ui32PageNum,
+ unsigned long *pulStart)
+{
+ IMG_CPU_PHYADDR CpuPAddr;
+ CpuPAddr = psLinuxMemArea->uData.sIONTilerAlloc.pCPUPhysAddrs[ui32PageNumOffset + ui32PageNum];
+ *pulStart = CpuPAddr.uiAddr;
+ return IMG_TRUE;
+}
+
+#endif /* defined(CONFIG_OUTER_CACHE) */
+
+/* g_sMMapMutex must be held while this function is called */
+
+static
+IMG_VOID *FindMMapBaseVAddr(struct list_head *psMMapOffsetStructList,
+ IMG_VOID *pvRangeAddrStart, IMG_UINT32 ui32Length)
+{
+ PKV_OFFSET_STRUCT psOffsetStruct;
+ IMG_VOID *pvMinVAddr;
+
+ /* There's no kernel-virtual for this type of allocation, so if
+ * we're flushing it, it must be user-virtual, and therefore
+ * have a mapping.
+ */
+ list_for_each_entry(psOffsetStruct, psMMapOffsetStructList, sAreaItem)
+ {
+ if(OSGetCurrentProcessIDKM() != psOffsetStruct->ui32PID)
+ continue;
+
+ pvMinVAddr = (IMG_VOID *)psOffsetStruct->ui32UserVAddr;
+
+ /* Within permissible range */
+ if(pvRangeAddrStart >= pvMinVAddr &&
+ ui32Length <= psOffsetStruct->ui32RealByteSize)
+ return pvMinVAddr;
+ }
+
+ return IMG_NULL;
+}
+
+extern PVRSRV_LINUX_MUTEX g_sMMapMutex;
+
+static inline void DoInnerCacheOp(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length,
+ InnerCacheOp_t pfnInnerCacheOp)
+{
+ LinuxMemArea *psLinuxMemArea = hOSMemHandle;
+
+ if (!psLinuxMemArea->hBMHandle)
+ {
+ pfnInnerCacheOp(pvRangeAddrStart, pvRangeAddrStart + ui32Length);
+ }
+ else
+ {
+ IMG_UINT32 ui32ByteRemain = ui32Length;
+ IMG_UINT32 ui32BytesToDo = PAGE_SIZE - (((IMG_UINT32) pvRangeAddrStart) & (~PAGE_MASK));
+ IMG_UINT8 *pbDo = (IMG_UINT8 *) pvRangeAddrStart;
+
+ while(ui32ByteRemain)
+ {
+ if (BM_MapPageAtOffset(psLinuxMemArea->hBMHandle, ui32ByteOffset + (ui32Length - ui32ByteRemain)))
+ {
+ pfnInnerCacheOp(pbDo, pbDo + ui32BytesToDo);
+ }
+ pbDo += ui32BytesToDo;
+ ui32ByteRemain -= ui32BytesToDo;
+ ui32BytesToDo = MIN(ui32ByteRemain, PAGE_SIZE);
+ }
+ }
+}
+
+static
+IMG_BOOL CheckExecuteCacheOp(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length,
+ InnerCacheOp_t pfnInnerCacheOp,
+ OuterCacheOp_t pfnOuterCacheOp)
+{
+ LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
+ IMG_UINT32 ui32AreaLength, ui32AreaOffset = 0;
+ struct list_head *psMMapOffsetStructList;
+ IMG_VOID *pvMinVAddr;
+
+#if defined(CONFIG_OUTER_CACHE)
+ MemAreaToPhys_t pfnMemAreaToPhys = IMG_NULL;
+ IMG_UINT32 ui32PageNumOffset = 0;
+#endif
+
+ PVR_ASSERT(psLinuxMemArea != IMG_NULL);
+
+ LinuxLockMutex(&g_sMMapMutex);
+
+ psMMapOffsetStructList = &psLinuxMemArea->sMMapOffsetStructList;
+ ui32AreaLength = psLinuxMemArea->ui32ByteSize;
+
+ /*
+ Don't check the length in the case of sparse mappings as
+ we only know the physical length not the virtual
+ */
+ if (!psLinuxMemArea->hBMHandle)
+ {
+ PVR_ASSERT(ui32Length <= ui32AreaLength);
+ }
+
+ if(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC)
+ {
+ ui32AreaOffset = psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset;
+ psLinuxMemArea = psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea;
+ }
+
+ /* Recursion surely isn't possible? */
+ PVR_ASSERT(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC);
+
+ switch(psLinuxMemArea->eAreaType)
+ {
+ case LINUX_MEM_AREA_VMALLOC:
+ {
+ if(is_vmalloc_addr(pvRangeAddrStart))
+ {
+ pvMinVAddr = psLinuxMemArea->uData.sVmalloc.pvVmallocAddress + ui32AreaOffset;
+
+ /* Outside permissible range */
+ if(pvRangeAddrStart < pvMinVAddr)
+ goto err_blocked;
+
+ DoInnerCacheOp(hOSMemHandle,
+ ui32ByteOffset,
+ pvRangeAddrStart,
+ ui32Length,
+ pfnInnerCacheOp);
+ }
+ else
+ {
+ /* If this isn't a vmalloc address, assume we're flushing by
+ * user-virtual. Compute the mmap base vaddr and use this to
+ * compute the offset in vmalloc space.
+ */
+
+ pvMinVAddr = FindMMapBaseVAddr(psMMapOffsetStructList,
+ pvRangeAddrStart, ui32Length);
+ if(!pvMinVAddr)
+ goto err_blocked;
+
+ DoInnerCacheOp(hOSMemHandle,
+ ui32ByteOffset,
+ pvRangeAddrStart,
+ ui32Length,
+ pfnInnerCacheOp);
+
+#if defined(CONFIG_OUTER_CACHE)
+ /*
+ * We don't need to worry about cache aliasing here because
+ * we have already flushed the virtually-indexed caches (L1
+ * etc.) by the supplied user-virtual addresses.
+ *
+ * The vmalloc address will only be used to determine
+ * affected physical pages for outer cache flushing.
+ */
+ pvRangeAddrStart = psLinuxMemArea->uData.sVmalloc.pvVmallocAddress +
+ (ui32AreaOffset & PAGE_MASK) + (pvRangeAddrStart - pvMinVAddr);
+ }
+
+ pfnMemAreaToPhys = VMallocAreaToPhys;
+#else /* defined(CONFIG_OUTER_CACHE) */
+ }
+#endif /* defined(CONFIG_OUTER_CACHE) */
+ break;
+ }
+
+ case LINUX_MEM_AREA_EXTERNAL_KV:
+ {
+ /* We'll only see bPhysContig for frame buffers, and we shouldn't
+ * be flushing those (they're write combined or uncached).
+ */
+ if (psLinuxMemArea->uData.sExternalKV.bPhysContig == IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s: Attempt to flush contiguous external memory", __func__));
+ goto err_blocked;
+ }
+
+ /* If it has a kernel virtual address, something odd has happened.
+ * We expect EXTERNAL_KV _only_ from the wrapping of ALLOC_PAGES.
+ */
+ if (psLinuxMemArea->uData.sExternalKV.pvExternalKV != IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s: Attempt to flush external memory with a kernel virtual address", __func__));
+ goto err_blocked;
+ }
+
+ pvMinVAddr = FindMMapBaseVAddr(psMMapOffsetStructList,
+ pvRangeAddrStart, ui32Length);
+ if(!pvMinVAddr)
+ goto err_blocked;
+
+ DoInnerCacheOp(hOSMemHandle,
+ ui32ByteOffset,
+ pvRangeAddrStart,
+ ui32Length,
+ pfnInnerCacheOp);
+
+#if defined(CONFIG_OUTER_CACHE)
+ ui32PageNumOffset = ((ui32AreaOffset & PAGE_MASK) + (pvRangeAddrStart - pvMinVAddr)) >> PAGE_SHIFT;
+ pfnMemAreaToPhys = ExternalKVAreaToPhys;
+#endif
+ break;
+ }
+
+ case LINUX_MEM_AREA_ION:
+ {
+ pvMinVAddr = FindMMapBaseVAddr(psMMapOffsetStructList,
+ pvRangeAddrStart, ui32Length);
+ if(!pvMinVAddr)
+ goto err_blocked;
+
+ DoInnerCacheOp(hOSMemHandle,
+ ui32ByteOffset,
+ pvRangeAddrStart,
+ ui32Length,
+ pfnInnerCacheOp);
+
+#if defined(CONFIG_OUTER_CACHE)
+ ui32PageNumOffset = ((ui32AreaOffset & PAGE_MASK) + (pvRangeAddrStart - pvMinVAddr)) >> PAGE_SHIFT;
+ pfnMemAreaToPhys = IONAreaToPhys;
+#endif
+ break;
+ }
+
+ case LINUX_MEM_AREA_ALLOC_PAGES:
+ {
+ pvMinVAddr = FindMMapBaseVAddr(psMMapOffsetStructList,
+ pvRangeAddrStart, ui32Length);
+ if(!pvMinVAddr)
+ goto err_blocked;
+
+ DoInnerCacheOp(hOSMemHandle,
+ ui32ByteOffset,
+ pvRangeAddrStart,
+ ui32Length,
+ pfnInnerCacheOp);
+
+#if defined(CONFIG_OUTER_CACHE)
+ ui32PageNumOffset = ((ui32AreaOffset & PAGE_MASK) + (pvRangeAddrStart - pvMinVAddr)) >> PAGE_SHIFT;
+ if (psLinuxMemArea->hBMHandle)
+ {
+ pfnMemAreaToPhys = AllocPagesSparseAreaToPhys;
+ }
+ else
+ {
+ pfnMemAreaToPhys = AllocPagesAreaToPhys;
+ }
+#endif
+ break;
+ }
+
+ default:
+ PVR_DBG_BREAK;
+ }
+
+ LinuxUnLockMutex(&g_sMMapMutex);
+
+#if defined(CONFIG_OUTER_CACHE)
+ PVR_ASSERT(pfnMemAreaToPhys != IMG_NULL);
+
+ /* Outer caches need some more work, to get a list of physical addresses */
+ {
+ unsigned long ulStart, ulEnd, ulLength, ulStartOffset, ulEndOffset;
+ IMG_UINT32 i, ui32NumPages;
+ IMG_BOOL bValidPage;
+
+ /* Length and offsets of flush region WRT page alignment */
+ ulLength = (unsigned long)ui32Length;
+ ulStartOffset = ((unsigned long)pvRangeAddrStart) & (PAGE_SIZE - 1);
+ ulEndOffset = ((unsigned long)pvRangeAddrStart + ulLength) & (PAGE_SIZE - 1);
+
+ /* The affected pages, rounded up */
+ ui32NumPages = (ulStartOffset + ulLength + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+ for(i = 0; i < ui32NumPages; i++)
+ {
+ bValidPage = pfnMemAreaToPhys(psLinuxMemArea, pvRangeAddrStart,
+ ui32PageNumOffset, i, &ulStart);
+ if (bValidPage)
+ {
+ ulEnd = ulStart + PAGE_SIZE;
+
+ if(i == ui32NumPages - 1 && ulEndOffset != 0)
+ ulEnd = ulStart + ulEndOffset;
+
+ if(i == 0)
+ ulStart += ulStartOffset;
+
+ pfnOuterCacheOp(ulStart, ulEnd);
+ }
+ }
+ }
+#endif
+
+ return IMG_TRUE;
+
+err_blocked:
+ PVR_DPF((PVR_DBG_WARNING, "%s: Blocked cache op on virtual range "
+ "%p-%p (type %d)", __func__,
+ pvRangeAddrStart, pvRangeAddrStart + ui32Length,
+ psLinuxMemArea->eAreaType));
+ LinuxUnLockMutex(&g_sMMapMutex);
+ return IMG_FALSE;
+}
+
+#if defined(__i386__)
+
+#define ROUND_UP(x,a) (((x) + (a) - 1) & ~((a) - 1))
+
+static void per_cpu_cache_flush(void *arg)
+{
+ PVR_UNREFERENCED_PARAMETER(arg);
+ wbinvd();
+}
+
+static void x86_flush_cache_range(const void *pvStart, const void *pvEnd)
+{
+ IMG_BYTE *pbStart = (IMG_BYTE *)pvStart;
+ IMG_BYTE *pbEnd = (IMG_BYTE *)pvEnd;
+ IMG_BYTE *pbBase;
+
+ pbEnd = (IMG_BYTE *)ROUND_UP((IMG_UINTPTR_T)pbEnd,
+ boot_cpu_data.x86_clflush_size);
+
+ mb();
+ for(pbBase = pbStart; pbBase < pbEnd; pbBase += boot_cpu_data.x86_clflush_size)
+ {
+ clflush(pbBase);
+ }
+ mb();
+}
+
+IMG_VOID OSCleanCPUCacheKM(IMG_VOID)
+{
+ /* No clean feature on x86 */
+ ON_EACH_CPU(per_cpu_cache_flush, NULL, 1);
+}
+
+IMG_VOID OSFlushCPUCacheKM(IMG_VOID)
+{
+ ON_EACH_CPU(per_cpu_cache_flush, NULL, 1);
+}
+
+IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ /* Write-back and invalidate */
+ return CheckExecuteCacheOp(hOSMemHandle, ui32ByteOffset, pvRangeAddrStart, ui32Length,
+ x86_flush_cache_range, IMG_NULL);
+}
+
+IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ /* No clean feature on x86 */
+ return CheckExecuteCacheOp(hOSMemHandle, ui32ByteOffset, pvRangeAddrStart, ui32Length,
+ x86_flush_cache_range, IMG_NULL);
+}
+
+IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ /* No invalidate-only support */
+ return CheckExecuteCacheOp(hOSMemHandle, ui32ByteOffset, pvRangeAddrStart, ui32Length,
+ x86_flush_cache_range, IMG_NULL);
+}
+
+#else /* defined(__i386__) */
+
+#if defined(__arm__)
+
+static void per_cpu_cache_flush(void *arg)
+{
+ PVR_UNREFERENCED_PARAMETER(arg);
+ flush_cache_all();
+}
+
+IMG_VOID OSCleanCPUCacheKM(IMG_VOID)
+{
+ /* No full (inner) cache clean op */
+ ON_EACH_CPU(per_cpu_cache_flush, NULL, 1);
+#if defined(CONFIG_OUTER_CACHE)
+ outer_clean_range(0, ULONG_MAX);
+#endif
+}
+
+IMG_VOID OSFlushCPUCacheKM(IMG_VOID)
+{
+ ON_EACH_CPU(per_cpu_cache_flush, NULL, 1);
+#if defined(CONFIG_OUTER_CACHE) && \
+ (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+ /* To use the "deferred flush" (not clean) DDK feature you need a kernel
+ * implementation of outer_flush_all() for ARM CPUs with an outer cache
+ * controller (e.g. PL310, common with Cortex A9 and later).
+ *
+ * Reference DDKs don't require this functionality, as they will only
+ * clean the cache, never flush (clean+invalidate) it.
+ */
+ outer_flush_all();
+#endif
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
+static inline size_t pvr_dmac_range_len(const void *pvStart, const void *pvEnd)
+{
+ return (size_t)((char *)pvEnd - (char *)pvStart);
+}
+#endif
+
+static void pvr_dmac_inv_range(const void *pvStart, const void *pvEnd)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34))
+ dmac_inv_range(pvStart, pvEnd);
+#else
+ dmac_map_area(pvStart, pvr_dmac_range_len(pvStart, pvEnd), DMA_FROM_DEVICE);
+#endif
+}
+
+static void pvr_dmac_clean_range(const void *pvStart, const void *pvEnd)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34))
+ dmac_clean_range(pvStart, pvEnd);
+#else
+ dmac_map_area(pvStart, pvr_dmac_range_len(pvStart, pvEnd), DMA_TO_DEVICE);
+#endif
+}
+
+IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ return CheckExecuteCacheOp(hOSMemHandle, ui32ByteOffset,
+ pvRangeAddrStart, ui32Length,
+ dmac_flush_range, outer_flush_range);
+}
+
+IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ return CheckExecuteCacheOp(hOSMemHandle, ui32ByteOffset,
+ pvRangeAddrStart, ui32Length,
+ pvr_dmac_clean_range, outer_clean_range);
+}
+
+IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ return CheckExecuteCacheOp(hOSMemHandle, ui32ByteOffset,
+ pvRangeAddrStart, ui32Length,
+ pvr_dmac_inv_range, outer_inv_range);
+}
+
+#else /* defined(__arm__) */
+
+#if defined(__mips__)
+/*
+ * dmac cache functions are supposed to be used for dma
+ * memory which comes from dma-able memory. However examining
+ * the implementation of dmac cache functions and experimenting,
+ * can assert that dmac functions are safe to use for high-mem
+ * memory as well for our OS{Clean/Flush/Invalidate}Cache functions
+ *
+ */
+
+IMG_VOID OSCleanCPUCacheKM(IMG_VOID)
+{
+ /* dmac functions flush full cache if size is larger than
+ * p-cache size. This is a workaround for the fact that
+ * __flush_cache_all is not an exported symbol. Please
+ * replace with custom function if available in latest
+ * version of linux being used.
+ * Arbitrary large number (1MB) which should be larger than
+ * mips p-cache sizes for some time in future.
+ * */
+ dma_cache_wback(0, 0x100000);
+}
+
+IMG_VOID OSFlushCPUCacheKM(IMG_VOID)
+{
+ /* dmac functions flush full cache if size is larger than
+ * p-cache size. This is a workaround for the fact that
+ * __flush_cache_all is not an exported symbol. Please
+ * replace with custom function if available in latest
+ * version of linux being used.
+ * Arbitrary large number (1MB) which should be larger than
+ * mips p-cache sizes for some time in future.
+ * */
+ dma_cache_wback_inv(0, 0x100000);
+}
+
+static inline IMG_UINT32 pvr_dma_range_len(const void *pvStart, const void *pvEnd)
+{
+ return (IMG_UINT32)((char *)pvEnd - (char *)pvStart);
+}
+
+static void pvr_dma_cache_wback_inv(const void *pvStart, const void *pvEnd)
+{
+ dma_cache_wback_inv((IMG_UINTPTR_T)pvStart, pvr_dma_range_len(pvStart, pvEnd));
+}
+
+static void pvr_dma_cache_wback(const void *pvStart, const void *pvEnd)
+{
+ dma_cache_wback((IMG_UINTPTR_T)pvStart, pvr_dma_range_len(pvStart, pvEnd));
+}
+
+static void pvr_dma_cache_inv(const void *pvStart, const void *pvEnd)
+{
+ dma_cache_inv((IMG_UINTPTR_T)pvStart, pvr_dma_range_len(pvStart, pvEnd));
+}
+
+IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ return CheckExecuteCacheOp(hOSMemHandle, ui32ByteOffset,
+ pvRangeAddrStart, ui32Length,
+ pvr_dma_cache_wback_inv, IMG_NULL);
+}
+
+IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ return CheckExecuteCacheOp(hOSMemHandle, ui32ByteOffset,
+ pvRangeAddrStart, ui32Length,
+ pvr_dma_cache_wback, IMG_NULL);
+}
+
+IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ return CheckExecuteCacheOp(hOSMemHandle, ui32ByteOffset,
+ pvRangeAddrStart, ui32Length,
+ pvr_dma_cache_inv, IMG_NULL);
+}
+
+#else /* defined(__mips__) */
+
+#error "Implement CPU cache flush/clean/invalidate primitives for this CPU!"
+
+#endif /* defined(__mips__) */
+
+#endif /* defined(__arm__) */
+
+#endif /* defined(__i386__) */
+
+typedef struct _AtomicStruct
+{
+ atomic_t RefCount;
+} AtomicStruct;
+
+PVRSRV_ERROR OSAtomicAlloc(IMG_PVOID *ppvRefCount)
+{
+ AtomicStruct *psRefCount;
+
+ psRefCount = kmalloc(sizeof(AtomicStruct), GFP_KERNEL);
+ if (psRefCount == NULL)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ atomic_set(&psRefCount->RefCount, 0);
+
+ *ppvRefCount = psRefCount;
+ return PVRSRV_OK;
+}
+
+IMG_VOID OSAtomicFree(IMG_PVOID pvRefCount)
+{
+ AtomicStruct *psRefCount = pvRefCount;
+
+ PVR_ASSERT(atomic_read(&psRefCount->RefCount) == 0);
+ kfree(psRefCount);
+}
+
+IMG_VOID OSAtomicInc(IMG_PVOID pvRefCount)
+{
+ AtomicStruct *psRefCount = pvRefCount;
+
+ atomic_inc(&psRefCount->RefCount);
+}
+
+IMG_BOOL OSAtomicDecAndTest(IMG_PVOID pvRefCount)
+{
+ AtomicStruct *psRefCount = pvRefCount;
+
+ return atomic_dec_and_test(&psRefCount->RefCount) ? IMG_TRUE:IMG_FALSE;
+}
+
+IMG_UINT32 OSAtomicRead(IMG_PVOID pvRefCount)
+{
+ AtomicStruct *psRefCount = pvRefCount;
+
+ return (IMG_UINT32) atomic_read(&psRefCount->RefCount);
+}
+
+IMG_VOID OSReleaseBridgeLock(IMG_VOID)
+{
+ LinuxUnLockMutex(&gPVRSRVLock);
+}
+
+IMG_VOID OSReacquireBridgeLock(IMG_VOID)
+{
+ LinuxLockMutex(&gPVRSRVLock);
+}
+
+typedef struct _OSTime
+{
+ unsigned long ulTime;
+} OSTime;
+
+PVRSRV_ERROR OSTimeCreateWithUSOffset(IMG_PVOID *pvRet, IMG_UINT32 ui32USOffset)
+{
+ OSTime *psOSTime;
+
+ psOSTime = kmalloc(sizeof(OSTime), GFP_KERNEL);
+ if (psOSTime == IMG_NULL)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ psOSTime->ulTime = usecs_to_jiffies(jiffies_to_usecs(jiffies) + ui32USOffset);
+ *pvRet = psOSTime;
+ return PVRSRV_OK;
+}
+
+
+IMG_BOOL OSTimeHasTimePassed(IMG_PVOID pvData)
+{
+ OSTime *psOSTime = pvData;
+
+ if (time_is_before_jiffies(psOSTime->ulTime))
+ {
+ return IMG_TRUE;
+ }
+ return IMG_FALSE;
+}
+
+IMG_VOID OSTimeDestroy(IMG_PVOID pvData)
+{
+ kfree(pvData);
+}
+
+IMG_VOID OSGetCurrentProcessNameKM(IMG_CHAR *pszName, IMG_UINT32 ui32Size)
+{
+ strncpy(pszName, current->comm, MIN(ui32Size,TASK_COMM_LEN));
+}
+
+/* One time osfunc initialisation */
+PVRSRV_ERROR PVROSFuncInit(IMG_VOID)
+{
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+ {
+ psTimerWorkQueue = create_workqueue("pvr_timer");
+ if (psTimerWorkQueue == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: couldn't create timer workqueue", __FUNCTION__));
+ return PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD;
+
+ }
+ }
+#endif
+
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
+ {
+ IMG_UINT32 ui32i;
+
+ for (ui32i = 0; ui32i < OS_MAX_TIMERS; ui32i++)
+ {
+ TIMER_CALLBACK_DATA *psTimerCBData = &sTimers[ui32i];
+
+ INIT_WORK(&psTimerCBData->sWork, OSTimerWorkQueueCallBack);
+ }
+ }
+#endif
+
+#if defined (SUPPORT_ION)
+ {
+ PVRSRV_ERROR eError;
+
+ eError = IonInit();
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: IonInit failed", __FUNCTION__));
+ }
+ }
+#endif
+ return PVRSRV_OK;
+}
+
+/*
+ * Osfunc deinitialisation.
+ * Note that PVROSFuncInit may not have been called
+ */
+IMG_VOID PVROSFuncDeInit(IMG_VOID)
+{
+#if defined (SUPPORT_ION)
+ IonDeinit();
+#endif
+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES)
+ if (psTimerWorkQueue != NULL)
+ {
+ destroy_workqueue(psTimerWorkQueue);
+ }
+#endif
+}
diff --git a/pvr-source/services4/srvkm/env/linux/osperproc.c b/pvr-source/services4/srvkm/env/linux/osperproc.c
new file mode 100644
index 0000000..a22b461
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/osperproc.c
@@ -0,0 +1,146 @@
+/*************************************************************************/ /*!
+@Title Linux specific per process data functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "services_headers.h"
+#include "osperproc.h"
+
+#include "env_perproc.h"
+#include "proc.h"
+#if defined (SUPPORT_ION)
+#include "linux/ion.h"
+
+extern struct ion_device *psIonDev;
+#endif
+extern IMG_UINT32 gui32ReleasePID;
+
+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,
+ "Environment per Process Data");
+
+ 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;
+
+ /* Linux specific mmap processing */
+ LinuxMMapPerProcessConnect(psEnvPerProc);
+
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+ /* Linked list of PVRSRV_FILE_PRIVATE_DATA structures */
+ INIT_LIST_HEAD(&psEnvPerProc->sDRMAuthListHead);
+#endif
+#if defined(SUPPORT_ION)
+ OSSNPrintf(psEnvPerProc->azIonClientName, ION_CLIENT_NAME_SIZE, "pvr_ion_client-%d", OSGetCurrentProcessIDKM());
+ psEnvPerProc->psIONClient =
+ ion_client_create(psIonDev,
+ 1 << ION_HEAP_TYPE_SYSTEM_CONTIG |
+ 1 << ION_HEAP_TYPE_SYSTEM,
+ psEnvPerProc->azIonClientName);
+
+ if (IS_ERR_OR_NULL(psEnvPerProc->psIONClient))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "OSPerProcessPrivateDataInit: Couldn't create "
+ "ion client for per process data"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+#endif /* SUPPORT_ION */
+ 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;
+
+ /* Linux specific mmap processing */
+ LinuxMMapPerProcessDisconnect(psEnvPerProc);
+
+ /* Remove per process /proc entries */
+ RemovePerProcessProcDir(psEnvPerProc);
+
+ eError = OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+ sizeof(PVRSRV_ENV_PER_PROCESS_DATA),
+ hOsPrivateData,
+ psEnvPerProc->hBlockAlloc);
+ /*not nulling pointer, copy on stack*/
+
+ 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);
+}
+
+IMG_HANDLE LinuxTerminatingProcessPrivateData(IMG_VOID)
+{
+ if(!gui32ReleasePID)
+ return NULL;
+ return PVRSRVPerProcessPrivateData(gui32ReleasePID);
+}
diff --git a/pvr-source/services4/srvkm/env/linux/pdump.c b/pvr-source/services4/srvkm/env/linux/pdump.c
new file mode 100644
index 0000000..0124737
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/pdump.c
@@ -0,0 +1,804 @@
+/*************************************************************************/ /*!
+@Title Parameter dump macro target routines
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if defined (SUPPORT_SGX) || defined (SUPPORT_VGX)
+#if defined (PDUMP)
+
+#include <asm/atomic.h>
+#include <stdarg.h>
+#if defined (SUPPORT_SGX)
+#include "sgxdefs.h" /* Is this still needed? */
+#endif
+#include "services_headers.h"
+
+#include "pvrversion.h"
+#include "pvr_debug.h"
+
+#include "dbgdrvif.h"
+#if defined (SUPPORT_SGX)
+#include "sgxmmu.h"/* Is this still needed? */
+#endif
+#include "mm.h"
+#include "pdump_km.h"
+#include "pdump_int.h"
+
+#include <linux/kernel.h> // sprintf
+#include <linux/string.h> // strncpy, strlen
+
+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_VOID DbgSetMarker (PDBG_STREAM psStream, IMG_UINT32 ui32Marker);
+
+#define PDUMP_DATAMASTER_PIXEL (1)
+#define PDUMP_DATAMASTER_EDM (3)
+
+/*
+ Maximum file size to split output files
+*/
+#define MAX_FILE_SIZE 0x40000000
+
+static atomic_t gsPDumpSuspended = ATOMIC_INIT(0);
+
+static PDBGKM_SERVICE_TABLE gpfnDbgDrv = IMG_NULL;
+
+
+
+IMG_CHAR *pszStreamName[PDUMP_NUM_STREAMS] = { "ParamStream2",
+ "ScriptStream2",
+ "DriverInfoStream"};
+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
+
+
+
+
+static inline IMG_BOOL PDumpSuspended(IMG_VOID)
+{
+ return (atomic_read(&gsPDumpSuspended) != 0) ? IMG_TRUE : IMG_FALSE;
+}
+
+/*!
+ * \name PDumpOSGetScriptString
+ */
+PVRSRV_ERROR PDumpOSGetScriptString(IMG_HANDLE *phScript,
+ IMG_UINT32 *pui32MaxLen)
+{
+ *phScript = (IMG_HANDLE)gsDBGPdumpState.pszScript;
+ *pui32MaxLen = SZ_SCRIPT_SIZE_MAX;
+ if ((!*phScript) || PDumpSuspended())
+ {
+ return PVRSRV_ERROR_PDUMP_NOT_ACTIVE;
+ }
+ return PVRSRV_OK;
+}
+
+/*!
+ * \name PDumpOSGetMessageString
+ */
+PVRSRV_ERROR PDumpOSGetMessageString(IMG_CHAR **ppszMsg,
+ IMG_UINT32 *pui32MaxLen)
+{
+ *ppszMsg = gsDBGPdumpState.pszMsg;
+ *pui32MaxLen = SZ_MSG_SIZE_MAX;
+ if ((!*ppszMsg) || PDumpSuspended())
+ {
+ return PVRSRV_ERROR_PDUMP_NOT_ACTIVE;
+ }
+ return PVRSRV_OK;
+}
+
+/*!
+ * \name PDumpOSGetFilenameString
+ */
+PVRSRV_ERROR PDumpOSGetFilenameString(IMG_CHAR **ppszFile,
+ IMG_UINT32 *pui32MaxLen)
+{
+ *ppszFile = gsDBGPdumpState.pszFile;
+ *pui32MaxLen = SZ_FILENAME_SIZE_MAX;
+ if ((!*ppszFile) || PDumpSuspended())
+ {
+ return PVRSRV_ERROR_PDUMP_NOT_ACTIVE;
+ }
+ return PVRSRV_OK;
+}
+
+/*!
+ * \name PDumpOSWriteString2
+ */
+IMG_BOOL PDumpOSWriteString2(IMG_HANDLE hScript, IMG_UINT32 ui32Flags)
+{
+ return PDumpWriteString2(hScript, ui32Flags);
+}
+
+/*!
+ * \name PDumpOSBufprintf
+ */
+PVRSRV_ERROR PDumpOSBufprintf(IMG_HANDLE hBuf, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, ...)
+{
+ IMG_CHAR* pszBuf = hBuf;
+ IMG_INT32 n;
+ va_list vaArgs;
+
+ va_start(vaArgs, pszFormat);
+
+ n = vsnprintf(pszBuf, ui32ScriptSizeMax, pszFormat, vaArgs);
+
+ va_end(vaArgs);
+
+ if (n>=(IMG_INT32)ui32ScriptSizeMax || n==-1) /* glibc >= 2.1 or glibc 2.0 */
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete."));
+
+ return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW;
+ }
+
+#if defined(PDUMP_DEBUG_OUTFILES)
+ g_ui32EveryLineCounter++;
+#endif
+ return PVRSRV_OK;
+}
+
+/*!
+ * \name PDumpOSVSprintf
+ */
+PVRSRV_ERROR PDumpOSVSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, PDUMP_va_list vaArgs)
+{
+ IMG_INT32 n;
+
+ n = vsnprintf(pszComment, ui32ScriptSizeMax, pszFormat, vaArgs);
+
+ if (n>=(IMG_INT32)ui32ScriptSizeMax || n==-1) /* glibc >= 2.1 or glibc 2.0 */
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete."));
+
+ return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW;
+ }
+
+ return PVRSRV_OK;
+}
+
+/*!
+ * \name PDumpOSDebugPrintf
+ */
+IMG_VOID PDumpOSDebugPrintf(IMG_CHAR* pszFormat, ...)
+{
+ PVR_UNREFERENCED_PARAMETER(pszFormat);
+
+ /* FIXME: Implement using services PVR_DBG or otherwise with kprintf */
+}
+
+/*!
+ * \name PDumpOSSprintf
+ */
+PVRSRV_ERROR PDumpOSSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR *pszFormat, ...)
+{
+ IMG_INT32 n;
+ va_list vaArgs;
+
+ va_start(vaArgs, pszFormat);
+
+ n = vsnprintf(pszComment, ui32ScriptSizeMax, pszFormat, vaArgs);
+
+ va_end(vaArgs);
+
+ if (n>=(IMG_INT32)ui32ScriptSizeMax || n==-1) /* glibc >= 2.1 or glibc 2.0 */
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete."));
+
+ return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW;
+ }
+
+ return PVRSRV_OK;
+}
+
+/*!
+ * \name PDumpOSBuflen
+ */
+IMG_UINT32 PDumpOSBuflen(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax)
+{
+ IMG_CHAR* pszBuf = hBuffer;
+ IMG_UINT32 ui32Count = 0;
+
+ while ((pszBuf[ui32Count]!=0) && (ui32Count<ui32BufferSizeMax) )
+ {
+ ui32Count++;
+ }
+ return(ui32Count);
+}
+
+/*!
+ * \name PDumpOSVerifyLineEnding
+ */
+IMG_VOID PDumpOSVerifyLineEnding(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax)
+{
+ IMG_UINT32 ui32Count;
+ IMG_CHAR* pszBuf = hBuffer;
+
+ /* strlen */
+ ui32Count = PDumpOSBuflen(hBuffer, ui32BufferSizeMax);
+
+ /* Put \r \n sequence at the end if it isn't already there */
+ if ((ui32Count >= 1) && (pszBuf[ui32Count-1] != '\n') && (ui32Count<ui32BufferSizeMax))
+ {
+ pszBuf[ui32Count] = '\n';
+ ui32Count++;
+ pszBuf[ui32Count] = '\0';
+ }
+ if ((ui32Count >= 2) && (pszBuf[ui32Count-2] != '\r') && (ui32Count<ui32BufferSizeMax))
+ {
+ pszBuf[ui32Count-1] = '\r';
+ pszBuf[ui32Count] = '\n';
+ ui32Count++;
+ pszBuf[ui32Count] = '\0';
+ }
+}
+
+/*!
+ * \name PDumpOSGetStream
+ */
+IMG_HANDLE PDumpOSGetStream(IMG_UINT32 ePDumpStream)
+{
+ return (IMG_HANDLE)gsDBGPdumpState.psStream[ePDumpStream];
+}
+
+/*!
+ * \name PDumpOSGetStreamOffset
+ */
+IMG_UINT32 PDumpOSGetStreamOffset(IMG_UINT32 ePDumpStream)
+{
+ PDBG_STREAM psStream = gsDBGPdumpState.psStream[ePDumpStream];
+ return gpfnDbgDrv->pfnGetStreamOffset(psStream);
+}
+
+/*!
+ * \name PDumpOSGetParamFileNum
+ */
+IMG_UINT32 PDumpOSGetParamFileNum(IMG_VOID)
+{
+ return gsDBGPdumpState.ui32ParamFileNum;
+}
+
+/*!
+ * \name PDumpOSWriteString
+ */
+IMG_BOOL PDumpOSWriteString(IMG_HANDLE hStream,
+ IMG_UINT8 *psui8Data,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32Flags)
+{
+ PDBG_STREAM psStream = (PDBG_STREAM)hStream;
+ return PDumpWriteILock(psStream,
+ psui8Data,
+ ui32Size,
+ ui32Flags);
+}
+
+/*!
+ * \name PDumpOSCheckForSplitting
+ */
+IMG_VOID PDumpOSCheckForSplitting(IMG_HANDLE hStream, IMG_UINT32 ui32Size, IMG_UINT32 ui32Flags)
+{
+ /* File size limit not implemented for this OS.
+ */
+ PVR_UNREFERENCED_PARAMETER(hStream);
+ PVR_UNREFERENCED_PARAMETER(ui32Size);
+ PVR_UNREFERENCED_PARAMETER(ui32Flags);
+}
+
+/*!
+ * \name PDumpOSJTInitialised
+ */
+IMG_BOOL PDumpOSJTInitialised(IMG_VOID)
+{
+ if(gpfnDbgDrv)
+ {
+ return IMG_TRUE;
+ }
+ return IMG_FALSE;
+}
+
+/*!
+ * \name PDumpOSIsSuspended
+ */
+inline IMG_BOOL PDumpOSIsSuspended(IMG_VOID)
+{
+ return (atomic_read(&gsPDumpSuspended) != 0) ? IMG_TRUE : IMG_FALSE;
+}
+
+/*!
+ * \name PDumpOSCPUVAddrToDevPAddr
+ */
+IMG_VOID PDumpOSCPUVAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType,
+ IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32Offset,
+ IMG_UINT8 *pui8LinAddr,
+ IMG_UINT32 ui32PageSize,
+ IMG_DEV_PHYADDR *psDevPAddr)
+{
+ IMG_CPU_PHYADDR sCpuPAddr;
+
+ PVR_UNREFERENCED_PARAMETER(pui8LinAddr);
+ PVR_UNREFERENCED_PARAMETER(ui32PageSize); /* for when no assert */
+
+ /* Caller must now alway supply hOSMemHandle, even though we only (presently)
+ use it here in the linux implementation */
+
+ PVR_ASSERT (hOSMemHandle != IMG_NULL);
+
+ sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset);
+ PVR_ASSERT((sCpuPAddr.uiAddr & (ui32PageSize - 1)) == 0);
+
+ /* convert CPU physical addr to device physical */
+ *psDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
+}
+
+/*!
+ * \name PDumpOSCPUVAddrToPhysPages
+ */
+IMG_VOID PDumpOSCPUVAddrToPhysPages(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32Offset,
+ IMG_PUINT8 pui8LinAddr,
+ IMG_UINT32 ui32DataPageMask,
+ IMG_UINT32 *pui32PageOffset)
+{
+ if(hOSMemHandle)
+ {
+ /*
+ * If a Services memory handle is provided then use it.
+ */
+ IMG_CPU_PHYADDR sCpuPAddr;
+
+ PVR_UNREFERENCED_PARAMETER(pui8LinAddr);
+
+ sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset);
+ *pui32PageOffset = sCpuPAddr.uiAddr & ui32DataPageMask;
+ }
+ else
+ {
+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+ PVR_UNREFERENCED_PARAMETER(ui32Offset);
+
+ *pui32PageOffset = ((IMG_UINT32)pui8LinAddr & ui32DataPageMask);
+ }
+}
+
+/*!
+ * \name PDumpOSDebugDriverWrite
+ */
+IMG_UINT32 PDumpOSDebugDriverWrite( PDBG_STREAM psStream,
+ PDUMP_DDWMODE eDbgDrvWriteMode,
+ IMG_UINT8 *pui8Data,
+ IMG_UINT32 ui32BCount,
+ IMG_UINT32 ui32Level,
+ IMG_UINT32 ui32DbgDrvFlags)
+{
+ switch(eDbgDrvWriteMode)
+ {
+ case PDUMP_WRITE_MODE_CONTINUOUS:
+ PVR_UNREFERENCED_PARAMETER(ui32DbgDrvFlags);
+ return gpfnDbgDrv->pfnDBGDrivWrite2(psStream, pui8Data, ui32BCount, ui32Level);
+ case PDUMP_WRITE_MODE_LASTFRAME:
+ return gpfnDbgDrv->pfnWriteLF(psStream, pui8Data, ui32BCount, ui32Level, ui32DbgDrvFlags);
+ case PDUMP_WRITE_MODE_BINCM:
+ PVR_UNREFERENCED_PARAMETER(ui32DbgDrvFlags);
+ return gpfnDbgDrv->pfnWriteBINCM(psStream, pui8Data, ui32BCount, ui32Level);
+ case PDUMP_WRITE_MODE_PERSISTENT:
+ PVR_UNREFERENCED_PARAMETER(ui32DbgDrvFlags);
+ return gpfnDbgDrv->pfnWritePersist(psStream, pui8Data, ui32BCount, ui32Level);
+ default:
+ PVR_UNREFERENCED_PARAMETER(ui32DbgDrvFlags);
+ break;
+ }
+ return 0xFFFFFFFFU;
+}
+
+/*!
+ * \name PDumpOSReleaseExecution
+ */
+IMG_VOID PDumpOSReleaseExecution(IMG_VOID)
+{
+ OSReleaseThreadQuanta();
+}
+
+/**************************************************************************
+ * Function Name : PDumpInit
+ * Outputs : None
+ * Returns :
+ * Description : Reset connection to vldbgdrv
+ * Then try to connect to PDUMP streams
+**************************************************************************/
+IMG_VOID PDumpInit(IMG_VOID)
+{
+ IMG_UINT32 i;
+ DBGKM_CONNECT_NOTIFIER sConnectNotifier;
+
+ /* If we tried this earlier, then we might have connected to the driver
+ * But if pdump.exe was running then the stream connected would fail
+ */
+ if (!gpfnDbgDrv)
+ {
+ DBGDrvGetServiceTable(&gpfnDbgDrv);
+
+
+ // If something failed then no point in trying to connect streams
+ if (gpfnDbgDrv == IMG_NULL)
+ {
+ return;
+ }
+
+ /*
+ * Pass the connection notify callback
+ */
+ sConnectNotifier.pfnConnectNotifier = &PDumpConnectionNotify;
+ gpfnDbgDrv->pfnSetConnectNotifier(sConnectNotifier);
+
+ if(!gsDBGPdumpState.pszFile)
+ {
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszFile, 0,
+ "Filename string") != PVRSRV_OK)
+ {
+ goto init_failed;
+ }
+ }
+
+ if(!gsDBGPdumpState.pszMsg)
+ {
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszMsg, 0,
+ "Message string") != PVRSRV_OK)
+ {
+ goto init_failed;
+ }
+ }
+
+ if(!gsDBGPdumpState.pszScript)
+ {
+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszScript, 0,
+ "Script string") != 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_FAMILY);
+ 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;
+ }
+
+ /*
+ * Remove the connection notify callback
+ */
+ sConnectNotifier.pfnConnectNotifier = 0;
+ gpfnDbgDrv->pfnSetConnectNotifier(sConnectNotifier);
+
+ gpfnDbgDrv = IMG_NULL;
+}
+
+
+IMG_VOID PDumpDeInit(IMG_VOID)
+{
+ IMG_UINT32 i;
+ DBGKM_CONNECT_NOTIFIER sConnectNotifier;
+
+ 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;
+ }
+
+ /*
+ * Remove the connection notify callback
+ */
+ sConnectNotifier.pfnConnectNotifier = 0;
+ gpfnDbgDrv->pfnSetConnectNotifier(sConnectNotifier);
+
+ gpfnDbgDrv = IMG_NULL;
+}
+
+/**************************************************************************
+ * Function Name : PDumpStartInitPhaseKM
+ * Inputs : None
+ * Outputs : None
+ * Returns : None
+ * Description : Resume init phase state
+**************************************************************************/
+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;
+}
+
+/**************************************************************************
+ * Function Name : PDumpStopInitPhaseKM
+ * Inputs : None
+ * Outputs : None
+ * Returns : None
+ * Description : End init phase state
+**************************************************************************/
+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;
+}
+
+/**************************************************************************
+ * Function Name : PDumpIsLastCaptureFrameKM
+ * Inputs : None
+ * Outputs : None
+ * Returns : True or false
+ * Description : Tests whether the current frame is being pdumped
+**************************************************************************/
+IMG_BOOL PDumpIsLastCaptureFrameKM(IMG_VOID)
+{
+ return gpfnDbgDrv->pfnIsLastCaptureFrame(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2]);
+}
+
+
+/**************************************************************************
+ * Function Name : PDumpIsCaptureFrameKM
+ * Inputs : None
+ * Outputs : None
+ * Returns : True or false
+ * Description : Tests whether the current frame is being pdumped
+**************************************************************************/
+IMG_BOOL PDumpOSIsCaptureFrameKM(IMG_VOID)
+{
+ if (PDumpSuspended())
+ {
+ return IMG_FALSE;
+ }
+ return gpfnDbgDrv->pfnIsCaptureFrame(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2], IMG_FALSE);
+}
+
+/**************************************************************************
+ * Function Name : PDumpSetFrameKM
+ * Inputs : None
+ * Outputs : None
+ * Returns : None
+ * Description : Sets a frame
+**************************************************************************/
+PVRSRV_ERROR PDumpOSSetFrameKM(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;
+}
+
+
+/*****************************************************************************
+ FUNCTION : PDumpWriteString2
+
+ PURPOSE :
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_BOOL PDumpWriteString2(IMG_CHAR * pszString, IMG_UINT32 ui32Flags)
+{
+ return PDumpWriteILock(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2], (IMG_UINT8 *) pszString, strlen(pszString), ui32Flags);
+}
+
+
+/*****************************************************************************
+ FUNCTION : PDumpWriteILock
+
+ PURPOSE : Writes, making sure it all goes...
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_BOOL PDumpWriteILock(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32Count, IMG_UINT32 ui32Flags)
+{
+ IMG_UINT32 ui32Written = 0;
+ if ((psStream == IMG_NULL) || PDumpSuspended() || ((ui32Flags & PDUMP_FLAGS_NEVER) != 0))
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "PDumpWriteILock: Failed to write 0x%x bytes to stream 0x%x", ui32Count, (IMG_UINT32)psStream));
+ return IMG_TRUE;
+ }
+
+
+ /*
+ Set the stream marker to split output files
+ */
+
+ 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++;
+ }
+ }
+ }
+
+ ui32Written = DbgWrite(psStream, pui8Data, ui32Count, ui32Flags);
+
+ if (ui32Written == 0xFFFFFFFF)
+ {
+ return IMG_FALSE;
+ }
+
+ return IMG_TRUE;
+}
+
+/*****************************************************************************
+ FUNCTION : DbgSetFrame
+
+ PURPOSE : Sets the frame in the stream
+
+ PARAMETERS : psStream - Stream pointer
+ ui32Frame - Frame number to set
+
+ RETURNS : None
+*****************************************************************************/
+static IMG_VOID DbgSetFrame(PDBG_STREAM psStream, IMG_UINT32 ui32Frame)
+{
+ gpfnDbgDrv->pfnSetFrame(psStream, ui32Frame);
+}
+
+/*****************************************************************************
+ FUNCTION : DbgSetMarker
+
+ PURPOSE : Sets the marker of the stream to split output files
+
+ PARAMETERS : psStream - Stream pointer
+ ui32Marker - Marker number to set
+
+ RETURNS : None
+*****************************************************************************/
+static IMG_VOID DbgSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker)
+{
+ gpfnDbgDrv->pfnSetMarker(psStream, ui32Marker);
+}
+
+IMG_VOID PDumpSuspendKM(IMG_VOID)
+{
+ atomic_inc(&gsPDumpSuspended);
+}
+
+IMG_VOID PDumpResumeKM(IMG_VOID)
+{
+ atomic_dec(&gsPDumpSuspended);
+}
+
+#endif /* #if defined (PDUMP) */
+#endif /* #if defined (SUPPORT_SGX) */
+/*****************************************************************************
+ End of file (PDUMP.C)
+*****************************************************************************/
diff --git a/pvr-source/services4/srvkm/env/linux/private_data.h b/pvr-source/services4/srvkm/env/linux/private_data.h
new file mode 100644
index 0000000..6b09705
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/private_data.h
@@ -0,0 +1,95 @@
+/*************************************************************************/ /*!
+@Title Linux private data structure
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __INCLUDED_PRIVATE_DATA_H_
+#define __INCLUDED_PRIVATE_DATA_H_
+
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+#include <linux/list.h>
+#include <drm/drmP.h>
+#endif
+
+/* This structure is required in the rare case that a process creates
+ * a connection to services, but before closing the file descriptor,
+ * does a fork(). This fork() will duplicate the file descriptor in the
+ * child process. If the parent process dies before the child, this can
+ * cause the PVRSRVRelease() method to be called in a different process
+ * context than the original PVRSRVOpen(). This is bad because we need
+ * to update the per-process data reference count and/or free the
+ * per-process data. So we must keep a record of which PID's per-process
+ * data to inspect during ->release().
+ */
+
+typedef struct
+{
+ /* PID that created this services connection */
+ IMG_UINT32 ui32OpenPID;
+
+ /* Global kernel MemInfo handle */
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hKernelMemInfo;
+#else
+ IMG_HANDLE hKernelMemInfo;
+#endif
+
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+ /* The private data is on a list in the per-process data structure */
+ struct list_head sDRMAuthListItem;
+
+ struct drm_file *psDRMFile;
+#endif
+
+#if defined(SUPPORT_MEMINFO_IDS)
+ /* Globally unique "stamp" for kernel MemInfo */
+ IMG_UINT64 ui64Stamp;
+#endif /* defined(SUPPORT_MEMINFO_IDS) */
+
+ /* Accounting for OSAllocMem */
+ IMG_HANDLE hBlockAlloc;
+
+#if defined(SUPPORT_DRI_DRM_EXT)
+ IMG_PVOID pPriv; /*private data for extending this struct*/
+#endif
+}
+PVRSRV_FILE_PRIVATE_DATA;
+
+#endif /* __INCLUDED_PRIVATE_DATA_H_ */
+
diff --git a/pvr-source/services4/srvkm/env/linux/proc.c b/pvr-source/services4/srvkm/env/linux/proc.c
new file mode 100644
index 0000000..7307257
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/proc.c
@@ -0,0 +1,1414 @@
+/*************************************************************************/ /*!
+@Title Proc files implementation.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Functions for creating and reading proc filesystem entries.
+ Proc filesystem support must be built into the kernel for
+ these functions to be any use.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/sched.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"
+
+#include "lists.h"
+
+// The proc entry for our /proc/pvr directory
+static struct proc_dir_entry * dir;
+
+static const IMG_CHAR PVRProcDirRoot[] = "pvr";
+
+static IMG_INT pvr_proc_open(struct inode *inode,struct file *file);
+static void *pvr_proc_seq_start (struct seq_file *m, loff_t *pos);
+static void pvr_proc_seq_stop (struct seq_file *m, void *v);
+static void *pvr_proc_seq_next (struct seq_file *m, void *v, loff_t *pos);
+static int pvr_proc_seq_show (struct seq_file *m, void *v);
+static ssize_t pvr_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos);
+
+static struct file_operations pvr_proc_operations =
+{
+ .open = pvr_proc_open,
+ .read = seq_read,
+ .write = pvr_proc_write,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static struct seq_operations pvr_proc_seq_operations =
+{
+ .start = pvr_proc_seq_start,
+ .next = pvr_proc_seq_next,
+ .stop = pvr_proc_seq_stop,
+ .show = pvr_proc_seq_show,
+};
+
+static struct proc_dir_entry* g_pProcQueue;
+static struct proc_dir_entry* g_pProcVersion;
+static struct proc_dir_entry* g_pProcSysNodes;
+
+#ifdef DEBUG
+static struct proc_dir_entry* g_pProcDebugLevel;
+#endif
+
+#ifdef PVR_MANUAL_POWER_CONTROL
+static struct proc_dir_entry* g_pProcPowerLevel;
+#endif
+
+
+static void ProcSeqShowVersion(struct seq_file *sfile,void* el);
+
+static void ProcSeqShowSysNodes(struct seq_file *sfile,void* el);
+static void* ProcSeqOff2ElementSysNodes(struct seq_file * sfile, loff_t off);
+
+/*!
+******************************************************************************
+
+ @Function : printAppend
+
+ @Description
+
+ Print into the supplied buffer at the specified offset remaining within
+ the specified total buffer size.
+
+ @Input size : the total size of the buffer
+
+ @Input off : the offset into the buffer to start printing
+
+ @Input format : the printf format string
+
+ @Input ... : format args
+
+ @Return : The number of chars now in the buffer (original value of 'off'
+ plus number of chars added); 'size' if full.
+
+*****************************************************************************/
+off_t printAppend(IMG_CHAR * buffer, size_t size, off_t off, const IMG_CHAR * format, ...)
+{
+ IMG_INT n;
+ size_t space = size - (size_t)off;
+ va_list ap;
+
+ va_start (ap, format);
+
+ n = vsnprintf (buffer+off, space, format, ap);
+
+ va_end (ap);
+ /* According to POSIX, n is greater than or equal to the size available if
+ * the print would have overflowed the buffer. Other platforms may
+ * return -1 if printing was truncated.
+ */
+ if (n >= (IMG_INT)space || n < 0)
+ {
+ /* Ensure final string is terminated */
+ buffer[size - 1] = 0;
+ return (off_t)(size - 1);
+ }
+ else
+ {
+ return (off + (off_t)n);
+ }
+}
+
+
+/*!
+******************************************************************************
+
+ @Function : ProcSeq1ElementOff2Element
+
+ @Description
+
+ Heleper Offset -> Element function for /proc files with only one entry
+ without header.
+
+ @Input sfile : seq_file object related to /proc/ file
+
+ @Input off : the offset into the buffer (id of object)
+
+ @Return : Pointer to element to be shown.
+
+*****************************************************************************/
+void* ProcSeq1ElementOff2Element(struct seq_file *sfile, loff_t off)
+{
+ PVR_UNREFERENCED_PARAMETER(sfile);
+ // Return anything that is not PVR_RPOC_SEQ_START_TOKEN and NULL
+ if(!off)
+ return (void*)2;
+ return NULL;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function : ProcSeq1ElementHeaderOff2Element
+
+ @Description
+
+ Heleper Offset -> Element function for /proc files with only one entry
+ with header.
+
+ @Input sfile : seq_file object related to /proc/ file
+
+ @Input off : the offset into the buffer (id of object)
+
+ @Return : Pointer to element to be shown.
+
+*****************************************************************************/
+void* ProcSeq1ElementHeaderOff2Element(struct seq_file *sfile, loff_t off)
+{
+ PVR_UNREFERENCED_PARAMETER(sfile);
+
+ if(!off)
+ {
+ return PVR_PROC_SEQ_START_TOKEN;
+ }
+
+ // Return anything that is not PVR_RPOC_SEQ_START_TOKEN and NULL
+ if(off == 1)
+ return (void*)2;
+
+ return NULL;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function : pvr_proc_open
+
+ @Description
+ File opening function passed to proc_dir_entry->proc_fops for /proc entries
+ created by CreateProcReadEntrySeq.
+
+ @Input inode : inode entry of opened /proc file
+
+ @Input file : file entry of opened /proc file
+
+ @Return : 0 if no errors
+
+*****************************************************************************/
+static IMG_INT pvr_proc_open(struct inode *inode,struct file *file)
+{
+ IMG_INT ret = seq_open(file, &pvr_proc_seq_operations);
+
+ struct seq_file *seq = (struct seq_file*)file->private_data;
+ struct proc_dir_entry* pvr_proc_entry = PDE(inode);
+
+ /* Add pointer to handlers to seq_file structure */
+ seq->private = pvr_proc_entry->data;
+ return ret;
+}
+
+/*!
+******************************************************************************
+
+ @Function : pvr_proc_write
+
+ @Description
+ File writing function passed to proc_dir_entry->proc_fops for /proc files.
+ It's exacly the same function that is used as default one (->fs/proc/generic.c),
+ it calls proc_dir_entry->write_proc for writing procedure.
+
+*****************************************************************************/
+static ssize_t pvr_proc_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct inode *inode = file->f_path.dentry->d_inode;
+ struct proc_dir_entry * dp;
+
+ PVR_UNREFERENCED_PARAMETER(ppos);
+ dp = PDE(inode);
+
+ if (!dp->write_proc)
+ return -EIO;
+
+ return dp->write_proc(file, buffer, count, dp->data);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function : pvr_proc_seq_start
+
+ @Description
+ Seq_file start function. Detailed description of seq_file workflow can
+ be found here: http://tldp.org/LDP/lkmpg/2.6/html/x861.html.
+ This function ises off2element handler.
+
+ @Input proc_seq_file : sequence file entry
+
+ @Input pos : offset within file (id of entry)
+
+ @Return : Pointer to element from we start enumeration (0 ends it)
+
+*****************************************************************************/
+static void *pvr_proc_seq_start (struct seq_file *proc_seq_file, loff_t *pos)
+{
+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
+ if(handlers->startstop != NULL)
+ handlers->startstop(proc_seq_file, IMG_TRUE);
+ return handlers->off2element(proc_seq_file, *pos);
+}
+
+/*!
+******************************************************************************
+
+ @Function : pvr_proc_seq_stop
+
+ @Description
+ Seq_file stop function. Detailed description of seq_file workflow can
+ be found here: http://tldp.org/LDP/lkmpg/2.6/html/x861.html.
+
+ @Input proc_seq_file : sequence file entry
+
+ @Input v : current element pointer
+
+*****************************************************************************/
+static void pvr_proc_seq_stop (struct seq_file *proc_seq_file, void *v)
+{
+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
+ PVR_UNREFERENCED_PARAMETER(v);
+
+ if(handlers->startstop != NULL)
+ handlers->startstop(proc_seq_file, IMG_FALSE);
+}
+
+/*!
+******************************************************************************
+
+ @Function : pvr_proc_seq_next
+
+ @Description
+ Seq_file next element function. Detailed description of seq_file workflow can
+ be found here: http://tldp.org/LDP/lkmpg/2.6/html/x861.html.
+ It uses supplied 'next' handler for fetching next element (or 0 if there is no one)
+
+ @Input proc_seq_file : sequence file entry
+
+ @Input pos : offset within file (id of entry)
+
+ @Input v : current element pointer
+
+ @Return : next element pointer (or 0 if end)
+
+*****************************************************************************/
+static void *pvr_proc_seq_next (struct seq_file *proc_seq_file, void *v, loff_t *pos)
+{
+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
+ (*pos)++;
+ if( handlers->next != NULL)
+ return handlers->next( proc_seq_file, v, *pos );
+ return handlers->off2element(proc_seq_file, *pos);
+}
+
+/*!
+******************************************************************************
+
+ @Function : pvr_proc_seq_show
+
+ @Description
+ Seq_file show element function. Detailed description of seq_file workflow can
+ be found here: http://tldp.org/LDP/lkmpg/2.6/html/x861.html.
+ It call proper 'show' handler to show (dump) current element using seq_* functions
+
+ @Input proc_seq_file : sequence file entry
+
+ @Input v : current element pointer
+
+ @Return : 0 if everything is OK
+
+*****************************************************************************/
+static int pvr_proc_seq_show (struct seq_file *proc_seq_file, void *v)
+{
+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
+ handlers->show( proc_seq_file,v );
+ return 0;
+}
+
+
+
+/*!
+******************************************************************************
+
+ @Function : CreateProcEntryInDirSeq
+
+ @Description
+
+ Create a file under the given directory. These dynamic files can be used at
+ runtime to get or set information about the device. Whis version uses seq_file
+ interface
+
+ @Input pdir : parent directory
+
+ @Input name : the name of the file to create
+
+ @Input data : aditional data that will be passed to handlers
+
+ @Input next_handler : the function to call to provide the next element. OPTIONAL, if not
+ supplied, then off2element function is used instead
+
+ @Input show_handler : the function to call to show element
+
+ @Input off2element_handler : the function to call when it is needed to translate offest to element
+
+ @Input startstop_handler : the function to call when output memory page starts or stops. OPTIONAL.
+
+ @Input whandler : the function to interpret writes from the user
+
+ @Return Ptr to proc entry , 0 for failure
+
+
+*****************************************************************************/
+static struct proc_dir_entry* CreateProcEntryInDirSeq(
+ struct proc_dir_entry *pdir,
+ const IMG_CHAR * name,
+ IMG_VOID* data,
+ pvr_next_proc_seq_t next_handler,
+ pvr_show_proc_seq_t show_handler,
+ pvr_off2element_proc_seq_t off2element_handler,
+ pvr_startstop_proc_seq_t startstop_handler,
+ write_proc_t whandler
+ )
+{
+
+ struct proc_dir_entry * file;
+ mode_t mode;
+
+ if (!dir)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDirSeq: cannot make proc entry /proc/%s/%s: no parent", PVRProcDirRoot, name));
+ return NULL;
+ }
+
+ mode = S_IFREG;
+
+ if (show_handler)
+ {
+ mode |= S_IRUGO;
+ }
+
+ if (whandler)
+ {
+ mode |= S_IWUSR;
+ }
+
+ file=create_proc_entry(name, mode, pdir);
+
+ if (file)
+ {
+ PVR_PROC_SEQ_HANDLERS *seq_handlers;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
+ file->owner = THIS_MODULE;
+#endif
+
+ file->proc_fops = &pvr_proc_operations;
+ file->write_proc = whandler;
+
+ /* Pass the handlers */
+ file->data = kmalloc(sizeof(PVR_PROC_SEQ_HANDLERS), GFP_KERNEL);
+ if(file->data)
+ {
+ seq_handlers = (PVR_PROC_SEQ_HANDLERS*)file->data;
+ seq_handlers->next = next_handler;
+ seq_handlers->show = show_handler;
+ seq_handlers->off2element = off2element_handler;
+ seq_handlers->startstop = startstop_handler;
+ seq_handlers->data = data;
+
+ return file;
+ }
+ }
+
+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDirSeq: cannot make proc entry /proc/%s/%s: no memory", PVRProcDirRoot, name));
+ return NULL;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function : CreateProcReadEntrySeq
+
+ @Description
+
+ Create a file under /proc/pvr. These dynamic files can be used at runtime
+ to get information about the device. Creation WILL fail if proc support is
+ not compiled into the kernel. That said, the Linux kernel is not even happy
+ to build without /proc support these days. This version uses seq_file structure
+ for handling content generation.
+
+ @Input name : the name of the file to create
+
+ @Input data : aditional data that will be passed to handlers
+
+ @Input next_handler : the function to call to provide the next element. OPTIONAL, if not
+ supplied, then off2element function is used instead
+
+ @Input show_handler : the function to call to show element
+
+ @Input off2element_handler : the function to call when it is needed to translate offest to element
+
+ @Input startstop_handler : the function to call when output memory page starts or stops. OPTIONAL.
+
+ @Return Ptr to proc entry , 0 for failure
+
+*****************************************************************************/
+struct proc_dir_entry* CreateProcReadEntrySeq (
+ const IMG_CHAR * name,
+ IMG_VOID* data,
+ pvr_next_proc_seq_t next_handler,
+ pvr_show_proc_seq_t show_handler,
+ pvr_off2element_proc_seq_t off2element_handler,
+ pvr_startstop_proc_seq_t startstop_handler
+ )
+{
+ return CreateProcEntrySeq(name,
+ data,
+ next_handler,
+ show_handler,
+ off2element_handler,
+ startstop_handler,
+ NULL);
+}
+
+/*!
+******************************************************************************
+
+ @Function : CreateProcEntrySeq
+
+ @Description
+
+ @Description
+
+ Create a file under /proc/pvr. These dynamic files can be used at runtime
+ to get information about the device. Creation WILL fail if proc support is
+ not compiled into the kernel. That said, the Linux kernel is not even happy
+ to build without /proc support these days. This version uses seq_file structure
+ for handling content generation and is fuller than CreateProcReadEntrySeq (it
+ supports write access);
+
+ @Input name : the name of the file to create
+
+ @Input data : aditional data that will be passed to handlers
+
+ @Input next_handler : the function to call to provide the next element. OPTIONAL, if not
+ supplied, then off2element function is used instead
+
+ @Input show_handler : the function to call to show element
+
+ @Input off2element_handler : the function to call when it is needed to translate offest to element
+
+ @Input startstop_handler : the function to call when output memory page starts or stops. OPTIONAL.
+
+ @Input whandler : the function to interpret writes from the user
+
+ @Return Ptr to proc entry , 0 for failure
+
+*****************************************************************************/
+struct proc_dir_entry* CreateProcEntrySeq (
+ const IMG_CHAR * name,
+ IMG_VOID* data,
+ pvr_next_proc_seq_t next_handler,
+ pvr_show_proc_seq_t show_handler,
+ pvr_off2element_proc_seq_t off2element_handler,
+ pvr_startstop_proc_seq_t startstop_handler,
+ write_proc_t whandler
+ )
+{
+ return CreateProcEntryInDirSeq(
+ dir,
+ name,
+ data,
+ next_handler,
+ show_handler,
+ off2element_handler,
+ startstop_handler,
+ whandler
+ );
+}
+
+
+
+/*!
+******************************************************************************
+
+ @Function : CreatePerProcessProcEntrySeq
+
+ @Description
+
+ Create a file under /proc/pvr/<current process ID>. Apart from the
+ directory where the file is created, this works the same way as
+ CreateProcEntry. It's seq_file version.
+
+
+
+ @Input name : the name of the file to create
+
+ @Input data : aditional data that will be passed to handlers
+
+ @Input next_handler : the function to call to provide the next element. OPTIONAL, if not
+ supplied, then off2element function is used instead
+
+ @Input show_handler : the function to call to show element
+
+ @Input off2element_handler : the function to call when it is needed to translate offest to element
+
+ @Input startstop_handler : the function to call when output memory page starts or stops. OPTIONAL.
+
+ @Input whandler : the function to interpret writes from the user
+
+ @Return Ptr to proc entry , 0 for failure
+
+*****************************************************************************/
+struct proc_dir_entry* CreatePerProcessProcEntrySeq (
+ const IMG_CHAR * name,
+ IMG_VOID* data,
+ pvr_next_proc_seq_t next_handler,
+ pvr_show_proc_seq_t show_handler,
+ pvr_off2element_proc_seq_t off2element_handler,
+ pvr_startstop_proc_seq_t startstop_handler,
+ write_proc_t whandler
+ )
+{
+ PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
+ IMG_UINT32 ui32PID;
+
+ if (!dir)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntrySeq: /proc/%s doesn't exist", PVRProcDirRoot));
+ return NULL;
+ }
+
+ ui32PID = OSGetCurrentProcessIDKM();
+
+ psPerProc = PVRSRVPerProcessPrivateData(ui32PID);
+ if (!psPerProc)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntrySeq: no per process data"));
+
+ return NULL;
+ }
+
+ if (!psPerProc->psProcDir)
+ {
+ IMG_CHAR dirname_buffer[256];
+ IMG_CHAR dirname[256];
+ IMG_INT ret;
+ const IMG_CHAR *proc_basename = dirname_buffer;
+ dirname_buffer[255] = dirname[255] = '\0';
+
+ OSGetProcCmdline(ui32PID, dirname_buffer, sizeof(dirname_buffer));
+ PVR_DPF((PVR_DBG_MESSAGE, "Command Line of the process with ID %u is %s", ui32PID, dirname_buffer));
+
+ proc_basename = OSGetPathBaseName(dirname_buffer, sizeof(dirname_buffer));
+ PVR_DPF((PVR_DBG_MESSAGE, "Base Name of the process with ID %u is %s\n", ui32PID, proc_basename));
+
+ ret = snprintf(dirname, sizeof(dirname), "%u-%s", ui32PID, proc_basename);
+ PVR_DPF((PVR_DBG_MESSAGE, "Creating a new process entry for %s with ID %u\n", proc_basename, ui32PID));
+
+ if (ret <=0 || ret >= (IMG_INT)sizeof(dirname))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't generate per process proc directory name \"%u\"", ui32PID));
+ return NULL;
+ }
+ 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 NULL;
+ }
+ }
+ }
+
+ return CreateProcEntryInDirSeq(psPerProc->psProcDir, name, data, next_handler,
+ show_handler,off2element_handler,startstop_handler,whandler);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function : RemoveProcEntrySeq
+
+ @Description
+
+ Remove a single node (created using *Seq function) under /proc/pvr.
+
+ @Input proc_entry : structure returned by Create function.
+
+ @Return nothing
+
+*****************************************************************************/
+IMG_VOID RemoveProcEntrySeq( struct proc_dir_entry* proc_entry )
+{
+ if (dir)
+ {
+ void* data = proc_entry->data ;
+ PVR_DPF((PVR_DBG_MESSAGE, "Removing /proc/%s/%s", PVRProcDirRoot, proc_entry->name));
+
+ remove_proc_entry(proc_entry->name, dir);
+ if( data)
+ kfree( data );
+
+ }
+}
+
+/*!
+******************************************************************************
+
+ @Function : RemovePerProcessProcEntry Seq
+
+ @Description
+
+ Remove a single node under the per process proc directory (created by *Seq function).
+
+ Remove a single node (created using *Seq function) under /proc/pvr.
+
+ @Input proc_entry : structure returned by Create function.
+
+ @Return nothing
+
+*****************************************************************************/
+IMG_VOID RemovePerProcessProcEntrySeq(struct proc_dir_entry* proc_entry)
+{
+ PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
+
+ psPerProc = LinuxTerminatingProcessPrivateData();
+ if (!psPerProc)
+ {
+ psPerProc = PVRSRVFindPerProcessPrivateData();
+ if (!psPerProc)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: can't "
+ "remove %s, no per process data", proc_entry->name));
+ return;
+ }
+ }
+
+ if (psPerProc->psProcDir)
+ {
+ void* data = proc_entry->data ;
+ PVR_DPF((PVR_DBG_MESSAGE, "Removing proc entry %s from %s", proc_entry->name, psPerProc->psProcDir->name));
+
+ remove_proc_entry(proc_entry->name, psPerProc->psProcDir);
+ if(data)
+ kfree( data );
+ }
+}
+
+/*!
+******************************************************************************
+
+ @Function : pvr_read_proc_vm
+
+ @Description
+
+ When the user accesses the proc filesystem entry for the device, we are
+ called here to create the content for the 'file'. We can print anything we
+ want here. If the info we want to return is too big for one page ('count'
+ chars), we return successive chunks on each call. For a number of ways of
+ achieving this, refer to proc_file_read() in linux/fs/proc/generic.c.
+
+ Here, as we are accessing lists of information, we output '1' in '*start' to
+ instruct proc to advance 'off' by 1 on each call. The number of chars placed
+ in the buffer is returned. Multiple calls are made here by the proc
+ filesystem until we set *eof. We can return zero without setting eof to
+ instruct proc to flush 'page' (causing it to be printed) if there is not
+ enough space left (eg for a complete line).
+
+ @Input page : where to write the output
+
+ @Input start : memory location into which should be written next offset
+ to read from.
+
+ @Input off : the offset into the /proc file being read
+
+ @Input count : the size of the buffer 'page'
+
+ @Input eof : memory location into which 1 should be written when at EOF
+
+ @Input data : data specific to this /proc file entry
+
+ @Return : length of string written to page
+
+*****************************************************************************/
+static IMG_INT pvr_read_proc(IMG_CHAR *page, IMG_CHAR **start, off_t off,
+ IMG_INT count, IMG_INT *eof, IMG_VOID *data)
+{
+ /* PRQA S 0307 1 */ /* ignore warning about casting to different pointer type */
+ pvr_read_proc_t *pprn = (pvr_read_proc_t *)data;
+
+ off_t len = pprn (page, (size_t)count, off);
+
+ if (len == END_OF_FILE)
+ {
+ len = 0;
+ *eof = 1;
+ }
+ else if (!len) /* not enough space in the buffer */
+ {
+ *start = (IMG_CHAR *) 0; /* don't advance the offset */
+ }
+ else
+ {
+ *start = (IMG_CHAR *) 1;
+ }
+
+ return len;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function : CreateProcEntryInDir
+
+ @Description
+
+ Create a file under the given directory. These dynamic files can be used at
+ runtime to get or set information about the device.
+
+ @Input pdir : parent directory
+
+ @Input name : the name of the file to create
+
+ @Input rhandler : the function to supply the content
+
+ @Input whandler : the function to interpret writes from the user
+
+ @Return success code : 0 or -errno.
+
+*****************************************************************************/
+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;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function : CreateProcEntry
+
+ @Description
+
+ Create a file under /proc/pvr. These dynamic files can be used at runtime
+ to get or set information about the device.
+
+ This interface is fuller than CreateProcReadEntry, and supports write access;
+ it is really just a wrapper for the native linux functions.
+
+ @Input name : the name of the file to create under /proc/pvr
+
+ @Input rhandler : the function to supply the content
+
+ @Input whandler : the function to interpret writes from the user
+
+ @Return success code : 0 or -errno.
+
+*****************************************************************************/
+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);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function : CreatePerProcessProcEntry
+
+ @Description
+
+ Create a file under /proc/pvr/<current process ID>. Apart from the
+ directory where the file is created, this works the same way as
+ CreateProcEntry.
+
+ @Input name : the name of the file to create under the per process /proc directory
+
+ @Input rhandler : the function to supply the content
+
+ @Input whandler : the function to interpret writes from the user
+
+ @Return success code : 0 or -errno.
+
+*****************************************************************************/
+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), "%u", ui32PID);
+
+ if (ret <=0 || ret >= (IMG_INT)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);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function : CreateProcReadEntry
+
+ @Description
+
+ Create a file under /proc/pvr. These dynamic files can be used at runtime
+ to get information about the device. Creation WILL fail if proc support is
+ not compiled into the kernel. That said, the Linux kernel is not even happy
+ to build without /proc support these days.
+
+ @Input name : the name of the file to create
+
+ @Input handler : the function to call to provide the content
+
+ @Return 0 for success, -errno for failure
+
+*****************************************************************************/
+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;
+ }
+
+ /* PRQA S 0307 1 */ /* ignore warning about casting to different pointer type */
+ 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;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function : CreateProcEntries
+
+ @Description
+
+ Create a directory /proc/pvr and the necessary entries within it. These
+ dynamic files can be used at runtime to get information about the device.
+ Creation might fail if proc support is not compiled into the kernel or if
+ there is no memory
+
+ @Input none
+
+ @Return nothing
+
+*****************************************************************************/
+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;
+ }
+
+ g_pProcQueue = CreateProcReadEntrySeq("queue", NULL, NULL, ProcSeqShowQueue, ProcSeqOff2ElementQueue, NULL);
+ g_pProcVersion = CreateProcReadEntrySeq("version", NULL, NULL, ProcSeqShowVersion, ProcSeq1ElementHeaderOff2Element, NULL);
+ g_pProcSysNodes = CreateProcReadEntrySeq("nodes", NULL, NULL, ProcSeqShowSysNodes, ProcSeqOff2ElementSysNodes, NULL);
+
+ if(!g_pProcQueue || !g_pProcVersion || !g_pProcSysNodes)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s files", PVRProcDirRoot));
+
+ return -ENOMEM;
+ }
+
+
+#ifdef DEBUG
+
+ g_pProcDebugLevel = CreateProcEntrySeq("debug_level", NULL, NULL,
+ ProcSeqShowDebugLevel,
+ ProcSeq1ElementOff2Element, NULL,
+ (IMG_VOID*)PVRDebugProcSetLevel);
+ if(!g_pProcDebugLevel)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s/debug_level", PVRProcDirRoot));
+
+ return -ENOMEM;
+ }
+
+#ifdef PVR_MANUAL_POWER_CONTROL
+ g_pProcPowerLevel = CreateProcEntrySeq("power_control", NULL, NULL,
+ ProcSeqShowPowerLevel,
+ ProcSeq1ElementOff2Element, NULL,
+ PVRProcSetPowerLevel);
+ if(!g_pProcPowerLevel)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s/power_control", PVRProcDirRoot));
+
+ return -ENOMEM;
+ }
+#endif
+#endif
+
+ return 0;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function : RemoveProcEntry
+
+ @Description
+
+ Remove a single node under /proc/pvr.
+
+ @Input name : the name of the node to remove
+
+ @Return nothing
+
+*****************************************************************************/
+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));
+ }
+}
+
+
+/*!
+******************************************************************************
+
+ @Function : RemovePerProcessProcEntry
+
+ @Description
+
+ Remove a single node under the per process proc directory.
+
+ @Input name : the name of the node to remove
+
+ @Return nothing
+
+*****************************************************************************/
+IMG_VOID RemovePerProcessProcEntry(const IMG_CHAR *name)
+{
+ PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
+
+ psPerProc = LinuxTerminatingProcessPrivateData();
+ if (!psPerProc)
+ {
+ 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));
+ }
+}
+
+
+/*!
+******************************************************************************
+
+ @Function : RemovePerProcessProcDir
+
+ @Description
+
+ Remove the per process directorty under /proc/pvr.
+
+ @Input psPerProc : environment specific per process data
+
+ @Return nothing
+
+*****************************************************************************/
+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);
+ }
+}
+
+/*!
+******************************************************************************
+
+ @Function : RemoveProcEntries
+
+ Description
+
+ Proc filesystem entry deletion - Remove all proc filesystem entries for
+ the driver.
+
+ @Input none
+
+ @Return nothing
+
+*****************************************************************************/
+IMG_VOID RemoveProcEntries(IMG_VOID)
+{
+#ifdef DEBUG
+ RemoveProcEntrySeq( g_pProcDebugLevel );
+#ifdef PVR_MANUAL_POWER_CONTROL
+ RemoveProcEntrySeq( g_pProcPowerLevel );
+#endif /* PVR_MANUAL_POWER_CONTROL */
+#endif
+
+ RemoveProcEntrySeq(g_pProcQueue);
+ RemoveProcEntrySeq(g_pProcVersion);
+ RemoveProcEntrySeq(g_pProcSysNodes);
+
+ 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);
+}
+
+/*****************************************************************************
+ FUNCTION : ProcSeqShowVersion
+
+ PURPOSE : Print the content of version to /proc file
+
+ PARAMETERS : sfile - /proc seq_file
+ el - Element to print
+*****************************************************************************/
+static void ProcSeqShowVersion(struct seq_file *sfile,void* el)
+{
+ SYS_DATA *psSysData;
+ IMG_CHAR *pszSystemVersionString = "None";
+
+ if(el == PVR_PROC_SEQ_START_TOKEN)
+ {
+ seq_printf(sfile,
+ "Version %s (%s) %s\n",
+ PVRVERSION_STRING,
+ PVR_BUILD_TYPE, PVR_BUILD_DIR);
+ return;
+ }
+
+ psSysData = SysAcquireDataNoCheck();
+ if(psSysData != IMG_NULL && psSysData->pszVersionString != IMG_NULL)
+ {
+ pszSystemVersionString = psSysData->pszVersionString;
+ }
+
+ seq_printf( sfile, "System Version String: %s\n", pszSystemVersionString);
+}
+
+/*!
+******************************************************************************
+
+ @Function procDumpSysNodes (plus deviceTypeToString and deviceClassToString)
+
+ @Description
+
+ Format the contents of /proc/pvr/nodes
+
+ @Input buf : where to place format contents data.
+
+ @Input size : the size of the buffer into which to place data
+
+ @Input off : how far into the file we are.
+
+ @Return amount of data placed in buffer, 0, or END_OF_FILE :
+
+******************************************************************************/
+static const IMG_CHAR *deviceTypeToString(PVRSRV_DEVICE_TYPE deviceType)
+{
+ switch (deviceType)
+ {
+ default:
+ {
+ static IMG_CHAR text[10];
+
+ sprintf(text, "?%x", (IMG_UINT)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", (IMG_UINT)deviceClass);
+ return text;
+ }
+ }
+}
+
+static IMG_VOID* DecOffPsDev_AnyVaCb(PVRSRV_DEVICE_NODE *psNode, va_list va)
+{
+ off_t *pOff = va_arg(va, off_t*);
+ if (--(*pOff))
+ {
+ return IMG_NULL;
+ }
+ else
+ {
+ return psNode;
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : ProcSeqShowSysNodes
+
+ PURPOSE : Print the content of version to /proc file
+
+ PARAMETERS : sfile - /proc seq_file
+ el - Element to print
+*****************************************************************************/
+static void ProcSeqShowSysNodes(struct seq_file *sfile,void* el)
+{
+ PVRSRV_DEVICE_NODE *psDevNode;
+
+ if(el == PVR_PROC_SEQ_START_TOKEN)
+ {
+ seq_printf( sfile,
+ "Registered nodes\n"
+ "Addr Type Class Index Ref pvDev Size Res\n");
+ return;
+ }
+
+ psDevNode = (PVRSRV_DEVICE_NODE*)el;
+
+ seq_printf( sfile,
+ "%p %-8s %-8s %4d %2u %p %3u %p\n",
+ psDevNode,
+ deviceTypeToString(psDevNode->sDevId.eDeviceType),
+ deviceClassToString(psDevNode->sDevId.eDeviceClass),
+ psDevNode->sDevId.eDeviceClass,
+ psDevNode->ui32RefCount,
+ psDevNode->pvDevice,
+ psDevNode->ui32pvDeviceSize,
+ psDevNode->hResManContext);
+}
+
+/*****************************************************************************
+ FUNCTION : ProcSeqOff2ElementSysNodes
+
+ PURPOSE : Transale offset to element (/proc stuff)
+
+ PARAMETERS : sfile - /proc seq_file
+ off - the offset into the buffer
+
+ RETURNS : element to print
+*****************************************************************************/
+static void* ProcSeqOff2ElementSysNodes(struct seq_file * sfile, loff_t off)
+{
+ SYS_DATA *psSysData;
+ PVRSRV_DEVICE_NODE*psDevNode = IMG_NULL;
+
+ PVR_UNREFERENCED_PARAMETER(sfile);
+
+ if(!off)
+ {
+ return PVR_PROC_SEQ_START_TOKEN;
+ }
+
+ psSysData = SysAcquireDataNoCheck();
+ if (psSysData != IMG_NULL)
+ {
+ /* Find Dev Node */
+ psDevNode = (PVRSRV_DEVICE_NODE*)
+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
+ DecOffPsDev_AnyVaCb,
+ &off);
+ }
+
+ /* Return anything that is not PVR_RPOC_SEQ_START_TOKEN and NULL */
+ return (void*)psDevNode;
+}
+
+/*****************************************************************************
+ End of file (proc.c)
+*****************************************************************************/
diff --git a/pvr-source/services4/srvkm/env/linux/proc.h b/pvr-source/services4/srvkm/env/linux/proc.h
new file mode 100644
index 0000000..bc2a554
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/proc.h
@@ -0,0 +1,127 @@
+/*************************************************************************/ /*!
+@Title Proc interface definition.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Functions for creating and reading proc filesystem entries.
+ Refer to proc.c
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __SERVICES_PROC_H__
+#define __SERVICES_PROC_H__
+
+#include <asm/system.h> // va_list etc
+#include <linux/proc_fs.h> // read_proc_t etc
+#include <linux/seq_file.h> // seq_file
+
+#define END_OF_FILE (off_t) -1
+
+typedef off_t (pvr_read_proc_t)(IMG_CHAR *, size_t, off_t);
+
+
+#define PVR_PROC_SEQ_START_TOKEN (void*)1
+typedef void* (pvr_next_proc_seq_t)(struct seq_file *,void*,loff_t);
+typedef void* (pvr_off2element_proc_seq_t)(struct seq_file *, loff_t);
+typedef void (pvr_show_proc_seq_t)(struct seq_file *,void*);
+typedef void (pvr_startstop_proc_seq_t)(struct seq_file *, IMG_BOOL start);
+
+typedef struct _PVR_PROC_SEQ_HANDLERS_ {
+ pvr_next_proc_seq_t *next;
+ pvr_show_proc_seq_t *show;
+ pvr_off2element_proc_seq_t *off2element;
+ pvr_startstop_proc_seq_t *startstop;
+ IMG_VOID *data;
+} PVR_PROC_SEQ_HANDLERS;
+
+
+/** off2element function for elements with only ONE element (no header) */
+void* ProcSeq1ElementOff2Element(struct seq_file *sfile, loff_t off);
+
+/** off2element function for elements with only ONE element (+ header) */
+void* ProcSeq1ElementHeaderOff2Element(struct seq_file *sfile, loff_t off);
+
+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);
+
+struct proc_dir_entry* CreateProcReadEntrySeq (
+ const IMG_CHAR* name,
+ IMG_VOID* data,
+ pvr_next_proc_seq_t next_handler,
+ pvr_show_proc_seq_t show_handler,
+ pvr_off2element_proc_seq_t off2element_handler,
+ pvr_startstop_proc_seq_t startstop_handler
+ );
+
+struct proc_dir_entry* CreateProcEntrySeq (
+ const IMG_CHAR* name,
+ IMG_VOID* data,
+ pvr_next_proc_seq_t next_handler,
+ pvr_show_proc_seq_t show_handler,
+ pvr_off2element_proc_seq_t off2element_handler,
+ pvr_startstop_proc_seq_t startstop_handler,
+ write_proc_t whandler
+ );
+
+struct proc_dir_entry* CreatePerProcessProcEntrySeq (
+ const IMG_CHAR* name,
+ IMG_VOID* data,
+ pvr_next_proc_seq_t next_handler,
+ pvr_show_proc_seq_t show_handler,
+ pvr_off2element_proc_seq_t off2element_handler,
+ pvr_startstop_proc_seq_t startstop_handler,
+ write_proc_t whandler
+ );
+
+
+IMG_VOID RemoveProcEntrySeq(struct proc_dir_entry* proc_entry);
+IMG_VOID RemovePerProcessProcEntrySeq(struct proc_dir_entry* proc_entry);
+
+#endif
diff --git a/pvr-source/services4/srvkm/env/linux/pvr_bridge_k.c b/pvr-source/services4/srvkm/env/linux/pvr_bridge_k.c
new file mode 100644
index 0000000..5d1ad8c
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/pvr_bridge_k.c
@@ -0,0 +1,524 @@
+/*************************************************************************/ /*!
+@Title PVR Bridge Module (kernel side)
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Receives calls from the user portion of services and
+ despatches them to functions in the kernel portion.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#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"
+#include "pvr_bridge_km.h"
+#include "pvr_uaccess.h"
+#include "refcount.h"
+#include "buffer_manager.h"
+
+#if defined(SUPPORT_DRI_DRM)
+#include <drm/drmP.h>
+#include "pvr_drm.h"
+#if defined(PVR_SECURE_DRM_AUTH_EXPORT)
+#include "env_perproc.h"
+#endif
+#endif
+
+/* VGX: */
+#if defined(SUPPORT_VGX)
+#include "vgx_bridge.h"
+#endif
+
+/* SGX: */
+#if defined(SUPPORT_SGX)
+#include "sgx_bridge.h"
+#endif
+
+#include "bridged_pvr_bridge.h"
+
+#if defined(SUPPORT_DRI_DRM)
+#define PRIVATE_DATA(pFile) ((pFile)->driver_priv)
+#else
+#define PRIVATE_DATA(pFile) ((pFile)->private_data)
+#endif
+
+#if defined(DEBUG_BRIDGE_KM)
+
+static struct proc_dir_entry *g_ProcBridgeStats =0;
+static void* ProcSeqNextBridgeStats(struct seq_file *sfile,void* el,loff_t off);
+static void ProcSeqShowBridgeStats(struct seq_file *sfile,void* el);
+static void* ProcSeqOff2ElementBridgeStats(struct seq_file * sfile, loff_t off);
+static void ProcSeqStartstopBridgeStats(struct seq_file *sfile,IMG_BOOL start);
+
+#endif
+
+extern PVRSRV_LINUX_MUTEX gPVRSRVLock;
+
+#if defined(SUPPORT_MEMINFO_IDS)
+static IMG_UINT64 ui64Stamp;
+#endif /* defined(SUPPORT_MEMINFO_IDS) */
+
+PVRSRV_ERROR
+LinuxBridgeInit(IMG_VOID)
+{
+#if defined(DEBUG_BRIDGE_KM)
+ {
+ g_ProcBridgeStats = CreateProcReadEntrySeq(
+ "bridge_stats",
+ NULL,
+ ProcSeqNextBridgeStats,
+ ProcSeqShowBridgeStats,
+ ProcSeqOff2ElementBridgeStats,
+ ProcSeqStartstopBridgeStats
+ );
+ if(!g_ProcBridgeStats)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+ }
+#endif
+ return CommonBridgeInit();
+}
+
+IMG_VOID
+LinuxBridgeDeInit(IMG_VOID)
+{
+#if defined(DEBUG_BRIDGE_KM)
+ RemoveProcEntrySeq(g_ProcBridgeStats);
+#endif
+}
+
+#if defined(DEBUG_BRIDGE_KM)
+
+/*
+ * Lock MMap regions list (called on page start/stop while reading /proc/mmap)
+ *
+ * sfile : seq_file that handles /proc file
+ * start : TRUE if it's start, FALSE if it's stop
+ *
+ */
+static void ProcSeqStartstopBridgeStats(struct seq_file *sfile,IMG_BOOL start)
+{
+ if(start)
+ {
+ LinuxLockMutex(&gPVRSRVLock);
+ }
+ else
+ {
+ LinuxUnLockMutex(&gPVRSRVLock);
+ }
+}
+
+
+/*
+ * Convert offset (index from KVOffsetTable) to element
+ * (called when reading /proc/mmap file)
+
+ * sfile : seq_file that handles /proc file
+ * off : index into the KVOffsetTable from which to print
+ *
+ * returns void* : Pointer to element that will be dumped
+ *
+*/
+static void* ProcSeqOff2ElementBridgeStats(struct seq_file *sfile, loff_t off)
+{
+ if(!off)
+ {
+ return PVR_PROC_SEQ_START_TOKEN;
+ }
+
+ if(off > BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)
+ {
+ return (void*)0;
+ }
+
+
+ return (void*)&g_BridgeDispatchTable[off-1];
+}
+
+/*
+ * Gets next MMap element to show. (called when reading /proc/mmap file)
+
+ * sfile : seq_file that handles /proc file
+ * el : actual element
+ * off : index into the KVOffsetTable from which to print
+ *
+ * returns void* : Pointer to element to show (0 ends iteration)
+*/
+static void* ProcSeqNextBridgeStats(struct seq_file *sfile,void* el,loff_t off)
+{
+ return ProcSeqOff2ElementBridgeStats(sfile,off);
+}
+
+
+/*
+ * Show MMap element (called when reading /proc/mmap file)
+
+ * sfile : seq_file that handles /proc file
+ * el : actual element
+ *
+*/
+static void ProcSeqShowBridgeStats(struct seq_file *sfile,void* el)
+{
+ PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psEntry = ( PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY*)el;
+
+ if(el == PVR_PROC_SEQ_START_TOKEN)
+ {
+ seq_printf(sfile,
+ "Total ioctl call count = %u\n"
+ "Total number of bytes copied via copy_from_user = %u\n"
+ "Total number of bytes copied via copy_to_user = %u\n"
+ "Total number of bytes copied via copy_*_user = %u\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"
+ );
+ return;
+ }
+
+ seq_printf(sfile,
+ "%-45s %-40s %-10u %-20u %-10u\n",
+ psEntry->pszIOCName,
+ psEntry->pszFunctionName,
+ psEntry->ui32CallCount,
+ psEntry->ui32CopyFromUserTotalBytes,
+ psEntry->ui32CopyToUserTotalBytes);
+}
+
+#endif /* DEBUG_BRIDGE_KM */
+
+
+#if defined(SUPPORT_DRI_DRM)
+int
+PVRSRV_BridgeDispatchKM(struct drm_device unref__ *dev, void *arg, struct drm_file *pFile)
+#else
+long
+PVRSRV_BridgeDispatchKM(struct file *pFile, unsigned int unref__ ioctlCmd, unsigned long arg)
+#endif
+{
+ IMG_UINT32 cmd;
+#if !defined(SUPPORT_DRI_DRM)
+ PVRSRV_BRIDGE_PACKAGE *psBridgePackageUM = (PVRSRV_BRIDGE_PACKAGE *)arg;
+ PVRSRV_BRIDGE_PACKAGE sBridgePackageKM;
+#endif
+ PVRSRV_BRIDGE_PACKAGE *psBridgePackageKM;
+ IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
+ PVRSRV_PER_PROCESS_DATA *psPerProc;
+ IMG_INT err = -EFAULT;
+
+ LinuxLockMutex(&gPVRSRVLock);
+
+#if defined(SUPPORT_DRI_DRM)
+ psBridgePackageKM = (PVRSRV_BRIDGE_PACKAGE *)arg;
+ PVR_ASSERT(psBridgePackageKM != IMG_NULL);
+#else
+ psBridgePackageKM = &sBridgePackageKM;
+
+ 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;
+ }
+
+ /* FIXME - Currently the CopyFromUserWrapper which collects stats about
+ * how much data is shifted to/from userspace isn't available to us
+ * here. */
+ if(OSCopyFromUser(IMG_NULL,
+ psBridgePackageKM,
+ psBridgePackageUM,
+ sizeof(PVRSRV_BRIDGE_PACKAGE))
+ != PVRSRV_OK)
+ {
+ goto unlock_and_return;
+ }
+#endif
+
+ cmd = psBridgePackageKM->ui32BridgeID;
+
+ if(cmd != PVRSRV_BRIDGE_CONNECT_SERVICES)
+ {
+ PVRSRV_ERROR eError;
+
+ eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+ (IMG_PVOID *)&psPerProc,
+ psBridgePackageKM->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
+ {
+ /* lookup per-process data for this process */
+ 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;
+ }
+ }
+
+ psBridgePackageKM->ui32BridgeID = PVRSRV_GET_BRIDGE_ID(psBridgePackageKM->ui32BridgeID);
+
+ switch(cmd)
+ {
+ case PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2:
+ {
+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
+
+ 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_2:
+ {
+ PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *psMapDevMemIN =
+ (PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *)psBridgePackageKM->pvParamIn;
+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
+
+ if(!psPrivateData->hKernelMemInfo)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: File descriptor has no "
+ "associated MemInfo handle", __FUNCTION__));
+ err = -EINVAL;
+ goto unlock_and_return;
+ }
+
+ if (pvr_put_user(psPrivateData->hKernelMemInfo, &psMapDevMemIN->hKernelMemInfo) != 0)
+ {
+ err = -EFAULT;
+ goto unlock_and_return;
+ }
+ break;
+ }
+
+ default:
+ {
+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
+
+ if(psPrivateData->hKernelMemInfo)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Import/Export handle tried "
+ "to use privileged service", __FUNCTION__));
+ goto unlock_and_return;
+ }
+ break;
+ }
+ }
+
+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
+ switch(cmd)
+ {
+ case PVRSRV_BRIDGE_MAP_DEV_MEMORY:
+ case PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY:
+ {
+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
+ int authenticated = pFile->authenticated;
+ PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
+
+ if (authenticated)
+ {
+ break;
+ }
+
+ /*
+ * The DRM file structure we are using for Services
+ * is not one that DRI authentication was done on.
+ * Look for an authenticated file structure for
+ * this process, making sure the DRM master is the
+ * same as ours.
+ */
+ psEnvPerProc = (PVRSRV_ENV_PER_PROCESS_DATA *)PVRSRVProcessPrivateData(psPerProc);
+ if (psEnvPerProc == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Process private data not allocated", __FUNCTION__));
+ err = -EFAULT;
+ goto unlock_and_return;
+ }
+
+ list_for_each_entry(psPrivateData, &psEnvPerProc->sDRMAuthListHead, sDRMAuthListItem)
+ {
+ struct drm_file *psDRMFile = psPrivateData->psDRMFile;
+
+ if (pFile->master == psDRMFile->master)
+ {
+ authenticated |= psDRMFile->authenticated;
+ if (authenticated)
+ {
+ break;
+ }
+ }
+ }
+
+ if (!authenticated)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Not authenticated for mapping device or device class memory", __FUNCTION__));
+ err = -EPERM;
+ goto unlock_and_return;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+#endif /* defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT) */
+
+ err = BridgedDispatchKM(psPerProc, psBridgePackageKM);
+ if(err != PVRSRV_OK)
+ goto unlock_and_return;
+
+ switch(cmd)
+ {
+ case PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2:
+ {
+ PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *psExportDeviceMemOUT =
+ (PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *)psBridgePackageKM->pvParamOut;
+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
+ IMG_HANDLE hMemInfo;
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+
+ if (pvr_get_user(hMemInfo, &psExportDeviceMemOUT->hMemInfo) != 0)
+ {
+ err = -EFAULT;
+ goto unlock_and_return;
+ }
+
+ /* Look up the meminfo we just exported */
+ if(PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+ (IMG_PVOID *)&psKernelMemInfo,
+ hMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to look up export handle", __FUNCTION__));
+ err = -EFAULT;
+ goto unlock_and_return;
+ }
+
+ /* Bump the refcount; decremented on release of the fd */
+ PVRSRVKernelMemInfoIncRef(psKernelMemInfo);
+
+ /* Tell the XProc about the export if required */
+ if (psKernelMemInfo->sShareMemWorkaround.bInUse)
+ {
+ BM_XProcIndexAcquire(psKernelMemInfo->sShareMemWorkaround.ui32ShareIndex);
+ }
+
+ psPrivateData->hKernelMemInfo = hMemInfo;
+#if defined(SUPPORT_MEMINFO_IDS)
+ psPrivateData->ui64Stamp = ++ui64Stamp;
+
+ psKernelMemInfo->ui64Stamp = psPrivateData->ui64Stamp;
+ if (pvr_put_user(psPrivateData->ui64Stamp, &psExportDeviceMemOUT->ui64Stamp) != 0)
+ {
+ err = -EFAULT;
+ goto unlock_and_return;
+ }
+#endif
+ break;
+ }
+
+#if defined(SUPPORT_MEMINFO_IDS)
+ case PVRSRV_BRIDGE_MAP_DEV_MEMORY:
+ case PVRSRV_BRIDGE_MAP_DEV_MEMORY_2:
+ {
+ PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *psMapDeviceMemoryOUT =
+ (PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *)psBridgePackageKM->pvParamOut;
+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
+ if (pvr_put_user(psPrivateData->ui64Stamp, &psMapDeviceMemoryOUT->sDstClientMemInfo.ui64Stamp) != 0)
+ {
+ err = -EFAULT;
+ goto unlock_and_return;
+ }
+ break;
+ }
+
+ case PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY:
+ {
+ PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *psDeviceClassMemoryOUT =
+ (PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *)psBridgePackageKM->pvParamOut;
+ if (pvr_put_user(++ui64Stamp, &psDeviceClassMemoryOUT->sClientMemInfo.ui64Stamp) != 0)
+ {
+ err = -EFAULT;
+ goto unlock_and_return;
+ }
+ break;
+ }
+#endif /* defined(SUPPORT_MEMINFO_IDS) */
+
+ default:
+ break;
+ }
+
+unlock_and_return:
+ LinuxUnLockMutex(&gPVRSRVLock);
+ return err;
+}
diff --git a/pvr-source/services4/srvkm/env/linux/pvr_debug.c b/pvr-source/services4/srvkm/env/linux/pvr_debug.c
new file mode 100644
index 0000000..04e42ad
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/pvr_debug.c
@@ -0,0 +1,506 @@
+/*************************************************************************/ /*!
+@Title Debug Functionality
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Provides kernel side Debug Functionality
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#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/string.h> // strncpy, strlen
+#include <stdarg.h>
+#include "img_types.h"
+#include "servicesext.h"
+#include "pvr_debug.h"
+#include "srvkm.h"
+#include "proc.h"
+#include "mutex.h"
+#include "linkage.h"
+#include "pvr_uaccess.h"
+
+#if !defined(CONFIG_PREEMPT)
+#define PVR_DEBUG_ALWAYS_USE_SPINLOCK
+#endif
+
+static IMG_BOOL VBAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz,
+ const IMG_CHAR* pszFormat, va_list VArgs)
+ IMG_FORMAT_PRINTF(3, 0);
+
+
+#if defined(PVRSRV_NEED_PVR_DPF)
+
+#define PVR_MAX_FILEPATH_LEN 256
+
+static IMG_BOOL BAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz,
+ const IMG_CHAR *pszFormat, ...)
+ IMG_FORMAT_PRINTF(3, 4);
+
+/* NOTE: Must NOT be static! Used in module.c.. */
+IMG_UINT32 gPVRDebugLevel =
+ (DBGPRIV_FATAL | DBGPRIV_ERROR | DBGPRIV_WARNING);
+
+#endif /* defined(PVRSRV_NEED_PVR_DPF) || defined(PVRSRV_NEED_PVR_TRACE) */
+
+#define PVR_MAX_MSG_LEN PVR_MAX_DEBUG_MESSAGE_LEN
+
+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
+/* Message buffer for non-IRQ messages */
+static IMG_CHAR gszBufferNonIRQ[PVR_MAX_MSG_LEN + 1];
+#endif
+
+/* Message buffer for IRQ messages */
+static IMG_CHAR gszBufferIRQ[PVR_MAX_MSG_LEN + 1];
+
+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
+/* The lock is used to control access to gszBufferNonIRQ */
+static PVRSRV_LINUX_MUTEX gsDebugMutexNonIRQ;
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39))
+/* The lock is used to control access to gszBufferIRQ */
+/* PRQA S 0671,0685 1 */ /* ignore warnings about C99 style initialisation */
+static spinlock_t gsDebugLockIRQ = SPIN_LOCK_UNLOCKED;
+#else
+static DEFINE_SPINLOCK(gsDebugLockIRQ);
+#endif
+
+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
+#if !defined (USE_SPIN_LOCK) /* to keep QAC happy */
+#define USE_SPIN_LOCK (in_interrupt() || !preemptible())
+#endif
+#endif
+
+static inline void GetBufferLock(unsigned long *pulLockFlags)
+{
+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
+ if (USE_SPIN_LOCK)
+#endif
+ {
+ spin_lock_irqsave(&gsDebugLockIRQ, *pulLockFlags);
+ }
+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
+ else
+ {
+ LinuxLockMutex(&gsDebugMutexNonIRQ);
+ }
+#endif
+}
+
+static inline void ReleaseBufferLock(unsigned long ulLockFlags)
+{
+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
+ if (USE_SPIN_LOCK)
+#endif
+ {
+ spin_unlock_irqrestore(&gsDebugLockIRQ, ulLockFlags);
+ }
+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
+ else
+ {
+ LinuxUnLockMutex(&gsDebugMutexNonIRQ);
+ }
+#endif
+}
+
+static inline void SelectBuffer(IMG_CHAR **ppszBuf, IMG_UINT32 *pui32BufSiz)
+{
+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
+ if (USE_SPIN_LOCK)
+#endif
+ {
+ *ppszBuf = gszBufferIRQ;
+ *pui32BufSiz = sizeof(gszBufferIRQ);
+ }
+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
+ else
+ {
+ *ppszBuf = gszBufferNonIRQ;
+ *pui32BufSiz = sizeof(gszBufferNonIRQ);
+ }
+#endif
+}
+
+/*
+ * Append a string to a buffer using formatted conversion.
+ * The function takes a variable number of arguments, pointed
+ * to by the var args list.
+ */
+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 true if string was truncated */
+ return (i32Len < 0 || i32Len >= (IMG_INT32)ui32Space) ? IMG_TRUE : IMG_FALSE;
+}
+
+/* Actually required for ReleasePrintf too */
+
+IMG_VOID PVRDPFInit(IMG_VOID)
+{
+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
+ LinuxInitMutex(&gsDebugMutexNonIRQ);
+#endif
+}
+
+/*!
+******************************************************************************
+ @Function PVRSRVReleasePrintf
+ @Description To output an important message to the user in release builds
+ @Input pszFormat - The message format string
+ @Input ... - Zero or more arguments for use by the format string
+ @Return None
+ ******************************************************************************/
+IMG_VOID PVRSRVReleasePrintf(const IMG_CHAR *pszFormat, ...)
+{
+ va_list vaArgs;
+ unsigned long ulLockFlags = 0;
+ IMG_CHAR *pszBuf;
+ IMG_UINT32 ui32BufSiz;
+
+ SelectBuffer(&pszBuf, &ui32BufSiz);
+
+ va_start(vaArgs, pszFormat);
+
+ GetBufferLock(&ulLockFlags);
+ strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1));
+
+ if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
+ {
+ printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
+ }
+ else
+ {
+ printk(KERN_INFO "%s\n", pszBuf);
+ }
+
+ ReleaseBufferLock(ulLockFlags);
+ va_end(vaArgs);
+
+}
+
+#if defined(PVRSRV_NEED_PVR_TRACE)
+
+/*!
+******************************************************************************
+ @Function PVRTrace
+ @Description To output a debug message to the user
+ @Input pszFormat - The message format string
+ @Input ... - Zero or more arguments for use by the format string
+ @Return None
+ ******************************************************************************/
+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);
+}
+
+#endif /* defined(PVRSRV_NEED_PVR_TRACE) */
+
+#if defined(PVRSRV_NEED_PVR_DPF)
+
+/*
+ * Append a string to a buffer using formatted conversion.
+ * The function takes a variable number of arguments, calling
+ * VBAppend to do the actual work.
+ */
+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;
+}
+
+/*!
+******************************************************************************
+ @Function PVRSRVDebugPrintf
+ @Description To output a debug message to the user
+ @Input uDebugLevel - The current debug level
+ @Input pszFile - The source file generating the message
+ @Input uLine - The line of the source file
+ @Input pszFormat - The message format string
+ @Input ... - Zero or more arguments for use by the format string
+ @Return None
+ ******************************************************************************/
+IMG_VOID PVRSRVDebugPrintf (
+ IMG_UINT32 ui32DebugLevel,
+ const IMG_CHAR* pszFullFileName,
+ IMG_UINT32 ui32Line,
+ const IMG_CHAR* pszFormat,
+ ...
+ )
+{
+ IMG_BOOL bTrace;
+ const IMG_CHAR *pszFileName = pszFullFileName;
+ IMG_CHAR *pszLeafName;
+
+
+ bTrace = (IMG_BOOL)(ui32DebugLevel & DBGPRIV_CALLTRACE) ? IMG_TRUE : IMG_FALSE;
+
+ if (gPVRDebugLevel & ui32DebugLevel)
+ {
+ va_list vaArgs;
+ unsigned long ulLockFlags = 0;
+ IMG_CHAR *pszBuf;
+ IMG_UINT32 ui32BufSiz;
+
+ SelectBuffer(&pszBuf, &ui32BufSiz);
+
+ va_start(vaArgs, pszFormat);
+
+ GetBufferLock(&ulLockFlags);
+
+ /* Add in the level of warning */
+ if (bTrace == IMG_FALSE)
+ {
+ 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
+ {
+ /* Traces don't need a location */
+ if (bTrace == IMG_FALSE)
+ {
+#ifdef DEBUG_LOG_PATH_TRUNCATE
+ /* Buffer for rewriting filepath in log messages */
+ static IMG_CHAR szFileNameRewrite[PVR_MAX_FILEPATH_LEN];
+
+ IMG_CHAR* pszTruncIter;
+ IMG_CHAR* pszTruncBackInter;
+
+ /* Truncate path (DEBUG_LOG_PATH_TRUNCATE shoud be set to EURASIA env var)*/
+ if (strlen(pszFullFileName) > strlen(DEBUG_LOG_PATH_TRUNCATE)+1)
+ pszFileName = pszFullFileName + strlen(DEBUG_LOG_PATH_TRUNCATE)+1;
+
+ /* Try to find '/../' entries and remove it together with
+ previous entry. Repeat unit all removed */
+ strncpy(szFileNameRewrite, pszFileName,PVR_MAX_FILEPATH_LEN);
+
+ if(strlen(szFileNameRewrite) == PVR_MAX_FILEPATH_LEN-1) {
+ IMG_CHAR szTruncateMassage[] = "FILENAME TRUNCATED";
+ strcpy(szFileNameRewrite + (PVR_MAX_FILEPATH_LEN - 1 - strlen(szTruncateMassage)), szTruncateMassage);
+ }
+
+ pszTruncIter = szFileNameRewrite;
+ while(*pszTruncIter++ != 0)
+ {
+ IMG_CHAR* pszNextStartPoint;
+ /* Find '/../' pattern */
+ if(
+ !( ( *pszTruncIter == '/' && (pszTruncIter-4 >= szFileNameRewrite) ) &&
+ ( *(pszTruncIter-1) == '.') &&
+ ( *(pszTruncIter-2) == '.') &&
+ ( *(pszTruncIter-3) == '/') )
+ ) continue;
+
+ /* Find previous '/' */
+ pszTruncBackInter = pszTruncIter - 3;
+ while(*(--pszTruncBackInter) != '/')
+ {
+ if(pszTruncBackInter <= szFileNameRewrite) break;
+ }
+ pszNextStartPoint = pszTruncBackInter;
+
+ /* Remove found region */
+ while(*pszTruncIter != 0)
+ {
+ *pszTruncBackInter++ = *pszTruncIter++;
+ }
+ *pszTruncBackInter = 0;
+
+ /* Start again */
+ pszTruncIter = pszNextStartPoint;
+ }
+
+ pszFileName = szFileNameRewrite;
+ /* Remove first '/' if exist (it's always relative path */
+ if(*pszFileName == '/') pszFileName++;
+#endif
+
+#if !defined(__sh__)
+ pszLeafName = (IMG_CHAR *)strrchr (pszFileName, '\\');
+
+ if (pszLeafName)
+ {
+ pszFileName = pszLeafName;
+ }
+#endif /* __sh__ */
+
+ if (BAppend(pszBuf, ui32BufSiz, " [%u, %s]", ui32Line, pszFileName))
+ {
+ printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
+ }
+ else
+ {
+ printk(KERN_INFO "%s\n", pszBuf);
+ }
+ }
+ else
+ {
+ printk(KERN_INFO "%s\n", pszBuf);
+ }
+ }
+
+ ReleaseBufferLock(ulLockFlags);
+
+ va_end (vaArgs);
+ }
+}
+
+#endif /* PVRSRV_NEED_PVR_DPF */
+
+#if defined(DEBUG)
+
+IMG_INT PVRDebugProcSetLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data)
+{
+#define _PROC_SET_BUFFER_SZ 6
+ IMG_CHAR data_buffer[_PROC_SET_BUFFER_SZ];
+
+ if (count > _PROC_SET_BUFFER_SZ)
+ {
+ return -EINVAL;
+ }
+ else
+ {
+ if (pvr_copy_from_user(data_buffer, buffer, count))
+ return -EINVAL;
+ if (data_buffer[count - 1] != '\n')
+ return -EINVAL;
+ if (sscanf(data_buffer, "%i", &gPVRDebugLevel) == 0)
+ return -EINVAL;
+ gPVRDebugLevel &= (1 << DBGPRIV_DBGLEVEL_COUNT) - 1;
+ }
+ return (count);
+}
+
+void ProcSeqShowDebugLevel(struct seq_file *sfile,void* el)
+{
+ seq_printf(sfile, "%u\n", gPVRDebugLevel);
+}
+
+#endif /* defined(DEBUG) */
diff --git a/pvr-source/services4/srvkm/env/linux/pvr_uaccess.h b/pvr-source/services4/srvkm/env/linux/pvr_uaccess.h
new file mode 100644
index 0000000..7583d7e
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/pvr_uaccess.h
@@ -0,0 +1,88 @@
+/*************************************************************************/ /*!
+@Title Utility functions for user space access
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef __PVR_UACCESS_H__
+#define __PVR_UACCESS_H__
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#endif
+
+#include <asm/uaccess.h>
+
+static inline unsigned long pvr_copy_to_user(void __user *pvTo, const void *pvFrom, unsigned long ulBytes)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
+ if (access_ok(VERIFY_WRITE, pvTo, ulBytes))
+ {
+ return __copy_to_user(pvTo, pvFrom, ulBytes);
+ }
+ return ulBytes;
+#else
+ return copy_to_user(pvTo, pvFrom, ulBytes);
+#endif
+}
+
+static inline unsigned long pvr_copy_from_user(void *pvTo, const void __user *pvFrom, unsigned long ulBytes)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
+ /*
+ * The compile time correctness checking introduced for copy_from_user in
+ * Linux 2.6.33 isn't fully comaptible with our usage of the function.
+ */
+ if (access_ok(VERIFY_READ, pvFrom, ulBytes))
+ {
+ return __copy_from_user(pvTo, pvFrom, ulBytes);
+ }
+ return ulBytes;
+#else
+ return copy_from_user(pvTo, pvFrom, ulBytes);
+#endif
+}
+
+#define pvr_put_user put_user
+#define pvr_get_user get_user
+
+#endif /* __PVR_UACCESS_H__ */
+
diff --git a/pvr-source/services4/srvkm/env/linux/sysfs.c b/pvr-source/services4/srvkm/env/linux/sysfs.c
new file mode 100644
index 0000000..63066ad
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/sysfs.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2012 Texas Instruments, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
+#include <linux/stat.h>
+#include <asm/page.h>
+#include <linux/slab.h>
+#include "services_headers.h"
+#include "pdump_km.h"
+#include "sysfs.h"
+
+/* sysfs structures */
+struct pvrsrv_attribute {
+ struct attribute attr;
+ int sgx_version;
+ int sgx_revision;
+};
+
+static struct pvrsrv_attribute PVRSRVAttr = {
+ .attr.name = "egl.cfg",
+ .attr.mode = S_IRUGO,
+ .sgx_version = SGXCORE,
+ .sgx_revision = SGX_CORE_REV,
+};
+
+/* sysfs read function */
+static ssize_t PVRSRVEglCfgShow(struct kobject *kobj, struct attribute *attr,
+ char *buffer) {
+ struct pvrsrv_attribute *pvrsrv_attr;
+
+ pvrsrv_attr = container_of(attr, struct pvrsrv_attribute, attr);
+ return snprintf(buffer, PAGE_SIZE, "0 0 android\n0 1 POWERVR_SGX%d_%d",
+ pvrsrv_attr->sgx_version, pvrsrv_attr->sgx_revision);
+}
+
+/* sysfs write function unsupported*/
+static ssize_t PVRSRVEglCfgStore(struct kobject *kobj, struct attribute *attr,
+ const char *buffer, size_t size) {
+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVEglCfgStore not implemented"));
+ return 0;
+}
+
+static struct attribute *pvrsrv_sysfs_attrs[] = {
+ &PVRSRVAttr.attr,
+ NULL
+};
+
+static const struct sysfs_ops pvrsrv_sysfs_ops = {
+ .show = PVRSRVEglCfgShow,
+ .store = PVRSRVEglCfgStore,
+};
+
+static struct kobj_type pvrsrv_ktype = {
+ .sysfs_ops = &pvrsrv_sysfs_ops,
+ .default_attrs = pvrsrv_sysfs_attrs,
+};
+
+/* create sysfs entry /sys/egl/egl.cfg to determine
+ which gfx libraries to load */
+
+int PVRSRVCreateSysfsEntry(void)
+{
+ struct kobject *egl_cfg_kobject;
+ int r;
+
+ egl_cfg_kobject = kzalloc(sizeof(*egl_cfg_kobject), GFP_KERNEL);
+ r = kobject_init_and_add(egl_cfg_kobject, &pvrsrv_ktype, NULL, "egl");
+
+ if (r) {
+ PVR_DPF((PVR_DBG_ERROR,
+ "Failed to create egl.cfg sysfs entry"));
+ return PVRSRV_ERROR_INIT_FAILURE;
+ }
+
+ return PVRSRV_OK;
+}
diff --git a/pvr-source/services4/srvkm/env/linux/sysfs.h b/pvr-source/services4/srvkm/env/linux/sysfs.h
new file mode 100644
index 0000000..fb8d20f
--- /dev/null
+++ b/pvr-source/services4/srvkm/env/linux/sysfs.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2012 Texas Instruments, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __SYSFS_H
+#define __SYSFS_H
+
+int PVRSRVCreateSysfsEntry(void);
+
+#endif
diff --git a/pvr-source/services4/srvkm/hwdefs/mnemedefs.h b/pvr-source/services4/srvkm/hwdefs/mnemedefs.h
new file mode 100644
index 0000000..83a65f5
--- /dev/null
+++ b/pvr-source/services4/srvkm/hwdefs/mnemedefs.h
@@ -0,0 +1,117 @@
+/*************************************************************************/ /*!
+@Title Hardware defs for MNEME.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _MNEMEDEFS_KM_H_
+#define _MNEMEDEFS_KM_H_
+
+/* Register MNE_CR_CTRL */
+#define MNE_CR_CTRL 0x0D00
+#define MNE_CR_CTRL_BYP_CC_N_MASK 0x00010000U
+#define MNE_CR_CTRL_BYP_CC_N_SHIFT 16
+#define MNE_CR_CTRL_BYP_CC_N_SIGNED 0
+#define MNE_CR_CTRL_BYP_CC_MASK 0x00008000U
+#define MNE_CR_CTRL_BYP_CC_SHIFT 15
+#define MNE_CR_CTRL_BYP_CC_SIGNED 0
+#define MNE_CR_CTRL_USE_INVAL_REQ_MASK 0x00007800U
+#define MNE_CR_CTRL_USE_INVAL_REQ_SHIFT 11
+#define MNE_CR_CTRL_USE_INVAL_REQ_SIGNED 0
+#define MNE_CR_CTRL_BYPASS_ALL_MASK 0x00000400U
+#define MNE_CR_CTRL_BYPASS_ALL_SHIFT 10
+#define MNE_CR_CTRL_BYPASS_ALL_SIGNED 0
+#define MNE_CR_CTRL_BYPASS_MASK 0x000003E0U
+#define MNE_CR_CTRL_BYPASS_SHIFT 5
+#define MNE_CR_CTRL_BYPASS_SIGNED 0
+#define MNE_CR_CTRL_PAUSE_MASK 0x00000010U
+#define MNE_CR_CTRL_PAUSE_SHIFT 4
+#define MNE_CR_CTRL_PAUSE_SIGNED 0
+/* Register MNE_CR_USE_INVAL */
+#define MNE_CR_USE_INVAL 0x0D04
+#define MNE_CR_USE_INVAL_ADDR_MASK 0xFFFFFFFFU
+#define MNE_CR_USE_INVAL_ADDR_SHIFT 0
+#define MNE_CR_USE_INVAL_ADDR_SIGNED 0
+/* Register MNE_CR_STAT */
+#define MNE_CR_STAT 0x0D08
+#define MNE_CR_STAT_PAUSED_MASK 0x00000400U
+#define MNE_CR_STAT_PAUSED_SHIFT 10
+#define MNE_CR_STAT_PAUSED_SIGNED 0
+#define MNE_CR_STAT_READS_MASK 0x000003FFU
+#define MNE_CR_STAT_READS_SHIFT 0
+#define MNE_CR_STAT_READS_SIGNED 0
+/* Register MNE_CR_STAT_STATS */
+#define MNE_CR_STAT_STATS 0x0D0C
+#define MNE_CR_STAT_STATS_RST_MASK 0x000FFFF0U
+#define MNE_CR_STAT_STATS_RST_SHIFT 4
+#define MNE_CR_STAT_STATS_RST_SIGNED 0
+#define MNE_CR_STAT_STATS_SEL_MASK 0x0000000FU
+#define MNE_CR_STAT_STATS_SEL_SHIFT 0
+#define MNE_CR_STAT_STATS_SEL_SIGNED 0
+/* Register MNE_CR_STAT_STATS_OUT */
+#define MNE_CR_STAT_STATS_OUT 0x0D10
+#define MNE_CR_STAT_STATS_OUT_VALUE_MASK 0xFFFFFFFFU
+#define MNE_CR_STAT_STATS_OUT_VALUE_SHIFT 0
+#define MNE_CR_STAT_STATS_OUT_VALUE_SIGNED 0
+/* Register MNE_CR_EVENT_STATUS */
+#define MNE_CR_EVENT_STATUS 0x0D14
+#define MNE_CR_EVENT_STATUS_INVAL_MASK 0x00000001U
+#define MNE_CR_EVENT_STATUS_INVAL_SHIFT 0
+#define MNE_CR_EVENT_STATUS_INVAL_SIGNED 0
+/* Register MNE_CR_EVENT_CLEAR */
+#define MNE_CR_EVENT_CLEAR 0x0D18
+#define MNE_CR_EVENT_CLEAR_INVAL_MASK 0x00000001U
+#define MNE_CR_EVENT_CLEAR_INVAL_SHIFT 0
+#define MNE_CR_EVENT_CLEAR_INVAL_SIGNED 0
+/* Register MNE_CR_CTRL_INVAL */
+#define MNE_CR_CTRL_INVAL 0x0D20
+#define MNE_CR_CTRL_INVAL_PREQ_PDS_MASK 0x00000008U
+#define MNE_CR_CTRL_INVAL_PREQ_PDS_SHIFT 3
+#define MNE_CR_CTRL_INVAL_PREQ_PDS_SIGNED 0
+#define MNE_CR_CTRL_INVAL_PREQ_USEC_MASK 0x00000004U
+#define MNE_CR_CTRL_INVAL_PREQ_USEC_SHIFT 2
+#define MNE_CR_CTRL_INVAL_PREQ_USEC_SIGNED 0
+#define MNE_CR_CTRL_INVAL_PREQ_CACHE_MASK 0x00000002U
+#define MNE_CR_CTRL_INVAL_PREQ_CACHE_SHIFT 1
+#define MNE_CR_CTRL_INVAL_PREQ_CACHE_SIGNED 0
+#define MNE_CR_CTRL_INVAL_ALL_MASK 0x00000001U
+#define MNE_CR_CTRL_INVAL_ALL_SHIFT 0
+#define MNE_CR_CTRL_INVAL_ALL_SIGNED 0
+
+#endif /* _MNEMEDEFS_KM_H_ */
+
diff --git a/pvr-source/services4/srvkm/hwdefs/ocpdefs.h b/pvr-source/services4/srvkm/hwdefs/ocpdefs.h
new file mode 100644
index 0000000..07a6412
--- /dev/null
+++ b/pvr-source/services4/srvkm/hwdefs/ocpdefs.h
@@ -0,0 +1,308 @@
+/*************************************************************************/ /*!
+@Title OCP HW definitions.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _OCPDEFS_H_
+#define _OCPDEFS_H_
+
+/* Register EUR_CR_OCP_REVISION */
+#define EUR_CR_OCP_REVISION 0xFE00
+#define EUR_CR_OCP_REVISION_REV_MASK 0xFFFFFFFFUL
+#define EUR_CR_OCP_REVISION_REV_SHIFT 0
+#define EUR_CR_OCP_REVISION_REV_SIGNED 0
+
+/* Register EUR_CR_OCP_HWINFO */
+#define EUR_CR_OCP_HWINFO 0xFE04
+#define EUR_CR_OCP_HWINFO_SYS_BUS_WIDTH_MASK 0x00000003UL
+#define EUR_CR_OCP_HWINFO_SYS_BUS_WIDTH_SHIFT 0
+#define EUR_CR_OCP_HWINFO_SYS_BUS_WIDTH_SIGNED 0
+
+#define EUR_CR_OCP_HWINFO_MEM_BUS_WIDTH_MASK 0x00000004UL
+#define EUR_CR_OCP_HWINFO_MEM_BUS_WIDTH_SHIFT 2
+#define EUR_CR_OCP_HWINFO_MEM_BUS_WIDTH_SIGNED 0
+
+/* Register EUR_CR_OCP_SYSCONFIG */
+#define EUR_CR_OCP_SYSCONFIG 0xFE10
+#define EUR_CR_OCP_SYSCONFIG_IDLE_MODE_MASK 0x0000000CUL
+#define EUR_CR_OCP_SYSCONFIG_IDLE_MODE_SHIFT 2
+#define EUR_CR_OCP_SYSCONFIG_IDLE_MODE_SIGNED 0
+
+#define EUR_CR_OCP_SYSCONFIG_STANDBY_MODE_MASK 0x00000030UL
+#define EUR_CR_OCP_SYSCONFIG_STANDBY_MODE_SHIFT 4
+#define EUR_CR_OCP_SYSCONFIG_STANDBY_MODE_SIGNED 0
+
+/* Register EUR_CR_OCP_IRQSTATUS_RAW_0 */
+#define EUR_CR_OCP_IRQSTATUS_RAW_0 0xFE24
+#define EUR_CR_OCP_IRQSTATUS_RAW_0_INIT_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQSTATUS_RAW_0_INIT_SHIFT 0
+#define EUR_CR_OCP_IRQSTATUS_RAW_0_INIT_SIGNED 0
+
+/* Register EUR_CR_OCP_IRQSTATUS_RAW_1 */
+#define EUR_CR_OCP_IRQSTATUS_RAW_1 0xFE28
+#define EUR_CR_OCP_IRQSTATUS_RAW_1_TARGET_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQSTATUS_RAW_1_TARGET_SHIFT 0
+#define EUR_CR_OCP_IRQSTATUS_RAW_1_TARGET_SIGNED 0
+
+/* Register EUR_CR_OCP_IRQSTATUS_RAW_2 */
+#define EUR_CR_OCP_IRQSTATUS_RAW_2 0xFE2C
+#define EUR_CR_OCP_IRQSTATUS_RAW_2_SGXCORE_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQSTATUS_RAW_2_SGXCORE_SHIFT 0
+#define EUR_CR_OCP_IRQSTATUS_RAW_2_SGXCORE_SIGNED 0
+
+/* Register EUR_CR_OCP_IRQSTATUS_0 */
+#define EUR_CR_OCP_IRQSTATUS_0 0xFE30
+#define EUR_CR_OCP_IRQSTATUS_0_INIT_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQSTATUS_0_INIT_SHIFT 0
+#define EUR_CR_OCP_IRQSTATUS_0_INIT_SIGNED 0
+
+/* Register EUR_CR_OCP_IRQSTATUS_1 */
+#define EUR_CR_OCP_IRQSTATUS_1 0xFE34
+#define EUR_CR_OCP_IRQSTATUS_1_TARGET_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQSTATUS_1_TARGET_SHIFT 0
+#define EUR_CR_OCP_IRQSTATUS_1_TARGET_SIGNED 0
+
+/* Register EUR_CR_OCP_IRQSTATUS_2 */
+#define EUR_CR_OCP_IRQSTATUS_2 0xFE38
+#define EUR_CR_OCP_IRQSTATUS_2_SGXCORE_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQSTATUS_2_SGXCORE_SHIFT 0
+#define EUR_CR_OCP_IRQSTATUS_2_SGXCORE_SIGNED 0
+
+/* Register EUR_CR_OCP_IRQENABLE_SET_0 */
+#define EUR_CR_OCP_IRQENABLE_SET_0 0xFE3C
+#define EUR_CR_OCP_IRQENABLE_SET_0_INIT_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQENABLE_SET_0_INIT_SHIFT 0
+#define EUR_CR_OCP_IRQENABLE_SET_0_INIT_SIGNED 0
+
+/* Register EUR_CR_OCP_IRQENABLE_SET_1 */
+#define EUR_CR_OCP_IRQENABLE_SET_1 0xFE40
+#define EUR_CR_OCP_IRQENABLE_SET_1_TARGET_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQENABLE_SET_1_TARGET_SHIFT 0
+#define EUR_CR_OCP_IRQENABLE_SET_1_TARGET_SIGNED 0
+
+/* Register EUR_CR_OCP_IRQENABLE_SET_2 */
+#define EUR_CR_OCP_IRQENABLE_SET_2 0xFE44
+#define EUR_CR_OCP_IRQENABLE_SET_2_SGXCORE_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQENABLE_SET_2_SGXCORE_SHIFT 0
+#define EUR_CR_OCP_IRQENABLE_SET_2_SGXCORE_SIGNED 0
+
+/* Register EUR_CR_OCP_IRQENABLE_CLR_0 */
+#define EUR_CR_OCP_IRQENABLE_CLR_0 0xFE48
+#define EUR_CR_OCP_IRQENABLE_CLR_0_INIT_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQENABLE_CLR_0_INIT_SHIFT 0
+#define EUR_CR_OCP_IRQENABLE_CLR_0_INIT_SIGNED 0
+
+/* Register EUR_CR_OCP_IRQENABLE_CLR_1 */
+#define EUR_CR_OCP_IRQENABLE_CLR_1 0xFE4C
+#define EUR_CR_OCP_IRQENABLE_CLR_1_TARGET_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQENABLE_CLR_1_TARGET_SHIFT 0
+#define EUR_CR_OCP_IRQENABLE_CLR_1_TARGET_SIGNED 0
+
+/* Register EUR_CR_OCP_IRQENABLE_CLR_2 */
+#define EUR_CR_OCP_IRQENABLE_CLR_2 0xFE50
+#define EUR_CR_OCP_IRQENABLE_CLR_2_SGXCORE_MASK 0x00000001UL
+#define EUR_CR_OCP_IRQENABLE_CLR_2_SGXCORE_SHIFT 0
+#define EUR_CR_OCP_IRQENABLE_CLR_2_SGXCORE_SIGNED 0
+
+/* Register EUR_CR_OCP_PAGE_CONFIG */
+#define EUR_CR_OCP_PAGE_CONFIG 0xFF00
+#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_SIZE_MASK 0x00000001UL
+#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_SIZE_SHIFT 0
+#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_SIZE_SIGNED 0
+
+#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_CHECK_ENABLE_MASK 0x00000004UL
+#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_CHECK_ENABLE_SHIFT 2
+#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_CHECK_ENABLE_SIGNED 0
+
+#define EUR_CR_OCP_PAGE_CONFIG_SIZE_MASK 0x00000018UL
+#define EUR_CR_OCP_PAGE_CONFIG_SIZE_SHIFT 3
+#define EUR_CR_OCP_PAGE_CONFIG_SIZE_SIGNED 0
+
+/* Register EUR_CR_OCP_INTERRUPT_EVENT */
+#define EUR_CR_OCP_INTERRUPT_EVENT 0xFF04
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNEXPECTED_MASK 0x00000001UL
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNEXPECTED_SHIFT 0
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNEXPECTED_SIGNED 0
+
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNUSED_TAG_MASK 0x00000002UL
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNUSED_TAG_SHIFT 1
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNUSED_TAG_SIGNED 0
+
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_ERROR_MASK 0x00000004UL
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_ERROR_SHIFT 2
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_ERROR_SIGNED 0
+
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_PAGE_CROSS_ERROR_MASK 0x00000008UL
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_PAGE_CROSS_ERROR_SHIFT 3
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_PAGE_CROSS_ERROR_SIGNED 0
+
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_READ_TAG_FIFO_OVR_MASK 0x00000010UL
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_READ_TAG_FIFO_OVR_SHIFT 4
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_READ_TAG_FIFO_OVR_SIGNED 0
+
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_MEM_REQ_FIFO_OVR_MASK 0x00000020UL
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_MEM_REQ_FIFO_OVR_SHIFT 5
+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_MEM_REQ_FIFO_OVR_SIGNED 0
+
+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_RESP_FIFO_FULL_MASK 0x00000100UL
+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_RESP_FIFO_FULL_SHIFT 8
+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_RESP_FIFO_FULL_SIGNED 0
+
+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_CMD_FIFO_FULL_MASK 0x00000200UL
+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_CMD_FIFO_FULL_SHIFT 9
+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_CMD_FIFO_FULL_SIGNED 0
+
+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_INVALID_OCP_CMD_MASK 0x00000400UL
+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_INVALID_OCP_CMD_SHIFT 10
+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_INVALID_OCP_CMD_SIGNED 0
+
+/* Register EUR_CR_OCP_DEBUG_CONFIG */
+#define EUR_CR_OCP_DEBUG_CONFIG 0xFF08
+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_TARGET_IDLE_MASK 0x00000003UL
+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_TARGET_IDLE_SHIFT 0
+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_TARGET_IDLE_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_INIT_IDLE_MASK 0x0000000CUL
+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_INIT_IDLE_SHIFT 2
+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_INIT_IDLE_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_PASS_DATA_MASK 0x00000010UL
+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_PASS_DATA_SHIFT 4
+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_PASS_DATA_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_CONFIG_SELECT_INIT_IDLE_MASK 0x00000020UL
+#define EUR_CR_OCP_DEBUG_CONFIG_SELECT_INIT_IDLE_SHIFT 5
+#define EUR_CR_OCP_DEBUG_CONFIG_SELECT_INIT_IDLE_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_MASK 0x80000000UL
+#define EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_SHIFT 31
+#define EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_SIGNED 0
+
+/* Register EUR_CR_OCP_DEBUG_STATUS */
+#define EUR_CR_OCP_DEBUG_STATUS 0xFF0C
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_MCONNECT_MASK 0x00000003UL
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_MCONNECT_SHIFT 0
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_MCONNECT_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SCONNECT_MASK 0x00000004UL
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SCONNECT_SHIFT 2
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SCONNECT_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEREQ_MASK 0x00000008UL
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEREQ_SHIFT 3
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEREQ_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SDISCACK_MASK 0x00000030UL
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SDISCACK_SHIFT 4
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SDISCACK_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEACK_MASK 0x000000C0UL
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEACK_SHIFT 6
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEACK_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MCONNECT0_MASK 0x00000300UL
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MCONNECT0_SHIFT 8
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MCONNECT0_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT0_MASK 0x00000400UL
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT0_SHIFT 10
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT0_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT1_MASK 0x00000800UL
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT1_SHIFT 11
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT1_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT2_MASK 0x00001000UL
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT2_SHIFT 12
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT2_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCACK_MASK 0x00006000UL
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCACK_SHIFT 13
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCACK_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCREQ_MASK 0x00008000UL
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCREQ_SHIFT 15
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCREQ_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MWAIT_MASK 0x00010000UL
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MWAIT_SHIFT 16
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MWAIT_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MSTANDBY_MASK 0x00020000UL
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MSTANDBY_SHIFT 17
+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MSTANDBY_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_CMD_OUT_MASK 0x001C0000UL
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_CMD_OUT_SHIFT 18
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_CMD_OUT_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_WHICH_TARGET_REGISTER_MASK 0x03E00000UL
+#define EUR_CR_OCP_DEBUG_STATUS_WHICH_TARGET_REGISTER_SHIFT 21
+#define EUR_CR_OCP_DEBUG_STATUS_WHICH_TARGET_REGISTER_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_RESP_ERROR_MASK 0x04000000UL
+#define EUR_CR_OCP_DEBUG_STATUS_RESP_ERROR_SHIFT 26
+#define EUR_CR_OCP_DEBUG_STATUS_RESP_ERROR_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_CMD_FIFO_FULL_MASK 0x08000000UL
+#define EUR_CR_OCP_DEBUG_STATUS_CMD_FIFO_FULL_SHIFT 27
+#define EUR_CR_OCP_DEBUG_STATUS_CMD_FIFO_FULL_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_RESP_FIFO_FULL_MASK 0x10000000UL
+#define EUR_CR_OCP_DEBUG_STATUS_RESP_FIFO_FULL_SHIFT 28
+#define EUR_CR_OCP_DEBUG_STATUS_RESP_FIFO_FULL_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_IDLE_MASK 0x20000000UL
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_IDLE_SHIFT 29
+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_IDLE_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_CMD_RESP_DEBUG_STATE_MASK 0x40000000UL
+#define EUR_CR_OCP_DEBUG_STATUS_CMD_RESP_DEBUG_STATE_SHIFT 30
+#define EUR_CR_OCP_DEBUG_STATUS_CMD_RESP_DEBUG_STATE_SIGNED 0
+
+#define EUR_CR_OCP_DEBUG_STATUS_CMD_DEBUG_STATE_MASK 0x80000000UL
+#define EUR_CR_OCP_DEBUG_STATUS_CMD_DEBUG_STATE_SHIFT 31
+#define EUR_CR_OCP_DEBUG_STATUS_CMD_DEBUG_STATE_SIGNED 0
+
+
+#endif /* _OCPDEFS_H_ */
+
+/*****************************************************************************
+ End of file (ocpdefs.h)
+*****************************************************************************/
diff --git a/pvr-source/services4/srvkm/hwdefs/sgx520defs.h b/pvr-source/services4/srvkm/hwdefs/sgx520defs.h
new file mode 100644
index 0000000..80c3363
--- /dev/null
+++ b/pvr-source/services4/srvkm/hwdefs/sgx520defs.h
@@ -0,0 +1,555 @@
+/*************************************************************************/ /*!
+@Title Hardware defs for SGX520.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _SGX520DEFS_KM_H_
+#define _SGX520DEFS_KM_H_
+
+/* Register EUR_CR_CLKGATECTL */
+#define EUR_CR_CLKGATECTL 0x0000
+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL_TA_CLKG_MASK 0x00003000U
+#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT 12
+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL_USE_CLKG_MASK 0x00300000U
+#define EUR_CR_CLKGATECTL_USE_CLKG_SHIFT 20
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
+/* Register EUR_CR_CLKGATESTATUS */
+#define EUR_CR_CLKGATESTATUS 0x0004
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK 0x00000010U
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 4
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK 0x00000100U
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 8
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK 0x00001000U
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT 12
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK 0x00010000U
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 16
+#define EUR_CR_CLKGATESTATUS_USE_CLKS_MASK 0x00100000U
+#define EUR_CR_CLKGATESTATUS_USE_CLKS_SHIFT 20
+/* Register EUR_CR_CLKGATECTLOVR */
+#define EUR_CR_CLKGATECTLOVR 0x0008
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK 0x00000030U
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 4
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK 0x00000300U
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 8
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK 0x00003000U
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT 12
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK 0x00030000U
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 16
+#define EUR_CR_CLKGATECTLOVR_USE_CLKO_MASK 0x00300000U
+#define EUR_CR_CLKGATECTLOVR_USE_CLKO_SHIFT 20
+/* Register EUR_CR_CORE_ID */
+#define EUR_CR_CORE_ID 0x0010
+#define EUR_CR_CORE_ID_CONFIG_MASK 0x0000FFFFU
+#define EUR_CR_CORE_ID_CONFIG_SHIFT 0
+#define EUR_CR_CORE_ID_ID_MASK 0xFFFF0000U
+#define EUR_CR_CORE_ID_ID_SHIFT 16
+/* Register EUR_CR_CORE_REVISION */
+#define EUR_CR_CORE_REVISION 0x0014
+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
+#define EUR_CR_CORE_REVISION_MINOR_MASK 0x0000FF00U
+#define EUR_CR_CORE_REVISION_MINOR_SHIFT 8
+#define EUR_CR_CORE_REVISION_MAJOR_MASK 0x00FF0000U
+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT 16
+#define EUR_CR_CORE_REVISION_DESIGNER_MASK 0xFF000000U
+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
+/* Register EUR_CR_DESIGNER_REV_FIELD1 */
+#define EUR_CR_DESIGNER_REV_FIELD1 0x0018
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
+/* Register EUR_CR_DESIGNER_REV_FIELD2 */
+#define EUR_CR_DESIGNER_REV_FIELD2 0x001C
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
+/* Register EUR_CR_SOFT_RESET */
+#define EUR_CR_SOFT_RESET 0x0080
+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK 0x00000001U
+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT 0
+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK 0x00000004U
+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT 2
+#define EUR_CR_SOFT_RESET_TA_RESET_MASK 0x00000008U
+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT 3
+#define EUR_CR_SOFT_RESET_USE_RESET_MASK 0x00000010U
+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT 4
+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK 0x00000020U
+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT 5
+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK 0x00000040U
+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT 6
+/* Register EUR_CR_EVENT_HOST_ENABLE2 */
+#define EUR_CR_EVENT_HOST_ENABLE2 0x0110
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
+/* Register EUR_CR_EVENT_HOST_CLEAR2 */
+#define EUR_CR_EVENT_HOST_CLEAR2 0x0114
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
+/* Register EUR_CR_EVENT_STATUS2 */
+#define EUR_CR_EVENT_STATUS2 0x0118
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
+/* Register EUR_CR_EVENT_STATUS */
+#define EUR_CR_EVENT_STATUS 0x012C
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_STATUS_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT 29
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_STATUS_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_STATUS_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
+/* Register EUR_CR_EVENT_HOST_ENABLE */
+#define EUR_CR_EVENT_HOST_ENABLE 0x0130
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#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 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
+/* Register EUR_CR_EVENT_HOST_CLEAR */
+#define EUR_CR_EVENT_HOST_CLEAR 0x0134
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#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 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
+/* Register EUR_CR_TIMER */
+#define EUR_CR_TIMER 0x0144
+#define EUR_CR_TIMER_VALUE_MASK 0xFFFFFFFFU
+#define EUR_CR_TIMER_VALUE_SHIFT 0
+/* Register EUR_CR_USE_CODE_BASE_0 */
+#define EUR_CR_USE_CODE_BASE_0 0x0A0C
+#define EUR_CR_USE_CODE_BASE_ADDR_00_MASK 0x000FFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_00_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_00_MASK 0x00300000U
+#define EUR_CR_USE_CODE_BASE_DM_00_SHIFT 20
+/* Register EUR_CR_USE_CODE_BASE_1 */
+#define EUR_CR_USE_CODE_BASE_1 0x0A10
+#define EUR_CR_USE_CODE_BASE_ADDR_01_MASK 0x000FFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_01_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_01_MASK 0x00300000U
+#define EUR_CR_USE_CODE_BASE_DM_01_SHIFT 20
+/* Register EUR_CR_USE_CODE_BASE_2 */
+#define EUR_CR_USE_CODE_BASE_2 0x0A14
+#define EUR_CR_USE_CODE_BASE_ADDR_02_MASK 0x000FFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_02_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_02_MASK 0x00300000U
+#define EUR_CR_USE_CODE_BASE_DM_02_SHIFT 20
+/* Register EUR_CR_USE_CODE_BASE_3 */
+#define EUR_CR_USE_CODE_BASE_3 0x0A18
+#define EUR_CR_USE_CODE_BASE_ADDR_03_MASK 0x000FFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_03_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_03_MASK 0x00300000U
+#define EUR_CR_USE_CODE_BASE_DM_03_SHIFT 20
+/* Register EUR_CR_USE_CODE_BASE_4 */
+#define EUR_CR_USE_CODE_BASE_4 0x0A1C
+#define EUR_CR_USE_CODE_BASE_ADDR_04_MASK 0x000FFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_04_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_04_MASK 0x00300000U
+#define EUR_CR_USE_CODE_BASE_DM_04_SHIFT 20
+/* Register EUR_CR_USE_CODE_BASE_5 */
+#define EUR_CR_USE_CODE_BASE_5 0x0A20
+#define EUR_CR_USE_CODE_BASE_ADDR_05_MASK 0x000FFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_05_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_05_MASK 0x00300000U
+#define EUR_CR_USE_CODE_BASE_DM_05_SHIFT 20
+/* Register EUR_CR_USE_CODE_BASE_6 */
+#define EUR_CR_USE_CODE_BASE_6 0x0A24
+#define EUR_CR_USE_CODE_BASE_ADDR_06_MASK 0x000FFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_06_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_06_MASK 0x00300000U
+#define EUR_CR_USE_CODE_BASE_DM_06_SHIFT 20
+/* Register EUR_CR_USE_CODE_BASE_7 */
+#define EUR_CR_USE_CODE_BASE_7 0x0A28
+#define EUR_CR_USE_CODE_BASE_ADDR_07_MASK 0x000FFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_07_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_07_MASK 0x00300000U
+#define EUR_CR_USE_CODE_BASE_DM_07_SHIFT 20
+/* Register EUR_CR_USE_CODE_BASE_8 */
+#define EUR_CR_USE_CODE_BASE_8 0x0A2C
+#define EUR_CR_USE_CODE_BASE_ADDR_08_MASK 0x000FFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_08_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_08_MASK 0x00300000U
+#define EUR_CR_USE_CODE_BASE_DM_08_SHIFT 20
+/* Register EUR_CR_USE_CODE_BASE_9 */
+#define EUR_CR_USE_CODE_BASE_9 0x0A30
+#define EUR_CR_USE_CODE_BASE_ADDR_09_MASK 0x000FFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_09_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_09_MASK 0x00300000U
+#define EUR_CR_USE_CODE_BASE_DM_09_SHIFT 20
+/* Register EUR_CR_USE_CODE_BASE_10 */
+#define EUR_CR_USE_CODE_BASE_10 0x0A34
+#define EUR_CR_USE_CODE_BASE_ADDR_10_MASK 0x000FFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_10_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_10_MASK 0x00300000U
+#define EUR_CR_USE_CODE_BASE_DM_10_SHIFT 20
+/* Register EUR_CR_USE_CODE_BASE_11 */
+#define EUR_CR_USE_CODE_BASE_11 0x0A38
+#define EUR_CR_USE_CODE_BASE_ADDR_11_MASK 0x000FFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_11_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_11_MASK 0x00300000U
+#define EUR_CR_USE_CODE_BASE_DM_11_SHIFT 20
+/* Register EUR_CR_USE_CODE_BASE_12 */
+#define EUR_CR_USE_CODE_BASE_12 0x0A3C
+#define EUR_CR_USE_CODE_BASE_ADDR_12_MASK 0x000FFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_12_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_12_MASK 0x00300000U
+#define EUR_CR_USE_CODE_BASE_DM_12_SHIFT 20
+/* Register EUR_CR_USE_CODE_BASE_13 */
+#define EUR_CR_USE_CODE_BASE_13 0x0A40
+#define EUR_CR_USE_CODE_BASE_ADDR_13_MASK 0x000FFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_13_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_13_MASK 0x00300000U
+#define EUR_CR_USE_CODE_BASE_DM_13_SHIFT 20
+/* Register EUR_CR_USE_CODE_BASE_14 */
+#define EUR_CR_USE_CODE_BASE_14 0x0A44
+#define EUR_CR_USE_CODE_BASE_ADDR_14_MASK 0x000FFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_14_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_14_MASK 0x00300000U
+#define EUR_CR_USE_CODE_BASE_DM_14_SHIFT 20
+/* Register EUR_CR_USE_CODE_BASE_15 */
+#define EUR_CR_USE_CODE_BASE_15 0x0A48
+#define EUR_CR_USE_CODE_BASE_ADDR_15_MASK 0x000FFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_15_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_15_MASK 0x00300000U
+#define EUR_CR_USE_CODE_BASE_DM_15_SHIFT 20
+/* Register EUR_CR_PDS_EXEC_BASE */
+#define EUR_CR_PDS_EXEC_BASE 0x0AB8
+#define EUR_CR_PDS_EXEC_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_PDS_EXEC_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_EVENT_KICKER */
+#define EUR_CR_EVENT_KICKER 0x0AC4
+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK 0x0FFFFFF0U
+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT 4
+/* Register EUR_CR_EVENT_KICK */
+#define EUR_CR_EVENT_KICK 0x0AC8
+#define EUR_CR_EVENT_KICK_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK_NOW_SHIFT 0
+/* Register EUR_CR_EVENT_TIMER */
+#define EUR_CR_EVENT_TIMER 0x0ACC
+#define EUR_CR_EVENT_TIMER_ENABLE_MASK 0x01000000U
+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT 24
+#define EUR_CR_EVENT_TIMER_VALUE_MASK 0x00FFFFFFU
+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT 0
+/* Register EUR_CR_PDS_INV0 */
+#define EUR_CR_PDS_INV0 0x0AD0
+#define EUR_CR_PDS_INV0_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV0_DSC_SHIFT 0
+/* Register EUR_CR_PDS_INV1 */
+#define EUR_CR_PDS_INV1 0x0AD4
+#define EUR_CR_PDS_INV1_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV1_DSC_SHIFT 0
+/* Register EUR_CR_PDS_INV2 */
+#define EUR_CR_PDS_INV2 0x0AD8
+#define EUR_CR_PDS_INV2_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV2_DSC_SHIFT 0
+/* Register EUR_CR_PDS_INV3 */
+#define EUR_CR_PDS_INV3 0x0ADC
+#define EUR_CR_PDS_INV3_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV3_DSC_SHIFT 0
+/* Register EUR_CR_PDS_INV_CSC */
+#define EUR_CR_PDS_INV_CSC 0x0AE0
+#define EUR_CR_PDS_INV_CSC_KICK_MASK 0x00000001U
+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT 0
+/* Register EUR_CR_PDS_PC_BASE */
+#define EUR_CR_PDS_PC_BASE 0x0B2C
+#define EUR_CR_PDS_PC_BASE_ADDRESS_MASK 0x3FFFFFFFU
+#define EUR_CR_PDS_PC_BASE_ADDRESS_SHIFT 0
+/* Register EUR_CR_BIF_CTRL */
+#define EUR_CR_BIF_CTRL 0x0C00
+#define EUR_CR_BIF_CTRL_NOREORDER_MASK 0x00000001U
+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT 0
+#define EUR_CR_BIF_CTRL_PAUSE_MASK 0x00000002U
+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT 1
+#define EUR_CR_BIF_CTRL_FLUSH_MASK 0x00000004U
+#define EUR_CR_BIF_CTRL_FLUSH_SHIFT 2
+#define EUR_CR_BIF_CTRL_INVALDC_MASK 0x00000008U
+#define EUR_CR_BIF_CTRL_INVALDC_SHIFT 3
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT 4
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_MASK 0x00000100U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SHIFT 8
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_MASK 0x00000400U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SHIFT 10
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15
+/* Register EUR_CR_BIF_INT_STAT */
+#define EUR_CR_BIF_INT_STAT 0x0C04
+#define EUR_CR_BIF_INT_STAT_FAULT_MASK 0x00003FFFU
+#define EUR_CR_BIF_INT_STAT_FAULT_SHIFT 0
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_MASK 0x00004000U
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_SHIFT 14
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00008000U
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 15
+/* Register EUR_CR_BIF_FAULT */
+#define EUR_CR_BIF_FAULT 0x0C08
+#define EUR_CR_BIF_FAULT_ADDR_MASK 0x0FFFF000U
+#define EUR_CR_BIF_FAULT_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_DIR_LIST_BASE0 */
+#define EUR_CR_BIF_DIR_LIST_BASE0 0x0C84
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_TA_REQ_BASE */
+#define EUR_CR_BIF_TA_REQ_BASE 0x0C90
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_BIF_MEM_REQ_STAT */
+#define EUR_CR_BIF_MEM_REQ_STAT 0x0CA8
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK 0x000000FFU
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
+/* Register EUR_CR_BIF_3D_REQ_BASE */
+#define EUR_CR_BIF_3D_REQ_BASE 0x0CAC
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_BIF_ZLS_REQ_BASE */
+#define EUR_CR_BIF_ZLS_REQ_BASE 0x0CB0
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT 20
+/* Table EUR_CR_USE_CODE_BASE */
+/* Register EUR_CR_USE_CODE_BASE */
+#define EUR_CR_USE_CODE_BASE(X) (0x0A0C + (4 * (X)))
+#define EUR_CR_USE_CODE_BASE_ADDR_MASK 0x000FFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_MASK 0x00300000U
+#define EUR_CR_USE_CODE_BASE_DM_SHIFT 20
+/* Number of entries in table EUR_CR_USE_CODE_BASE */
+#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16
+#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16
+
+#endif /* _SGX520DEFS_KM_H_ */
+
diff --git a/pvr-source/services4/srvkm/hwdefs/sgx530defs.h b/pvr-source/services4/srvkm/hwdefs/sgx530defs.h
new file mode 100644
index 0000000..3223feb
--- /dev/null
+++ b/pvr-source/services4/srvkm/hwdefs/sgx530defs.h
@@ -0,0 +1,542 @@
+/*************************************************************************/ /*!
+@Title Hardware defs for SGX530.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _SGX530DEFS_KM_H_
+#define _SGX530DEFS_KM_H_
+
+/* Register EUR_CR_CLKGATECTL */
+#define EUR_CR_CLKGATECTL 0x0000
+#define EUR_CR_CLKGATECTL_2D_CLKG_MASK 0x00000003U
+#define EUR_CR_CLKGATECTL_2D_CLKG_SHIFT 0
+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL_TA_CLKG_MASK 0x00003000U
+#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT 12
+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL_USE_CLKG_MASK 0x00300000U
+#define EUR_CR_CLKGATECTL_USE_CLKG_SHIFT 20
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
+/* Register EUR_CR_CLKGATESTATUS */
+#define EUR_CR_CLKGATESTATUS 0x0004
+#define EUR_CR_CLKGATESTATUS_2D_CLKS_MASK 0x00000001U
+#define EUR_CR_CLKGATESTATUS_2D_CLKS_SHIFT 0
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK 0x00000010U
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 4
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK 0x00000100U
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 8
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK 0x00001000U
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT 12
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK 0x00010000U
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 16
+#define EUR_CR_CLKGATESTATUS_USE_CLKS_MASK 0x00100000U
+#define EUR_CR_CLKGATESTATUS_USE_CLKS_SHIFT 20
+/* Register EUR_CR_CLKGATECTLOVR */
+#define EUR_CR_CLKGATECTLOVR 0x0008
+#define EUR_CR_CLKGATECTLOVR_2D_CLKO_MASK 0x00000003U
+#define EUR_CR_CLKGATECTLOVR_2D_CLKO_SHIFT 0
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK 0x00000030U
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 4
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK 0x00000300U
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 8
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK 0x00003000U
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT 12
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK 0x00030000U
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 16
+#define EUR_CR_CLKGATECTLOVR_USE_CLKO_MASK 0x00300000U
+#define EUR_CR_CLKGATECTLOVR_USE_CLKO_SHIFT 20
+/* Register EUR_CR_CORE_ID */
+#define EUR_CR_CORE_ID 0x0010
+#define EUR_CR_CORE_ID_CONFIG_MASK 0x0000FFFFU
+#define EUR_CR_CORE_ID_CONFIG_SHIFT 0
+#define EUR_CR_CORE_ID_ID_MASK 0xFFFF0000U
+#define EUR_CR_CORE_ID_ID_SHIFT 16
+/* Register EUR_CR_CORE_REVISION */
+#define EUR_CR_CORE_REVISION 0x0014
+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
+#define EUR_CR_CORE_REVISION_MINOR_MASK 0x0000FF00U
+#define EUR_CR_CORE_REVISION_MINOR_SHIFT 8
+#define EUR_CR_CORE_REVISION_MAJOR_MASK 0x00FF0000U
+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT 16
+#define EUR_CR_CORE_REVISION_DESIGNER_MASK 0xFF000000U
+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
+/* Register EUR_CR_DESIGNER_REV_FIELD1 */
+#define EUR_CR_DESIGNER_REV_FIELD1 0x0018
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
+/* Register EUR_CR_DESIGNER_REV_FIELD2 */
+#define EUR_CR_DESIGNER_REV_FIELD2 0x001C
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
+/* Register EUR_CR_SOFT_RESET */
+#define EUR_CR_SOFT_RESET 0x0080
+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK 0x00000001U
+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT 0
+#define EUR_CR_SOFT_RESET_TWOD_RESET_MASK 0x00000002U
+#define EUR_CR_SOFT_RESET_TWOD_RESET_SHIFT 1
+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK 0x00000004U
+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT 2
+#define EUR_CR_SOFT_RESET_TA_RESET_MASK 0x00000008U
+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT 3
+#define EUR_CR_SOFT_RESET_USE_RESET_MASK 0x00000010U
+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT 4
+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK 0x00000020U
+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT 5
+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK 0x00000040U
+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT 6
+/* Register EUR_CR_EVENT_HOST_ENABLE2 */
+#define EUR_CR_EVENT_HOST_ENABLE2 0x0110
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
+/* Register EUR_CR_EVENT_HOST_CLEAR2 */
+#define EUR_CR_EVENT_HOST_CLEAR2 0x0114
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
+/* Register EUR_CR_EVENT_STATUS2 */
+#define EUR_CR_EVENT_STATUS2 0x0118
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
+/* Register EUR_CR_EVENT_STATUS */
+#define EUR_CR_EVENT_STATUS 0x012CU
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_STATUS_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT 29
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_STATUS_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_STATUS_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
+/* Register EUR_CR_EVENT_HOST_ENABLE */
+#define EUR_CR_EVENT_HOST_ENABLE 0x0130
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#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 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
+/* Register EUR_CR_EVENT_HOST_CLEAR */
+#define EUR_CR_EVENT_HOST_CLEAR 0x0134
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#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 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
+/* Register EUR_CR_PDS_EXEC_BASE */
+#define EUR_CR_PDS_EXEC_BASE 0x0AB8
+#define EUR_CR_PDS_EXEC_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_PDS_EXEC_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_EVENT_KICKER */
+#define EUR_CR_EVENT_KICKER 0x0AC4
+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK 0x0FFFFFF0U
+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT 4
+/* Register EUR_CR_EVENT_KICK */
+#define EUR_CR_EVENT_KICK 0x0AC8
+#define EUR_CR_EVENT_KICK_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK_NOW_SHIFT 0
+/* Register EUR_CR_EVENT_TIMER */
+#define EUR_CR_EVENT_TIMER 0x0ACC
+#define EUR_CR_EVENT_TIMER_ENABLE_MASK 0x01000000U
+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT 24
+#define EUR_CR_EVENT_TIMER_VALUE_MASK 0x00FFFFFFU
+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT 0
+/* Register EUR_CR_PDS_INV0 */
+#define EUR_CR_PDS_INV0 0x0AD0
+#define EUR_CR_PDS_INV0_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV0_DSC_SHIFT 0
+/* Register EUR_CR_PDS_INV1 */
+#define EUR_CR_PDS_INV1 0x0AD4
+#define EUR_CR_PDS_INV1_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV1_DSC_SHIFT 0
+/* Register EUR_CR_PDS_INV2 */
+#define EUR_CR_PDS_INV2 0x0AD8
+#define EUR_CR_PDS_INV2_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV2_DSC_SHIFT 0
+/* Register EUR_CR_PDS_INV3 */
+#define EUR_CR_PDS_INV3 0x0ADC
+#define EUR_CR_PDS_INV3_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV3_DSC_SHIFT 0
+/* Register EUR_CR_PDS_INV_CSC */
+#define EUR_CR_PDS_INV_CSC 0x0AE0
+#define EUR_CR_PDS_INV_CSC_KICK_MASK 0x00000001U
+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT 0
+/* Register EUR_CR_PDS_PC_BASE */
+#define EUR_CR_PDS_PC_BASE 0x0B2C
+#define EUR_CR_PDS_PC_BASE_ADDRESS_MASK 0x3FFFFFFFU
+#define EUR_CR_PDS_PC_BASE_ADDRESS_SHIFT 0
+/* Register EUR_CR_BIF_CTRL */
+#define EUR_CR_BIF_CTRL 0x0C00
+#define EUR_CR_BIF_CTRL_NOREORDER_MASK 0x00000001U
+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT 0
+#define EUR_CR_BIF_CTRL_PAUSE_MASK 0x00000002U
+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT 1
+#define EUR_CR_BIF_CTRL_FLUSH_MASK 0x00000004U
+#define EUR_CR_BIF_CTRL_FLUSH_SHIFT 2
+#define EUR_CR_BIF_CTRL_INVALDC_MASK 0x00000008U
+#define EUR_CR_BIF_CTRL_INVALDC_SHIFT 3
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT 4
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_MASK 0x00000100U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SHIFT 8
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_MASK 0x00000400U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SHIFT 10
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TWOD_MASK 0x00000800U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TWOD_SHIFT 11
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15
+/* Register EUR_CR_BIF_INT_STAT */
+#define EUR_CR_BIF_INT_STAT 0x0C04
+#define EUR_CR_BIF_INT_STAT_FAULT_MASK 0x00003FFFU
+#define EUR_CR_BIF_INT_STAT_FAULT_SHIFT 0
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_MASK 0x00004000U
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_SHIFT 14
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00008000U
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 15
+/* Register EUR_CR_BIF_FAULT */
+#define EUR_CR_BIF_FAULT 0x0C08
+#define EUR_CR_BIF_FAULT_ADDR_MASK 0x0FFFF000U
+#define EUR_CR_BIF_FAULT_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_DIR_LIST_BASE0 */
+#define EUR_CR_BIF_DIR_LIST_BASE0 0x0C84
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_TWOD_REQ_BASE */
+#define EUR_CR_BIF_TWOD_REQ_BASE 0x0C88
+#define EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_TWOD_REQ_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_BIF_TA_REQ_BASE */
+#define EUR_CR_BIF_TA_REQ_BASE 0x0C90
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_BIF_MEM_REQ_STAT */
+#define EUR_CR_BIF_MEM_REQ_STAT 0x0CA8
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK 0x000000FFU
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
+/* Register EUR_CR_BIF_3D_REQ_BASE */
+#define EUR_CR_BIF_3D_REQ_BASE 0x0CAC
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_BIF_ZLS_REQ_BASE */
+#define EUR_CR_BIF_ZLS_REQ_BASE 0x0CB0
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_2D_BLIT_STATUS */
+#define EUR_CR_2D_BLIT_STATUS 0x0E04
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFU
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0
+#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK 0x01000000U
+#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT 24
+/* Register EUR_CR_2D_VIRTUAL_FIFO_0 */
+#define EUR_CR_2D_VIRTUAL_FIFO_0 0x0E10
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EU
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12
+/* Register EUR_CR_2D_VIRTUAL_FIFO_1 */
+#define EUR_CR_2D_VIRTUAL_FIFO_1 0x0E14
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFU
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24
+/* Table EUR_CR_USE_CODE_BASE */
+/* Register EUR_CR_USE_CODE_BASE */
+#define EUR_CR_USE_CODE_BASE(X) (0x0A0C + (4 * (X)))
+#define EUR_CR_USE_CODE_BASE_ADDR_MASK 0x00FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_MASK 0x03000000U
+#define EUR_CR_USE_CODE_BASE_DM_SHIFT 24
+/* Number of entries in table EUR_CR_USE_CODE_BASE */
+#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 0x00010000U
+#define EUR_CR_MNE_CR_CTRL_BYP_CC_N_SHIFT 16
+#define EUR_CR_MNE_CR_CTRL_BYP_CC_MASK 0x00008000U
+#define EUR_CR_MNE_CR_CTRL_BYP_CC_SHIFT 15
+#define EUR_CR_MNE_CR_CTRL_USE_INVAL_ADDR_MASK 0x00007800U
+#define EUR_CR_MNE_CR_CTRL_USE_INVAL_ADDR_SHIFT 11
+#define EUR_CR_MNE_CR_CTRL_BYPASS_ALL_MASK 0x00000400U
+#define EUR_CR_MNE_CR_CTRL_BYPASS_ALL_SHIFT 10
+#define EUR_CR_MNE_CR_CTRL_BYPASS_MASK 0x000003E0U
+#define EUR_CR_MNE_CR_CTRL_BYPASS_SHIFT 5
+#define EUR_CR_MNE_CR_CTRL_PAUSE_MASK 0x00000010U
+#define EUR_CR_MNE_CR_CTRL_PAUSE_SHIFT 4
+#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_MASK 0x0000000EU
+#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_SHIFT 1
+#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_PDS_MASK (1UL<<EUR_CR_MNE_CR_CTRL_INVAL_PREQ_SHIFT+2)
+#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_USEC_MASK (1UL<<EUR_CR_MNE_CR_CTRL_INVAL_PREQ_SHIFT+1)
+#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_CACHE_MASK (1UL<<EUR_CR_MNE_CR_CTRL_INVAL_PREQ_SHIFT)
+#define EUR_CR_MNE_CR_CTRL_INVAL_ALL_MASK 0x00000001U
+#define EUR_CR_MNE_CR_CTRL_INVAL_ALL_SHIFT 0
+#define EUR_CR_MNE_CR_USE_INVAL 0x0D04
+#define EUR_CR_MNE_CR_USE_INVAL_ADDR_MASK 0xFFFFFFFFU
+#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 0x00000400U
+#define EUR_CR_MNE_CR_STAT_PAUSED_SHIFT 10
+#define EUR_CR_MNE_CR_STAT_READS_MASK 0x000003FFU
+#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 0x000FFFF0U
+#define EUR_CR_MNE_CR_STAT_STATS_RST_SHIFT 4
+#define EUR_CR_MNE_CR_STAT_STATS_SEL_MASK 0x0000000FU
+#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 0xFFFFFFFFU
+#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 0x00000001U
+#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 0x00000001U
+#define EUR_CR_MNE_CR_EVENT_CLEAR_INVAL_SHIFT 0
+#define EUR_CR_MNE_CR_CTRL_INVAL 0x0D20
+
+#endif /* _SGX530DEFS_KM_H_ */
+
diff --git a/pvr-source/services4/srvkm/hwdefs/sgx531defs.h b/pvr-source/services4/srvkm/hwdefs/sgx531defs.h
new file mode 100644
index 0000000..3295d89
--- /dev/null
+++ b/pvr-source/services4/srvkm/hwdefs/sgx531defs.h
@@ -0,0 +1,601 @@
+/*************************************************************************/ /*!
+@Title Hardware defs for SGX531.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _SGX531DEFS_KM_H_
+#define _SGX531DEFS_KM_H_
+
+/* Register EUR_CR_CLKGATECTL */
+#define EUR_CR_CLKGATECTL 0x0000
+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK 0x00000003U
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT 0
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SHIFT 2
+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL_TE_CLKG_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTL_TE_CLKG_SHIFT 6
+#define EUR_CR_CLKGATECTL_MTE_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL_MTE_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT 10
+#define EUR_CR_CLKGATECTL_VDM_CLKG_MASK 0x00003000U
+#define EUR_CR_CLKGATECTL_VDM_CLKG_SHIFT 12
+#define EUR_CR_CLKGATECTL_PDS_CLKG_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTL_PDS_CLKG_SHIFT 14
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL_TA_CLKG_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT 18
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_MASK 0x10000000U
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_SHIFT 28
+/* Register EUR_CR_CLKGATECTL2 */
+#define EUR_CR_CLKGATECTL2 0x0004
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_MASK 0x00000003U
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SHIFT 0
+#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_SHIFT 2
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SHIFT 6
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SHIFT 10
+#define EUR_CR_CLKGATECTL2_MADD0_CLKG_MASK 0x00003000U
+#define EUR_CR_CLKGATECTL2_MADD0_CLKG_SHIFT 12
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SHIFT 14
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SHIFT 18
+#define EUR_CR_CLKGATECTL2_MADD1_CLKG_MASK 0x00300000U
+#define EUR_CR_CLKGATECTL2_MADD1_CLKG_SHIFT 20
+/* Register EUR_CR_CLKGATESTATUS */
+#define EUR_CR_CLKGATESTATUS 0x0008
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK 0x00000001U
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 0
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_MASK 0x00000002U
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SHIFT 1
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK 0x00000004U
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 2
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_MASK 0x00000008U
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SHIFT 3
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_MASK 0x00000010U
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SHIFT 4
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK 0x00000020U
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 5
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_MASK 0x00000040U
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SHIFT 6
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_MASK 0x00000080U
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_SHIFT 7
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_MASK 0x00000100U
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SHIFT 8
+#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_MASK 0x00000200U
+#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_SHIFT 9
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_MASK 0x00000400U
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SHIFT 10
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_MASK 0x00000800U
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SHIFT 11
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_MASK 0x00001000U
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SHIFT 12
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_MASK 0x00002000U
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SHIFT 13
+#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_MASK 0x00004000U
+#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_SHIFT 14
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_MASK 0x00008000U
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SHIFT 15
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_MASK 0x00010000U
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SHIFT 16
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_MASK 0x00020000U
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SHIFT 17
+#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_MASK 0x00040000U
+#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_SHIFT 18
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_MASK 0x00080000U
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_SHIFT 19
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK 0x00100000U
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT 20
+/* Register EUR_CR_CLKGATECTLOVR */
+#define EUR_CR_CLKGATECTLOVR 0x000C
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK 0x00000003U
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 0
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SHIFT 2
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK 0x00000030U
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 4
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SHIFT 6
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_MASK 0x00000300U
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SHIFT 8
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 10
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_MASK 0x00003000U
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SHIFT 12
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_SHIFT 14
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_MASK 0x00030000U
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_SHIFT 16
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT 18
+/* Register EUR_CR_CORE_ID */
+#define EUR_CR_CORE_ID 0x0020
+#define EUR_CR_CORE_ID_CONFIG_MASK 0x0000FFFFU
+#define EUR_CR_CORE_ID_CONFIG_SHIFT 0
+#define EUR_CR_CORE_ID_ID_MASK 0xFFFF0000U
+#define EUR_CR_CORE_ID_ID_SHIFT 16
+/* Register EUR_CR_CORE_REVISION */
+#define EUR_CR_CORE_REVISION 0x0024
+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
+#define EUR_CR_CORE_REVISION_MINOR_MASK 0x0000FF00U
+#define EUR_CR_CORE_REVISION_MINOR_SHIFT 8
+#define EUR_CR_CORE_REVISION_MAJOR_MASK 0x00FF0000U
+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT 16
+#define EUR_CR_CORE_REVISION_DESIGNER_MASK 0xFF000000U
+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
+/* Register EUR_CR_DESIGNER_REV_FIELD1 */
+#define EUR_CR_DESIGNER_REV_FIELD1 0x0028
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
+/* Register EUR_CR_DESIGNER_REV_FIELD2 */
+#define EUR_CR_DESIGNER_REV_FIELD2 0x002C
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
+/* Register EUR_CR_SOFT_RESET */
+#define EUR_CR_SOFT_RESET 0x0080
+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK 0x00000001U
+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT 0
+#define EUR_CR_SOFT_RESET_VDM_RESET_MASK 0x00000002U
+#define EUR_CR_SOFT_RESET_VDM_RESET_SHIFT 1
+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK 0x00000004U
+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT 2
+#define EUR_CR_SOFT_RESET_TE_RESET_MASK 0x00000008U
+#define EUR_CR_SOFT_RESET_TE_RESET_SHIFT 3
+#define EUR_CR_SOFT_RESET_MTE_RESET_MASK 0x00000010U
+#define EUR_CR_SOFT_RESET_MTE_RESET_SHIFT 4
+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK 0x00000020U
+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT 5
+#define EUR_CR_SOFT_RESET_ISP2_RESET_MASK 0x00000040U
+#define EUR_CR_SOFT_RESET_ISP2_RESET_SHIFT 6
+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK 0x00000080U
+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT 7
+#define EUR_CR_SOFT_RESET_PDS_RESET_MASK 0x00000100U
+#define EUR_CR_SOFT_RESET_PDS_RESET_SHIFT 8
+#define EUR_CR_SOFT_RESET_PBE_RESET_MASK 0x00000200U
+#define EUR_CR_SOFT_RESET_PBE_RESET_SHIFT 9
+#define EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK 0x00000400U
+#define EUR_CR_SOFT_RESET_CACHEL2_RESET_SHIFT 10
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK 0x00000800U
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_SHIFT 11
+#define EUR_CR_SOFT_RESET_MADD_RESET_MASK 0x00001000U
+#define EUR_CR_SOFT_RESET_MADD_RESET_SHIFT 12
+#define EUR_CR_SOFT_RESET_ITR_RESET_MASK 0x00002000U
+#define EUR_CR_SOFT_RESET_ITR_RESET_SHIFT 13
+#define EUR_CR_SOFT_RESET_TEX_RESET_MASK 0x00004000U
+#define EUR_CR_SOFT_RESET_TEX_RESET_SHIFT 14
+#define EUR_CR_SOFT_RESET_USE_RESET_MASK 0x00008000U
+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT 15
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK 0x00010000U
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_SHIFT 16
+#define EUR_CR_SOFT_RESET_TA_RESET_MASK 0x00020000U
+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT 17
+/* Register EUR_CR_EVENT_HOST_ENABLE2 */
+#define EUR_CR_EVENT_HOST_ENABLE2 0x0110
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
+/* Register EUR_CR_EVENT_HOST_CLEAR2 */
+#define EUR_CR_EVENT_HOST_CLEAR2 0x0114
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
+/* Register EUR_CR_EVENT_STATUS2 */
+#define EUR_CR_EVENT_STATUS2 0x0118
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
+/* Register EUR_CR_EVENT_STATUS */
+#define EUR_CR_EVENT_STATUS 0x012CU
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_STATUS_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT 29
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_STATUS_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_STATUS_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
+/* Register EUR_CR_EVENT_HOST_ENABLE */
+#define EUR_CR_EVENT_HOST_ENABLE 0x0130
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#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 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
+/* Register EUR_CR_EVENT_HOST_CLEAR */
+#define EUR_CR_EVENT_HOST_CLEAR 0x0134
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#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 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
+/* Register EUR_CR_TIMER */
+#define EUR_CR_TIMER 0x0144
+#define EUR_CR_TIMER_VALUE_MASK 0xFFFFFFFFU
+#define EUR_CR_TIMER_VALUE_SHIFT 0
+/* Register EUR_CR_EVENT_KICK1 */
+#define EUR_CR_EVENT_KICK1 0x0AB0
+#define EUR_CR_EVENT_KICK1_NOW_MASK 0x000000FFU
+#define EUR_CR_EVENT_KICK1_NOW_SHIFT 0
+/* Register EUR_CR_PDS_EXEC_BASE */
+#define EUR_CR_PDS_EXEC_BASE 0x0AB8
+#define EUR_CR_PDS_EXEC_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_PDS_EXEC_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_EVENT_KICK2 */
+#define EUR_CR_EVENT_KICK2 0x0AC0
+#define EUR_CR_EVENT_KICK2_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK2_NOW_SHIFT 0
+/* Register EUR_CR_EVENT_KICKER */
+#define EUR_CR_EVENT_KICKER 0x0AC4
+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK 0x0FFFFFF0U
+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT 4
+/* Register EUR_CR_EVENT_KICK */
+#define EUR_CR_EVENT_KICK 0x0AC8
+#define EUR_CR_EVENT_KICK_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK_NOW_SHIFT 0
+/* Register EUR_CR_EVENT_TIMER */
+#define EUR_CR_EVENT_TIMER 0x0ACC
+#define EUR_CR_EVENT_TIMER_ENABLE_MASK 0x01000000U
+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT 24
+#define EUR_CR_EVENT_TIMER_VALUE_MASK 0x00FFFFFFU
+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT 0
+/* Register EUR_CR_PDS_INV0 */
+#define EUR_CR_PDS_INV0 0x0AD0
+#define EUR_CR_PDS_INV0_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV0_DSC_SHIFT 0
+/* Register EUR_CR_PDS_INV1 */
+#define EUR_CR_PDS_INV1 0x0AD4
+#define EUR_CR_PDS_INV1_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV1_DSC_SHIFT 0
+/* Register EUR_CR_EVENT_KICK3 */
+#define EUR_CR_EVENT_KICK3 0x0AD8
+#define EUR_CR_EVENT_KICK3_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK3_NOW_SHIFT 0
+/* Register EUR_CR_PDS_INV3 */
+#define EUR_CR_PDS_INV3 0x0ADC
+#define EUR_CR_PDS_INV3_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV3_DSC_SHIFT 0
+/* Register EUR_CR_PDS_INV_CSC */
+#define EUR_CR_PDS_INV_CSC 0x0AE0
+#define EUR_CR_PDS_INV_CSC_KICK_MASK 0x00000001U
+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT 0
+/* Register EUR_CR_PDS_PC_BASE */
+#define EUR_CR_PDS_PC_BASE 0x0B2C
+#define EUR_CR_PDS_PC_BASE_ADDRESS_MASK 0x00FFFFFFU
+#define EUR_CR_PDS_PC_BASE_ADDRESS_SHIFT 0
+/* Register EUR_CR_BIF_CTRL */
+#define EUR_CR_BIF_CTRL 0x0C00
+#define EUR_CR_BIF_CTRL_NOREORDER_MASK 0x00000001U
+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT 0
+#define EUR_CR_BIF_CTRL_PAUSE_MASK 0x00000002U
+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT 1
+#define EUR_CR_BIF_CTRL_FLUSH_MASK 0x00000004U
+#define EUR_CR_BIF_CTRL_FLUSH_SHIFT 2
+#define EUR_CR_BIF_CTRL_INVALDC_MASK 0x00000008U
+#define EUR_CR_BIF_CTRL_INVALDC_SHIFT 3
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT 4
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_MASK 0x00000100U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SHIFT 8
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_MASK 0x00000400U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SHIFT 10
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15
+/* Register EUR_CR_BIF_INT_STAT */
+#define EUR_CR_BIF_INT_STAT 0x0C04
+#define EUR_CR_BIF_INT_STAT_FAULT_MASK 0x00003FFFU
+#define EUR_CR_BIF_INT_STAT_FAULT_SHIFT 0
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_MASK 0x00004000U
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_SHIFT 14
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00008000U
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 15
+/* Register EUR_CR_BIF_FAULT */
+#define EUR_CR_BIF_FAULT 0x0C08
+#define EUR_CR_BIF_FAULT_SB_MASK 0x000001F0U
+#define EUR_CR_BIF_FAULT_SB_SHIFT 4
+#define EUR_CR_BIF_FAULT_ADDR_MASK 0x0FFFF000U
+#define EUR_CR_BIF_FAULT_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_DIR_LIST_BASE0 */
+#define EUR_CR_BIF_DIR_LIST_BASE0 0x0C84
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_TA_REQ_BASE */
+#define EUR_CR_BIF_TA_REQ_BASE 0x0C90
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_BIF_MEM_REQ_STAT */
+#define EUR_CR_BIF_MEM_REQ_STAT 0x0CA8
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK 0x000000FFU
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
+/* Register EUR_CR_BIF_3D_REQ_BASE */
+#define EUR_CR_BIF_3D_REQ_BASE 0x0CAC
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_BIF_ZLS_REQ_BASE */
+#define EUR_CR_BIF_ZLS_REQ_BASE 0x0CB0
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_2D_BLIT_STATUS */
+#define EUR_CR_2D_BLIT_STATUS 0x0E04
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFU
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0
+#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK 0x01000000U
+#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT 24
+/* Register EUR_CR_2D_VIRTUAL_FIFO_0 */
+#define EUR_CR_2D_VIRTUAL_FIFO_0 0x0E10
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EU
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12
+/* Register EUR_CR_2D_VIRTUAL_FIFO_1 */
+#define EUR_CR_2D_VIRTUAL_FIFO_1 0x0E14
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFU
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24
+/* Table EUR_CR_USE_CODE_BASE */
+/* Register EUR_CR_USE_CODE_BASE */
+#define EUR_CR_USE_CODE_BASE(X) (0x0A0C + (4 * (X)))
+#define EUR_CR_USE_CODE_BASE_ADDR_MASK 0x00FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_MASK 0x03000000U
+#define EUR_CR_USE_CODE_BASE_DM_SHIFT 24
+/* Number of entries in table EUR_CR_USE_CODE_BASE */
+#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16
+#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16
+
+#endif /* _SGX531DEFS_KM_H_ */
+
diff --git a/pvr-source/services4/srvkm/hwdefs/sgx535defs.h b/pvr-source/services4/srvkm/hwdefs/sgx535defs.h
new file mode 100644
index 0000000..8039da4
--- /dev/null
+++ b/pvr-source/services4/srvkm/hwdefs/sgx535defs.h
@@ -0,0 +1,739 @@
+/*************************************************************************/ /*!
+@Title Hardware defs for SGX535.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _SGX535DEFS_KM_H_
+#define _SGX535DEFS_KM_H_
+
+/* Register EUR_CR_CLKGATECTL */
+#define EUR_CR_CLKGATECTL 0x0000
+#define EUR_CR_CLKGATECTL_2D_CLKG_MASK 0x00000003U
+#define EUR_CR_CLKGATECTL_2D_CLKG_SHIFT 0
+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL_TA_CLKG_MASK 0x00003000U
+#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT 12
+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL_USE_CLKG_MASK 0x00300000U
+#define EUR_CR_CLKGATECTL_USE_CLKG_SHIFT 20
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
+/* Register EUR_CR_CLKGATESTATUS */
+#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 0x00000010U
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 4
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK 0x00000100U
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 8
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK 0x00001000U
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT 12
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK 0x00010000U
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 16
+#define EUR_CR_CLKGATESTATUS_USE_CLKS_MASK 0x00100000U
+#define EUR_CR_CLKGATESTATUS_USE_CLKS_SHIFT 20
+/* Register EUR_CR_CLKGATECTLOVR */
+#define EUR_CR_CLKGATECTLOVR 0x0008
+#define EUR_CR_CLKGATECTLOVR_2D_CLKO_MASK 0x00000003U
+#define EUR_CR_CLKGATECTLOVR_2D_CLKO_SHIFT 0
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK 0x00000030U
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 4
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK 0x00000300U
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 8
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK 0x00003000U
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT 12
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK 0x00030000U
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 16
+#define EUR_CR_CLKGATECTLOVR_USE_CLKO_MASK 0x00300000U
+#define EUR_CR_CLKGATECTLOVR_USE_CLKO_SHIFT 20
+/* Register EUR_CR_CORE_ID */
+#define EUR_CR_CORE_ID 0x0010
+#define EUR_CR_CORE_ID_CONFIG_MASK 0x0000FFFFU
+#define EUR_CR_CORE_ID_CONFIG_SHIFT 0
+#define EUR_CR_CORE_ID_ID_MASK 0xFFFF0000U
+#define EUR_CR_CORE_ID_ID_SHIFT 16
+/* Register EUR_CR_CORE_REVISION */
+#define EUR_CR_CORE_REVISION 0x0014
+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
+#define EUR_CR_CORE_REVISION_MINOR_MASK 0x0000FF00U
+#define EUR_CR_CORE_REVISION_MINOR_SHIFT 8
+#define EUR_CR_CORE_REVISION_MAJOR_MASK 0x00FF0000U
+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT 16
+#define EUR_CR_CORE_REVISION_DESIGNER_MASK 0xFF000000U
+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
+/* Register EUR_CR_DESIGNER_REV_FIELD1 */
+#define EUR_CR_DESIGNER_REV_FIELD1 0x0018
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
+/* Register EUR_CR_DESIGNER_REV_FIELD2 */
+#define EUR_CR_DESIGNER_REV_FIELD2 0x001C
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
+/* Register EUR_CR_SOFT_RESET */
+#define EUR_CR_SOFT_RESET 0x0080
+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK 0x00000001U
+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT 0
+#define EUR_CR_SOFT_RESET_TWOD_RESET_MASK 0x00000002U
+#define EUR_CR_SOFT_RESET_TWOD_RESET_SHIFT 1
+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK 0x00000004U
+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT 2
+#define EUR_CR_SOFT_RESET_TA_RESET_MASK 0x00000008U
+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT 3
+#define EUR_CR_SOFT_RESET_USE_RESET_MASK 0x00000010U
+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT 4
+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK 0x00000020U
+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT 5
+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK 0x00000040U
+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT 6
+/* Register EUR_CR_EVENT_HOST_ENABLE2 */
+#define EUR_CR_EVENT_HOST_ENABLE2 0x0110
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE2_BIF_REQUESTER_FAULT_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE2_BIF_REQUESTER_FAULT_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_DHOST_FREE_LOAD_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_DHOST_FREE_LOAD_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_HOST_FREE_LOAD_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_HOST_FREE_LOAD_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
+/* Register EUR_CR_EVENT_HOST_CLEAR2 */
+#define EUR_CR_EVENT_HOST_CLEAR2 0x0114
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR2_BIF_REQUESTER_FAULT_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR2_BIF_REQUESTER_FAULT_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_DHOST_FREE_LOAD_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_DHOST_FREE_LOAD_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_HOST_FREE_LOAD_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_HOST_FREE_LOAD_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
+/* Register EUR_CR_EVENT_STATUS2 */
+#define EUR_CR_EVENT_STATUS2 0x0118U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT 7
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT 6
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT 5
+#define EUR_CR_EVENT_STATUS2_BIF_REQUESTER_FAULT_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS2_BIF_REQUESTER_FAULT_SHIFT 4
+#define EUR_CR_EVENT_STATUS2_DPM_DHOST_FREE_LOAD_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS2_DPM_DHOST_FREE_LOAD_SHIFT 3
+#define EUR_CR_EVENT_STATUS2_DPM_HOST_FREE_LOAD_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS2_DPM_HOST_FREE_LOAD_SHIFT 2
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
+/* Register EUR_CR_EVENT_STATUS */
+#define EUR_CR_EVENT_STATUS 0x012CU
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_STATUS_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT 29
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_STATUS_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_STATUS_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
+/* Register EUR_CR_EVENT_HOST_ENABLE */
+#define EUR_CR_EVENT_HOST_ENABLE 0x0130
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#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 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
+/* Register EUR_CR_EVENT_HOST_CLEAR */
+#define EUR_CR_EVENT_HOST_CLEAR 0x0134
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#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 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
+/* Register EUR_CR_PDS_EXEC_BASE */
+#define EUR_CR_PDS_EXEC_BASE 0x0AB8
+#define EUR_CR_PDS_EXEC_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_PDS_EXEC_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_EVENT_KICKER */
+#define EUR_CR_EVENT_KICKER 0x0AC4
+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT 4
+/* Register EUR_CR_EVENT_KICK */
+#define EUR_CR_EVENT_KICK 0x0AC8
+#define EUR_CR_EVENT_KICK_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK_NOW_SHIFT 0
+/* Register EUR_CR_EVENT_TIMER */
+#define EUR_CR_EVENT_TIMER 0x0ACC
+#define EUR_CR_EVENT_TIMER_ENABLE_MASK 0x01000000U
+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT 24
+#define EUR_CR_EVENT_TIMER_VALUE_MASK 0x00FFFFFFU
+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT 0
+/* Register EUR_CR_PDS_INV0 */
+#define EUR_CR_PDS_INV0 0x0AD0
+#define EUR_CR_PDS_INV0_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV0_DSC_SHIFT 0
+/* Register EUR_CR_PDS_INV1 */
+#define EUR_CR_PDS_INV1 0x0AD4
+#define EUR_CR_PDS_INV1_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV1_DSC_SHIFT 0
+/* Register EUR_CR_PDS_INV2 */
+#define EUR_CR_PDS_INV2 0x0AD8
+#define EUR_CR_PDS_INV2_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV2_DSC_SHIFT 0
+/* Register EUR_CR_PDS_INV3 */
+#define EUR_CR_PDS_INV3 0x0ADC
+#define EUR_CR_PDS_INV3_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV3_DSC_SHIFT 0
+/* Register EUR_CR_PDS_INV_CSC */
+#define EUR_CR_PDS_INV_CSC 0x0AE0
+#define EUR_CR_PDS_INV_CSC_KICK_MASK 0x00000001U
+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT 0
+/* Register EUR_CR_PDS_PC_BASE */
+#define EUR_CR_PDS_PC_BASE 0x0B2C
+#define EUR_CR_PDS_PC_BASE_ADDRESS_MASK 0x3FFFFFFFU
+#define EUR_CR_PDS_PC_BASE_ADDRESS_SHIFT 0
+/* Register EUR_CR_BIF_CTRL */
+#define EUR_CR_BIF_CTRL 0x0C00
+#define EUR_CR_BIF_CTRL_NOREORDER_MASK 0x00000001U
+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT 0
+#define EUR_CR_BIF_CTRL_PAUSE_MASK 0x00000002U
+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT 1
+#define EUR_CR_BIF_CTRL_FLUSH_MASK 0x00000004U
+#define EUR_CR_BIF_CTRL_FLUSH_SHIFT 2
+#define EUR_CR_BIF_CTRL_INVALDC_MASK 0x00000008U
+#define EUR_CR_BIF_CTRL_INVALDC_SHIFT 3
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT 4
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_MASK 0x00000100U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SHIFT 8
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_MASK 0x00000400U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SHIFT 10
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TWOD_MASK 0x00000800U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TWOD_SHIFT 11
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK 0x00010000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_SHIFT 16
+/* Register EUR_CR_BIF_INT_STAT */
+#define EUR_CR_BIF_INT_STAT 0x0C04
+#define EUR_CR_BIF_INT_STAT_FAULT_MASK 0x00003FFFU
+#define EUR_CR_BIF_INT_STAT_FAULT_SHIFT 0
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_MASK 0x00004000U
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_SHIFT 14
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00008000U
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 15
+/* Register EUR_CR_BIF_FAULT */
+#define EUR_CR_BIF_FAULT 0x0C08
+#define EUR_CR_BIF_FAULT_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_FAULT_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_TILE0 */
+#define EUR_CR_BIF_TILE0 0x0C0C
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE0_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE0_CFG_SHIFT 24
+/* Register EUR_CR_BIF_TILE1 */
+#define EUR_CR_BIF_TILE1 0x0C10
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE1_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE1_CFG_SHIFT 24
+/* Register EUR_CR_BIF_TILE2 */
+#define EUR_CR_BIF_TILE2 0x0C14
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE2_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE2_CFG_SHIFT 24
+/* Register EUR_CR_BIF_TILE3 */
+#define EUR_CR_BIF_TILE3 0x0C18
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE3_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE3_CFG_SHIFT 24
+/* Register EUR_CR_BIF_TILE4 */
+#define EUR_CR_BIF_TILE4 0x0C1C
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE4_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE4_CFG_SHIFT 24
+/* Register EUR_CR_BIF_TILE5 */
+#define EUR_CR_BIF_TILE5 0x0C20
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE5_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE5_CFG_SHIFT 24
+/* Register EUR_CR_BIF_TILE6 */
+#define EUR_CR_BIF_TILE6 0x0C24
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE6_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE6_CFG_SHIFT 24
+/* Register EUR_CR_BIF_TILE7 */
+#define EUR_CR_BIF_TILE7 0x0C28
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE7_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE7_CFG_SHIFT 24
+/* Register EUR_CR_BIF_TILE8 */
+#define EUR_CR_BIF_TILE8 0x0C2C
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE8_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE8_CFG_SHIFT 24
+/* Register EUR_CR_BIF_TILE9 */
+#define EUR_CR_BIF_TILE9 0x0C30
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE9_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE9_CFG_SHIFT 24
+/* Register EUR_CR_BIF_DIR_LIST_BASE1 */
+#define EUR_CR_BIF_DIR_LIST_BASE1 0x0C38
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_DIR_LIST_BASE2 */
+#define EUR_CR_BIF_DIR_LIST_BASE2 0x0C3C
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_DIR_LIST_BASE3 */
+#define EUR_CR_BIF_DIR_LIST_BASE3 0x0C40
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_DIR_LIST_BASE4 */
+#define EUR_CR_BIF_DIR_LIST_BASE4 0x0C44
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_DIR_LIST_BASE5 */
+#define EUR_CR_BIF_DIR_LIST_BASE5 0x0C48
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_DIR_LIST_BASE6 */
+#define EUR_CR_BIF_DIR_LIST_BASE6 0x0C4C
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_DIR_LIST_BASE7 */
+#define EUR_CR_BIF_DIR_LIST_BASE7 0x0C50
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_DIR_LIST_BASE8 */
+#define EUR_CR_BIF_DIR_LIST_BASE8 0x0C54
+#define EUR_CR_BIF_DIR_LIST_BASE8_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE8_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_DIR_LIST_BASE9 */
+#define EUR_CR_BIF_DIR_LIST_BASE9 0x0C58
+#define EUR_CR_BIF_DIR_LIST_BASE9_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE9_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_DIR_LIST_BASE10 */
+#define EUR_CR_BIF_DIR_LIST_BASE10 0x0C5C
+#define EUR_CR_BIF_DIR_LIST_BASE10_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE10_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_DIR_LIST_BASE11 */
+#define EUR_CR_BIF_DIR_LIST_BASE11 0x0C60
+#define EUR_CR_BIF_DIR_LIST_BASE11_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE11_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_DIR_LIST_BASE12 */
+#define EUR_CR_BIF_DIR_LIST_BASE12 0x0C64
+#define EUR_CR_BIF_DIR_LIST_BASE12_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE12_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_DIR_LIST_BASE13 */
+#define EUR_CR_BIF_DIR_LIST_BASE13 0x0C68
+#define EUR_CR_BIF_DIR_LIST_BASE13_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE13_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_DIR_LIST_BASE14 */
+#define EUR_CR_BIF_DIR_LIST_BASE14 0x0C6C
+#define EUR_CR_BIF_DIR_LIST_BASE14_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE14_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_DIR_LIST_BASE15 */
+#define EUR_CR_BIF_DIR_LIST_BASE15 0x0C70
+#define EUR_CR_BIF_DIR_LIST_BASE15_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE15_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_BANK_SET */
+#define EUR_CR_BIF_BANK_SET 0x0C74
+#define EUR_CR_BIF_BANK_SET_SELECT_MASK 0x000003FFU
+#define EUR_CR_BIF_BANK_SET_SELECT_SHIFT 0
+/* Register EUR_CR_BIF_BANK0 */
+#define EUR_CR_BIF_BANK0 0x0C78
+#define EUR_CR_BIF_BANK0_INDEX_EDM_MASK 0x0000000FU
+#define EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT 0
+#define EUR_CR_BIF_BANK0_INDEX_TA_MASK 0x000000F0U
+#define EUR_CR_BIF_BANK0_INDEX_TA_SHIFT 4
+#define EUR_CR_BIF_BANK0_INDEX_HOST_MASK 0x00000F00U
+#define EUR_CR_BIF_BANK0_INDEX_HOST_SHIFT 8
+#define EUR_CR_BIF_BANK0_INDEX_3D_MASK 0x0000F000U
+#define EUR_CR_BIF_BANK0_INDEX_3D_SHIFT 12
+#define EUR_CR_BIF_BANK0_INDEX_2D_MASK 0x000F0000U
+#define EUR_CR_BIF_BANK0_INDEX_2D_SHIFT 16
+/* Register EUR_CR_BIF_BANK1 */
+#define EUR_CR_BIF_BANK1 0x0C7C
+#define EUR_CR_BIF_BANK1_INDEX_EDM_MASK 0x0000000FU
+#define EUR_CR_BIF_BANK1_INDEX_EDM_SHIFT 0
+#define EUR_CR_BIF_BANK1_INDEX_TA_MASK 0x000000F0U
+#define EUR_CR_BIF_BANK1_INDEX_TA_SHIFT 4
+#define EUR_CR_BIF_BANK1_INDEX_HOST_MASK 0x00000F00U
+#define EUR_CR_BIF_BANK1_INDEX_HOST_SHIFT 8
+#define EUR_CR_BIF_BANK1_INDEX_3D_MASK 0x0000F000U
+#define EUR_CR_BIF_BANK1_INDEX_3D_SHIFT 12
+#define EUR_CR_BIF_BANK1_INDEX_2D_MASK 0x000F0000U
+#define EUR_CR_BIF_BANK1_INDEX_2D_SHIFT 16
+/* Register EUR_CR_BIF_ADT_TTE */
+#define EUR_CR_BIF_ADT_TTE 0x0C80
+#define EUR_CR_BIF_ADT_TTE_VALUE_MASK 0x000000FFU
+#define EUR_CR_BIF_ADT_TTE_VALUE_SHIFT 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE0 */
+#define EUR_CR_BIF_DIR_LIST_BASE0 0x0C84
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_TWOD_REQ_BASE */
+#define EUR_CR_BIF_TWOD_REQ_BASE 0x0C88
+#define EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_BIF_TWOD_REQ_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_BIF_TA_REQ_BASE */
+#define EUR_CR_BIF_TA_REQ_BASE 0x0C90
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_BIF_MEM_ARB_FLOWRATES_1 */
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1 0x0C94
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_MMU_MASK 0x00000007U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_MMU_SHIFT 0
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_CACHE_MASK 0x00000038U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_CACHE_SHIFT 3
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_VDM_MASK 0x000001C0U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_VDM_SHIFT 6
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_TE_MASK 0x00000E00U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_TE_SHIFT 9
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_TWOD_MASK 0x00007000U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_TWOD_SHIFT 12
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_PBE_MASK 0x00038000U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_1_PBE_SHIFT 15
+/* Register EUR_CR_BIF_MEM_ARB_FLOWRATES_2 */
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2 0x0C98
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_HOST_MASK 0x00000007U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_HOST_SHIFT 0
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_USE_MASK 0x00000038U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_USE_SHIFT 3
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_ISP_MASK 0x000001C0U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_ISP_SHIFT 6
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_TSPP_MASK 0x00000E00U
+#define EUR_CR_BIF_MEM_ARB_FLOWRATES_2_TSPP_SHIFT 9
+/* Register EUR_CR_BIF_MEM_ARB_CONFIG */
+#define EUR_CR_BIF_MEM_ARB_CONFIG 0x0CA0
+#define EUR_CR_BIF_MEM_ARB_CONFIG_PAGE_SIZE_MASK 0x0000000FU
+#define EUR_CR_BIF_MEM_ARB_CONFIG_PAGE_SIZE_SHIFT 0
+#define EUR_CR_BIF_MEM_ARB_CONFIG_BEST_CNT_MASK 0x00000FF0U
+#define EUR_CR_BIF_MEM_ARB_CONFIG_BEST_CNT_SHIFT 4
+#define EUR_CR_BIF_MEM_ARB_CONFIG_TTE_THRESH_MASK 0x00FFF000U
+#define EUR_CR_BIF_MEM_ARB_CONFIG_TTE_THRESH_SHIFT 12
+/* Register EUR_CR_BIF_MEM_REQ_STAT */
+#define EUR_CR_BIF_MEM_REQ_STAT 0x0CA8
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK 0x000000FFU
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
+/* Register EUR_CR_BIF_3D_REQ_BASE */
+#define EUR_CR_BIF_3D_REQ_BASE 0x0CAC
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_BIF_ZLS_REQ_BASE */
+#define EUR_CR_BIF_ZLS_REQ_BASE 0x0CB0
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_BIF_BANK_STATUS */
+#define EUR_CR_BIF_BANK_STATUS 0x0CB4
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_MASK 0x00000001U
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_SHIFT 0
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_MASK 0x00000002U
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_SHIFT 1
+/* Register EUR_CR_2D_BLIT_STATUS */
+#define EUR_CR_2D_BLIT_STATUS 0x0E04
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFU
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0
+#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK 0x01000000U
+#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT 24
+/* Register EUR_CR_2D_VIRTUAL_FIFO_0 */
+#define EUR_CR_2D_VIRTUAL_FIFO_0 0x0E10
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EU
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12
+/* Register EUR_CR_2D_VIRTUAL_FIFO_1 */
+#define EUR_CR_2D_VIRTUAL_FIFO_1 0x0E14
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFU
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24
+/* Register EUR_CR_2D_SOCIF */
+#define EUR_CR_2D_SOCIF 0x0E18
+#define EUR_CR_2D_SOCIF_FREESPACE_MASK 0x000000FFU
+#define EUR_CR_2D_SOCIF_FREESPACE_SHIFT 0
+/* Register EUR_CR_2D_ALPHA */
+#define EUR_CR_2D_ALPHA 0x0E1C
+#define EUR_CR_2D_ALPHA_COMPONENT_ONE_MASK 0x0000FF00U
+#define EUR_CR_2D_ALPHA_COMPONENT_ONE_SHIFT 8
+#define EUR_CR_2D_ALPHA_COMPONENT_ZERO_MASK 0x000000FFU
+#define EUR_CR_2D_ALPHA_COMPONENT_ZERO_SHIFT 0
+/* Table EUR_CR_USE_CODE_BASE */
+/* Register EUR_CR_USE_CODE_BASE */
+#define EUR_CR_USE_CODE_BASE(X) (0x0A0C + (4 * (X)))
+#define EUR_CR_USE_CODE_BASE_ADDR_MASK 0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_MASK 0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_SHIFT 25
+/* Number of entries in table EUR_CR_USE_CODE_BASE */
+#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16
+#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16
+
+#endif /* _SGX535DEFS_KM_H_ */
+
diff --git a/pvr-source/services4/srvkm/hwdefs/sgx540defs.h b/pvr-source/services4/srvkm/hwdefs/sgx540defs.h
new file mode 100644
index 0000000..47080c7
--- /dev/null
+++ b/pvr-source/services4/srvkm/hwdefs/sgx540defs.h
@@ -0,0 +1,605 @@
+/*************************************************************************/ /*!
+@Title Hardware defs for SGX540.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _SGX540DEFS_KM_H_
+#define _SGX540DEFS_KM_H_
+
+/* Register EUR_CR_CLKGATECTL */
+#define EUR_CR_CLKGATECTL 0x0000
+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK 0x00000003U
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT 0
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SHIFT 2
+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL_TE_CLKG_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTL_TE_CLKG_SHIFT 6
+#define EUR_CR_CLKGATECTL_MTE_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL_MTE_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT 10
+#define EUR_CR_CLKGATECTL_VDM_CLKG_MASK 0x00003000U
+#define EUR_CR_CLKGATECTL_VDM_CLKG_SHIFT 12
+#define EUR_CR_CLKGATECTL_PDS_CLKG_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTL_PDS_CLKG_SHIFT 14
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL_TA_CLKG_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT 18
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_MASK 0x10000000U
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_SHIFT 28
+/* Register EUR_CR_CLKGATECTL2 */
+#define EUR_CR_CLKGATECTL2 0x0004
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_MASK 0x00000003U
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SHIFT 0
+#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_SHIFT 2
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SHIFT 6
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SHIFT 10
+#define EUR_CR_CLKGATECTL2_MADD0_CLKG_MASK 0x00003000U
+#define EUR_CR_CLKGATECTL2_MADD0_CLKG_SHIFT 12
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SHIFT 14
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SHIFT 18
+#define EUR_CR_CLKGATECTL2_MADD1_CLKG_MASK 0x00300000U
+#define EUR_CR_CLKGATECTL2_MADD1_CLKG_SHIFT 20
+/* Register EUR_CR_CLKGATESTATUS */
+#define EUR_CR_CLKGATESTATUS 0x0008
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK 0x00000001U
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 0
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_MASK 0x00000002U
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SHIFT 1
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK 0x00000004U
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 2
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_MASK 0x00000008U
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SHIFT 3
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_MASK 0x00000010U
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SHIFT 4
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK 0x00000020U
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 5
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_MASK 0x00000040U
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SHIFT 6
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_MASK 0x00000080U
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_SHIFT 7
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_MASK 0x00000100U
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SHIFT 8
+#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_MASK 0x00000200U
+#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_SHIFT 9
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_MASK 0x00000400U
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SHIFT 10
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_MASK 0x00000800U
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SHIFT 11
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_MASK 0x00001000U
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SHIFT 12
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_MASK 0x00002000U
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SHIFT 13
+#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_MASK 0x00004000U
+#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_SHIFT 14
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_MASK 0x00008000U
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SHIFT 15
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_MASK 0x00010000U
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SHIFT 16
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_MASK 0x00020000U
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SHIFT 17
+#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_MASK 0x00040000U
+#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_SHIFT 18
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_MASK 0x00080000U
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_SHIFT 19
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK 0x00100000U
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT 20
+/* Register EUR_CR_CLKGATECTLOVR */
+#define EUR_CR_CLKGATECTLOVR 0x000C
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK 0x00000003U
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 0
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SHIFT 2
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK 0x00000030U
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 4
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SHIFT 6
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_MASK 0x00000300U
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SHIFT 8
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 10
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_MASK 0x00003000U
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SHIFT 12
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_SHIFT 14
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_MASK 0x00030000U
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_SHIFT 16
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT 18
+/* Register EUR_CR_POWER */
+#define EUR_CR_POWER 0x001C
+#define EUR_CR_POWER_PIPE_DISABLE_MASK 0x00000001U
+#define EUR_CR_POWER_PIPE_DISABLE_SHIFT 0
+/* Register EUR_CR_CORE_ID */
+#define EUR_CR_CORE_ID 0x0020
+#define EUR_CR_CORE_ID_CONFIG_MASK 0x0000FFFFU
+#define EUR_CR_CORE_ID_CONFIG_SHIFT 0
+#define EUR_CR_CORE_ID_ID_MASK 0xFFFF0000U
+#define EUR_CR_CORE_ID_ID_SHIFT 16
+/* Register EUR_CR_CORE_REVISION */
+#define EUR_CR_CORE_REVISION 0x0024
+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
+#define EUR_CR_CORE_REVISION_MINOR_MASK 0x0000FF00U
+#define EUR_CR_CORE_REVISION_MINOR_SHIFT 8
+#define EUR_CR_CORE_REVISION_MAJOR_MASK 0x00FF0000U
+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT 16
+#define EUR_CR_CORE_REVISION_DESIGNER_MASK 0xFF000000U
+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
+/* Register EUR_CR_DESIGNER_REV_FIELD1 */
+#define EUR_CR_DESIGNER_REV_FIELD1 0x0028
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
+/* Register EUR_CR_DESIGNER_REV_FIELD2 */
+#define EUR_CR_DESIGNER_REV_FIELD2 0x002C
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
+/* Register EUR_CR_SOFT_RESET */
+#define EUR_CR_SOFT_RESET 0x0080
+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK 0x00000001U
+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT 0
+#define EUR_CR_SOFT_RESET_VDM_RESET_MASK 0x00000002U
+#define EUR_CR_SOFT_RESET_VDM_RESET_SHIFT 1
+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK 0x00000004U
+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT 2
+#define EUR_CR_SOFT_RESET_TE_RESET_MASK 0x00000008U
+#define EUR_CR_SOFT_RESET_TE_RESET_SHIFT 3
+#define EUR_CR_SOFT_RESET_MTE_RESET_MASK 0x00000010U
+#define EUR_CR_SOFT_RESET_MTE_RESET_SHIFT 4
+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK 0x00000020U
+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT 5
+#define EUR_CR_SOFT_RESET_ISP2_RESET_MASK 0x00000040U
+#define EUR_CR_SOFT_RESET_ISP2_RESET_SHIFT 6
+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK 0x00000080U
+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT 7
+#define EUR_CR_SOFT_RESET_PDS_RESET_MASK 0x00000100U
+#define EUR_CR_SOFT_RESET_PDS_RESET_SHIFT 8
+#define EUR_CR_SOFT_RESET_PBE_RESET_MASK 0x00000200U
+#define EUR_CR_SOFT_RESET_PBE_RESET_SHIFT 9
+#define EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK 0x00000400U
+#define EUR_CR_SOFT_RESET_CACHEL2_RESET_SHIFT 10
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK 0x00000800U
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_SHIFT 11
+#define EUR_CR_SOFT_RESET_MADD_RESET_MASK 0x00001000U
+#define EUR_CR_SOFT_RESET_MADD_RESET_SHIFT 12
+#define EUR_CR_SOFT_RESET_ITR_RESET_MASK 0x00002000U
+#define EUR_CR_SOFT_RESET_ITR_RESET_SHIFT 13
+#define EUR_CR_SOFT_RESET_TEX_RESET_MASK 0x00004000U
+#define EUR_CR_SOFT_RESET_TEX_RESET_SHIFT 14
+#define EUR_CR_SOFT_RESET_USE_RESET_MASK 0x00008000U
+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT 15
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK 0x00010000U
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_SHIFT 16
+#define EUR_CR_SOFT_RESET_TA_RESET_MASK 0x00020000U
+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT 17
+/* Register EUR_CR_EVENT_HOST_ENABLE2 */
+#define EUR_CR_EVENT_HOST_ENABLE2 0x0110
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
+/* Register EUR_CR_EVENT_HOST_CLEAR2 */
+#define EUR_CR_EVENT_HOST_CLEAR2 0x0114
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
+/* Register EUR_CR_EVENT_STATUS2 */
+#define EUR_CR_EVENT_STATUS2 0x0118
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
+/* Register EUR_CR_EVENT_STATUS */
+#define EUR_CR_EVENT_STATUS 0x012CU
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_STATUS_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT 29
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_STATUS_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_STATUS_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
+/* Register EUR_CR_EVENT_HOST_ENABLE */
+#define EUR_CR_EVENT_HOST_ENABLE 0x0130
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#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 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
+/* Register EUR_CR_EVENT_HOST_CLEAR */
+#define EUR_CR_EVENT_HOST_CLEAR 0x0134
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_MASK 0x08000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_SHIFT 27
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_MASK 0x00020000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_SHIFT 17
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#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 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
+/* Register EUR_CR_TIMER */
+#define EUR_CR_TIMER 0x0144
+#define EUR_CR_TIMER_VALUE_MASK 0xFFFFFFFFU
+#define EUR_CR_TIMER_VALUE_SHIFT 0
+/* Register EUR_CR_EVENT_KICK1 */
+#define EUR_CR_EVENT_KICK1 0x0AB0
+#define EUR_CR_EVENT_KICK1_NOW_MASK 0x000000FFU
+#define EUR_CR_EVENT_KICK1_NOW_SHIFT 0
+/* Register EUR_CR_PDS_EXEC_BASE */
+#define EUR_CR_PDS_EXEC_BASE 0x0AB8
+#define EUR_CR_PDS_EXEC_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_PDS_EXEC_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_EVENT_KICK2 */
+#define EUR_CR_EVENT_KICK2 0x0AC0
+#define EUR_CR_EVENT_KICK2_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK2_NOW_SHIFT 0
+/* Register EUR_CR_EVENT_KICKER */
+#define EUR_CR_EVENT_KICKER 0x0AC4
+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK 0x0FFFFFF0U
+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT 4
+/* Register EUR_CR_EVENT_KICK */
+#define EUR_CR_EVENT_KICK 0x0AC8
+#define EUR_CR_EVENT_KICK_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK_NOW_SHIFT 0
+/* Register EUR_CR_EVENT_TIMER */
+#define EUR_CR_EVENT_TIMER 0x0ACC
+#define EUR_CR_EVENT_TIMER_ENABLE_MASK 0x01000000U
+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT 24
+#define EUR_CR_EVENT_TIMER_VALUE_MASK 0x00FFFFFFU
+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT 0
+/* Register EUR_CR_PDS_INV0 */
+#define EUR_CR_PDS_INV0 0x0AD0
+#define EUR_CR_PDS_INV0_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV0_DSC_SHIFT 0
+/* Register EUR_CR_PDS_INV1 */
+#define EUR_CR_PDS_INV1 0x0AD4
+#define EUR_CR_PDS_INV1_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV1_DSC_SHIFT 0
+/* Register EUR_CR_EVENT_KICK3 */
+#define EUR_CR_EVENT_KICK3 0x0AD8
+#define EUR_CR_EVENT_KICK3_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK3_NOW_SHIFT 0
+/* Register EUR_CR_PDS_INV3 */
+#define EUR_CR_PDS_INV3 0x0ADC
+#define EUR_CR_PDS_INV3_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV3_DSC_SHIFT 0
+/* Register EUR_CR_PDS_INV_CSC */
+#define EUR_CR_PDS_INV_CSC 0x0AE0
+#define EUR_CR_PDS_INV_CSC_KICK_MASK 0x00000001U
+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT 0
+/* Register EUR_CR_PDS_PC_BASE */
+#define EUR_CR_PDS_PC_BASE 0x0B2C
+#define EUR_CR_PDS_PC_BASE_ADDRESS_MASK 0x00FFFFFFU
+#define EUR_CR_PDS_PC_BASE_ADDRESS_SHIFT 0
+/* Register EUR_CR_BIF_CTRL */
+#define EUR_CR_BIF_CTRL 0x0C00
+#define EUR_CR_BIF_CTRL_NOREORDER_MASK 0x00000001U
+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT 0
+#define EUR_CR_BIF_CTRL_PAUSE_MASK 0x00000002U
+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT 1
+#define EUR_CR_BIF_CTRL_FLUSH_MASK 0x00000004U
+#define EUR_CR_BIF_CTRL_FLUSH_SHIFT 2
+#define EUR_CR_BIF_CTRL_INVALDC_MASK 0x00000008U
+#define EUR_CR_BIF_CTRL_INVALDC_SHIFT 3
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT 4
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_MASK 0x00000100U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SHIFT 8
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_MASK 0x00000400U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SHIFT 10
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15
+/* Register EUR_CR_BIF_INT_STAT */
+#define EUR_CR_BIF_INT_STAT 0x0C04
+#define EUR_CR_BIF_INT_STAT_FAULT_MASK 0x00003FFFU
+#define EUR_CR_BIF_INT_STAT_FAULT_SHIFT 0
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_MASK 0x00004000U
+#define EUR_CR_BIF_INT_STAT_PF_N_RW_SHIFT 14
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00008000U
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 15
+/* Register EUR_CR_BIF_FAULT */
+#define EUR_CR_BIF_FAULT 0x0C08
+#define EUR_CR_BIF_FAULT_SB_MASK 0x000001F0U
+#define EUR_CR_BIF_FAULT_SB_SHIFT 4
+#define EUR_CR_BIF_FAULT_ADDR_MASK 0x0FFFF000U
+#define EUR_CR_BIF_FAULT_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_DIR_LIST_BASE0 */
+#define EUR_CR_BIF_DIR_LIST_BASE0 0x0C84
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12
+/* Register EUR_CR_BIF_TA_REQ_BASE */
+#define EUR_CR_BIF_TA_REQ_BASE 0x0C90
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_BIF_MEM_REQ_STAT */
+#define EUR_CR_BIF_MEM_REQ_STAT 0x0CA8
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK 0x000000FFU
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
+/* Register EUR_CR_BIF_3D_REQ_BASE */
+#define EUR_CR_BIF_3D_REQ_BASE 0x0CAC
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_BIF_ZLS_REQ_BASE */
+#define EUR_CR_BIF_ZLS_REQ_BASE 0x0CB0
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK 0x0FF00000U
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT 20
+/* Register EUR_CR_2D_BLIT_STATUS */
+#define EUR_CR_2D_BLIT_STATUS 0x0E04
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFU
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0
+#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK 0x01000000U
+#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT 24
+/* Register EUR_CR_2D_VIRTUAL_FIFO_0 */
+#define EUR_CR_2D_VIRTUAL_FIFO_0 0x0E10
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EU
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12
+/* Register EUR_CR_2D_VIRTUAL_FIFO_1 */
+#define EUR_CR_2D_VIRTUAL_FIFO_1 0x0E14
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFU
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24
+/* Table EUR_CR_USE_CODE_BASE */
+/* Register EUR_CR_USE_CODE_BASE */
+#define EUR_CR_USE_CODE_BASE(X) (0x0A0C + (4 * (X)))
+#define EUR_CR_USE_CODE_BASE_ADDR_MASK 0x00FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_DM_MASK 0x03000000U
+#define EUR_CR_USE_CODE_BASE_DM_SHIFT 24
+/* Number of entries in table EUR_CR_USE_CODE_BASE */
+#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16
+#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16
+
+#endif /* _SGX540DEFS_KM_H_ */
+
diff --git a/pvr-source/services4/srvkm/hwdefs/sgx543_v1.164defs.h b/pvr-source/services4/srvkm/hwdefs/sgx543_v1.164defs.h
new file mode 100644
index 0000000..8c8b353
--- /dev/null
+++ b/pvr-source/services4/srvkm/hwdefs/sgx543_v1.164defs.h
@@ -0,0 +1,1396 @@
+/*************************************************************************/ /*!
+@Title Hardware defs for SGX543_V1.164.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _SGX543_V1_164DEFS_KM_H_
+#define _SGX543_V1_164DEFS_KM_H_
+
+/* Register EUR_CR_CLKGATECTL */
+#define EUR_CR_CLKGATECTL 0x0000
+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK 0x00000003U
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT 0
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SHIFT 2
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_TE_CLKG_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTL_TE_CLKG_SHIFT 6
+#define EUR_CR_CLKGATECTL_TE_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_MTE_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL_MTE_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL_MTE_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT 10
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_VDM_CLKG_MASK 0x00003000U
+#define EUR_CR_CLKGATECTL_VDM_CLKG_SHIFT 12
+#define EUR_CR_CLKGATECTL_VDM_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_PDS_CLKG_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTL_PDS_CLKG_SHIFT 14
+#define EUR_CR_CLKGATECTL_PDS_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_TA_CLKG_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT 18
+#define EUR_CR_CLKGATECTL_TA_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_BIF_CORE_CLKG_MASK 0x00300000U
+#define EUR_CR_CLKGATECTL_BIF_CORE_CLKG_SHIFT 20
+#define EUR_CR_CLKGATECTL_BIF_CORE_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SIGNED 0
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_MASK 0x10000000U
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_SHIFT 28
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_SIGNED 0
+/* Register EUR_CR_CLKGATECTL2 */
+#define EUR_CR_CLKGATECTL2 0x0004
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_MASK 0x00000003U
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SHIFT 0
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_TCU_L2_CLKG_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTL2_TCU_L2_CLKG_SHIFT 2
+#define EUR_CR_CLKGATECTL2_TCU_L2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SHIFT 6
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SHIFT 10
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SHIFT 14
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SHIFT 18
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_DCU_L2_CLKG_MASK 0x00C00000U
+#define EUR_CR_CLKGATECTL2_DCU_L2_CLKG_SHIFT 22
+#define EUR_CR_CLKGATECTL2_DCU_L2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_DCU1_L0L1_CLKG_MASK 0x03000000U
+#define EUR_CR_CLKGATECTL2_DCU1_L0L1_CLKG_SHIFT 24
+#define EUR_CR_CLKGATECTL2_DCU1_L0L1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_DCU0_L0L1_CLKG_MASK 0x0C000000U
+#define EUR_CR_CLKGATECTL2_DCU0_L0L1_CLKG_SHIFT 26
+#define EUR_CR_CLKGATECTL2_DCU0_L0L1_CLKG_SIGNED 0
+/* Register EUR_CR_CLKGATESTATUS */
+#define EUR_CR_CLKGATESTATUS 0x0008
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK 0x00000001U
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 0
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_MASK 0x00000002U
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SHIFT 1
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK 0x00000004U
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 2
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_MASK 0x00000008U
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SHIFT 3
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_MASK 0x00000010U
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SHIFT 4
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK 0x00000020U
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 5
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_MASK 0x00000040U
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SHIFT 6
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_MASK 0x00000080U
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_SHIFT 7
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_MASK 0x00000100U
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SHIFT 8
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TCU_L2_CLKS_MASK 0x00000200U
+#define EUR_CR_CLKGATESTATUS_TCU_L2_CLKS_SHIFT 9
+#define EUR_CR_CLKGATESTATUS_TCU_L2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_MASK 0x00000400U
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SHIFT 10
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_MASK 0x00000800U
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SHIFT 11
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_MASK 0x00001000U
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SHIFT 12
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_MASK 0x00002000U
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SHIFT 13
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_MASK 0x00008000U
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SHIFT 15
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_MASK 0x00010000U
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SHIFT 16
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_MASK 0x00020000U
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SHIFT 17
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_MASK 0x00080000U
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_SHIFT 19
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK 0x00100000U
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT 20
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DCU_L2_CLKS_MASK 0x00200000U
+#define EUR_CR_CLKGATESTATUS_DCU_L2_CLKS_SHIFT 21
+#define EUR_CR_CLKGATESTATUS_DCU_L2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DCU0_L0L1_CLKS_MASK 0x00400000U
+#define EUR_CR_CLKGATESTATUS_DCU0_L0L1_CLKS_SHIFT 22
+#define EUR_CR_CLKGATESTATUS_DCU0_L0L1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DCU1_L0L1_CLKS_MASK 0x00800000U
+#define EUR_CR_CLKGATESTATUS_DCU1_L0L1_CLKS_SHIFT 23
+#define EUR_CR_CLKGATESTATUS_DCU1_L0L1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_BIF_CORE_CLKS_MASK 0x01000000U
+#define EUR_CR_CLKGATESTATUS_BIF_CORE_CLKS_SHIFT 24
+#define EUR_CR_CLKGATESTATUS_BIF_CORE_CLKS_SIGNED 0
+/* Register EUR_CR_CLKGATECTLOVR */
+#define EUR_CR_CLKGATECTLOVR 0x000C
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK 0x00000003U
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 0
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SHIFT 2
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK 0x00000030U
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 4
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SHIFT 6
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_MASK 0x00000300U
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SHIFT 8
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 10
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_MASK 0x00003000U
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SHIFT 12
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_SHIFT 14
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_MASK 0x00030000U
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_SHIFT 16
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT 18
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_BIF_CORE_CLKO_MASK 0x00300000U
+#define EUR_CR_CLKGATECTLOVR_BIF_CORE_CLKO_SHIFT 20
+#define EUR_CR_CLKGATECTLOVR_BIF_CORE_CLKO_SIGNED 0
+/* Register EUR_CR_POWER */
+#define EUR_CR_POWER 0x001C
+#define EUR_CR_POWER_PIPE_DISABLE_MASK 0x00000001U
+#define EUR_CR_POWER_PIPE_DISABLE_SHIFT 0
+#define EUR_CR_POWER_PIPE_DISABLE_SIGNED 0
+/* Register EUR_CR_CORE_ID */
+#define EUR_CR_CORE_ID 0x0020
+#define EUR_CR_CORE_ID_CONFIG_MULTI_MASK 0x00000001U
+#define EUR_CR_CORE_ID_CONFIG_MULTI_SHIFT 0
+#define EUR_CR_CORE_ID_CONFIG_MULTI_SIGNED 0
+#define EUR_CR_CORE_ID_CONFIG_BASE_MASK 0x00000002U
+#define EUR_CR_CORE_ID_CONFIG_BASE_SHIFT 1
+#define EUR_CR_CORE_ID_CONFIG_BASE_SIGNED 0
+#define EUR_CR_CORE_ID_CONFIG_MASK 0x000000FCU
+#define EUR_CR_CORE_ID_CONFIG_SHIFT 2
+#define EUR_CR_CORE_ID_CONFIG_SIGNED 0
+#define EUR_CR_CORE_ID_CONFIG_CORES_MASK 0x00000F00U
+#define EUR_CR_CORE_ID_CONFIG_CORES_SHIFT 8
+#define EUR_CR_CORE_ID_CONFIG_CORES_SIGNED 0
+#define EUR_CR_CORE_ID_CONFIG_SLC_MASK 0x0000F000U
+#define EUR_CR_CORE_ID_CONFIG_SLC_SHIFT 12
+#define EUR_CR_CORE_ID_CONFIG_SLC_SIGNED 0
+#define EUR_CR_CORE_ID_ID_MASK 0xFFFF0000U
+#define EUR_CR_CORE_ID_ID_SHIFT 16
+#define EUR_CR_CORE_ID_ID_SIGNED 0
+/* Register EUR_CR_CORE_REVISION */
+#define EUR_CR_CORE_REVISION 0x0024
+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SIGNED 0
+#define EUR_CR_CORE_REVISION_MINOR_MASK 0x0000FF00U
+#define EUR_CR_CORE_REVISION_MINOR_SHIFT 8
+#define EUR_CR_CORE_REVISION_MINOR_SIGNED 0
+#define EUR_CR_CORE_REVISION_MAJOR_MASK 0x00FF0000U
+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT 16
+#define EUR_CR_CORE_REVISION_MAJOR_SIGNED 0
+#define EUR_CR_CORE_REVISION_DESIGNER_MASK 0xFF000000U
+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
+#define EUR_CR_CORE_REVISION_DESIGNER_SIGNED 0
+/* Register EUR_CR_DESIGNER_REV_FIELD1 */
+#define EUR_CR_DESIGNER_REV_FIELD1 0x0028
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SIGNED 0
+/* Register EUR_CR_DESIGNER_REV_FIELD2 */
+#define EUR_CR_DESIGNER_REV_FIELD2 0x002C
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SIGNED 0
+/* Register EUR_CR_SOFT_RESET */
+#define EUR_CR_SOFT_RESET 0x0080
+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK 0x00000001U
+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT 0
+#define EUR_CR_SOFT_RESET_BIF_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_VDM_RESET_MASK 0x00000002U
+#define EUR_CR_SOFT_RESET_VDM_RESET_SHIFT 1
+#define EUR_CR_SOFT_RESET_VDM_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK 0x00000004U
+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT 2
+#define EUR_CR_SOFT_RESET_DPM_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TE_RESET_MASK 0x00000008U
+#define EUR_CR_SOFT_RESET_TE_RESET_SHIFT 3
+#define EUR_CR_SOFT_RESET_TE_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_MTE_RESET_MASK 0x00000010U
+#define EUR_CR_SOFT_RESET_MTE_RESET_SHIFT 4
+#define EUR_CR_SOFT_RESET_MTE_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK 0x00000020U
+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT 5
+#define EUR_CR_SOFT_RESET_ISP_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_ISP2_RESET_MASK 0x00000040U
+#define EUR_CR_SOFT_RESET_ISP2_RESET_SHIFT 6
+#define EUR_CR_SOFT_RESET_ISP2_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK 0x00000080U
+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT 7
+#define EUR_CR_SOFT_RESET_TSP_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_PDS_RESET_MASK 0x00000100U
+#define EUR_CR_SOFT_RESET_PDS_RESET_SHIFT 8
+#define EUR_CR_SOFT_RESET_PDS_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_PBE_RESET_MASK 0x00000200U
+#define EUR_CR_SOFT_RESET_PBE_RESET_SHIFT 9
+#define EUR_CR_SOFT_RESET_PBE_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TCU_L2_RESET_MASK 0x00000400U
+#define EUR_CR_SOFT_RESET_TCU_L2_RESET_SHIFT 10
+#define EUR_CR_SOFT_RESET_TCU_L2_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK 0x00000800U
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_SHIFT 11
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_ITR_RESET_MASK 0x00002000U
+#define EUR_CR_SOFT_RESET_ITR_RESET_SHIFT 13
+#define EUR_CR_SOFT_RESET_ITR_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TEX_RESET_MASK 0x00004000U
+#define EUR_CR_SOFT_RESET_TEX_RESET_SHIFT 14
+#define EUR_CR_SOFT_RESET_TEX_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_USE_RESET_MASK 0x00008000U
+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT 15
+#define EUR_CR_SOFT_RESET_USE_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK 0x00010000U
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_SHIFT 16
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TA_RESET_MASK 0x00020000U
+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT 17
+#define EUR_CR_SOFT_RESET_TA_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_DCU_L2_RESET_MASK 0x00040000U
+#define EUR_CR_SOFT_RESET_DCU_L2_RESET_SHIFT 18
+#define EUR_CR_SOFT_RESET_DCU_L2_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_DCU_L0L1_RESET_MASK 0x00080000U
+#define EUR_CR_SOFT_RESET_DCU_L0L1_RESET_SHIFT 19
+#define EUR_CR_SOFT_RESET_DCU_L0L1_RESET_SIGNED 0
+/* Register EUR_CR_EVENT_HOST_ENABLE2 */
+#define EUR_CR_EVENT_HOST_ENABLE2 0x0110
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_UNTRAPPED_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_UNTRAPPED_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_TRAPPED_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_TRAPPED_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_TRAPPED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_CONTEXT_DRAINED_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_CONTEXT_DRAINED_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_CONTEXT_DRAINED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_ISP2_ZLS_CSW_FINISHED_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE2_ISP2_ZLS_CSW_FINISHED_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE2_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TE_RGNHDR_INIT_COMPLETE_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE2_TE_RGNHDR_INIT_COMPLETE_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE2_TE_RGNHDR_INIT_COMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SIGNED 0
+/* Register EUR_CR_EVENT_HOST_CLEAR2 */
+#define EUR_CR_EVENT_HOST_CLEAR2 0x0114
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_CONTEXT_DRAINED_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_CONTEXT_DRAINED_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_CONTEXT_DRAINED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_ISP2_ZLS_CSW_FINISHED_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR2_ISP2_ZLS_CSW_FINISHED_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR2_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TE_RGNHDR_INIT_COMPLETE_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR2_TE_RGNHDR_INIT_COMPLETE_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR2_TE_RGNHDR_INIT_COMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SIGNED 0
+/* Register EUR_CR_EVENT_STATUS2 */
+#define EUR_CR_EVENT_STATUS2 0x0118
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_MASK 0x00000800U
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_SHIFT 11
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_MASK 0x00000400U
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_SHIFT 10
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_MTE_CONTEXT_DRAINED_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS2_MTE_CONTEXT_DRAINED_SHIFT 9
+#define EUR_CR_EVENT_STATUS2_MTE_CONTEXT_DRAINED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_ISP2_ZLS_CSW_FINISHED_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS2_ISP2_ZLS_CSW_FINISHED_SHIFT 8
+#define EUR_CR_EVENT_STATUS2_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_SHIFT 7
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_SHIFT 6
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TE_RGNHDR_INIT_COMPLETE_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS2_TE_RGNHDR_INIT_COMPLETE_SHIFT 5
+#define EUR_CR_EVENT_STATUS2_TE_RGNHDR_INIT_COMPLETE_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SIGNED 0
+/* Register EUR_CR_EVENT_STATUS */
+#define EUR_CR_EVENT_STATUS 0x012C
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT 29
+#define EUR_CR_EVENT_STATUS_TIMER_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TCU_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_STATUS_TCU_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_STATUS_TCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SIGNED 0
+/* Register EUR_CR_EVENT_HOST_ENABLE */
+#define EUR_CR_EVENT_HOST_ENABLE 0x0130
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TCU_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TCU_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_ENABLE_TCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SIGNED 0
+/* Register EUR_CR_EVENT_HOST_CLEAR */
+#define EUR_CR_EVENT_HOST_CLEAR 0x0134
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TCU_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TCU_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_CLEAR_TCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SIGNED 0
+/* Register EUR_CR_TIMER */
+#define EUR_CR_TIMER 0x0144
+#define EUR_CR_TIMER_VALUE_MASK 0xFFFFFFFFU
+#define EUR_CR_TIMER_VALUE_SHIFT 0
+#define EUR_CR_TIMER_VALUE_SIGNED 0
+/* Register EUR_CR_EVENT_KICK1 */
+#define EUR_CR_EVENT_KICK1 0x0AB0
+#define EUR_CR_EVENT_KICK1_NOW_MASK 0x000000FFU
+#define EUR_CR_EVENT_KICK1_NOW_SHIFT 0
+#define EUR_CR_EVENT_KICK1_NOW_SIGNED 0
+/* Register EUR_CR_EVENT_KICK2 */
+#define EUR_CR_EVENT_KICK2 0x0AC0
+#define EUR_CR_EVENT_KICK2_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK2_NOW_SHIFT 0
+#define EUR_CR_EVENT_KICK2_NOW_SIGNED 0
+/* Register EUR_CR_EVENT_KICKER */
+#define EUR_CR_EVENT_KICKER 0x0AC4
+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT 4
+#define EUR_CR_EVENT_KICKER_ADDRESS_SIGNED 0
+/* Register EUR_CR_EVENT_KICK */
+#define EUR_CR_EVENT_KICK 0x0AC8
+#define EUR_CR_EVENT_KICK_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK_NOW_SHIFT 0
+#define EUR_CR_EVENT_KICK_NOW_SIGNED 0
+/* Register EUR_CR_EVENT_TIMER */
+#define EUR_CR_EVENT_TIMER 0x0ACC
+#define EUR_CR_EVENT_TIMER_ENABLE_MASK 0x01000000U
+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT 24
+#define EUR_CR_EVENT_TIMER_ENABLE_SIGNED 0
+#define EUR_CR_EVENT_TIMER_VALUE_MASK 0x00FFFFFFU
+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT 0
+#define EUR_CR_EVENT_TIMER_VALUE_SIGNED 0
+/* Register EUR_CR_PDS_INV0 */
+#define EUR_CR_PDS_INV0 0x0AD0
+#define EUR_CR_PDS_INV0_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV0_DSC_SHIFT 0
+#define EUR_CR_PDS_INV0_DSC_SIGNED 0
+/* Register EUR_CR_PDS_INV1 */
+#define EUR_CR_PDS_INV1 0x0AD4
+#define EUR_CR_PDS_INV1_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV1_DSC_SHIFT 0
+#define EUR_CR_PDS_INV1_DSC_SIGNED 0
+/* Register EUR_CR_EVENT_KICK3 */
+#define EUR_CR_EVENT_KICK3 0x0AD8
+#define EUR_CR_EVENT_KICK3_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK3_NOW_SHIFT 0
+#define EUR_CR_EVENT_KICK3_NOW_SIGNED 0
+/* Register EUR_CR_PDS_INV3 */
+#define EUR_CR_PDS_INV3 0x0ADC
+#define EUR_CR_PDS_INV3_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV3_DSC_SHIFT 0
+#define EUR_CR_PDS_INV3_DSC_SIGNED 0
+/* Register EUR_CR_PDS_INV_CSC */
+#define EUR_CR_PDS_INV_CSC 0x0AE0
+#define EUR_CR_PDS_INV_CSC_KICK_MASK 0x00000001U
+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT 0
+#define EUR_CR_PDS_INV_CSC_KICK_SIGNED 0
+/* Register EUR_CR_BIF_CTRL */
+#define EUR_CR_BIF_CTRL 0x0C00
+#define EUR_CR_BIF_CTRL_NOREORDER_MASK 0x00000001U
+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT 0
+#define EUR_CR_BIF_CTRL_NOREORDER_SIGNED 0
+#define EUR_CR_BIF_CTRL_PAUSE_MASK 0x00000002U
+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT 1
+#define EUR_CR_BIF_CTRL_PAUSE_SIGNED 0
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT 4
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TA_MASK 0x00000400U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TA_SHIFT 10
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TA_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PTLA_MASK 0x00010000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PTLA_SHIFT 16
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PTLA_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_VDM_MASK 0x00020000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_VDM_SHIFT 17
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_VDM_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_IPF_MASK 0x00040000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_IPF_SHIFT 18
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_IPF_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_DPM_MASK 0x00080000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_DPM_SHIFT 19
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_DPM_SIGNED 0
+/* Register EUR_CR_BIF_INT_STAT */
+#define EUR_CR_BIF_INT_STAT 0x0C04
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_MASK 0x00003FFFU
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_SHIFT 0
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_SIGNED 0
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_MASK 0x00070000U
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_SHIFT 16
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_SIGNED 0
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00080000U
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 19
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SIGNED 0
+/* Register EUR_CR_BIF_FAULT */
+#define EUR_CR_BIF_FAULT 0x0C08
+#define EUR_CR_BIF_FAULT_CID_MASK 0x0000000FU
+#define EUR_CR_BIF_FAULT_CID_SHIFT 0
+#define EUR_CR_BIF_FAULT_CID_SIGNED 0
+#define EUR_CR_BIF_FAULT_SB_MASK 0x000001F0U
+#define EUR_CR_BIF_FAULT_SB_SHIFT 4
+#define EUR_CR_BIF_FAULT_SB_SIGNED 0
+#define EUR_CR_BIF_FAULT_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_FAULT_ADDR_SHIFT 12
+#define EUR_CR_BIF_FAULT_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_TILE0 */
+#define EUR_CR_BIF_TILE0 0x0C0C
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE0_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE0_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE0_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE1 */
+#define EUR_CR_BIF_TILE1 0x0C10
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE1_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE1_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE1_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE2 */
+#define EUR_CR_BIF_TILE2 0x0C14
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE2_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE2_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE2_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE3 */
+#define EUR_CR_BIF_TILE3 0x0C18
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE3_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE3_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE3_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE4 */
+#define EUR_CR_BIF_TILE4 0x0C1C
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE4_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE4_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE4_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE5 */
+#define EUR_CR_BIF_TILE5 0x0C20
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE5_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE5_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE5_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE6 */
+#define EUR_CR_BIF_TILE6 0x0C24
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE6_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE6_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE6_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE7 */
+#define EUR_CR_BIF_TILE7 0x0C28
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE7_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE7_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE7_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE8 */
+#define EUR_CR_BIF_TILE8 0x0C2C
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE8_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE8_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE8_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE9 */
+#define EUR_CR_BIF_TILE9 0x0C30
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE9_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE9_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE9_CFG_SIGNED 0
+/* Register EUR_CR_BIF_CTRL_INVAL */
+#define EUR_CR_BIF_CTRL_INVAL 0x0C34
+#define EUR_CR_BIF_CTRL_INVAL_PTE_MASK 0x00000004U
+#define EUR_CR_BIF_CTRL_INVAL_PTE_SHIFT 2
+#define EUR_CR_BIF_CTRL_INVAL_PTE_SIGNED 0
+#define EUR_CR_BIF_CTRL_INVAL_ALL_MASK 0x00000008U
+#define EUR_CR_BIF_CTRL_INVAL_ALL_SHIFT 3
+#define EUR_CR_BIF_CTRL_INVAL_ALL_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE1 */
+#define EUR_CR_BIF_DIR_LIST_BASE1 0x0C38
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE2 */
+#define EUR_CR_BIF_DIR_LIST_BASE2 0x0C3C
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE3 */
+#define EUR_CR_BIF_DIR_LIST_BASE3 0x0C40
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE4 */
+#define EUR_CR_BIF_DIR_LIST_BASE4 0x0C44
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE5 */
+#define EUR_CR_BIF_DIR_LIST_BASE5 0x0C48
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE6 */
+#define EUR_CR_BIF_DIR_LIST_BASE6 0x0C4C
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE7 */
+#define EUR_CR_BIF_DIR_LIST_BASE7 0x0C50
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_BANK_SET */
+#define EUR_CR_BIF_BANK_SET 0x0C74
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_MASK 0x00000001U
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_SHIFT 0
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_MASK 0x0000000CU
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_SHIFT 2
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_MASK 0x00000010U
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_SHIFT 4
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_MASK 0x000000C0U
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_SHIFT 6
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_MASK 0x00000100U
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_SHIFT 8
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_MASK 0x00000200U
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_SHIFT 9
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_SIGNED 0
+/* Register EUR_CR_BIF_BANK0 */
+#define EUR_CR_BIF_BANK0 0x0C78
+#define EUR_CR_BIF_BANK0_INDEX_EDM_MASK 0x0000000FU
+#define EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT 0
+#define EUR_CR_BIF_BANK0_INDEX_EDM_SIGNED 0
+#define EUR_CR_BIF_BANK0_INDEX_TA_MASK 0x000000F0U
+#define EUR_CR_BIF_BANK0_INDEX_TA_SHIFT 4
+#define EUR_CR_BIF_BANK0_INDEX_TA_SIGNED 0
+#define EUR_CR_BIF_BANK0_INDEX_3D_MASK 0x0000F000U
+#define EUR_CR_BIF_BANK0_INDEX_3D_SHIFT 12
+#define EUR_CR_BIF_BANK0_INDEX_3D_SIGNED 0
+#define EUR_CR_BIF_BANK0_INDEX_PTLA_MASK 0x000F0000U
+#define EUR_CR_BIF_BANK0_INDEX_PTLA_SHIFT 16
+#define EUR_CR_BIF_BANK0_INDEX_PTLA_SIGNED 0
+/* Register EUR_CR_BIF_BANK1 */
+#define EUR_CR_BIF_BANK1 0x0C7C
+#define EUR_CR_BIF_BANK1_INDEX_EDM_MASK 0x0000000FU
+#define EUR_CR_BIF_BANK1_INDEX_EDM_SHIFT 0
+#define EUR_CR_BIF_BANK1_INDEX_EDM_SIGNED 0
+#define EUR_CR_BIF_BANK1_INDEX_TA_MASK 0x000000F0U
+#define EUR_CR_BIF_BANK1_INDEX_TA_SHIFT 4
+#define EUR_CR_BIF_BANK1_INDEX_TA_SIGNED 0
+#define EUR_CR_BIF_BANK1_INDEX_3D_MASK 0x0000F000U
+#define EUR_CR_BIF_BANK1_INDEX_3D_SHIFT 12
+#define EUR_CR_BIF_BANK1_INDEX_3D_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE0 */
+#define EUR_CR_BIF_DIR_LIST_BASE0 0x0C84
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_TA_REQ_BASE */
+#define EUR_CR_BIF_TA_REQ_BASE 0x0C90
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_MEM_REQ_STAT */
+#define EUR_CR_BIF_MEM_REQ_STAT 0x0CA8
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK 0x000000FFU
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SIGNED 0
+/* Register EUR_CR_BIF_3D_REQ_BASE */
+#define EUR_CR_BIF_3D_REQ_BASE 0x0CAC
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_ZLS_REQ_BASE */
+#define EUR_CR_BIF_ZLS_REQ_BASE 0x0CB0
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_BANK_STATUS */
+#define EUR_CR_BIF_BANK_STATUS 0x0CB4
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_MASK 0x00000001U
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_SHIFT 0
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_SIGNED 0
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_MASK 0x00000002U
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_SHIFT 1
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_SIGNED 0
+/* Register EUR_CR_BIF_MMU_CTRL */
+#define EUR_CR_BIF_MMU_CTRL 0x0CD0
+#define EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_MASK 0x00000001U
+#define EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_SHIFT 0
+#define EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_SIGNED 0
+#define EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_MASK 0x00000006U
+#define EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT 1
+#define EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_SIGNED 0
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_WRITE_BURST_COLLATE_MASK 0x00000008U
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_WRITE_BURST_COLLATE_SHIFT 3
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_WRITE_BURST_COLLATE_SIGNED 0
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_MASK 0x00000010U
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_SHIFT 4
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_SIGNED 0
+/* Register EUR_CR_2D_BLIT_STATUS */
+#define EUR_CR_2D_BLIT_STATUS 0x0E04
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFU
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SIGNED 0
+#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK 0x01000000U
+#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT 24
+#define EUR_CR_2D_BLIT_STATUS_BUSY_SIGNED 0
+/* Register EUR_CR_2D_VIRTUAL_FIFO_0 */
+#define EUR_CR_2D_VIRTUAL_FIFO_0 0x0E10
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EU
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SIGNED 0
+/* Register EUR_CR_2D_VIRTUAL_FIFO_1 */
+#define EUR_CR_2D_VIRTUAL_FIFO_1 0x0E14
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFU
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SIGNED 0
+/* Register EUR_CR_BREAKPOINT0_START */
+#define EUR_CR_BREAKPOINT0_START 0x0F44
+#define EUR_CR_BREAKPOINT0_START_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT0_START_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT0_START_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT0_END */
+#define EUR_CR_BREAKPOINT0_END 0x0F48
+#define EUR_CR_BREAKPOINT0_END_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT0_END_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT0_END_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT0 */
+#define EUR_CR_BREAKPOINT0 0x0F4C
+#define EUR_CR_BREAKPOINT0_MASK_DM_MASK 0x00000038U
+#define EUR_CR_BREAKPOINT0_MASK_DM_SHIFT 3
+#define EUR_CR_BREAKPOINT0_MASK_DM_SIGNED 0
+#define EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_SHIFT 2
+#define EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT0_CTRL_WENABLE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT0_CTRL_WENABLE_SHIFT 1
+#define EUR_CR_BREAKPOINT0_CTRL_WENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT0_CTRL_RENABLE_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT0_CTRL_RENABLE_SHIFT 0
+#define EUR_CR_BREAKPOINT0_CTRL_RENABLE_SIGNED 0
+/* Register EUR_CR_BREAKPOINT1_START */
+#define EUR_CR_BREAKPOINT1_START 0x0F50
+#define EUR_CR_BREAKPOINT1_START_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT1_START_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT1_START_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT1_END */
+#define EUR_CR_BREAKPOINT1_END 0x0F54
+#define EUR_CR_BREAKPOINT1_END_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT1_END_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT1_END_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT1 */
+#define EUR_CR_BREAKPOINT1 0x0F58
+#define EUR_CR_BREAKPOINT1_MASK_DM_MASK 0x00000038U
+#define EUR_CR_BREAKPOINT1_MASK_DM_SHIFT 3
+#define EUR_CR_BREAKPOINT1_MASK_DM_SIGNED 0
+#define EUR_CR_BREAKPOINT1_CTRL_TRAPENABLE_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT1_CTRL_TRAPENABLE_SHIFT 2
+#define EUR_CR_BREAKPOINT1_CTRL_TRAPENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT1_CTRL_WENABLE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT1_CTRL_WENABLE_SHIFT 1
+#define EUR_CR_BREAKPOINT1_CTRL_WENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT1_CTRL_RENABLE_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT1_CTRL_RENABLE_SHIFT 0
+#define EUR_CR_BREAKPOINT1_CTRL_RENABLE_SIGNED 0
+/* Register EUR_CR_BREAKPOINT2_START */
+#define EUR_CR_BREAKPOINT2_START 0x0F5C
+#define EUR_CR_BREAKPOINT2_START_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT2_START_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT2_START_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT2_END */
+#define EUR_CR_BREAKPOINT2_END 0x0F60
+#define EUR_CR_BREAKPOINT2_END_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT2_END_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT2_END_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT2 */
+#define EUR_CR_BREAKPOINT2 0x0F64
+#define EUR_CR_BREAKPOINT2_MASK_DM_MASK 0x00000038U
+#define EUR_CR_BREAKPOINT2_MASK_DM_SHIFT 3
+#define EUR_CR_BREAKPOINT2_MASK_DM_SIGNED 0
+#define EUR_CR_BREAKPOINT2_CTRL_TRAPENABLE_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT2_CTRL_TRAPENABLE_SHIFT 2
+#define EUR_CR_BREAKPOINT2_CTRL_TRAPENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT2_CTRL_WENABLE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT2_CTRL_WENABLE_SHIFT 1
+#define EUR_CR_BREAKPOINT2_CTRL_WENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT2_CTRL_RENABLE_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT2_CTRL_RENABLE_SHIFT 0
+#define EUR_CR_BREAKPOINT2_CTRL_RENABLE_SIGNED 0
+/* Register EUR_CR_BREAKPOINT3_START */
+#define EUR_CR_BREAKPOINT3_START 0x0F68
+#define EUR_CR_BREAKPOINT3_START_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT3_START_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT3_START_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT3_END */
+#define EUR_CR_BREAKPOINT3_END 0x0F6C
+#define EUR_CR_BREAKPOINT3_END_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT3_END_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT3_END_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT3 */
+#define EUR_CR_BREAKPOINT3 0x0F70
+#define EUR_CR_BREAKPOINT3_MASK_DM_MASK 0x00000038U
+#define EUR_CR_BREAKPOINT3_MASK_DM_SHIFT 3
+#define EUR_CR_BREAKPOINT3_MASK_DM_SIGNED 0
+#define EUR_CR_BREAKPOINT3_CTRL_TRAPENABLE_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT3_CTRL_TRAPENABLE_SHIFT 2
+#define EUR_CR_BREAKPOINT3_CTRL_TRAPENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT3_CTRL_WENABLE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT3_CTRL_WENABLE_SHIFT 1
+#define EUR_CR_BREAKPOINT3_CTRL_WENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT3_CTRL_RENABLE_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT3_CTRL_RENABLE_SHIFT 0
+#define EUR_CR_BREAKPOINT3_CTRL_RENABLE_SIGNED 0
+/* Register EUR_CR_BREAKPOINT_READ */
+#define EUR_CR_BREAKPOINT_READ 0x0F74
+#define EUR_CR_BREAKPOINT_READ_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT_READ_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT_READ_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT_TRAP */
+#define EUR_CR_BREAKPOINT_TRAP 0x0F78
+#define EUR_CR_BREAKPOINT_TRAP_CONTINUE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT_TRAP_CONTINUE_SHIFT 1
+#define EUR_CR_BREAKPOINT_TRAP_CONTINUE_SIGNED 0
+#define EUR_CR_BREAKPOINT_TRAP_WRNOTIFY_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT_TRAP_WRNOTIFY_SHIFT 0
+#define EUR_CR_BREAKPOINT_TRAP_WRNOTIFY_SIGNED 0
+/* Register EUR_CR_BREAKPOINT */
+#define EUR_CR_BREAKPOINT 0x0F7C
+#define EUR_CR_BREAKPOINT_MODULE_ID_MASK 0x000003C0U
+#define EUR_CR_BREAKPOINT_MODULE_ID_SHIFT 6
+#define EUR_CR_BREAKPOINT_MODULE_ID_SIGNED 0
+#define EUR_CR_BREAKPOINT_ID_MASK 0x00000030U
+#define EUR_CR_BREAKPOINT_ID_SHIFT 4
+#define EUR_CR_BREAKPOINT_ID_SIGNED 0
+#define EUR_CR_BREAKPOINT_UNTRAPPED_MASK 0x00000008U
+#define EUR_CR_BREAKPOINT_UNTRAPPED_SHIFT 3
+#define EUR_CR_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_BREAKPOINT_TRAPPED_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT_TRAPPED_SHIFT 2
+#define EUR_CR_BREAKPOINT_TRAPPED_SIGNED 0
+/* Register EUR_CR_BREAKPOINT_TRAP_INFO0 */
+#define EUR_CR_BREAKPOINT_TRAP_INFO0 0x0F80
+#define EUR_CR_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT_TRAP_INFO0_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT_TRAP_INFO0_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT_TRAP_INFO1 */
+#define EUR_CR_BREAKPOINT_TRAP_INFO1 0x0F84
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_SIZE_MASK 0x00007C00U
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT 10
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_SIZE_SIGNED 0
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_NUMBER_MASK 0x00000300U
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT 8
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_NUMBER_SIGNED 0
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_TAG_MASK 0x000000F8U
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_TAG_SHIFT 3
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_TAG_SIGNED 0
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK 0x00000006U
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT 1
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SIGNED 0
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_RNW_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_RNW_SHIFT 0
+#define EUR_CR_BREAKPOINT_TRAP_INFO1_RNW_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_0 */
+#define EUR_CR_USE_CODE_BASE_0 0x0A0C
+#define EUR_CR_USE_CODE_BASE_ADDR_00_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_00_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_00_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_00_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_00_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_00_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_1 */
+#define EUR_CR_USE_CODE_BASE_1 0x0A10
+#define EUR_CR_USE_CODE_BASE_ADDR_01_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_01_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_01_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_01_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_01_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_01_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_2 */
+#define EUR_CR_USE_CODE_BASE_2 0x0A14
+#define EUR_CR_USE_CODE_BASE_ADDR_02_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_02_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_02_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_02_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_02_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_02_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_3 */
+#define EUR_CR_USE_CODE_BASE_3 0x0A18
+#define EUR_CR_USE_CODE_BASE_ADDR_03_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_03_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_03_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_03_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_03_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_03_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_4 */
+#define EUR_CR_USE_CODE_BASE_4 0x0A1C
+#define EUR_CR_USE_CODE_BASE_ADDR_04_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_04_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_04_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_04_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_04_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_04_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_5 */
+#define EUR_CR_USE_CODE_BASE_5 0x0A20
+#define EUR_CR_USE_CODE_BASE_ADDR_05_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_05_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_05_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_05_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_05_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_05_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_6 */
+#define EUR_CR_USE_CODE_BASE_6 0x0A24
+#define EUR_CR_USE_CODE_BASE_ADDR_06_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_06_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_06_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_06_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_06_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_06_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_7 */
+#define EUR_CR_USE_CODE_BASE_7 0x0A28
+#define EUR_CR_USE_CODE_BASE_ADDR_07_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_07_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_07_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_07_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_07_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_07_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_8 */
+#define EUR_CR_USE_CODE_BASE_8 0x0A2C
+#define EUR_CR_USE_CODE_BASE_ADDR_08_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_08_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_08_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_08_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_08_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_08_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_9 */
+#define EUR_CR_USE_CODE_BASE_9 0x0A30
+#define EUR_CR_USE_CODE_BASE_ADDR_09_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_09_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_09_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_09_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_09_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_09_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_10 */
+#define EUR_CR_USE_CODE_BASE_10 0x0A34
+#define EUR_CR_USE_CODE_BASE_ADDR_10_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_10_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_10_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_10_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_10_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_10_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_11 */
+#define EUR_CR_USE_CODE_BASE_11 0x0A38
+#define EUR_CR_USE_CODE_BASE_ADDR_11_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_11_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_11_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_11_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_11_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_11_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_12 */
+#define EUR_CR_USE_CODE_BASE_12 0x0A3C
+#define EUR_CR_USE_CODE_BASE_ADDR_12_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_12_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_12_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_12_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_12_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_12_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_13 */
+#define EUR_CR_USE_CODE_BASE_13 0x0A40
+#define EUR_CR_USE_CODE_BASE_ADDR_13_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_13_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_13_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_13_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_13_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_13_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_14 */
+#define EUR_CR_USE_CODE_BASE_14 0x0A44
+#define EUR_CR_USE_CODE_BASE_ADDR_14_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_14_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_14_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_14_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_14_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_14_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_15 */
+#define EUR_CR_USE_CODE_BASE_15 0x0A48
+#define EUR_CR_USE_CODE_BASE_ADDR_15_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_15_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_15_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_15_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_15_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_15_SIGNED 0
+/* Table EUR_CR_USE_CODE_BASE */
+/* Register EUR_CR_USE_CODE_BASE */
+#define EUR_CR_USE_CODE_BASE(X) (0x0A0C + (4 * (X)))
+#define EUR_CR_USE_CODE_BASE_ADDR_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_SIGNED 0
+/* Number of entries in table EUR_CR_USE_CODE_BASE */
+#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16
+#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16
+
+#endif /* _SGX543_V1_164DEFS_KM_H_ */
+
diff --git a/pvr-source/services4/srvkm/hwdefs/sgx543defs.h b/pvr-source/services4/srvkm/hwdefs/sgx543defs.h
new file mode 100644
index 0000000..0d3568d
--- /dev/null
+++ b/pvr-source/services4/srvkm/hwdefs/sgx543defs.h
@@ -0,0 +1,1487 @@
+/*************************************************************************/ /*!
+@Title Hardware defs for SGX543.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _SGX543DEFS_KM_H_
+#define _SGX543DEFS_KM_H_
+
+/* Register EUR_CR_CLKGATECTL */
+#define EUR_CR_CLKGATECTL 0x0000
+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK 0x00000003U
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT 0
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SHIFT 2
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_TE_CLKG_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTL_TE_CLKG_SHIFT 6
+#define EUR_CR_CLKGATECTL_TE_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_MTE_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL_MTE_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL_MTE_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT 10
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_VDM_CLKG_MASK 0x00003000U
+#define EUR_CR_CLKGATECTL_VDM_CLKG_SHIFT 12
+#define EUR_CR_CLKGATECTL_VDM_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_PDS_CLKG_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTL_PDS_CLKG_SHIFT 14
+#define EUR_CR_CLKGATECTL_PDS_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_TA_CLKG_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT 18
+#define EUR_CR_CLKGATECTL_TA_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_BIF_CORE_CLKG_MASK 0x00300000U
+#define EUR_CR_CLKGATECTL_BIF_CORE_CLKG_SHIFT 20
+#define EUR_CR_CLKGATECTL_BIF_CORE_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SIGNED 0
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_MASK 0x10000000U
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_SHIFT 28
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_SIGNED 0
+/* Register EUR_CR_CLKGATECTL2 */
+#define EUR_CR_CLKGATECTL2 0x0004
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_MASK 0x00000003U
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SHIFT 0
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_TCU_L2_CLKG_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTL2_TCU_L2_CLKG_SHIFT 2
+#define EUR_CR_CLKGATECTL2_TCU_L2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SHIFT 6
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SHIFT 10
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SHIFT 14
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SHIFT 18
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_DCU_L2_CLKG_MASK 0x00C00000U
+#define EUR_CR_CLKGATECTL2_DCU_L2_CLKG_SHIFT 22
+#define EUR_CR_CLKGATECTL2_DCU_L2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_DCU1_L0L1_CLKG_MASK 0x03000000U
+#define EUR_CR_CLKGATECTL2_DCU1_L0L1_CLKG_SHIFT 24
+#define EUR_CR_CLKGATECTL2_DCU1_L0L1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_DCU0_L0L1_CLKG_MASK 0x0C000000U
+#define EUR_CR_CLKGATECTL2_DCU0_L0L1_CLKG_SHIFT 26
+#define EUR_CR_CLKGATECTL2_DCU0_L0L1_CLKG_SIGNED 0
+/* Register EUR_CR_CLKGATESTATUS */
+#define EUR_CR_CLKGATESTATUS 0x0008
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK 0x00000001U
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 0
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_MASK 0x00000002U
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SHIFT 1
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK 0x00000004U
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 2
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_MASK 0x00000008U
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SHIFT 3
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_MASK 0x00000010U
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SHIFT 4
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK 0x00000020U
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 5
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_MASK 0x00000040U
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SHIFT 6
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_MASK 0x00000080U
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_SHIFT 7
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_MASK 0x00000100U
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SHIFT 8
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TCU_L2_CLKS_MASK 0x00000200U
+#define EUR_CR_CLKGATESTATUS_TCU_L2_CLKS_SHIFT 9
+#define EUR_CR_CLKGATESTATUS_TCU_L2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_MASK 0x00000400U
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SHIFT 10
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_MASK 0x00000800U
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SHIFT 11
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_MASK 0x00001000U
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SHIFT 12
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_MASK 0x00002000U
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SHIFT 13
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_MASK 0x00008000U
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SHIFT 15
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_MASK 0x00010000U
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SHIFT 16
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_MASK 0x00020000U
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SHIFT 17
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_MASK 0x00080000U
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_SHIFT 19
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK 0x00100000U
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT 20
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DCU_L2_CLKS_MASK 0x00200000U
+#define EUR_CR_CLKGATESTATUS_DCU_L2_CLKS_SHIFT 21
+#define EUR_CR_CLKGATESTATUS_DCU_L2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DCU0_L0L1_CLKS_MASK 0x00400000U
+#define EUR_CR_CLKGATESTATUS_DCU0_L0L1_CLKS_SHIFT 22
+#define EUR_CR_CLKGATESTATUS_DCU0_L0L1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DCU1_L0L1_CLKS_MASK 0x00800000U
+#define EUR_CR_CLKGATESTATUS_DCU1_L0L1_CLKS_SHIFT 23
+#define EUR_CR_CLKGATESTATUS_DCU1_L0L1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_BIF_CORE_CLKS_MASK 0x01000000U
+#define EUR_CR_CLKGATESTATUS_BIF_CORE_CLKS_SHIFT 24
+#define EUR_CR_CLKGATESTATUS_BIF_CORE_CLKS_SIGNED 0
+/* Register EUR_CR_CLKGATECTLOVR */
+#define EUR_CR_CLKGATECTLOVR 0x000C
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK 0x00000003U
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 0
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SHIFT 2
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK 0x00000030U
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 4
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SHIFT 6
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_MASK 0x00000300U
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SHIFT 8
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 10
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_MASK 0x00003000U
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SHIFT 12
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_SHIFT 14
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_MASK 0x00030000U
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_SHIFT 16
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT 18
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_BIF_CORE_CLKO_MASK 0x00300000U
+#define EUR_CR_CLKGATECTLOVR_BIF_CORE_CLKO_SHIFT 20
+#define EUR_CR_CLKGATECTLOVR_BIF_CORE_CLKO_SIGNED 0
+/* Register EUR_CR_POWER */
+#define EUR_CR_POWER 0x001C
+#define EUR_CR_POWER_PIPE_DISABLE_MASK 0x00000001U
+#define EUR_CR_POWER_PIPE_DISABLE_SHIFT 0
+#define EUR_CR_POWER_PIPE_DISABLE_SIGNED 0
+/* Register EUR_CR_CORE_ID */
+#define EUR_CR_CORE_ID 0x0020
+#define EUR_CR_CORE_ID_CONFIG_MULTI_MASK 0x00000001U
+#define EUR_CR_CORE_ID_CONFIG_MULTI_SHIFT 0
+#define EUR_CR_CORE_ID_CONFIG_MULTI_SIGNED 0
+#define EUR_CR_CORE_ID_CONFIG_BASE_MASK 0x00000002U
+#define EUR_CR_CORE_ID_CONFIG_BASE_SHIFT 1
+#define EUR_CR_CORE_ID_CONFIG_BASE_SIGNED 0
+#define EUR_CR_CORE_ID_CONFIG_MASK 0x000000FCU
+#define EUR_CR_CORE_ID_CONFIG_SHIFT 2
+#define EUR_CR_CORE_ID_CONFIG_SIGNED 0
+#define EUR_CR_CORE_ID_CONFIG_CORES_MASK 0x00000F00U
+#define EUR_CR_CORE_ID_CONFIG_CORES_SHIFT 8
+#define EUR_CR_CORE_ID_CONFIG_CORES_SIGNED 0
+#define EUR_CR_CORE_ID_CONFIG_SLC_MASK 0x0000F000U
+#define EUR_CR_CORE_ID_CONFIG_SLC_SHIFT 12
+#define EUR_CR_CORE_ID_CONFIG_SLC_SIGNED 0
+#define EUR_CR_CORE_ID_ID_MASK 0xFFFF0000U
+#define EUR_CR_CORE_ID_ID_SHIFT 16
+#define EUR_CR_CORE_ID_ID_SIGNED 0
+/* Register EUR_CR_CORE_REVISION */
+#define EUR_CR_CORE_REVISION 0x0024
+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SIGNED 0
+#define EUR_CR_CORE_REVISION_MINOR_MASK 0x0000FF00U
+#define EUR_CR_CORE_REVISION_MINOR_SHIFT 8
+#define EUR_CR_CORE_REVISION_MINOR_SIGNED 0
+#define EUR_CR_CORE_REVISION_MAJOR_MASK 0x00FF0000U
+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT 16
+#define EUR_CR_CORE_REVISION_MAJOR_SIGNED 0
+#define EUR_CR_CORE_REVISION_DESIGNER_MASK 0xFF000000U
+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
+#define EUR_CR_CORE_REVISION_DESIGNER_SIGNED 0
+/* Register EUR_CR_DESIGNER_REV_FIELD1 */
+#define EUR_CR_DESIGNER_REV_FIELD1 0x0028
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SIGNED 0
+/* Register EUR_CR_DESIGNER_REV_FIELD2 */
+#define EUR_CR_DESIGNER_REV_FIELD2 0x002C
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SIGNED 0
+/* Register EUR_CR_SOFT_RESET */
+#define EUR_CR_SOFT_RESET 0x0080
+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK 0x00000001U
+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT 0
+#define EUR_CR_SOFT_RESET_BIF_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_VDM_RESET_MASK 0x00000002U
+#define EUR_CR_SOFT_RESET_VDM_RESET_SHIFT 1
+#define EUR_CR_SOFT_RESET_VDM_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK 0x00000004U
+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT 2
+#define EUR_CR_SOFT_RESET_DPM_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TE_RESET_MASK 0x00000008U
+#define EUR_CR_SOFT_RESET_TE_RESET_SHIFT 3
+#define EUR_CR_SOFT_RESET_TE_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_MTE_RESET_MASK 0x00000010U
+#define EUR_CR_SOFT_RESET_MTE_RESET_SHIFT 4
+#define EUR_CR_SOFT_RESET_MTE_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK 0x00000020U
+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT 5
+#define EUR_CR_SOFT_RESET_ISP_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_ISP2_RESET_MASK 0x00000040U
+#define EUR_CR_SOFT_RESET_ISP2_RESET_SHIFT 6
+#define EUR_CR_SOFT_RESET_ISP2_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK 0x00000080U
+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT 7
+#define EUR_CR_SOFT_RESET_TSP_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_PDS_RESET_MASK 0x00000100U
+#define EUR_CR_SOFT_RESET_PDS_RESET_SHIFT 8
+#define EUR_CR_SOFT_RESET_PDS_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_PBE_RESET_MASK 0x00000200U
+#define EUR_CR_SOFT_RESET_PBE_RESET_SHIFT 9
+#define EUR_CR_SOFT_RESET_PBE_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TCU_L2_RESET_MASK 0x00000400U
+#define EUR_CR_SOFT_RESET_TCU_L2_RESET_SHIFT 10
+#define EUR_CR_SOFT_RESET_TCU_L2_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK 0x00000800U
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_SHIFT 11
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_ITR_RESET_MASK 0x00002000U
+#define EUR_CR_SOFT_RESET_ITR_RESET_SHIFT 13
+#define EUR_CR_SOFT_RESET_ITR_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TEX_RESET_MASK 0x00004000U
+#define EUR_CR_SOFT_RESET_TEX_RESET_SHIFT 14
+#define EUR_CR_SOFT_RESET_TEX_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_USE_RESET_MASK 0x00008000U
+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT 15
+#define EUR_CR_SOFT_RESET_USE_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK 0x00010000U
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_SHIFT 16
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TA_RESET_MASK 0x00020000U
+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT 17
+#define EUR_CR_SOFT_RESET_TA_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_DCU_L2_RESET_MASK 0x00040000U
+#define EUR_CR_SOFT_RESET_DCU_L2_RESET_SHIFT 18
+#define EUR_CR_SOFT_RESET_DCU_L2_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_DCU_L0L1_RESET_MASK 0x00080000U
+#define EUR_CR_SOFT_RESET_DCU_L0L1_RESET_SHIFT 19
+#define EUR_CR_SOFT_RESET_DCU_L0L1_RESET_SIGNED 0
+/* Register EUR_CR_EVENT_HOST_ENABLE2 */
+#define EUR_CR_EVENT_HOST_ENABLE2 0x0110
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_UNTRAPPED_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_UNTRAPPED_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_TRAPPED_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_TRAPPED_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_TRAPPED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_CONTEXT_DRAINED_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_CONTEXT_DRAINED_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_CONTEXT_DRAINED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_ISP2_ZLS_CSW_FINISHED_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE2_ISP2_ZLS_CSW_FINISHED_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE2_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TE_RGNHDR_INIT_COMPLETE_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE2_TE_RGNHDR_INIT_COMPLETE_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE2_TE_RGNHDR_INIT_COMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SIGNED 0
+/* Register EUR_CR_EVENT_HOST_CLEAR2 */
+#define EUR_CR_EVENT_HOST_CLEAR2 0x0114
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_CONTEXT_DRAINED_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_CONTEXT_DRAINED_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_CONTEXT_DRAINED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_ISP2_ZLS_CSW_FINISHED_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR2_ISP2_ZLS_CSW_FINISHED_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR2_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TE_RGNHDR_INIT_COMPLETE_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR2_TE_RGNHDR_INIT_COMPLETE_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR2_TE_RGNHDR_INIT_COMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SIGNED 0
+/* Register EUR_CR_EVENT_STATUS2 */
+#define EUR_CR_EVENT_STATUS2 0x0118
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_MASK 0x00000800U
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_SHIFT 11
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_MASK 0x00000400U
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_SHIFT 10
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_MTE_CONTEXT_DRAINED_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS2_MTE_CONTEXT_DRAINED_SHIFT 9
+#define EUR_CR_EVENT_STATUS2_MTE_CONTEXT_DRAINED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_ISP2_ZLS_CSW_FINISHED_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS2_ISP2_ZLS_CSW_FINISHED_SHIFT 8
+#define EUR_CR_EVENT_STATUS2_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_SHIFT 7
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_SHIFT 6
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TE_RGNHDR_INIT_COMPLETE_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS2_TE_RGNHDR_INIT_COMPLETE_SHIFT 5
+#define EUR_CR_EVENT_STATUS2_TE_RGNHDR_INIT_COMPLETE_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SIGNED 0
+/* Register EUR_CR_EVENT_STATUS */
+#define EUR_CR_EVENT_STATUS 0x012C
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT 29
+#define EUR_CR_EVENT_STATUS_TIMER_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TCU_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_STATUS_TCU_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_STATUS_TCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SIGNED 0
+/* Register EUR_CR_EVENT_HOST_ENABLE */
+#define EUR_CR_EVENT_HOST_ENABLE 0x0130
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TCU_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TCU_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_ENABLE_TCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SIGNED 0
+/* Register EUR_CR_EVENT_HOST_CLEAR */
+#define EUR_CR_EVENT_HOST_CLEAR 0x0134
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TCU_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TCU_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_CLEAR_TCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SIGNED 0
+/* Register EUR_CR_TIMER */
+#define EUR_CR_TIMER 0x0144
+#define EUR_CR_TIMER_VALUE_MASK 0xFFFFFFFFU
+#define EUR_CR_TIMER_VALUE_SHIFT 0
+#define EUR_CR_TIMER_VALUE_SIGNED 0
+/* Register EUR_CR_EVENT_KICK1 */
+#define EUR_CR_EVENT_KICK1 0x0AB0
+#define EUR_CR_EVENT_KICK1_NOW_MASK 0x000000FFU
+#define EUR_CR_EVENT_KICK1_NOW_SHIFT 0
+#define EUR_CR_EVENT_KICK1_NOW_SIGNED 0
+/* Register EUR_CR_EVENT_KICK2 */
+#define EUR_CR_EVENT_KICK2 0x0AC0
+#define EUR_CR_EVENT_KICK2_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK2_NOW_SHIFT 0
+#define EUR_CR_EVENT_KICK2_NOW_SIGNED 0
+/* Register EUR_CR_EVENT_KICKER */
+#define EUR_CR_EVENT_KICKER 0x0AC4
+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT 4
+#define EUR_CR_EVENT_KICKER_ADDRESS_SIGNED 0
+/* Register EUR_CR_EVENT_KICK */
+#define EUR_CR_EVENT_KICK 0x0AC8
+#define EUR_CR_EVENT_KICK_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK_NOW_SHIFT 0
+#define EUR_CR_EVENT_KICK_NOW_SIGNED 0
+/* Register EUR_CR_EVENT_TIMER */
+#define EUR_CR_EVENT_TIMER 0x0ACC
+#define EUR_CR_EVENT_TIMER_ENABLE_MASK 0x01000000U
+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT 24
+#define EUR_CR_EVENT_TIMER_ENABLE_SIGNED 0
+#define EUR_CR_EVENT_TIMER_VALUE_MASK 0x00FFFFFFU
+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT 0
+#define EUR_CR_EVENT_TIMER_VALUE_SIGNED 0
+/* Register EUR_CR_PDS_INV0 */
+#define EUR_CR_PDS_INV0 0x0AD0
+#define EUR_CR_PDS_INV0_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV0_DSC_SHIFT 0
+#define EUR_CR_PDS_INV0_DSC_SIGNED 0
+/* Register EUR_CR_PDS_INV1 */
+#define EUR_CR_PDS_INV1 0x0AD4
+#define EUR_CR_PDS_INV1_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV1_DSC_SHIFT 0
+#define EUR_CR_PDS_INV1_DSC_SIGNED 0
+/* Register EUR_CR_EVENT_KICK3 */
+#define EUR_CR_EVENT_KICK3 0x0AD8
+#define EUR_CR_EVENT_KICK3_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK3_NOW_SHIFT 0
+#define EUR_CR_EVENT_KICK3_NOW_SIGNED 0
+/* Register EUR_CR_PDS_INV3 */
+#define EUR_CR_PDS_INV3 0x0ADC
+#define EUR_CR_PDS_INV3_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV3_DSC_SHIFT 0
+#define EUR_CR_PDS_INV3_DSC_SIGNED 0
+/* Register EUR_CR_PDS_INV_CSC */
+#define EUR_CR_PDS_INV_CSC 0x0AE0
+#define EUR_CR_PDS_INV_CSC_KICK_MASK 0x00000001U
+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT 0
+#define EUR_CR_PDS_INV_CSC_KICK_SIGNED 0
+/* Register EUR_CR_BIF_CTRL */
+#define EUR_CR_BIF_CTRL 0x0C00
+#define EUR_CR_BIF_CTRL_NOREORDER_MASK 0x00000001U
+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT 0
+#define EUR_CR_BIF_CTRL_NOREORDER_SIGNED 0
+#define EUR_CR_BIF_CTRL_PAUSE_MASK 0x00000002U
+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT 1
+#define EUR_CR_BIF_CTRL_PAUSE_SIGNED 0
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT 4
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TA_MASK 0x00000400U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TA_SHIFT 10
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TA_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PTLA_MASK 0x00010000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PTLA_SHIFT 16
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PTLA_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_VDM_MASK 0x00020000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_VDM_SHIFT 17
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_VDM_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_IPF_MASK 0x00040000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_IPF_SHIFT 18
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_IPF_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_DPM_MASK 0x00080000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_DPM_SHIFT 19
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_DPM_SIGNED 0
+/* Register EUR_CR_BIF_INT_STAT */
+#define EUR_CR_BIF_INT_STAT 0x0C04
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_MASK 0x00003FFFU
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_SHIFT 0
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_SIGNED 0
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_MASK 0x00070000U
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_SHIFT 16
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_SIGNED 0
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00080000U
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 19
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SIGNED 0
+/* Register EUR_CR_BIF_FAULT */
+#define EUR_CR_BIF_FAULT 0x0C08
+#define EUR_CR_BIF_FAULT_CID_MASK 0x0000000FU
+#define EUR_CR_BIF_FAULT_CID_SHIFT 0
+#define EUR_CR_BIF_FAULT_CID_SIGNED 0
+#define EUR_CR_BIF_FAULT_SB_MASK 0x000001F0U
+#define EUR_CR_BIF_FAULT_SB_SHIFT 4
+#define EUR_CR_BIF_FAULT_SB_SIGNED 0
+#define EUR_CR_BIF_FAULT_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_FAULT_ADDR_SHIFT 12
+#define EUR_CR_BIF_FAULT_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_TILE0 */
+#define EUR_CR_BIF_TILE0 0x0C0C
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE0_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE0_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE0_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE1 */
+#define EUR_CR_BIF_TILE1 0x0C10
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE1_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE1_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE1_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE2 */
+#define EUR_CR_BIF_TILE2 0x0C14
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE2_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE2_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE2_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE3 */
+#define EUR_CR_BIF_TILE3 0x0C18
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE3_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE3_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE3_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE4 */
+#define EUR_CR_BIF_TILE4 0x0C1C
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE4_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE4_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE4_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE5 */
+#define EUR_CR_BIF_TILE5 0x0C20
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE5_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE5_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE5_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE6 */
+#define EUR_CR_BIF_TILE6 0x0C24
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE6_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE6_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE6_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE7 */
+#define EUR_CR_BIF_TILE7 0x0C28
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE7_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE7_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE7_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE8 */
+#define EUR_CR_BIF_TILE8 0x0C2C
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE8_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE8_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE8_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE9 */
+#define EUR_CR_BIF_TILE9 0x0C30
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE9_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE9_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE9_CFG_SIGNED 0
+/* Register EUR_CR_BIF_CTRL_INVAL */
+#define EUR_CR_BIF_CTRL_INVAL 0x0C34
+#define EUR_CR_BIF_CTRL_INVAL_PTE_MASK 0x00000004U
+#define EUR_CR_BIF_CTRL_INVAL_PTE_SHIFT 2
+#define EUR_CR_BIF_CTRL_INVAL_PTE_SIGNED 0
+#define EUR_CR_BIF_CTRL_INVAL_ALL_MASK 0x00000008U
+#define EUR_CR_BIF_CTRL_INVAL_ALL_SHIFT 3
+#define EUR_CR_BIF_CTRL_INVAL_ALL_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE1 */
+#define EUR_CR_BIF_DIR_LIST_BASE1 0x0C38
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE2 */
+#define EUR_CR_BIF_DIR_LIST_BASE2 0x0C3C
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE3 */
+#define EUR_CR_BIF_DIR_LIST_BASE3 0x0C40
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE4 */
+#define EUR_CR_BIF_DIR_LIST_BASE4 0x0C44
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE5 */
+#define EUR_CR_BIF_DIR_LIST_BASE5 0x0C48
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE6 */
+#define EUR_CR_BIF_DIR_LIST_BASE6 0x0C4C
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE7 */
+#define EUR_CR_BIF_DIR_LIST_BASE7 0x0C50
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_BANK_SET */
+#define EUR_CR_BIF_BANK_SET 0x0C74
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_MASK 0x00000001U
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_SHIFT 0
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_MASK 0x0000000CU
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_SHIFT 2
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_MASK 0x00000010U
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_SHIFT 4
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_MASK 0x000000C0U
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_SHIFT 6
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_MASK 0x00000100U
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_SHIFT 8
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_MASK 0x00000200U
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_SHIFT 9
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_SIGNED 0
+/* Register EUR_CR_BIF_BANK0 */
+#define EUR_CR_BIF_BANK0 0x0C78
+#define EUR_CR_BIF_BANK0_INDEX_EDM_MASK 0x0000000FU
+#define EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT 0
+#define EUR_CR_BIF_BANK0_INDEX_EDM_SIGNED 0
+#define EUR_CR_BIF_BANK0_INDEX_TA_MASK 0x000000F0U
+#define EUR_CR_BIF_BANK0_INDEX_TA_SHIFT 4
+#define EUR_CR_BIF_BANK0_INDEX_TA_SIGNED 0
+#define EUR_CR_BIF_BANK0_INDEX_3D_MASK 0x0000F000U
+#define EUR_CR_BIF_BANK0_INDEX_3D_SHIFT 12
+#define EUR_CR_BIF_BANK0_INDEX_3D_SIGNED 0
+#define EUR_CR_BIF_BANK0_INDEX_PTLA_MASK 0x000F0000U
+#define EUR_CR_BIF_BANK0_INDEX_PTLA_SHIFT 16
+#define EUR_CR_BIF_BANK0_INDEX_PTLA_SIGNED 0
+/* Register EUR_CR_BIF_BANK1 */
+#define EUR_CR_BIF_BANK1 0x0C7C
+#define EUR_CR_BIF_BANK1_INDEX_EDM_MASK 0x0000000FU
+#define EUR_CR_BIF_BANK1_INDEX_EDM_SHIFT 0
+#define EUR_CR_BIF_BANK1_INDEX_EDM_SIGNED 0
+#define EUR_CR_BIF_BANK1_INDEX_TA_MASK 0x000000F0U
+#define EUR_CR_BIF_BANK1_INDEX_TA_SHIFT 4
+#define EUR_CR_BIF_BANK1_INDEX_TA_SIGNED 0
+#define EUR_CR_BIF_BANK1_INDEX_3D_MASK 0x0000F000U
+#define EUR_CR_BIF_BANK1_INDEX_3D_SHIFT 12
+#define EUR_CR_BIF_BANK1_INDEX_3D_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE0 */
+#define EUR_CR_BIF_DIR_LIST_BASE0 0x0C84
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_TA_REQ_BASE */
+#define EUR_CR_BIF_TA_REQ_BASE 0x0C90
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_MEM_REQ_STAT */
+#define EUR_CR_BIF_MEM_REQ_STAT 0x0CA8
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK 0x000000FFU
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SIGNED 0
+/* Register EUR_CR_BIF_3D_REQ_BASE */
+#define EUR_CR_BIF_3D_REQ_BASE 0x0CAC
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_ZLS_REQ_BASE */
+#define EUR_CR_BIF_ZLS_REQ_BASE 0x0CB0
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_BANK_STATUS */
+#define EUR_CR_BIF_BANK_STATUS 0x0CB4
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_MASK 0x00000001U
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_SHIFT 0
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_SIGNED 0
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_MASK 0x00000002U
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_SHIFT 1
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_SIGNED 0
+/* Register EUR_CR_BIF_MMU_CTRL */
+#define EUR_CR_BIF_MMU_CTRL 0x0CD0
+#define EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_MASK 0x00000001U
+#define EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_SHIFT 0
+#define EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_SIGNED 0
+#define EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_MASK 0x00000006U
+#define EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT 1
+#define EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_SIGNED 0
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_WRITE_BURST_COLLATE_MASK 0x00000008U
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_WRITE_BURST_COLLATE_SHIFT 3
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_WRITE_BURST_COLLATE_SIGNED 0
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_MASK 0x00000010U
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_SHIFT 4
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_SIGNED 0
+#define EUR_CR_BIF_MMU_CTRL_DISABLE_BURST_EXP_MASK 0x00000020U
+#define EUR_CR_BIF_MMU_CTRL_DISABLE_BURST_EXP_SHIFT 5
+#define EUR_CR_BIF_MMU_CTRL_DISABLE_BURST_EXP_SIGNED 0
+/* Register EUR_CR_2D_BLIT_STATUS */
+#define EUR_CR_2D_BLIT_STATUS 0x0E04
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFU
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SIGNED 0
+#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK 0x01000000U
+#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT 24
+#define EUR_CR_2D_BLIT_STATUS_BUSY_SIGNED 0
+/* Register EUR_CR_2D_VIRTUAL_FIFO_0 */
+#define EUR_CR_2D_VIRTUAL_FIFO_0 0x0E10
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EU
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SIGNED 0
+/* Register EUR_CR_2D_VIRTUAL_FIFO_1 */
+#define EUR_CR_2D_VIRTUAL_FIFO_1 0x0E14
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFU
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SIGNED 0
+/* Register EUR_CR_BREAKPOINT0_START */
+#define EUR_CR_BREAKPOINT0_START 0x0F44
+#define EUR_CR_BREAKPOINT0_START_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT0_START_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT0_START_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT0_END */
+#define EUR_CR_BREAKPOINT0_END 0x0F48
+#define EUR_CR_BREAKPOINT0_END_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT0_END_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT0_END_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT0 */
+#define EUR_CR_BREAKPOINT0 0x0F4C
+#define EUR_CR_BREAKPOINT0_MASK_DM_MASK 0x00000038U
+#define EUR_CR_BREAKPOINT0_MASK_DM_SHIFT 3
+#define EUR_CR_BREAKPOINT0_MASK_DM_SIGNED 0
+#define EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_SHIFT 2
+#define EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT0_CTRL_WENABLE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT0_CTRL_WENABLE_SHIFT 1
+#define EUR_CR_BREAKPOINT0_CTRL_WENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT0_CTRL_RENABLE_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT0_CTRL_RENABLE_SHIFT 0
+#define EUR_CR_BREAKPOINT0_CTRL_RENABLE_SIGNED 0
+/* Register EUR_CR_BREAKPOINT1_START */
+#define EUR_CR_BREAKPOINT1_START 0x0F50
+#define EUR_CR_BREAKPOINT1_START_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT1_START_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT1_START_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT1_END */
+#define EUR_CR_BREAKPOINT1_END 0x0F54
+#define EUR_CR_BREAKPOINT1_END_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT1_END_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT1_END_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT1 */
+#define EUR_CR_BREAKPOINT1 0x0F58
+#define EUR_CR_BREAKPOINT1_MASK_DM_MASK 0x00000038U
+#define EUR_CR_BREAKPOINT1_MASK_DM_SHIFT 3
+#define EUR_CR_BREAKPOINT1_MASK_DM_SIGNED 0
+#define EUR_CR_BREAKPOINT1_CTRL_TRAPENABLE_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT1_CTRL_TRAPENABLE_SHIFT 2
+#define EUR_CR_BREAKPOINT1_CTRL_TRAPENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT1_CTRL_WENABLE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT1_CTRL_WENABLE_SHIFT 1
+#define EUR_CR_BREAKPOINT1_CTRL_WENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT1_CTRL_RENABLE_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT1_CTRL_RENABLE_SHIFT 0
+#define EUR_CR_BREAKPOINT1_CTRL_RENABLE_SIGNED 0
+/* Register EUR_CR_BREAKPOINT2_START */
+#define EUR_CR_BREAKPOINT2_START 0x0F5C
+#define EUR_CR_BREAKPOINT2_START_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT2_START_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT2_START_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT2_END */
+#define EUR_CR_BREAKPOINT2_END 0x0F60
+#define EUR_CR_BREAKPOINT2_END_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT2_END_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT2_END_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT2 */
+#define EUR_CR_BREAKPOINT2 0x0F64
+#define EUR_CR_BREAKPOINT2_MASK_DM_MASK 0x00000038U
+#define EUR_CR_BREAKPOINT2_MASK_DM_SHIFT 3
+#define EUR_CR_BREAKPOINT2_MASK_DM_SIGNED 0
+#define EUR_CR_BREAKPOINT2_CTRL_TRAPENABLE_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT2_CTRL_TRAPENABLE_SHIFT 2
+#define EUR_CR_BREAKPOINT2_CTRL_TRAPENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT2_CTRL_WENABLE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT2_CTRL_WENABLE_SHIFT 1
+#define EUR_CR_BREAKPOINT2_CTRL_WENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT2_CTRL_RENABLE_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT2_CTRL_RENABLE_SHIFT 0
+#define EUR_CR_BREAKPOINT2_CTRL_RENABLE_SIGNED 0
+/* Register EUR_CR_BREAKPOINT3_START */
+#define EUR_CR_BREAKPOINT3_START 0x0F68
+#define EUR_CR_BREAKPOINT3_START_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT3_START_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT3_START_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT3_END */
+#define EUR_CR_BREAKPOINT3_END 0x0F6C
+#define EUR_CR_BREAKPOINT3_END_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT3_END_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT3_END_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT3 */
+#define EUR_CR_BREAKPOINT3 0x0F70
+#define EUR_CR_BREAKPOINT3_MASK_DM_MASK 0x00000038U
+#define EUR_CR_BREAKPOINT3_MASK_DM_SHIFT 3
+#define EUR_CR_BREAKPOINT3_MASK_DM_SIGNED 0
+#define EUR_CR_BREAKPOINT3_CTRL_TRAPENABLE_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT3_CTRL_TRAPENABLE_SHIFT 2
+#define EUR_CR_BREAKPOINT3_CTRL_TRAPENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT3_CTRL_WENABLE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT3_CTRL_WENABLE_SHIFT 1
+#define EUR_CR_BREAKPOINT3_CTRL_WENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT3_CTRL_RENABLE_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT3_CTRL_RENABLE_SHIFT 0
+#define EUR_CR_BREAKPOINT3_CTRL_RENABLE_SIGNED 0
+/* Register EUR_CR_BREAKPOINT_READ */
+#define EUR_CR_BREAKPOINT_READ 0x0F74
+#define EUR_CR_BREAKPOINT_READ_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT_READ_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT_READ_ADDRESS_SIGNED 0
+/* Register EUR_CR_PARTITION_BREAKPOINT_TRAP */
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP 0x0F78
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_CONTINUE_MASK 0x00000002U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_CONTINUE_SHIFT 1
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_CONTINUE_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_WRNOTIFY_MASK 0x00000001U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_WRNOTIFY_SHIFT 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_WRNOTIFY_SIGNED 0
+/* Register EUR_CR_PARTITION_BREAKPOINT */
+#define EUR_CR_PARTITION_BREAKPOINT 0x0F7C
+#define EUR_CR_PARTITION_BREAKPOINT_MODULE_ID_MASK 0x000003C0U
+#define EUR_CR_PARTITION_BREAKPOINT_MODULE_ID_SHIFT 6
+#define EUR_CR_PARTITION_BREAKPOINT_MODULE_ID_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_ID_MASK 0x00000030U
+#define EUR_CR_PARTITION_BREAKPOINT_ID_SHIFT 4
+#define EUR_CR_PARTITION_BREAKPOINT_ID_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_UNTRAPPED_MASK 0x00000008U
+#define EUR_CR_PARTITION_BREAKPOINT_UNTRAPPED_SHIFT 3
+#define EUR_CR_PARTITION_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAPPED_MASK 0x00000004U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAPPED_SHIFT 2
+#define EUR_CR_PARTITION_BREAKPOINT_TRAPPED_SIGNED 0
+/* Register EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0 */
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0 0x0F80
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0_ADDRESS_SHIFT 4
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0_ADDRESS_SIGNED 0
+/* Register EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1 */
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1 0x0F84
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_SIZE_MASK 0x00007C00U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT 10
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_SIZE_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_NUMBER_MASK 0x00000300U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT 8
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_NUMBER_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_TAG_MASK 0x000000F8U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_TAG_SHIFT 3
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_TAG_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK 0x00000006U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT 1
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_RNW_MASK 0x00000001U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_RNW_SHIFT 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_RNW_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_0 */
+#define EUR_CR_USE_CODE_BASE_0 0x0A0C
+#define EUR_CR_USE_CODE_BASE_ADDR_00_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_00_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_00_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_00_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_00_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_00_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_1 */
+#define EUR_CR_USE_CODE_BASE_1 0x0A10
+#define EUR_CR_USE_CODE_BASE_ADDR_01_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_01_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_01_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_01_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_01_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_01_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_2 */
+#define EUR_CR_USE_CODE_BASE_2 0x0A14
+#define EUR_CR_USE_CODE_BASE_ADDR_02_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_02_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_02_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_02_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_02_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_02_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_3 */
+#define EUR_CR_USE_CODE_BASE_3 0x0A18
+#define EUR_CR_USE_CODE_BASE_ADDR_03_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_03_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_03_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_03_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_03_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_03_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_4 */
+#define EUR_CR_USE_CODE_BASE_4 0x0A1C
+#define EUR_CR_USE_CODE_BASE_ADDR_04_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_04_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_04_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_04_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_04_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_04_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_5 */
+#define EUR_CR_USE_CODE_BASE_5 0x0A20
+#define EUR_CR_USE_CODE_BASE_ADDR_05_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_05_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_05_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_05_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_05_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_05_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_6 */
+#define EUR_CR_USE_CODE_BASE_6 0x0A24
+#define EUR_CR_USE_CODE_BASE_ADDR_06_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_06_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_06_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_06_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_06_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_06_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_7 */
+#define EUR_CR_USE_CODE_BASE_7 0x0A28
+#define EUR_CR_USE_CODE_BASE_ADDR_07_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_07_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_07_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_07_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_07_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_07_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_8 */
+#define EUR_CR_USE_CODE_BASE_8 0x0A2C
+#define EUR_CR_USE_CODE_BASE_ADDR_08_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_08_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_08_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_08_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_08_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_08_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_9 */
+#define EUR_CR_USE_CODE_BASE_9 0x0A30
+#define EUR_CR_USE_CODE_BASE_ADDR_09_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_09_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_09_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_09_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_09_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_09_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_10 */
+#define EUR_CR_USE_CODE_BASE_10 0x0A34
+#define EUR_CR_USE_CODE_BASE_ADDR_10_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_10_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_10_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_10_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_10_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_10_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_11 */
+#define EUR_CR_USE_CODE_BASE_11 0x0A38
+#define EUR_CR_USE_CODE_BASE_ADDR_11_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_11_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_11_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_11_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_11_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_11_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_12 */
+#define EUR_CR_USE_CODE_BASE_12 0x0A3C
+#define EUR_CR_USE_CODE_BASE_ADDR_12_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_12_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_12_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_12_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_12_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_12_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_13 */
+#define EUR_CR_USE_CODE_BASE_13 0x0A40
+#define EUR_CR_USE_CODE_BASE_ADDR_13_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_13_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_13_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_13_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_13_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_13_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_14 */
+#define EUR_CR_USE_CODE_BASE_14 0x0A44
+#define EUR_CR_USE_CODE_BASE_ADDR_14_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_14_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_14_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_14_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_14_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_14_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_15 */
+#define EUR_CR_USE_CODE_BASE_15 0x0A48
+#define EUR_CR_USE_CODE_BASE_ADDR_15_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_15_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_15_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_15_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_15_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_15_SIGNED 0
+/* Register EUR_CR_PIPE0_BREAKPOINT_TRAP */
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP 0x0F88
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_CONTINUE_MASK 0x00000002U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_CONTINUE_SHIFT 1
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_CONTINUE_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_WRNOTIFY_MASK 0x00000001U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_WRNOTIFY_SHIFT 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_WRNOTIFY_SIGNED 0
+/* Register EUR_CR_PIPE0_BREAKPOINT */
+#define EUR_CR_PIPE0_BREAKPOINT 0x0F8C
+#define EUR_CR_PIPE0_BREAKPOINT_MODULE_ID_MASK 0x000003C0U
+#define EUR_CR_PIPE0_BREAKPOINT_MODULE_ID_SHIFT 6
+#define EUR_CR_PIPE0_BREAKPOINT_MODULE_ID_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_ID_MASK 0x00000030U
+#define EUR_CR_PIPE0_BREAKPOINT_ID_SHIFT 4
+#define EUR_CR_PIPE0_BREAKPOINT_ID_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_UNTRAPPED_MASK 0x00000008U
+#define EUR_CR_PIPE0_BREAKPOINT_UNTRAPPED_SHIFT 3
+#define EUR_CR_PIPE0_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAPPED_MASK 0x00000004U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAPPED_SHIFT 2
+#define EUR_CR_PIPE0_BREAKPOINT_TRAPPED_SIGNED 0
+/* Register EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO0 */
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO0 0x0F90
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO0_ADDRESS_SHIFT 4
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO0_ADDRESS_SIGNED 0
+/* Register EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1 */
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1 0x0F94
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_SIZE_MASK 0x00007C00U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT 10
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_SIZE_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_NUMBER_MASK 0x00000300U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT 8
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_NUMBER_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_TAG_MASK 0x000000F8U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_TAG_SHIFT 3
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_TAG_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK 0x00000006U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT 1
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_RNW_MASK 0x00000001U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_RNW_SHIFT 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_RNW_SIGNED 0
+/* Register EUR_CR_PIPE1_BREAKPOINT_TRAP */
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP 0x0F98
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_CONTINUE_MASK 0x00000002U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_CONTINUE_SHIFT 1
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_CONTINUE_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_WRNOTIFY_MASK 0x00000001U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_WRNOTIFY_SHIFT 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_WRNOTIFY_SIGNED 0
+/* Register EUR_CR_PIPE1_BREAKPOINT */
+#define EUR_CR_PIPE1_BREAKPOINT 0x0F9C
+#define EUR_CR_PIPE1_BREAKPOINT_MODULE_ID_MASK 0x000003C0U
+#define EUR_CR_PIPE1_BREAKPOINT_MODULE_ID_SHIFT 6
+#define EUR_CR_PIPE1_BREAKPOINT_MODULE_ID_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_ID_MASK 0x00000030U
+#define EUR_CR_PIPE1_BREAKPOINT_ID_SHIFT 4
+#define EUR_CR_PIPE1_BREAKPOINT_ID_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_UNTRAPPED_MASK 0x00000008U
+#define EUR_CR_PIPE1_BREAKPOINT_UNTRAPPED_SHIFT 3
+#define EUR_CR_PIPE1_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAPPED_MASK 0x00000004U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAPPED_SHIFT 2
+#define EUR_CR_PIPE1_BREAKPOINT_TRAPPED_SIGNED 0
+/* Register EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO0 */
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO0 0x0FA0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO0_ADDRESS_SHIFT 4
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO0_ADDRESS_SIGNED 0
+/* Register EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1 */
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1 0x0FA4
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_SIZE_MASK 0x00007C00U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT 10
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_SIZE_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_NUMBER_MASK 0x00000300U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT 8
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_NUMBER_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_TAG_MASK 0x000000F8U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_TAG_SHIFT 3
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_TAG_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK 0x00000006U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT 1
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_RNW_MASK 0x00000001U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_RNW_SHIFT 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_RNW_SIGNED 0
+/* Table EUR_CR_USE_CODE_BASE */
+/* Register EUR_CR_USE_CODE_BASE */
+#define EUR_CR_USE_CODE_BASE(X) (0x0A0C + (4 * (X)))
+#define EUR_CR_USE_CODE_BASE_ADDR_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_SIGNED 0
+/* Number of entries in table EUR_CR_USE_CODE_BASE */
+#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16
+#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16
+
+#endif /* _SGX543DEFS_KM_H_ */
+
diff --git a/pvr-source/services4/srvkm/hwdefs/sgx544defs.h b/pvr-source/services4/srvkm/hwdefs/sgx544defs.h
new file mode 100644
index 0000000..79efcbc
--- /dev/null
+++ b/pvr-source/services4/srvkm/hwdefs/sgx544defs.h
@@ -0,0 +1,1487 @@
+/*************************************************************************/ /*!
+@Title Hardware defs for SGX544.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _SGX544DEFS_KM_H_
+#define _SGX544DEFS_KM_H_
+
+/* Register EUR_CR_CLKGATECTL */
+#define EUR_CR_CLKGATECTL 0x0000
+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK 0x00000003U
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT 0
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SHIFT 2
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_TE_CLKG_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTL_TE_CLKG_SHIFT 6
+#define EUR_CR_CLKGATECTL_TE_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_MTE_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL_MTE_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL_MTE_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT 10
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_VDM_CLKG_MASK 0x00003000U
+#define EUR_CR_CLKGATECTL_VDM_CLKG_SHIFT 12
+#define EUR_CR_CLKGATECTL_VDM_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_PDS_CLKG_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTL_PDS_CLKG_SHIFT 14
+#define EUR_CR_CLKGATECTL_PDS_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_TA_CLKG_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT 18
+#define EUR_CR_CLKGATECTL_TA_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_BIF_CORE_CLKG_MASK 0x00300000U
+#define EUR_CR_CLKGATECTL_BIF_CORE_CLKG_SHIFT 20
+#define EUR_CR_CLKGATECTL_BIF_CORE_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SIGNED 0
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_MASK 0x10000000U
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_SHIFT 28
+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_SIGNED 0
+/* Register EUR_CR_CLKGATECTL2 */
+#define EUR_CR_CLKGATECTL2 0x0004
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_MASK 0x00000003U
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SHIFT 0
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_TCU_L2_CLKG_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTL2_TCU_L2_CLKG_SHIFT 2
+#define EUR_CR_CLKGATECTL2_TCU_L2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SHIFT 6
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SHIFT 10
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SHIFT 14
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SHIFT 18
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_DCU_L2_CLKG_MASK 0x00C00000U
+#define EUR_CR_CLKGATECTL2_DCU_L2_CLKG_SHIFT 22
+#define EUR_CR_CLKGATECTL2_DCU_L2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_DCU1_L0L1_CLKG_MASK 0x03000000U
+#define EUR_CR_CLKGATECTL2_DCU1_L0L1_CLKG_SHIFT 24
+#define EUR_CR_CLKGATECTL2_DCU1_L0L1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_DCU0_L0L1_CLKG_MASK 0x0C000000U
+#define EUR_CR_CLKGATECTL2_DCU0_L0L1_CLKG_SHIFT 26
+#define EUR_CR_CLKGATECTL2_DCU0_L0L1_CLKG_SIGNED 0
+/* Register EUR_CR_CLKGATESTATUS */
+#define EUR_CR_CLKGATESTATUS 0x0008
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK 0x00000001U
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 0
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_MASK 0x00000002U
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SHIFT 1
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK 0x00000004U
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 2
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_MASK 0x00000008U
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SHIFT 3
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_MASK 0x00000010U
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SHIFT 4
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK 0x00000020U
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 5
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_MASK 0x00000040U
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SHIFT 6
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_MASK 0x00000080U
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_SHIFT 7
+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_MASK 0x00000100U
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SHIFT 8
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TCU_L2_CLKS_MASK 0x00000200U
+#define EUR_CR_CLKGATESTATUS_TCU_L2_CLKS_SHIFT 9
+#define EUR_CR_CLKGATESTATUS_TCU_L2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_MASK 0x00000400U
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SHIFT 10
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_MASK 0x00000800U
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SHIFT 11
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_MASK 0x00001000U
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SHIFT 12
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_MASK 0x00002000U
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SHIFT 13
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_MASK 0x00008000U
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SHIFT 15
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_MASK 0x00010000U
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SHIFT 16
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_MASK 0x00020000U
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SHIFT 17
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_MASK 0x00080000U
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_SHIFT 19
+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK 0x00100000U
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT 20
+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DCU_L2_CLKS_MASK 0x00200000U
+#define EUR_CR_CLKGATESTATUS_DCU_L2_CLKS_SHIFT 21
+#define EUR_CR_CLKGATESTATUS_DCU_L2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DCU0_L0L1_CLKS_MASK 0x00400000U
+#define EUR_CR_CLKGATESTATUS_DCU0_L0L1_CLKS_SHIFT 22
+#define EUR_CR_CLKGATESTATUS_DCU0_L0L1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DCU1_L0L1_CLKS_MASK 0x00800000U
+#define EUR_CR_CLKGATESTATUS_DCU1_L0L1_CLKS_SHIFT 23
+#define EUR_CR_CLKGATESTATUS_DCU1_L0L1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_BIF_CORE_CLKS_MASK 0x01000000U
+#define EUR_CR_CLKGATESTATUS_BIF_CORE_CLKS_SHIFT 24
+#define EUR_CR_CLKGATESTATUS_BIF_CORE_CLKS_SIGNED 0
+/* Register EUR_CR_CLKGATECTLOVR */
+#define EUR_CR_CLKGATECTLOVR 0x000C
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK 0x00000003U
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 0
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SHIFT 2
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK 0x00000030U
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 4
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SHIFT 6
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_MASK 0x00000300U
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SHIFT 8
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 10
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_MASK 0x00003000U
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SHIFT 12
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_SHIFT 14
+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_MASK 0x00030000U
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_SHIFT 16
+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT 18
+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_BIF_CORE_CLKO_MASK 0x00300000U
+#define EUR_CR_CLKGATECTLOVR_BIF_CORE_CLKO_SHIFT 20
+#define EUR_CR_CLKGATECTLOVR_BIF_CORE_CLKO_SIGNED 0
+/* Register EUR_CR_POWER */
+#define EUR_CR_POWER 0x001C
+#define EUR_CR_POWER_PIPE_DISABLE_MASK 0x00000001U
+#define EUR_CR_POWER_PIPE_DISABLE_SHIFT 0
+#define EUR_CR_POWER_PIPE_DISABLE_SIGNED 0
+/* Register EUR_CR_CORE_ID */
+#define EUR_CR_CORE_ID 0x0020
+#define EUR_CR_CORE_ID_CONFIG_MULTI_MASK 0x00000001U
+#define EUR_CR_CORE_ID_CONFIG_MULTI_SHIFT 0
+#define EUR_CR_CORE_ID_CONFIG_MULTI_SIGNED 0
+#define EUR_CR_CORE_ID_CONFIG_BASE_MASK 0x00000002U
+#define EUR_CR_CORE_ID_CONFIG_BASE_SHIFT 1
+#define EUR_CR_CORE_ID_CONFIG_BASE_SIGNED 0
+#define EUR_CR_CORE_ID_CONFIG_MASK 0x000000FCU
+#define EUR_CR_CORE_ID_CONFIG_SHIFT 2
+#define EUR_CR_CORE_ID_CONFIG_SIGNED 0
+#define EUR_CR_CORE_ID_CONFIG_CORES_MASK 0x00000F00U
+#define EUR_CR_CORE_ID_CONFIG_CORES_SHIFT 8
+#define EUR_CR_CORE_ID_CONFIG_CORES_SIGNED 0
+#define EUR_CR_CORE_ID_CONFIG_SLC_MASK 0x0000F000U
+#define EUR_CR_CORE_ID_CONFIG_SLC_SHIFT 12
+#define EUR_CR_CORE_ID_CONFIG_SLC_SIGNED 0
+#define EUR_CR_CORE_ID_ID_MASK 0xFFFF0000U
+#define EUR_CR_CORE_ID_ID_SHIFT 16
+#define EUR_CR_CORE_ID_ID_SIGNED 0
+/* Register EUR_CR_CORE_REVISION */
+#define EUR_CR_CORE_REVISION 0x0024
+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SIGNED 0
+#define EUR_CR_CORE_REVISION_MINOR_MASK 0x0000FF00U
+#define EUR_CR_CORE_REVISION_MINOR_SHIFT 8
+#define EUR_CR_CORE_REVISION_MINOR_SIGNED 0
+#define EUR_CR_CORE_REVISION_MAJOR_MASK 0x00FF0000U
+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT 16
+#define EUR_CR_CORE_REVISION_MAJOR_SIGNED 0
+#define EUR_CR_CORE_REVISION_DESIGNER_MASK 0xFF000000U
+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
+#define EUR_CR_CORE_REVISION_DESIGNER_SIGNED 0
+/* Register EUR_CR_DESIGNER_REV_FIELD1 */
+#define EUR_CR_DESIGNER_REV_FIELD1 0x0028
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SIGNED 0
+/* Register EUR_CR_DESIGNER_REV_FIELD2 */
+#define EUR_CR_DESIGNER_REV_FIELD2 0x002C
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SIGNED 0
+/* Register EUR_CR_SOFT_RESET */
+#define EUR_CR_SOFT_RESET 0x0080
+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK 0x00000001U
+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT 0
+#define EUR_CR_SOFT_RESET_BIF_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_VDM_RESET_MASK 0x00000002U
+#define EUR_CR_SOFT_RESET_VDM_RESET_SHIFT 1
+#define EUR_CR_SOFT_RESET_VDM_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK 0x00000004U
+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT 2
+#define EUR_CR_SOFT_RESET_DPM_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TE_RESET_MASK 0x00000008U
+#define EUR_CR_SOFT_RESET_TE_RESET_SHIFT 3
+#define EUR_CR_SOFT_RESET_TE_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_MTE_RESET_MASK 0x00000010U
+#define EUR_CR_SOFT_RESET_MTE_RESET_SHIFT 4
+#define EUR_CR_SOFT_RESET_MTE_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK 0x00000020U
+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT 5
+#define EUR_CR_SOFT_RESET_ISP_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_ISP2_RESET_MASK 0x00000040U
+#define EUR_CR_SOFT_RESET_ISP2_RESET_SHIFT 6
+#define EUR_CR_SOFT_RESET_ISP2_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK 0x00000080U
+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT 7
+#define EUR_CR_SOFT_RESET_TSP_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_PDS_RESET_MASK 0x00000100U
+#define EUR_CR_SOFT_RESET_PDS_RESET_SHIFT 8
+#define EUR_CR_SOFT_RESET_PDS_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_PBE_RESET_MASK 0x00000200U
+#define EUR_CR_SOFT_RESET_PBE_RESET_SHIFT 9
+#define EUR_CR_SOFT_RESET_PBE_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TCU_L2_RESET_MASK 0x00000400U
+#define EUR_CR_SOFT_RESET_TCU_L2_RESET_SHIFT 10
+#define EUR_CR_SOFT_RESET_TCU_L2_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK 0x00000800U
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_SHIFT 11
+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_ITR_RESET_MASK 0x00002000U
+#define EUR_CR_SOFT_RESET_ITR_RESET_SHIFT 13
+#define EUR_CR_SOFT_RESET_ITR_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TEX_RESET_MASK 0x00004000U
+#define EUR_CR_SOFT_RESET_TEX_RESET_SHIFT 14
+#define EUR_CR_SOFT_RESET_TEX_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_USE_RESET_MASK 0x00008000U
+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT 15
+#define EUR_CR_SOFT_RESET_USE_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK 0x00010000U
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_SHIFT 16
+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TA_RESET_MASK 0x00020000U
+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT 17
+#define EUR_CR_SOFT_RESET_TA_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_DCU_L2_RESET_MASK 0x00040000U
+#define EUR_CR_SOFT_RESET_DCU_L2_RESET_SHIFT 18
+#define EUR_CR_SOFT_RESET_DCU_L2_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_DCU_L0L1_RESET_MASK 0x00080000U
+#define EUR_CR_SOFT_RESET_DCU_L0L1_RESET_SHIFT 19
+#define EUR_CR_SOFT_RESET_DCU_L0L1_RESET_SIGNED 0
+/* Register EUR_CR_EVENT_HOST_ENABLE2 */
+#define EUR_CR_EVENT_HOST_ENABLE2 0x0110
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_UNTRAPPED_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_UNTRAPPED_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_TRAPPED_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_TRAPPED_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_TRAPPED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_CONTEXT_DRAINED_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_CONTEXT_DRAINED_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_CONTEXT_DRAINED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_ISP2_ZLS_CSW_FINISHED_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE2_ISP2_ZLS_CSW_FINISHED_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE2_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TE_RGNHDR_INIT_COMPLETE_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE2_TE_RGNHDR_INIT_COMPLETE_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE2_TE_RGNHDR_INIT_COMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SIGNED 0
+/* Register EUR_CR_EVENT_HOST_CLEAR2 */
+#define EUR_CR_EVENT_HOST_CLEAR2 0x0114
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_CONTEXT_DRAINED_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_CONTEXT_DRAINED_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_CONTEXT_DRAINED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_ISP2_ZLS_CSW_FINISHED_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR2_ISP2_ZLS_CSW_FINISHED_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR2_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TE_RGNHDR_INIT_COMPLETE_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR2_TE_RGNHDR_INIT_COMPLETE_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR2_TE_RGNHDR_INIT_COMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SIGNED 0
+/* Register EUR_CR_EVENT_STATUS2 */
+#define EUR_CR_EVENT_STATUS2 0x0118
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_MASK 0x00000800U
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_SHIFT 11
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_MASK 0x00000400U
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_SHIFT 10
+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_MTE_CONTEXT_DRAINED_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS2_MTE_CONTEXT_DRAINED_SHIFT 9
+#define EUR_CR_EVENT_STATUS2_MTE_CONTEXT_DRAINED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_ISP2_ZLS_CSW_FINISHED_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS2_ISP2_ZLS_CSW_FINISHED_SHIFT 8
+#define EUR_CR_EVENT_STATUS2_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_SHIFT 7
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_SHIFT 6
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TE_RGNHDR_INIT_COMPLETE_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS2_TE_RGNHDR_INIT_COMPLETE_SHIFT 5
+#define EUR_CR_EVENT_STATUS2_TE_RGNHDR_INIT_COMPLETE_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT 4
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT 3
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT 2
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SIGNED 0
+/* Register EUR_CR_EVENT_STATUS */
+#define EUR_CR_EVENT_STATUS 0x012C
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT 29
+#define EUR_CR_EVENT_STATUS_TIMER_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TCU_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_STATUS_TCU_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_STATUS_TCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SIGNED 0
+/* Register EUR_CR_EVENT_HOST_ENABLE */
+#define EUR_CR_EVENT_HOST_ENABLE 0x0130
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TCU_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TCU_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_ENABLE_TCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SIGNED 0
+/* Register EUR_CR_EVENT_HOST_CLEAR */
+#define EUR_CR_EVENT_HOST_CLEAR 0x0134
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TCU_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TCU_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_CLEAR_TCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SIGNED 0
+/* Register EUR_CR_TIMER */
+#define EUR_CR_TIMER 0x0144
+#define EUR_CR_TIMER_VALUE_MASK 0xFFFFFFFFU
+#define EUR_CR_TIMER_VALUE_SHIFT 0
+#define EUR_CR_TIMER_VALUE_SIGNED 0
+/* Register EUR_CR_EVENT_KICK1 */
+#define EUR_CR_EVENT_KICK1 0x0AB0
+#define EUR_CR_EVENT_KICK1_NOW_MASK 0x000000FFU
+#define EUR_CR_EVENT_KICK1_NOW_SHIFT 0
+#define EUR_CR_EVENT_KICK1_NOW_SIGNED 0
+/* Register EUR_CR_EVENT_KICK2 */
+#define EUR_CR_EVENT_KICK2 0x0AC0
+#define EUR_CR_EVENT_KICK2_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK2_NOW_SHIFT 0
+#define EUR_CR_EVENT_KICK2_NOW_SIGNED 0
+/* Register EUR_CR_EVENT_KICKER */
+#define EUR_CR_EVENT_KICKER 0x0AC4
+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT 4
+#define EUR_CR_EVENT_KICKER_ADDRESS_SIGNED 0
+/* Register EUR_CR_EVENT_KICK */
+#define EUR_CR_EVENT_KICK 0x0AC8
+#define EUR_CR_EVENT_KICK_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK_NOW_SHIFT 0
+#define EUR_CR_EVENT_KICK_NOW_SIGNED 0
+/* Register EUR_CR_EVENT_TIMER */
+#define EUR_CR_EVENT_TIMER 0x0ACC
+#define EUR_CR_EVENT_TIMER_ENABLE_MASK 0x01000000U
+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT 24
+#define EUR_CR_EVENT_TIMER_ENABLE_SIGNED 0
+#define EUR_CR_EVENT_TIMER_VALUE_MASK 0x00FFFFFFU
+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT 0
+#define EUR_CR_EVENT_TIMER_VALUE_SIGNED 0
+/* Register EUR_CR_PDS_INV0 */
+#define EUR_CR_PDS_INV0 0x0AD0
+#define EUR_CR_PDS_INV0_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV0_DSC_SHIFT 0
+#define EUR_CR_PDS_INV0_DSC_SIGNED 0
+/* Register EUR_CR_PDS_INV1 */
+#define EUR_CR_PDS_INV1 0x0AD4
+#define EUR_CR_PDS_INV1_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV1_DSC_SHIFT 0
+#define EUR_CR_PDS_INV1_DSC_SIGNED 0
+/* Register EUR_CR_EVENT_KICK3 */
+#define EUR_CR_EVENT_KICK3 0x0AD8
+#define EUR_CR_EVENT_KICK3_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK3_NOW_SHIFT 0
+#define EUR_CR_EVENT_KICK3_NOW_SIGNED 0
+/* Register EUR_CR_PDS_INV3 */
+#define EUR_CR_PDS_INV3 0x0ADC
+#define EUR_CR_PDS_INV3_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV3_DSC_SHIFT 0
+#define EUR_CR_PDS_INV3_DSC_SIGNED 0
+/* Register EUR_CR_PDS_INV_CSC */
+#define EUR_CR_PDS_INV_CSC 0x0AE0
+#define EUR_CR_PDS_INV_CSC_KICK_MASK 0x00000001U
+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT 0
+#define EUR_CR_PDS_INV_CSC_KICK_SIGNED 0
+/* Register EUR_CR_BIF_CTRL */
+#define EUR_CR_BIF_CTRL 0x0C00
+#define EUR_CR_BIF_CTRL_NOREORDER_MASK 0x00000001U
+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT 0
+#define EUR_CR_BIF_CTRL_NOREORDER_SIGNED 0
+#define EUR_CR_BIF_CTRL_PAUSE_MASK 0x00000002U
+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT 1
+#define EUR_CR_BIF_CTRL_PAUSE_SIGNED 0
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT 4
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TA_MASK 0x00000400U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TA_SHIFT 10
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TA_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PTLA_MASK 0x00010000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PTLA_SHIFT 16
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PTLA_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_VDM_MASK 0x00020000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_VDM_SHIFT 17
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_VDM_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_IPF_MASK 0x00040000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_IPF_SHIFT 18
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_IPF_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_DPM_MASK 0x00080000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_DPM_SHIFT 19
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_DPM_SIGNED 0
+/* Register EUR_CR_BIF_INT_STAT */
+#define EUR_CR_BIF_INT_STAT 0x0C04
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_MASK 0x00003FFFU
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_SHIFT 0
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_SIGNED 0
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_MASK 0x00070000U
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_SHIFT 16
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_SIGNED 0
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00080000U
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 19
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SIGNED 0
+/* Register EUR_CR_BIF_FAULT */
+#define EUR_CR_BIF_FAULT 0x0C08
+#define EUR_CR_BIF_FAULT_CID_MASK 0x0000000FU
+#define EUR_CR_BIF_FAULT_CID_SHIFT 0
+#define EUR_CR_BIF_FAULT_CID_SIGNED 0
+#define EUR_CR_BIF_FAULT_SB_MASK 0x000001F0U
+#define EUR_CR_BIF_FAULT_SB_SHIFT 4
+#define EUR_CR_BIF_FAULT_SB_SIGNED 0
+#define EUR_CR_BIF_FAULT_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_FAULT_ADDR_SHIFT 12
+#define EUR_CR_BIF_FAULT_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_TILE0 */
+#define EUR_CR_BIF_TILE0 0x0C0C
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE0_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE0_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE0_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE1 */
+#define EUR_CR_BIF_TILE1 0x0C10
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE1_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE1_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE1_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE2 */
+#define EUR_CR_BIF_TILE2 0x0C14
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE2_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE2_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE2_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE3 */
+#define EUR_CR_BIF_TILE3 0x0C18
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE3_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE3_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE3_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE4 */
+#define EUR_CR_BIF_TILE4 0x0C1C
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE4_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE4_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE4_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE5 */
+#define EUR_CR_BIF_TILE5 0x0C20
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE5_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE5_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE5_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE6 */
+#define EUR_CR_BIF_TILE6 0x0C24
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE6_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE6_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE6_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE7 */
+#define EUR_CR_BIF_TILE7 0x0C28
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE7_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE7_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE7_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE8 */
+#define EUR_CR_BIF_TILE8 0x0C2C
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE8_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE8_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE8_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE9 */
+#define EUR_CR_BIF_TILE9 0x0C30
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE9_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE9_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE9_CFG_SIGNED 0
+/* Register EUR_CR_BIF_CTRL_INVAL */
+#define EUR_CR_BIF_CTRL_INVAL 0x0C34
+#define EUR_CR_BIF_CTRL_INVAL_PTE_MASK 0x00000004U
+#define EUR_CR_BIF_CTRL_INVAL_PTE_SHIFT 2
+#define EUR_CR_BIF_CTRL_INVAL_PTE_SIGNED 0
+#define EUR_CR_BIF_CTRL_INVAL_ALL_MASK 0x00000008U
+#define EUR_CR_BIF_CTRL_INVAL_ALL_SHIFT 3
+#define EUR_CR_BIF_CTRL_INVAL_ALL_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE1 */
+#define EUR_CR_BIF_DIR_LIST_BASE1 0x0C38
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE2 */
+#define EUR_CR_BIF_DIR_LIST_BASE2 0x0C3C
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE3 */
+#define EUR_CR_BIF_DIR_LIST_BASE3 0x0C40
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE4 */
+#define EUR_CR_BIF_DIR_LIST_BASE4 0x0C44
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE5 */
+#define EUR_CR_BIF_DIR_LIST_BASE5 0x0C48
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE6 */
+#define EUR_CR_BIF_DIR_LIST_BASE6 0x0C4C
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE7 */
+#define EUR_CR_BIF_DIR_LIST_BASE7 0x0C50
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_BANK_SET */
+#define EUR_CR_BIF_BANK_SET 0x0C74
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_MASK 0x00000001U
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_SHIFT 0
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_MASK 0x0000000CU
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_SHIFT 2
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_MASK 0x00000010U
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_SHIFT 4
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_MASK 0x000000C0U
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_SHIFT 6
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_MASK 0x00000100U
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_SHIFT 8
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_MASK 0x00000200U
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_SHIFT 9
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_SIGNED 0
+/* Register EUR_CR_BIF_BANK0 */
+#define EUR_CR_BIF_BANK0 0x0C78
+#define EUR_CR_BIF_BANK0_INDEX_EDM_MASK 0x0000000FU
+#define EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT 0
+#define EUR_CR_BIF_BANK0_INDEX_EDM_SIGNED 0
+#define EUR_CR_BIF_BANK0_INDEX_TA_MASK 0x000000F0U
+#define EUR_CR_BIF_BANK0_INDEX_TA_SHIFT 4
+#define EUR_CR_BIF_BANK0_INDEX_TA_SIGNED 0
+#define EUR_CR_BIF_BANK0_INDEX_3D_MASK 0x0000F000U
+#define EUR_CR_BIF_BANK0_INDEX_3D_SHIFT 12
+#define EUR_CR_BIF_BANK0_INDEX_3D_SIGNED 0
+#define EUR_CR_BIF_BANK0_INDEX_PTLA_MASK 0x000F0000U
+#define EUR_CR_BIF_BANK0_INDEX_PTLA_SHIFT 16
+#define EUR_CR_BIF_BANK0_INDEX_PTLA_SIGNED 0
+/* Register EUR_CR_BIF_BANK1 */
+#define EUR_CR_BIF_BANK1 0x0C7C
+#define EUR_CR_BIF_BANK1_INDEX_EDM_MASK 0x0000000FU
+#define EUR_CR_BIF_BANK1_INDEX_EDM_SHIFT 0
+#define EUR_CR_BIF_BANK1_INDEX_EDM_SIGNED 0
+#define EUR_CR_BIF_BANK1_INDEX_TA_MASK 0x000000F0U
+#define EUR_CR_BIF_BANK1_INDEX_TA_SHIFT 4
+#define EUR_CR_BIF_BANK1_INDEX_TA_SIGNED 0
+#define EUR_CR_BIF_BANK1_INDEX_3D_MASK 0x0000F000U
+#define EUR_CR_BIF_BANK1_INDEX_3D_SHIFT 12
+#define EUR_CR_BIF_BANK1_INDEX_3D_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE0 */
+#define EUR_CR_BIF_DIR_LIST_BASE0 0x0C84
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_TA_REQ_BASE */
+#define EUR_CR_BIF_TA_REQ_BASE 0x0C90
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_MEM_REQ_STAT */
+#define EUR_CR_BIF_MEM_REQ_STAT 0x0CA8
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK 0x000000FFU
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SIGNED 0
+/* Register EUR_CR_BIF_3D_REQ_BASE */
+#define EUR_CR_BIF_3D_REQ_BASE 0x0CAC
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_ZLS_REQ_BASE */
+#define EUR_CR_BIF_ZLS_REQ_BASE 0x0CB0
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_BANK_STATUS */
+#define EUR_CR_BIF_BANK_STATUS 0x0CB4
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_MASK 0x00000001U
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_SHIFT 0
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_SIGNED 0
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_MASK 0x00000002U
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_SHIFT 1
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_SIGNED 0
+/* Register EUR_CR_BIF_MMU_CTRL */
+#define EUR_CR_BIF_MMU_CTRL 0x0CD0
+#define EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_MASK 0x00000001U
+#define EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_SHIFT 0
+#define EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_SIGNED 0
+#define EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_MASK 0x00000006U
+#define EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT 1
+#define EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_SIGNED 0
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_WRITE_BURST_COLLATE_MASK 0x00000008U
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_WRITE_BURST_COLLATE_SHIFT 3
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_WRITE_BURST_COLLATE_SIGNED 0
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_MASK 0x00000010U
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_SHIFT 4
+#define EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_SIGNED 0
+#define EUR_CR_BIF_MMU_CTRL_DISABLE_BURST_EXP_MASK 0x00000020U
+#define EUR_CR_BIF_MMU_CTRL_DISABLE_BURST_EXP_SHIFT 5
+#define EUR_CR_BIF_MMU_CTRL_DISABLE_BURST_EXP_SIGNED 0
+/* Register EUR_CR_2D_BLIT_STATUS */
+#define EUR_CR_2D_BLIT_STATUS 0x0E04
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFU
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0
+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SIGNED 0
+#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK 0x01000000U
+#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT 24
+#define EUR_CR_2D_BLIT_STATUS_BUSY_SIGNED 0
+/* Register EUR_CR_2D_VIRTUAL_FIFO_0 */
+#define EUR_CR_2D_VIRTUAL_FIFO_0 0x0E10
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EU
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000U
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SIGNED 0
+/* Register EUR_CR_2D_VIRTUAL_FIFO_1 */
+#define EUR_CR_2D_VIRTUAL_FIFO_1 0x0E14
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFU
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SIGNED 0
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000U
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24
+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SIGNED 0
+/* Register EUR_CR_BREAKPOINT0_START */
+#define EUR_CR_BREAKPOINT0_START 0x0F44
+#define EUR_CR_BREAKPOINT0_START_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT0_START_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT0_START_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT0_END */
+#define EUR_CR_BREAKPOINT0_END 0x0F48
+#define EUR_CR_BREAKPOINT0_END_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT0_END_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT0_END_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT0 */
+#define EUR_CR_BREAKPOINT0 0x0F4C
+#define EUR_CR_BREAKPOINT0_MASK_DM_MASK 0x00000038U
+#define EUR_CR_BREAKPOINT0_MASK_DM_SHIFT 3
+#define EUR_CR_BREAKPOINT0_MASK_DM_SIGNED 0
+#define EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_SHIFT 2
+#define EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT0_CTRL_WENABLE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT0_CTRL_WENABLE_SHIFT 1
+#define EUR_CR_BREAKPOINT0_CTRL_WENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT0_CTRL_RENABLE_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT0_CTRL_RENABLE_SHIFT 0
+#define EUR_CR_BREAKPOINT0_CTRL_RENABLE_SIGNED 0
+/* Register EUR_CR_BREAKPOINT1_START */
+#define EUR_CR_BREAKPOINT1_START 0x0F50
+#define EUR_CR_BREAKPOINT1_START_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT1_START_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT1_START_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT1_END */
+#define EUR_CR_BREAKPOINT1_END 0x0F54
+#define EUR_CR_BREAKPOINT1_END_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT1_END_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT1_END_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT1 */
+#define EUR_CR_BREAKPOINT1 0x0F58
+#define EUR_CR_BREAKPOINT1_MASK_DM_MASK 0x00000038U
+#define EUR_CR_BREAKPOINT1_MASK_DM_SHIFT 3
+#define EUR_CR_BREAKPOINT1_MASK_DM_SIGNED 0
+#define EUR_CR_BREAKPOINT1_CTRL_TRAPENABLE_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT1_CTRL_TRAPENABLE_SHIFT 2
+#define EUR_CR_BREAKPOINT1_CTRL_TRAPENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT1_CTRL_WENABLE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT1_CTRL_WENABLE_SHIFT 1
+#define EUR_CR_BREAKPOINT1_CTRL_WENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT1_CTRL_RENABLE_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT1_CTRL_RENABLE_SHIFT 0
+#define EUR_CR_BREAKPOINT1_CTRL_RENABLE_SIGNED 0
+/* Register EUR_CR_BREAKPOINT2_START */
+#define EUR_CR_BREAKPOINT2_START 0x0F5C
+#define EUR_CR_BREAKPOINT2_START_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT2_START_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT2_START_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT2_END */
+#define EUR_CR_BREAKPOINT2_END 0x0F60
+#define EUR_CR_BREAKPOINT2_END_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT2_END_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT2_END_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT2 */
+#define EUR_CR_BREAKPOINT2 0x0F64
+#define EUR_CR_BREAKPOINT2_MASK_DM_MASK 0x00000038U
+#define EUR_CR_BREAKPOINT2_MASK_DM_SHIFT 3
+#define EUR_CR_BREAKPOINT2_MASK_DM_SIGNED 0
+#define EUR_CR_BREAKPOINT2_CTRL_TRAPENABLE_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT2_CTRL_TRAPENABLE_SHIFT 2
+#define EUR_CR_BREAKPOINT2_CTRL_TRAPENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT2_CTRL_WENABLE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT2_CTRL_WENABLE_SHIFT 1
+#define EUR_CR_BREAKPOINT2_CTRL_WENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT2_CTRL_RENABLE_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT2_CTRL_RENABLE_SHIFT 0
+#define EUR_CR_BREAKPOINT2_CTRL_RENABLE_SIGNED 0
+/* Register EUR_CR_BREAKPOINT3_START */
+#define EUR_CR_BREAKPOINT3_START 0x0F68
+#define EUR_CR_BREAKPOINT3_START_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT3_START_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT3_START_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT3_END */
+#define EUR_CR_BREAKPOINT3_END 0x0F6C
+#define EUR_CR_BREAKPOINT3_END_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT3_END_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT3_END_ADDRESS_SIGNED 0
+/* Register EUR_CR_BREAKPOINT3 */
+#define EUR_CR_BREAKPOINT3 0x0F70
+#define EUR_CR_BREAKPOINT3_MASK_DM_MASK 0x00000038U
+#define EUR_CR_BREAKPOINT3_MASK_DM_SHIFT 3
+#define EUR_CR_BREAKPOINT3_MASK_DM_SIGNED 0
+#define EUR_CR_BREAKPOINT3_CTRL_TRAPENABLE_MASK 0x00000004U
+#define EUR_CR_BREAKPOINT3_CTRL_TRAPENABLE_SHIFT 2
+#define EUR_CR_BREAKPOINT3_CTRL_TRAPENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT3_CTRL_WENABLE_MASK 0x00000002U
+#define EUR_CR_BREAKPOINT3_CTRL_WENABLE_SHIFT 1
+#define EUR_CR_BREAKPOINT3_CTRL_WENABLE_SIGNED 0
+#define EUR_CR_BREAKPOINT3_CTRL_RENABLE_MASK 0x00000001U
+#define EUR_CR_BREAKPOINT3_CTRL_RENABLE_SHIFT 0
+#define EUR_CR_BREAKPOINT3_CTRL_RENABLE_SIGNED 0
+/* Register EUR_CR_BREAKPOINT_READ */
+#define EUR_CR_BREAKPOINT_READ 0x0F74
+#define EUR_CR_BREAKPOINT_READ_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_BREAKPOINT_READ_ADDRESS_SHIFT 4
+#define EUR_CR_BREAKPOINT_READ_ADDRESS_SIGNED 0
+/* Register EUR_CR_PARTITION_BREAKPOINT_TRAP */
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP 0x0F78
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_CONTINUE_MASK 0x00000002U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_CONTINUE_SHIFT 1
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_CONTINUE_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_WRNOTIFY_MASK 0x00000001U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_WRNOTIFY_SHIFT 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_WRNOTIFY_SIGNED 0
+/* Register EUR_CR_PARTITION_BREAKPOINT */
+#define EUR_CR_PARTITION_BREAKPOINT 0x0F7C
+#define EUR_CR_PARTITION_BREAKPOINT_MODULE_ID_MASK 0x000003C0U
+#define EUR_CR_PARTITION_BREAKPOINT_MODULE_ID_SHIFT 6
+#define EUR_CR_PARTITION_BREAKPOINT_MODULE_ID_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_ID_MASK 0x00000030U
+#define EUR_CR_PARTITION_BREAKPOINT_ID_SHIFT 4
+#define EUR_CR_PARTITION_BREAKPOINT_ID_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_UNTRAPPED_MASK 0x00000008U
+#define EUR_CR_PARTITION_BREAKPOINT_UNTRAPPED_SHIFT 3
+#define EUR_CR_PARTITION_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAPPED_MASK 0x00000004U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAPPED_SHIFT 2
+#define EUR_CR_PARTITION_BREAKPOINT_TRAPPED_SIGNED 0
+/* Register EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0 */
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0 0x0F80
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0_ADDRESS_SHIFT 4
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0_ADDRESS_SIGNED 0
+/* Register EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1 */
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1 0x0F84
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_SIZE_MASK 0x00007C00U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT 10
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_SIZE_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_NUMBER_MASK 0x00000300U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT 8
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_NUMBER_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_TAG_MASK 0x000000F8U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_TAG_SHIFT 3
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_TAG_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK 0x00000006U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT 1
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SIGNED 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_RNW_MASK 0x00000001U
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_RNW_SHIFT 0
+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_RNW_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_0 */
+#define EUR_CR_USE_CODE_BASE_0 0x0A0C
+#define EUR_CR_USE_CODE_BASE_ADDR_00_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_00_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_00_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_00_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_00_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_00_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_1 */
+#define EUR_CR_USE_CODE_BASE_1 0x0A10
+#define EUR_CR_USE_CODE_BASE_ADDR_01_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_01_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_01_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_01_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_01_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_01_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_2 */
+#define EUR_CR_USE_CODE_BASE_2 0x0A14
+#define EUR_CR_USE_CODE_BASE_ADDR_02_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_02_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_02_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_02_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_02_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_02_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_3 */
+#define EUR_CR_USE_CODE_BASE_3 0x0A18
+#define EUR_CR_USE_CODE_BASE_ADDR_03_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_03_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_03_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_03_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_03_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_03_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_4 */
+#define EUR_CR_USE_CODE_BASE_4 0x0A1C
+#define EUR_CR_USE_CODE_BASE_ADDR_04_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_04_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_04_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_04_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_04_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_04_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_5 */
+#define EUR_CR_USE_CODE_BASE_5 0x0A20
+#define EUR_CR_USE_CODE_BASE_ADDR_05_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_05_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_05_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_05_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_05_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_05_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_6 */
+#define EUR_CR_USE_CODE_BASE_6 0x0A24
+#define EUR_CR_USE_CODE_BASE_ADDR_06_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_06_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_06_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_06_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_06_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_06_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_7 */
+#define EUR_CR_USE_CODE_BASE_7 0x0A28
+#define EUR_CR_USE_CODE_BASE_ADDR_07_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_07_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_07_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_07_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_07_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_07_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_8 */
+#define EUR_CR_USE_CODE_BASE_8 0x0A2C
+#define EUR_CR_USE_CODE_BASE_ADDR_08_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_08_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_08_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_08_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_08_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_08_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_9 */
+#define EUR_CR_USE_CODE_BASE_9 0x0A30
+#define EUR_CR_USE_CODE_BASE_ADDR_09_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_09_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_09_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_09_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_09_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_09_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_10 */
+#define EUR_CR_USE_CODE_BASE_10 0x0A34
+#define EUR_CR_USE_CODE_BASE_ADDR_10_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_10_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_10_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_10_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_10_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_10_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_11 */
+#define EUR_CR_USE_CODE_BASE_11 0x0A38
+#define EUR_CR_USE_CODE_BASE_ADDR_11_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_11_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_11_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_11_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_11_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_11_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_12 */
+#define EUR_CR_USE_CODE_BASE_12 0x0A3C
+#define EUR_CR_USE_CODE_BASE_ADDR_12_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_12_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_12_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_12_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_12_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_12_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_13 */
+#define EUR_CR_USE_CODE_BASE_13 0x0A40
+#define EUR_CR_USE_CODE_BASE_ADDR_13_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_13_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_13_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_13_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_13_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_13_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_14 */
+#define EUR_CR_USE_CODE_BASE_14 0x0A44
+#define EUR_CR_USE_CODE_BASE_ADDR_14_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_14_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_14_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_14_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_14_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_14_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_15 */
+#define EUR_CR_USE_CODE_BASE_15 0x0A48
+#define EUR_CR_USE_CODE_BASE_ADDR_15_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_15_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_15_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_15_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_15_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_15_SIGNED 0
+/* Register EUR_CR_PIPE0_BREAKPOINT_TRAP */
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP 0x0F88
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_CONTINUE_MASK 0x00000002U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_CONTINUE_SHIFT 1
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_CONTINUE_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_WRNOTIFY_MASK 0x00000001U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_WRNOTIFY_SHIFT 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_WRNOTIFY_SIGNED 0
+/* Register EUR_CR_PIPE0_BREAKPOINT */
+#define EUR_CR_PIPE0_BREAKPOINT 0x0F8C
+#define EUR_CR_PIPE0_BREAKPOINT_MODULE_ID_MASK 0x000003C0U
+#define EUR_CR_PIPE0_BREAKPOINT_MODULE_ID_SHIFT 6
+#define EUR_CR_PIPE0_BREAKPOINT_MODULE_ID_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_ID_MASK 0x00000030U
+#define EUR_CR_PIPE0_BREAKPOINT_ID_SHIFT 4
+#define EUR_CR_PIPE0_BREAKPOINT_ID_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_UNTRAPPED_MASK 0x00000008U
+#define EUR_CR_PIPE0_BREAKPOINT_UNTRAPPED_SHIFT 3
+#define EUR_CR_PIPE0_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAPPED_MASK 0x00000004U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAPPED_SHIFT 2
+#define EUR_CR_PIPE0_BREAKPOINT_TRAPPED_SIGNED 0
+/* Register EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO0 */
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO0 0x0F90
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO0_ADDRESS_SHIFT 4
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO0_ADDRESS_SIGNED 0
+/* Register EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1 */
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1 0x0F94
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_SIZE_MASK 0x00007C00U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT 10
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_SIZE_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_NUMBER_MASK 0x00000300U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT 8
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_NUMBER_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_TAG_MASK 0x000000F8U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_TAG_SHIFT 3
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_TAG_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK 0x00000006U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT 1
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SIGNED 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_RNW_MASK 0x00000001U
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_RNW_SHIFT 0
+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_RNW_SIGNED 0
+/* Register EUR_CR_PIPE1_BREAKPOINT_TRAP */
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP 0x0F98
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_CONTINUE_MASK 0x00000002U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_CONTINUE_SHIFT 1
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_CONTINUE_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_WRNOTIFY_MASK 0x00000001U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_WRNOTIFY_SHIFT 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_WRNOTIFY_SIGNED 0
+/* Register EUR_CR_PIPE1_BREAKPOINT */
+#define EUR_CR_PIPE1_BREAKPOINT 0x0F9C
+#define EUR_CR_PIPE1_BREAKPOINT_MODULE_ID_MASK 0x000003C0U
+#define EUR_CR_PIPE1_BREAKPOINT_MODULE_ID_SHIFT 6
+#define EUR_CR_PIPE1_BREAKPOINT_MODULE_ID_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_ID_MASK 0x00000030U
+#define EUR_CR_PIPE1_BREAKPOINT_ID_SHIFT 4
+#define EUR_CR_PIPE1_BREAKPOINT_ID_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_UNTRAPPED_MASK 0x00000008U
+#define EUR_CR_PIPE1_BREAKPOINT_UNTRAPPED_SHIFT 3
+#define EUR_CR_PIPE1_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAPPED_MASK 0x00000004U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAPPED_SHIFT 2
+#define EUR_CR_PIPE1_BREAKPOINT_TRAPPED_SIGNED 0
+/* Register EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO0 */
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO0 0x0FA0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO0_ADDRESS_SHIFT 4
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO0_ADDRESS_SIGNED 0
+/* Register EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1 */
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1 0x0FA4
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_SIZE_MASK 0x00007C00U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT 10
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_SIZE_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_NUMBER_MASK 0x00000300U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT 8
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_NUMBER_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_TAG_MASK 0x000000F8U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_TAG_SHIFT 3
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_TAG_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK 0x00000006U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT 1
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SIGNED 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_RNW_MASK 0x00000001U
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_RNW_SHIFT 0
+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_RNW_SIGNED 0
+/* Table EUR_CR_USE_CODE_BASE */
+/* Register EUR_CR_USE_CODE_BASE */
+#define EUR_CR_USE_CODE_BASE(X) (0x0A0C + (4 * (X)))
+#define EUR_CR_USE_CODE_BASE_ADDR_MASK 0x03FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_MASK 0x0C000000U
+#define EUR_CR_USE_CODE_BASE_DM_SHIFT 26
+#define EUR_CR_USE_CODE_BASE_DM_SIGNED 0
+/* Number of entries in table EUR_CR_USE_CODE_BASE */
+#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16
+#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16
+
+#endif /* _SGX544DEFS_KM_H_ */
+
diff --git a/pvr-source/services4/srvkm/hwdefs/sgx545defs.h b/pvr-source/services4/srvkm/hwdefs/sgx545defs.h
new file mode 100644
index 0000000..c5adee2
--- /dev/null
+++ b/pvr-source/services4/srvkm/hwdefs/sgx545defs.h
@@ -0,0 +1,1290 @@
+/*************************************************************************/ /*!
+@Title Hardware defs for SGX545.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _SGX545DEFS_KM_H_
+#define _SGX545DEFS_KM_H_
+
+/* Register EUR_CR_CLKGATECTL */
+#define EUR_CR_CLKGATECTL 0x0000
+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK 0x00000003U
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT 0
+#define EUR_CR_CLKGATECTL_ISP_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SHIFT 2
+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL_TSP_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_TE_CLKG_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTL_TE_CLKG_SHIFT 6
+#define EUR_CR_CLKGATECTL_TE_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_MTE_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL_MTE_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL_MTE_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT 10
+#define EUR_CR_CLKGATECTL_DPM_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_VDM_CLKG_MASK 0x00003000U
+#define EUR_CR_CLKGATECTL_VDM_CLKG_SHIFT 12
+#define EUR_CR_CLKGATECTL_VDM_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_PDS0_CLKG_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTL_PDS0_CLKG_SHIFT 14
+#define EUR_CR_CLKGATECTL_PDS0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24
+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SIGNED 0
+/* Register EUR_CR_CLKGATECTL2 */
+#define EUR_CR_CLKGATECTL2 0x0004
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_MASK 0x00000003U
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SHIFT 0
+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_SHIFT 2
+#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_MASK 0x00000030U
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SHIFT 4
+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SHIFT 6
+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_MASK 0x00000300U
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SHIFT 8
+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SHIFT 10
+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_MADD0_CLKG_MASK 0x00003000U
+#define EUR_CR_CLKGATECTL2_MADD0_CLKG_SHIFT 12
+#define EUR_CR_CLKGATECTL2_MADD0_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SHIFT 14
+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_MASK 0x00030000U
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SHIFT 16
+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_MASK 0x000C0000U
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SHIFT 18
+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_MADD1_CLKG_MASK 0x00300000U
+#define EUR_CR_CLKGATECTL2_MADD1_CLKG_SHIFT 20
+#define EUR_CR_CLKGATECTL2_MADD1_CLKG_SIGNED 0
+#define EUR_CR_CLKGATECTL2_PDS1_CLKG_MASK 0x00C00000U
+#define EUR_CR_CLKGATECTL2_PDS1_CLKG_SHIFT 22
+#define EUR_CR_CLKGATECTL2_PDS1_CLKG_SIGNED 0
+/* Register EUR_CR_CLKGATESTATUS */
+#define EUR_CR_CLKGATESTATUS 0x0008
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK 0x00000001U
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 0
+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_MASK 0x00000002U
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SHIFT 1
+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK 0x00000004U
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 2
+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_MASK 0x00000008U
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SHIFT 3
+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_MASK 0x00000010U
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SHIFT 4
+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK 0x00000020U
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 5
+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_MASK 0x00000040U
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SHIFT 6
+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_PDS0_CLKS_MASK 0x00000080U
+#define EUR_CR_CLKGATESTATUS_PDS0_CLKS_SHIFT 7
+#define EUR_CR_CLKGATESTATUS_PDS0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_MASK 0x00000100U
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SHIFT 8
+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_MASK 0x00000200U
+#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_SHIFT 9
+#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_MASK 0x00000400U
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SHIFT 10
+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_MASK 0x00000800U
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SHIFT 11
+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_MASK 0x00001000U
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SHIFT 12
+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_MASK 0x00002000U
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SHIFT 13
+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_MASK 0x00004000U
+#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_SHIFT 14
+#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_MASK 0x00008000U
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SHIFT 15
+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_MASK 0x00010000U
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SHIFT 16
+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_MASK 0x00020000U
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SHIFT 17
+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_MASK 0x00040000U
+#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_SHIFT 18
+#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_SIGNED 0
+#define EUR_CR_CLKGATESTATUS_PDS1_CLKS_MASK 0x00080000U
+#define EUR_CR_CLKGATESTATUS_PDS1_CLKS_SHIFT 19
+#define EUR_CR_CLKGATESTATUS_PDS1_CLKS_SIGNED 0
+/* Register EUR_CR_CLKGATECTLOVR */
+#define EUR_CR_CLKGATECTLOVR 0x000C
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK 0x00000003U
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 0
+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_MASK 0x0000000CU
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SHIFT 2
+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK 0x00000030U
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 4
+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_MASK 0x000000C0U
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SHIFT 6
+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_MASK 0x00000300U
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SHIFT 8
+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK 0x00000C00U
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 10
+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_MASK 0x00003000U
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SHIFT 12
+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SIGNED 0
+#define EUR_CR_CLKGATECTLOVR_PDS0_CLKO_MASK 0x0000C000U
+#define EUR_CR_CLKGATECTLOVR_PDS0_CLKO_SHIFT 14
+#define EUR_CR_CLKGATECTLOVR_PDS0_CLKO_SIGNED 0
+/* Register EUR_CR_CORE_ID */
+#define EUR_CR_CORE_ID 0x001C
+#define EUR_CR_CORE_ID_CONFIG_MASK 0x0000FFFFU
+#define EUR_CR_CORE_ID_CONFIG_SHIFT 0
+#define EUR_CR_CORE_ID_CONFIG_SIGNED 0
+#define EUR_CR_CORE_ID_ID_MASK 0xFFFF0000U
+#define EUR_CR_CORE_ID_ID_SHIFT 16
+#define EUR_CR_CORE_ID_ID_SIGNED 0
+/* Register EUR_CR_CORE_REVISION */
+#define EUR_CR_CORE_REVISION 0x0020
+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0
+#define EUR_CR_CORE_REVISION_MAINTENANCE_SIGNED 0
+#define EUR_CR_CORE_REVISION_MINOR_MASK 0x0000FF00U
+#define EUR_CR_CORE_REVISION_MINOR_SHIFT 8
+#define EUR_CR_CORE_REVISION_MINOR_SIGNED 0
+#define EUR_CR_CORE_REVISION_MAJOR_MASK 0x00FF0000U
+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT 16
+#define EUR_CR_CORE_REVISION_MAJOR_SIGNED 0
+#define EUR_CR_CORE_REVISION_DESIGNER_MASK 0xFF000000U
+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24
+#define EUR_CR_CORE_REVISION_DESIGNER_SIGNED 0
+/* Register EUR_CR_DESIGNER_REV_FIELD1 */
+#define EUR_CR_DESIGNER_REV_FIELD1 0x0024
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0
+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SIGNED 0
+/* Register EUR_CR_DESIGNER_REV_FIELD2 */
+#define EUR_CR_DESIGNER_REV_FIELD2 0x002C
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0
+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SIGNED 0
+/* Register EUR_CR_SOFT_RESET */
+#define EUR_CR_SOFT_RESET 0x0080
+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK 0x00000001U
+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT 0
+#define EUR_CR_SOFT_RESET_BIF_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK 0x00000002U
+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT 1
+#define EUR_CR_SOFT_RESET_DPM_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TA_RESET_MASK 0x00000004U
+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT 2
+#define EUR_CR_SOFT_RESET_TA_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_USE_RESET_MASK 0x00000008U
+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT 3
+#define EUR_CR_SOFT_RESET_USE_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK 0x00000010U
+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT 4
+#define EUR_CR_SOFT_RESET_ISP_RESET_SIGNED 0
+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK 0x00000020U
+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT 5
+#define EUR_CR_SOFT_RESET_TSP_RESET_SIGNED 0
+/* Register EUR_CR_EVENT_HOST_ENABLE2 */
+#define EUR_CR_EVENT_HOST_ENABLE2 0x0110
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_SHIFT 15
+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_VDM_CONTEXT_LOAD_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_ENABLE2_VDM_CONTEXT_LOAD_SHIFT 14
+#define EUR_CR_EVENT_HOST_ENABLE2_VDM_CONTEXT_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_VDM_TASK_KICKED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_ENABLE2_VDM_TASK_KICKED_SHIFT 13
+#define EUR_CR_EVENT_HOST_ENABLE2_VDM_TASK_KICKED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_OTPM_MEM_CLEARED_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_ENABLE2_OTPM_MEM_CLEARED_SHIFT 12
+#define EUR_CR_EVENT_HOST_ENABLE2_OTPM_MEM_CLEARED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_OTPM_FLUSHED_INV_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE2_OTPM_FLUSHED_INV_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE2_OTPM_FLUSHED_INV_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_GSG_FLUSHED_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE2_GSG_FLUSHED_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE2_GSG_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_GSG_LOADED_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE2_GSG_LOADED_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE2_GSG_LOADED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_DHOST_FREE_LOAD_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_DHOST_FREE_LOAD_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_DHOST_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_HOST_FREE_LOAD_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_HOST_FREE_LOAD_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_HOST_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SIGNED 0
+/* Register EUR_CR_EVENT_HOST_CLEAR2 */
+#define EUR_CR_EVENT_HOST_CLEAR2 0x0114
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_SHIFT 15
+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_VDM_CONTEXT_LOAD_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_CLEAR2_VDM_CONTEXT_LOAD_SHIFT 14
+#define EUR_CR_EVENT_HOST_CLEAR2_VDM_CONTEXT_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_VDM_TASK_KICKED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_CLEAR2_VDM_TASK_KICKED_SHIFT 13
+#define EUR_CR_EVENT_HOST_CLEAR2_VDM_TASK_KICKED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_OTPM_MEM_CLEARED_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_CLEAR2_OTPM_MEM_CLEARED_SHIFT 12
+#define EUR_CR_EVENT_HOST_CLEAR2_OTPM_MEM_CLEARED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_OTPM_FLUSHED_INV_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR2_OTPM_FLUSHED_INV_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR2_OTPM_FLUSHED_INV_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_GSG_FLUSHED_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR2_GSG_FLUSHED_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR2_GSG_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_GSG_LOADED_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR2_GSG_LOADED_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR2_GSG_LOADED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_DHOST_FREE_LOAD_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_DHOST_FREE_LOAD_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_DHOST_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_HOST_FREE_LOAD_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_HOST_FREE_LOAD_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_HOST_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SIGNED 0
+/* Register EUR_CR_EVENT_STATUS2 */
+#define EUR_CR_EVENT_STATUS2 0x0118
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_MASK 0x00008000U
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_SHIFT 15
+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_VDM_CONTEXT_LOAD_MASK 0x00004000U
+#define EUR_CR_EVENT_STATUS2_VDM_CONTEXT_LOAD_SHIFT 14
+#define EUR_CR_EVENT_STATUS2_VDM_CONTEXT_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_VDM_TASK_KICKED_MASK 0x00002000U
+#define EUR_CR_EVENT_STATUS2_VDM_TASK_KICKED_SHIFT 13
+#define EUR_CR_EVENT_STATUS2_VDM_TASK_KICKED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_OTPM_MEM_CLEARED_MASK 0x00001000U
+#define EUR_CR_EVENT_STATUS2_OTPM_MEM_CLEARED_SHIFT 12
+#define EUR_CR_EVENT_STATUS2_OTPM_MEM_CLEARED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_OTPM_FLUSHED_INV_MASK 0x00000800U
+#define EUR_CR_EVENT_STATUS2_OTPM_FLUSHED_INV_SHIFT 11
+#define EUR_CR_EVENT_STATUS2_OTPM_FLUSHED_INV_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_MASK 0x00000400U
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_SHIFT 10
+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_GSG_FLUSHED_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS2_GSG_FLUSHED_SHIFT 9
+#define EUR_CR_EVENT_STATUS2_GSG_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_GSG_LOADED_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS2_GSG_LOADED_SHIFT 8
+#define EUR_CR_EVENT_STATUS2_GSG_LOADED_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT 7
+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT 6
+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT 5
+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DPM_DHOST_FREE_LOAD_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS2_DPM_DHOST_FREE_LOAD_SHIFT 3
+#define EUR_CR_EVENT_STATUS2_DPM_DHOST_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DPM_HOST_FREE_LOAD_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS2_DPM_HOST_FREE_LOAD_SHIFT 2
+#define EUR_CR_EVENT_STATUS2_DPM_HOST_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1
+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0
+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SIGNED 0
+/* Register EUR_CR_EVENT_STATUS */
+#define EUR_CR_EVENT_STATUS 0x012C
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT 29
+#define EUR_CR_EVENT_STATUS_TIMER_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_STATUS_ISP2_ZLS_CSW_FINISHED_MASK 0x00200000U
+#define EUR_CR_EVENT_STATUS_ISP2_ZLS_CSW_FINISHED_SHIFT 21
+#define EUR_CR_EVENT_STATUS_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_STATUS_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SIGNED 0
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_STATUS_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SIGNED 0
+/* Register EUR_CR_EVENT_HOST_ENABLE */
+#define EUR_CR_EVENT_HOST_ENABLE 0x0130
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_ISP2_ZLS_CSW_FINISHED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP2_ZLS_CSW_FINISHED_SHIFT 21
+#define EUR_CR_EVENT_HOST_ENABLE_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SIGNED 0
+/* Register EUR_CR_EVENT_HOST_CLEAR */
+#define EUR_CR_EVENT_HOST_CLEAR 0x0134
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31
+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK 0x20000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29
+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28
+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SHIFT 26
+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_ISP2_ZLS_CSW_FINISHED_MASK 0x00200000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP2_ZLS_CSW_FINISHED_SHIFT 21
+#define EUR_CR_EVENT_HOST_CLEAR_ISP2_ZLS_CSW_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19
+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18
+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_MASK 0x00010000U
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SHIFT 16
+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15
+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14
+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13
+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12
+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10
+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SIGNED 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0
+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SIGNED 0
+/* Register EUR_CR_TIMER */
+#define EUR_CR_TIMER 0x0144
+#define EUR_CR_TIMER_VALUE_MASK 0xFFFFFFFFU
+#define EUR_CR_TIMER_VALUE_SHIFT 0
+#define EUR_CR_TIMER_VALUE_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_0 */
+#define EUR_CR_USE_CODE_BASE_0 0x0A0C
+#define EUR_CR_USE_CODE_BASE_ADDR_00_MASK 0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_00_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_00_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_00_MASK 0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_00_SHIFT 25
+#define EUR_CR_USE_CODE_BASE_DM_00_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_1 */
+#define EUR_CR_USE_CODE_BASE_1 0x0A10
+#define EUR_CR_USE_CODE_BASE_ADDR_01_MASK 0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_01_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_01_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_01_MASK 0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_01_SHIFT 25
+#define EUR_CR_USE_CODE_BASE_DM_01_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_2 */
+#define EUR_CR_USE_CODE_BASE_2 0x0A14
+#define EUR_CR_USE_CODE_BASE_ADDR_02_MASK 0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_02_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_02_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_02_MASK 0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_02_SHIFT 25
+#define EUR_CR_USE_CODE_BASE_DM_02_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_3 */
+#define EUR_CR_USE_CODE_BASE_3 0x0A18
+#define EUR_CR_USE_CODE_BASE_ADDR_03_MASK 0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_03_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_03_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_03_MASK 0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_03_SHIFT 25
+#define EUR_CR_USE_CODE_BASE_DM_03_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_4 */
+#define EUR_CR_USE_CODE_BASE_4 0x0A1C
+#define EUR_CR_USE_CODE_BASE_ADDR_04_MASK 0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_04_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_04_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_04_MASK 0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_04_SHIFT 25
+#define EUR_CR_USE_CODE_BASE_DM_04_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_5 */
+#define EUR_CR_USE_CODE_BASE_5 0x0A20
+#define EUR_CR_USE_CODE_BASE_ADDR_05_MASK 0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_05_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_05_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_05_MASK 0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_05_SHIFT 25
+#define EUR_CR_USE_CODE_BASE_DM_05_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_6 */
+#define EUR_CR_USE_CODE_BASE_6 0x0A24
+#define EUR_CR_USE_CODE_BASE_ADDR_06_MASK 0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_06_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_06_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_06_MASK 0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_06_SHIFT 25
+#define EUR_CR_USE_CODE_BASE_DM_06_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_7 */
+#define EUR_CR_USE_CODE_BASE_7 0x0A28
+#define EUR_CR_USE_CODE_BASE_ADDR_07_MASK 0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_07_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_07_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_07_MASK 0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_07_SHIFT 25
+#define EUR_CR_USE_CODE_BASE_DM_07_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_8 */
+#define EUR_CR_USE_CODE_BASE_8 0x0A2C
+#define EUR_CR_USE_CODE_BASE_ADDR_08_MASK 0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_08_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_08_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_08_MASK 0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_08_SHIFT 25
+#define EUR_CR_USE_CODE_BASE_DM_08_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_9 */
+#define EUR_CR_USE_CODE_BASE_9 0x0A30
+#define EUR_CR_USE_CODE_BASE_ADDR_09_MASK 0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_09_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_09_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_09_MASK 0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_09_SHIFT 25
+#define EUR_CR_USE_CODE_BASE_DM_09_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_10 */
+#define EUR_CR_USE_CODE_BASE_10 0x0A34
+#define EUR_CR_USE_CODE_BASE_ADDR_10_MASK 0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_10_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_10_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_10_MASK 0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_10_SHIFT 25
+#define EUR_CR_USE_CODE_BASE_DM_10_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_11 */
+#define EUR_CR_USE_CODE_BASE_11 0x0A38
+#define EUR_CR_USE_CODE_BASE_ADDR_11_MASK 0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_11_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_11_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_11_MASK 0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_11_SHIFT 25
+#define EUR_CR_USE_CODE_BASE_DM_11_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_12 */
+#define EUR_CR_USE_CODE_BASE_12 0x0A3C
+#define EUR_CR_USE_CODE_BASE_ADDR_12_MASK 0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_12_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_12_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_12_MASK 0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_12_SHIFT 25
+#define EUR_CR_USE_CODE_BASE_DM_12_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_13 */
+#define EUR_CR_USE_CODE_BASE_13 0x0A40
+#define EUR_CR_USE_CODE_BASE_ADDR_13_MASK 0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_13_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_13_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_13_MASK 0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_13_SHIFT 25
+#define EUR_CR_USE_CODE_BASE_DM_13_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_14 */
+#define EUR_CR_USE_CODE_BASE_14 0x0A44
+#define EUR_CR_USE_CODE_BASE_ADDR_14_MASK 0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_14_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_14_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_14_MASK 0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_14_SHIFT 25
+#define EUR_CR_USE_CODE_BASE_DM_14_SIGNED 0
+/* Register EUR_CR_USE_CODE_BASE_15 */
+#define EUR_CR_USE_CODE_BASE_15 0x0A48
+#define EUR_CR_USE_CODE_BASE_ADDR_15_MASK 0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_15_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_15_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_15_MASK 0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_15_SHIFT 25
+#define EUR_CR_USE_CODE_BASE_DM_15_SIGNED 0
+/* Register EUR_CR_PDS_EXEC_BASE */
+#define EUR_CR_PDS_EXEC_BASE 0x0AB8
+#define EUR_CR_PDS_EXEC_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_PDS_EXEC_BASE_ADDR_SHIFT 20
+#define EUR_CR_PDS_EXEC_BASE_ADDR_SIGNED 0
+/* Register EUR_CR_EVENT_KICKER */
+#define EUR_CR_EVENT_KICKER 0x0AC4
+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT 4
+#define EUR_CR_EVENT_KICKER_ADDRESS_SIGNED 0
+/* Register EUR_CR_EVENT_KICK */
+#define EUR_CR_EVENT_KICK 0x0AC8
+#define EUR_CR_EVENT_KICK_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK_NOW_SHIFT 0
+#define EUR_CR_EVENT_KICK_NOW_SIGNED 0
+/* Register EUR_CR_EVENT_TIMER */
+#define EUR_CR_EVENT_TIMER 0x0ACC
+#define EUR_CR_EVENT_TIMER_ENABLE_MASK 0x01000000U
+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT 24
+#define EUR_CR_EVENT_TIMER_ENABLE_SIGNED 0
+#define EUR_CR_EVENT_TIMER_VALUE_MASK 0x00FFFFFFU
+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT 0
+#define EUR_CR_EVENT_TIMER_VALUE_SIGNED 0
+/* Register EUR_CR_PDS_INV0 */
+#define EUR_CR_PDS_INV0 0x0AD0
+#define EUR_CR_PDS_INV0_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV0_DSC_SHIFT 0
+#define EUR_CR_PDS_INV0_DSC_SIGNED 0
+/* Register EUR_CR_PDS_INV1 */
+#define EUR_CR_PDS_INV1 0x0AD4
+#define EUR_CR_PDS_INV1_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV1_DSC_SHIFT 0
+#define EUR_CR_PDS_INV1_DSC_SIGNED 0
+/* Register EUR_CR_PDS_INV3 */
+#define EUR_CR_PDS_INV3 0x0AD8
+#define EUR_CR_PDS_INV3_DSC_MASK 0x00000001U
+#define EUR_CR_PDS_INV3_DSC_SHIFT 0
+#define EUR_CR_PDS_INV3_DSC_SIGNED 0
+/* Register EUR_CR_PDS_INV_CSC */
+#define EUR_CR_PDS_INV_CSC 0x0AE0
+#define EUR_CR_PDS_INV_CSC_KICK_MASK 0x00000001U
+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT 0
+#define EUR_CR_PDS_INV_CSC_KICK_SIGNED 0
+/* Register EUR_CR_EVENT_KICK1 */
+#define EUR_CR_EVENT_KICK1 0x0AE4
+#define EUR_CR_EVENT_KICK1_NOW_MASK 0x000000FFU
+#define EUR_CR_EVENT_KICK1_NOW_SHIFT 0
+#define EUR_CR_EVENT_KICK1_NOW_SIGNED 0
+/* Register EUR_CR_EVENT_KICK2 */
+#define EUR_CR_EVENT_KICK2 0x0AE8
+#define EUR_CR_EVENT_KICK2_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK2_NOW_SHIFT 0
+#define EUR_CR_EVENT_KICK2_NOW_SIGNED 0
+/* Register EUR_CR_EVENT_KICK3 */
+#define EUR_CR_EVENT_KICK3 0x0AEC
+#define EUR_CR_EVENT_KICK3_NOW_MASK 0x00000001U
+#define EUR_CR_EVENT_KICK3_NOW_SHIFT 0
+#define EUR_CR_EVENT_KICK3_NOW_SIGNED 0
+/* Register EUR_CR_BIF_CTRL */
+#define EUR_CR_BIF_CTRL 0x0C00
+#define EUR_CR_BIF_CTRL_NOREORDER_MASK 0x00000001U
+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT 0
+#define EUR_CR_BIF_CTRL_NOREORDER_SIGNED 0
+#define EUR_CR_BIF_CTRL_PAUSE_MASK 0x00000002U
+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT 1
+#define EUR_CR_BIF_CTRL_PAUSE_SIGNED 0
+#define EUR_CR_BIF_CTRL_FLUSH_MASK 0x00000004U
+#define EUR_CR_BIF_CTRL_FLUSH_SHIFT 2
+#define EUR_CR_BIF_CTRL_FLUSH_SIGNED 0
+#define EUR_CR_BIF_CTRL_INVALDC_MASK 0x00000008U
+#define EUR_CR_BIF_CTRL_INVALDC_SHIFT 3
+#define EUR_CR_BIF_CTRL_INVALDC_SIGNED 0
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT 4
+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_MASK 0x00000100U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SHIFT 8
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_MASK 0x00000400U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SHIFT 10
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00000800U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 11
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00001000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 12
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00002000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 13
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00004000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 14
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SIGNED 0
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK 0x00008000U
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_SHIFT 15
+#define EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_SIGNED 0
+/* Register EUR_CR_BIF_INT_STAT */
+#define EUR_CR_BIF_INT_STAT 0x0C04
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_MASK 0x0000FFFFU
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_SHIFT 0
+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_SIGNED 0
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_MASK 0x00070000U
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_SHIFT 16
+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_SIGNED 0
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00080000U
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 19
+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SIGNED 0
+/* Register EUR_CR_BIF_FAULT */
+#define EUR_CR_BIF_FAULT 0x0C08
+#define EUR_CR_BIF_FAULT_CID_MASK 0x0000000FU
+#define EUR_CR_BIF_FAULT_CID_SHIFT 0
+#define EUR_CR_BIF_FAULT_CID_SIGNED 0
+#define EUR_CR_BIF_FAULT_SB_MASK 0x000001F0U
+#define EUR_CR_BIF_FAULT_SB_SHIFT 4
+#define EUR_CR_BIF_FAULT_SB_SIGNED 0
+#define EUR_CR_BIF_FAULT_ADDR_MASK 0xFFFFF000U
+#define EUR_CR_BIF_FAULT_ADDR_SHIFT 12
+#define EUR_CR_BIF_FAULT_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_TILE0 */
+#define EUR_CR_BIF_TILE0 0x0C0C
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE0_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE0_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE0_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE1 */
+#define EUR_CR_BIF_TILE1 0x0C10
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE1_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE1_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE1_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE2 */
+#define EUR_CR_BIF_TILE2 0x0C14
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE2_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE2_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE2_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE3 */
+#define EUR_CR_BIF_TILE3 0x0C18
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE3_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE3_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE3_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE4 */
+#define EUR_CR_BIF_TILE4 0x0C1C
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE4_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE4_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE4_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE5 */
+#define EUR_CR_BIF_TILE5 0x0C20
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE5_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE5_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE5_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE6 */
+#define EUR_CR_BIF_TILE6 0x0C24
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE6_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE6_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE6_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE7 */
+#define EUR_CR_BIF_TILE7 0x0C28
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE7_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE7_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE7_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE8 */
+#define EUR_CR_BIF_TILE8 0x0C2C
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE8_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE8_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE8_CFG_SIGNED 0
+/* Register EUR_CR_BIF_TILE9 */
+#define EUR_CR_BIF_TILE9 0x0C30
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_MASK 0x00000FFFU
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_SHIFT 0
+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_MASK 0x00FFF000U
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_SHIFT 12
+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_SIGNED 0
+#define EUR_CR_BIF_TILE9_CFG_MASK 0x0F000000U
+#define EUR_CR_BIF_TILE9_CFG_SHIFT 24
+#define EUR_CR_BIF_TILE9_CFG_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE1 */
+#define EUR_CR_BIF_DIR_LIST_BASE1 0x0C38
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE2 */
+#define EUR_CR_BIF_DIR_LIST_BASE2 0x0C3C
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE3 */
+#define EUR_CR_BIF_DIR_LIST_BASE3 0x0C40
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE4 */
+#define EUR_CR_BIF_DIR_LIST_BASE4 0x0C44
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE5 */
+#define EUR_CR_BIF_DIR_LIST_BASE5 0x0C48
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE6 */
+#define EUR_CR_BIF_DIR_LIST_BASE6 0x0C4C
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE7 */
+#define EUR_CR_BIF_DIR_LIST_BASE7 0x0C50
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE8 */
+#define EUR_CR_BIF_DIR_LIST_BASE8 0x0C54
+#define EUR_CR_BIF_DIR_LIST_BASE8_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE8_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE8_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE9 */
+#define EUR_CR_BIF_DIR_LIST_BASE9 0x0C58
+#define EUR_CR_BIF_DIR_LIST_BASE9_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE9_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE9_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE10 */
+#define EUR_CR_BIF_DIR_LIST_BASE10 0x0C5C
+#define EUR_CR_BIF_DIR_LIST_BASE10_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE10_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE10_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE11 */
+#define EUR_CR_BIF_DIR_LIST_BASE11 0x0C60
+#define EUR_CR_BIF_DIR_LIST_BASE11_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE11_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE11_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE12 */
+#define EUR_CR_BIF_DIR_LIST_BASE12 0x0C64
+#define EUR_CR_BIF_DIR_LIST_BASE12_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE12_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE12_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE13 */
+#define EUR_CR_BIF_DIR_LIST_BASE13 0x0C68
+#define EUR_CR_BIF_DIR_LIST_BASE13_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE13_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE13_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE14 */
+#define EUR_CR_BIF_DIR_LIST_BASE14 0x0C6C
+#define EUR_CR_BIF_DIR_LIST_BASE14_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE14_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE14_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE15 */
+#define EUR_CR_BIF_DIR_LIST_BASE15 0x0C70
+#define EUR_CR_BIF_DIR_LIST_BASE15_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE15_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE15_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_BANK_SET */
+#define EUR_CR_BIF_BANK_SET 0x0C74
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_MASK 0x00000001U
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_SHIFT 0
+#define EUR_CR_BIF_BANK_SET_SELECT_2D_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_MASK 0x0000000CU
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_SHIFT 2
+#define EUR_CR_BIF_BANK_SET_SELECT_3D_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_MASK 0x00000010U
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_SHIFT 4
+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_MASK 0x000000C0U
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_SHIFT 6
+#define EUR_CR_BIF_BANK_SET_SELECT_TA_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_MASK 0x00000100U
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_SHIFT 8
+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_SIGNED 0
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_MASK 0x00000200U
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_SHIFT 9
+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_SIGNED 0
+/* Register EUR_CR_BIF_BANK0 */
+#define EUR_CR_BIF_BANK0 0x0C78
+#define EUR_CR_BIF_BANK0_INDEX_EDM_MASK 0x0000000FU
+#define EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT 0
+#define EUR_CR_BIF_BANK0_INDEX_EDM_SIGNED 0
+#define EUR_CR_BIF_BANK0_INDEX_TA_MASK 0x000000F0U
+#define EUR_CR_BIF_BANK0_INDEX_TA_SHIFT 4
+#define EUR_CR_BIF_BANK0_INDEX_TA_SIGNED 0
+#define EUR_CR_BIF_BANK0_INDEX_HOST_MASK 0x00000F00U
+#define EUR_CR_BIF_BANK0_INDEX_HOST_SHIFT 8
+#define EUR_CR_BIF_BANK0_INDEX_HOST_SIGNED 0
+#define EUR_CR_BIF_BANK0_INDEX_3D_MASK 0x0000F000U
+#define EUR_CR_BIF_BANK0_INDEX_3D_SHIFT 12
+#define EUR_CR_BIF_BANK0_INDEX_3D_SIGNED 0
+#define EUR_CR_BIF_BANK0_INDEX_2D_MASK 0x000F0000U
+#define EUR_CR_BIF_BANK0_INDEX_2D_SHIFT 16
+#define EUR_CR_BIF_BANK0_INDEX_2D_SIGNED 0
+/* Register EUR_CR_BIF_BANK1 */
+#define EUR_CR_BIF_BANK1 0x0C7C
+#define EUR_CR_BIF_BANK1_INDEX_EDM_MASK 0x0000000FU
+#define EUR_CR_BIF_BANK1_INDEX_EDM_SHIFT 0
+#define EUR_CR_BIF_BANK1_INDEX_EDM_SIGNED 0
+#define EUR_CR_BIF_BANK1_INDEX_TA_MASK 0x000000F0U
+#define EUR_CR_BIF_BANK1_INDEX_TA_SHIFT 4
+#define EUR_CR_BIF_BANK1_INDEX_TA_SIGNED 0
+#define EUR_CR_BIF_BANK1_INDEX_HOST_MASK 0x00000F00U
+#define EUR_CR_BIF_BANK1_INDEX_HOST_SHIFT 8
+#define EUR_CR_BIF_BANK1_INDEX_HOST_SIGNED 0
+#define EUR_CR_BIF_BANK1_INDEX_3D_MASK 0x0000F000U
+#define EUR_CR_BIF_BANK1_INDEX_3D_SHIFT 12
+#define EUR_CR_BIF_BANK1_INDEX_3D_SIGNED 0
+#define EUR_CR_BIF_BANK1_INDEX_2D_MASK 0x000F0000U
+#define EUR_CR_BIF_BANK1_INDEX_2D_SHIFT 16
+#define EUR_CR_BIF_BANK1_INDEX_2D_SIGNED 0
+/* Register EUR_CR_BIF_DIR_LIST_BASE0 */
+#define EUR_CR_BIF_DIR_LIST_BASE0 0x0C84
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFFF00U
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 8
+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_TA_REQ_BASE */
+#define EUR_CR_BIF_TA_REQ_BASE 0x0C90
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_MEM_REQ_STAT */
+#define EUR_CR_BIF_MEM_REQ_STAT 0x0CA8
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK 0x000007FFU
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0
+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SIGNED 0
+/* Register EUR_CR_BIF_3D_REQ_BASE */
+#define EUR_CR_BIF_3D_REQ_BASE 0x0CAC
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_ZLS_REQ_BASE */
+#define EUR_CR_BIF_ZLS_REQ_BASE 0x0CB0
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK 0xFFF00000U
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT 20
+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SIGNED 0
+/* Register EUR_CR_BIF_BANK_STATUS */
+#define EUR_CR_BIF_BANK_STATUS 0x0CB4
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_MASK 0x00000001U
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_SHIFT 0
+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_SIGNED 0
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_MASK 0x00000002U
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_SHIFT 1
+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_SIGNED 0
+/* Register EUR_CR_BIF_36BIT_ADDRESSING */
+#define EUR_CR_BIF_36BIT_ADDRESSING 0x0CCC
+#define EUR_CR_BIF_36BIT_ADDRESSING_ENABLE_MASK 0x00000001U
+#define EUR_CR_BIF_36BIT_ADDRESSING_ENABLE_SHIFT 0
+#define EUR_CR_BIF_36BIT_ADDRESSING_ENABLE_SIGNED 0
+/* Register EUR_CR_BIF_TILE0_ADDR_EXT */
+#define EUR_CR_BIF_TILE0_ADDR_EXT 0x0CD0
+#define EUR_CR_BIF_TILE0_ADDR_EXT_MIN_MASK 0x000000FFU
+#define EUR_CR_BIF_TILE0_ADDR_EXT_MIN_SHIFT 0
+#define EUR_CR_BIF_TILE0_ADDR_EXT_MIN_SIGNED 0
+#define EUR_CR_BIF_TILE0_ADDR_EXT_MAX_MASK 0x0000FF00U
+#define EUR_CR_BIF_TILE0_ADDR_EXT_MAX_SHIFT 8
+#define EUR_CR_BIF_TILE0_ADDR_EXT_MAX_SIGNED 0
+/* Register EUR_CR_BIF_TILE1_ADDR_EXT */
+#define EUR_CR_BIF_TILE1_ADDR_EXT 0x0CD4
+#define EUR_CR_BIF_TILE1_ADDR_EXT_MIN_MASK 0x000000FFU
+#define EUR_CR_BIF_TILE1_ADDR_EXT_MIN_SHIFT 0
+#define EUR_CR_BIF_TILE1_ADDR_EXT_MIN_SIGNED 0
+#define EUR_CR_BIF_TILE1_ADDR_EXT_MAX_MASK 0x0000FF00U
+#define EUR_CR_BIF_TILE1_ADDR_EXT_MAX_SHIFT 8
+#define EUR_CR_BIF_TILE1_ADDR_EXT_MAX_SIGNED 0
+/* Register EUR_CR_BIF_TILE2_ADDR_EXT */
+#define EUR_CR_BIF_TILE2_ADDR_EXT 0x0CD8
+#define EUR_CR_BIF_TILE2_ADDR_EXT_MIN_MASK 0x000000FFU
+#define EUR_CR_BIF_TILE2_ADDR_EXT_MIN_SHIFT 0
+#define EUR_CR_BIF_TILE2_ADDR_EXT_MIN_SIGNED 0
+#define EUR_CR_BIF_TILE2_ADDR_EXT_MAX_MASK 0x0000FF00U
+#define EUR_CR_BIF_TILE2_ADDR_EXT_MAX_SHIFT 8
+#define EUR_CR_BIF_TILE2_ADDR_EXT_MAX_SIGNED 0
+/* Register EUR_CR_BIF_TILE3_ADDR_EXT */
+#define EUR_CR_BIF_TILE3_ADDR_EXT 0x0CDC
+#define EUR_CR_BIF_TILE3_ADDR_EXT_MIN_MASK 0x000000FFU
+#define EUR_CR_BIF_TILE3_ADDR_EXT_MIN_SHIFT 0
+#define EUR_CR_BIF_TILE3_ADDR_EXT_MIN_SIGNED 0
+#define EUR_CR_BIF_TILE3_ADDR_EXT_MAX_MASK 0x0000FF00U
+#define EUR_CR_BIF_TILE3_ADDR_EXT_MAX_SHIFT 8
+#define EUR_CR_BIF_TILE3_ADDR_EXT_MAX_SIGNED 0
+/* Register EUR_CR_BIF_TILE4_ADDR_EXT */
+#define EUR_CR_BIF_TILE4_ADDR_EXT 0x0CE0
+#define EUR_CR_BIF_TILE4_ADDR_EXT_MIN_MASK 0x000000FFU
+#define EUR_CR_BIF_TILE4_ADDR_EXT_MIN_SHIFT 0
+#define EUR_CR_BIF_TILE4_ADDR_EXT_MIN_SIGNED 0
+#define EUR_CR_BIF_TILE4_ADDR_EXT_MAX_MASK 0x0000FF00U
+#define EUR_CR_BIF_TILE4_ADDR_EXT_MAX_SHIFT 8
+#define EUR_CR_BIF_TILE4_ADDR_EXT_MAX_SIGNED 0
+/* Register EUR_CR_BIF_TILE5_ADDR_EXT */
+#define EUR_CR_BIF_TILE5_ADDR_EXT 0x0CE4
+#define EUR_CR_BIF_TILE5_ADDR_EXT_MIN_MASK 0x000000FFU
+#define EUR_CR_BIF_TILE5_ADDR_EXT_MIN_SHIFT 0
+#define EUR_CR_BIF_TILE5_ADDR_EXT_MIN_SIGNED 0
+#define EUR_CR_BIF_TILE5_ADDR_EXT_MAX_MASK 0x0000FF00U
+#define EUR_CR_BIF_TILE5_ADDR_EXT_MAX_SHIFT 8
+#define EUR_CR_BIF_TILE5_ADDR_EXT_MAX_SIGNED 0
+/* Register EUR_CR_BIF_TILE6_ADDR_EXT */
+#define EUR_CR_BIF_TILE6_ADDR_EXT 0x0CE8
+#define EUR_CR_BIF_TILE6_ADDR_EXT_MIN_MASK 0x000000FFU
+#define EUR_CR_BIF_TILE6_ADDR_EXT_MIN_SHIFT 0
+#define EUR_CR_BIF_TILE6_ADDR_EXT_MIN_SIGNED 0
+#define EUR_CR_BIF_TILE6_ADDR_EXT_MAX_MASK 0x0000FF00U
+#define EUR_CR_BIF_TILE6_ADDR_EXT_MAX_SHIFT 8
+#define EUR_CR_BIF_TILE6_ADDR_EXT_MAX_SIGNED 0
+/* Register EUR_CR_BIF_TILE7_ADDR_EXT */
+#define EUR_CR_BIF_TILE7_ADDR_EXT 0x0CEC
+#define EUR_CR_BIF_TILE7_ADDR_EXT_MIN_MASK 0x000000FFU
+#define EUR_CR_BIF_TILE7_ADDR_EXT_MIN_SHIFT 0
+#define EUR_CR_BIF_TILE7_ADDR_EXT_MIN_SIGNED 0
+#define EUR_CR_BIF_TILE7_ADDR_EXT_MAX_MASK 0x0000FF00U
+#define EUR_CR_BIF_TILE7_ADDR_EXT_MAX_SHIFT 8
+#define EUR_CR_BIF_TILE7_ADDR_EXT_MAX_SIGNED 0
+/* Register EUR_CR_BIF_TILE8_ADDR_EXT */
+#define EUR_CR_BIF_TILE8_ADDR_EXT 0x0CF0
+#define EUR_CR_BIF_TILE8_ADDR_EXT_MIN_MASK 0x000000FFU
+#define EUR_CR_BIF_TILE8_ADDR_EXT_MIN_SHIFT 0
+#define EUR_CR_BIF_TILE8_ADDR_EXT_MIN_SIGNED 0
+#define EUR_CR_BIF_TILE8_ADDR_EXT_MAX_MASK 0x0000FF00U
+#define EUR_CR_BIF_TILE8_ADDR_EXT_MAX_SHIFT 8
+#define EUR_CR_BIF_TILE8_ADDR_EXT_MAX_SIGNED 0
+/* Register EUR_CR_BIF_TILE9_ADDR_EXT */
+#define EUR_CR_BIF_TILE9_ADDR_EXT 0x0CF4
+#define EUR_CR_BIF_TILE9_ADDR_EXT_MIN_MASK 0x000000FFU
+#define EUR_CR_BIF_TILE9_ADDR_EXT_MIN_SHIFT 0
+#define EUR_CR_BIF_TILE9_ADDR_EXT_MIN_SIGNED 0
+#define EUR_CR_BIF_TILE9_ADDR_EXT_MAX_MASK 0x0000FF00U
+#define EUR_CR_BIF_TILE9_ADDR_EXT_MAX_SHIFT 8
+#define EUR_CR_BIF_TILE9_ADDR_EXT_MAX_SIGNED 0
+/* Register EUR_CR_BIF_CTRL_RDATA */
+#define EUR_CR_BIF_CTRL_RDATA 0x0CF8
+#define EUR_CR_BIF_CTRL_RDATA_LIMIT_MASK 0x000003FFU
+#define EUR_CR_BIF_CTRL_RDATA_LIMIT_SHIFT 0
+#define EUR_CR_BIF_CTRL_RDATA_LIMIT_SIGNED 0
+/* Table EUR_CR_USE_CODE_BASE */
+/* Register EUR_CR_USE_CODE_BASE */
+#define EUR_CR_USE_CODE_BASE(X) (0x0A0C + (4 * (X)))
+#define EUR_CR_USE_CODE_BASE_ADDR_MASK 0x01FFFFFFU
+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT 0
+#define EUR_CR_USE_CODE_BASE_ADDR_SIGNED 0
+#define EUR_CR_USE_CODE_BASE_DM_MASK 0x06000000U
+#define EUR_CR_USE_CODE_BASE_DM_SHIFT 25
+#define EUR_CR_USE_CODE_BASE_DM_SIGNED 0
+/* Number of entries in table EUR_CR_USE_CODE_BASE */
+#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16
+#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16
+
+#endif /* _SGX545DEFS_KM_H_ */
+
diff --git a/pvr-source/services4/srvkm/hwdefs/sgxdefs.h b/pvr-source/services4/srvkm/hwdefs/sgxdefs.h
new file mode 100644
index 0000000..ed24647
--- /dev/null
+++ b/pvr-source/services4/srvkm/hwdefs/sgxdefs.h
@@ -0,0 +1,112 @@
+/*************************************************************************/ /*!
+@Title SGX hw definitions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _SGXDEFS_H_
+#define _SGXDEFS_H_
+
+#include "sgxerrata.h"
+#include "sgxfeaturedefs.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(SGX543)
+#if defined(FIX_HW_BRN_29954)
+#include "sgx543_v1.164defs.h"
+#else
+#include "sgx543defs.h"
+#endif
+#else
+#if defined(SGX544)
+#include "sgx544defs.h"
+#else
+#if defined(SGX545)
+#include "sgx545defs.h"
+#else
+#if defined(SGX531)
+#include "sgx531defs.h"
+#else
+#if defined(SGX554)
+#include "sgx554defs.h"
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+
+#if defined(SGX_FEATURE_MP)
+#if defined(SGX554)
+#include "sgxmpplusdefs.h"
+#else
+#include "sgxmpdefs.h"
+#endif /* SGX554 */
+#else /* SGX_FEATURE_MP */
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+#include "mnemedefs.h"
+#endif
+#endif /* SGX_FEATURE_MP */
+
+/*****************************************************************************
+ Core specific defines.
+*****************************************************************************/
+
+#endif /* _SGXDEFS_H_ */
+
+/*****************************************************************************
+ End of file (sgxdefs.h)
+*****************************************************************************/
diff --git a/pvr-source/services4/srvkm/hwdefs/sgxerrata.h b/pvr-source/services4/srvkm/hwdefs/sgxerrata.h
new file mode 100644
index 0000000..711e356
--- /dev/null
+++ b/pvr-source/services4/srvkm/hwdefs/sgxerrata.h
@@ -0,0 +1,518 @@
+/*************************************************************************/ /*!
+@Title SGX HW errata definitions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Specifies associations between SGX core revisions
+ and SW workarounds required to fix HW errata that exist
+ in specific core revisions
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef _SGXERRATA_KM_H_
+#define _SGXERRATA_KM_H_
+
+/* ignore warnings about unrecognised preprocessing directives in conditional inclusion directives */
+/* PRQA S 3115 ++ */
+
+#if defined(SGX520) && !defined(SGX_CORE_DEFINED)
+ /* define the _current_ SGX520 RTL head revision */
+ #define SGX_CORE_REV_HEAD 0
+ #if defined(USE_SGX_CORE_REV_HEAD)
+ /* build config selects Core Revision to be the Head */
+ #define SGX_CORE_REV SGX_CORE_REV_HEAD
+ #endif
+
+ #if SGX_CORE_REV == 111
+ #else
+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD
+ /* RTL head - no BRNs to apply */
+ #else
+ #error "sgxerrata.h: SGX520 Core Revision unspecified"
+ #endif
+ #endif
+ /* signal that the Core Version has a valid definition */
+ #define SGX_CORE_DEFINED
+#endif
+
+#if defined(SGX530) && !defined(SGX_CORE_DEFINED)
+ /* define the _current_ SGX530 RTL head revision */
+ #define SGX_CORE_REV_HEAD 0
+ #if defined(USE_SGX_CORE_REV_HEAD)
+ /* build config selects Core Revision to be the Head */
+ #define SGX_CORE_REV SGX_CORE_REV_HEAD
+ #endif
+
+ #if SGX_CORE_REV == 120
+ #define FIX_HW_BRN_22934/* Workaround in sgx featuredefs */
+ #define FIX_HW_BRN_28889/* Workaround in services (srvkm) */
+ #else
+ #if SGX_CORE_REV == 121
+ #define FIX_HW_BRN_22934/* Workaround in sgx featuredefs */
+ #define FIX_HW_BRN_28889/* Workaround in services (srvkm) */
+ #else
+ #if SGX_CORE_REV == 125
+ #define FIX_HW_BRN_22934/* Workaround in sgx featuredefs */
+ #define FIX_HW_BRN_28889/* Workaround in services (srvkm) */
+ #else
+ #if SGX_CORE_REV == 130
+ #define FIX_HW_BRN_22934/* Workaround in sgx featuredefs */
+ #define FIX_HW_BRN_28889/* Workaround in services (srvkm) */
+ #else
+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD
+ /* RTL head - no BRNs to apply */
+ #else
+ #error "sgxerrata.h: SGX530 Core Revision unspecified"
+ #endif
+ #endif
+ #endif
+#endif
+ #endif
+ /* signal that the Core Version has a valid definition */
+ #define SGX_CORE_DEFINED
+#endif
+
+#if defined(SGX531) && !defined(SGX_CORE_DEFINED)
+ /* define the _current_ SGX531 RTL head revision */
+ #define SGX_CORE_REV_HEAD 0
+ #if defined(USE_SGX_CORE_REV_HEAD)
+ /* build config selects Core Revision to be the Head */
+ #define SGX_CORE_REV SGX_CORE_REV_HEAD
+ #endif
+
+ #if SGX_CORE_REV == 101
+ #define FIX_HW_BRN_26620/* Workaround in services (srvkm) */
+ #define FIX_HW_BRN_28011/* Workaround in services (srvkm) */
+ #define FIX_HW_BRN_34028/* Workaround in services (srvkm) */
+ #else
+ #if SGX_CORE_REV == 110
+ #define FIX_HW_BRN_34028/* Workaround in services (srvkm) */
+ #else
+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD
+ /* RTL head - no BRNs to apply */
+ #else
+ #error "sgxerrata.h: SGX531 Core Revision unspecified"
+ #endif
+ #endif
+ #endif
+ /* signal that the Core Version has a valid definition */
+ #define SGX_CORE_DEFINED
+#endif
+
+#if (defined(SGX535) || defined(SGX535_V1_1)) && !defined(SGX_CORE_DEFINED)
+ /* define the _current_ SGX535 RTL head revision */
+ #define SGX_CORE_REV_HEAD 0
+ #if defined(USE_SGX_CORE_REV_HEAD)
+ /* build config selects Core Revision to be the Head */
+ #define SGX_CORE_REV SGX_CORE_REV_HEAD
+ #endif
+
+ #if SGX_CORE_REV == 121
+ #define FIX_HW_BRN_22934/* Workaround in sgx featuredefs */
+ #define FIX_HW_BRN_23944/* Workaround in code (services) */
+ #define FIX_HW_BRN_23410/* Workaround in code (services) and ucode */
+ #else
+ #if SGX_CORE_REV == 126
+ #define FIX_HW_BRN_22934/* Workaround in sgx featuredefs */
+ #else
+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD
+ /* RTL head - no BRNs to apply */
+ #else
+ #error "sgxerrata.h: SGX535 Core Revision unspecified"
+
+ #endif
+ #endif
+ #endif
+ /* signal that the Core Version has a valid definition */
+ #define SGX_CORE_DEFINED
+#endif
+
+#if defined(SGX540) && !defined(SGX_CORE_DEFINED)
+ /* define the _current_ SGX540 RTL head revision */
+ #define SGX_CORE_REV_HEAD 0
+ #if defined(USE_SGX_CORE_REV_HEAD)
+ /* build config selects Core Revision to be the Head */
+ #define SGX_CORE_REV SGX_CORE_REV_HEAD
+ #endif
+
+ #if SGX_CORE_REV == 101
+ #define FIX_HW_BRN_25499/* Workaround in sgx featuredefs */
+ #define FIX_HW_BRN_25503/* Workaround in code (services) */
+ #define FIX_HW_BRN_26620/* Workaround in services (srvkm) */
+ #define FIX_HW_BRN_28011/* Workaround in services (srvkm) */
+ #define FIX_HW_BRN_34028/* Workaround in services (srvkm) */
+ #else
+ #if SGX_CORE_REV == 110
+ #define FIX_HW_BRN_25503/* Workaround in code (services) */
+ #define FIX_HW_BRN_26620/* Workaround in services (srvkm) */
+ #define FIX_HW_BRN_28011/* Workaround in services (srvkm) */
+ #define FIX_HW_BRN_34028/* Workaround in services (srvkm) */
+ #else
+ #if SGX_CORE_REV == 120
+ #define FIX_HW_BRN_26620/* Workaround in services (srvkm) */
+ #define FIX_HW_BRN_28011/* Workaround in services (srvkm) */
+ #define FIX_HW_BRN_34028/* Workaround in services (srvkm) */
+ #else
+ #if SGX_CORE_REV == 121
+ #define FIX_HW_BRN_28011/* Workaround in services (srvkm) */
+ #define FIX_HW_BRN_34028/* Workaround in services (srvkm) */
+ #else
+ #if SGX_CORE_REV == 130
+ #define FIX_HW_BRN_34028/* Workaround in services (srvkm) */
+ #else
+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD
+ /* RTL head - no BRNs to apply */
+ #else
+ #error "sgxerrata.h: SGX540 Core Revision unspecified"
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ /* signal that the Core Version has a valid definition */
+ #define SGX_CORE_DEFINED
+#endif
+
+
+#if defined(SGX543) && !defined(SGX_CORE_DEFINED)
+ /* define the _current_ SGX543 RTL head revision */
+ #define SGX_CORE_REV_HEAD 0
+ #if defined(USE_SGX_CORE_REV_HEAD)
+ /* build config selects Core Revision to be the Head */
+ #define SGX_CORE_REV SGX_CORE_REV_HEAD
+ #endif
+
+ #if SGX_CORE_REV == 122
+ #define FIX_HW_BRN_29954/* turns off regbank split feature */
+ #define FIX_HW_BRN_29997/* workaround in services */
+ #define FIX_HW_BRN_30954/* workaround in services */
+ #define FIX_HW_BRN_31093/* workaround in services */
+ #define FIX_HW_BRN_31195/* workaround in services */
+ #define FIX_HW_BRN_31272/* workaround in services (srvclient) and uKernel */
+ #define FIX_HW_BRN_31278/* disabled prefetching in MMU */
+ #define FIX_HW_BRN_31542/* workaround in uKernel and Services */
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31559/* workaround in services and uKernel */
+ #endif
+ #define FIX_HW_BRN_31620/* workaround in services */
+ #define FIX_HW_BRN_31780/* workaround in uKernel */
+ #define FIX_HW_BRN_32044 /* workaround in uKernel, services and client drivers */
+ #define FIX_HW_BRN_32085 /* workaround in services: prefetch fix applied, investigating PT based fix */
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657/* workaround in ukernel*/
+ #endif
+ #define FIX_HW_BRN_33920/* workaround in ukernel */
+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */
+ /* add BRNs here */
+ #else
+ #if SGX_CORE_REV == 1221
+ #define FIX_HW_BRN_29954/* turns off regbank split feature */
+ #define FIX_HW_BRN_31195/* workaround in services */
+ #define FIX_HW_BRN_31272/* workaround in services (srvclient) and uKernel */
+ #define FIX_HW_BRN_31278/* disabled prefetching in MMU */
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31559/* workaround in services and uKernel */
+ #endif
+ #define FIX_HW_BRN_31542/* workaround in uKernel and Services */
+ #define FIX_HW_BRN_31671/* workaround in uKernel */
+ #define FIX_HW_BRN_31780/* workaround in uKernel */
+ #define FIX_HW_BRN_32044/* workaround in uKernel, services and client drivers */
+ #define FIX_HW_BRN_32085 /* workaround in services: prefetch fix applied, investigating PT based fix */
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657/* workaround in ukernel*/
+ #endif
+ #define FIX_HW_BRN_33920/* workaround in ukernel */
+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */
+ /* add BRNs here */
+ #else
+ #if SGX_CORE_REV == 141
+ #define FIX_HW_BRN_29954/* turns off regbank split feature */
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31559/* workaround in services and uKernel */
+ #endif
+ #define FIX_HW_BRN_31671 /* workaround in uKernel */
+ #define FIX_HW_BRN_31780/* workaround in uKernel */
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657/* workaround in ukernel*/
+ #endif
+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */
+ /* add BRNs here */
+ #else
+ #if SGX_CORE_REV == 142
+ #define FIX_HW_BRN_29954/* turns off regbank split feature */
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31559/* workaround in services and uKernel */
+ #endif
+ #define FIX_HW_BRN_31671 /* workaround in uKernel */
+ #define FIX_HW_BRN_31780/* workaround in uKernel */
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657/* workaround in ukernel*/
+ #endif
+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */
+ /* add BRNs here */
+ #else
+ #if SGX_CORE_REV == 2111
+ #define FIX_HW_BRN_30982 /* workaround in uKernel and services */
+ #define FIX_HW_BRN_31093/* workaround in services */
+ #define FIX_HW_BRN_31195/* workaround in services */
+ #define FIX_HW_BRN_31272/* workaround in services (srvclient) and uKernel */
+ #define FIX_HW_BRN_31278/* disabled prefetching in MMU */
+ #define FIX_HW_BRN_31542/* workaround in uKernel and Services */
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31559/* workaround in services and uKernel */
+ #endif
+ #define FIX_HW_BRN_31620/* workaround in services */
+ #define FIX_HW_BRN_31780/* workaround in uKernel */
+ #define FIX_HW_BRN_32044 /* workaround in uKernel, services and client drivers */
+ #define FIX_HW_BRN_32085 /* workaround in services: prefetch fix applied, investigating PT based fix */
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657/* workaround in ukernel*/
+ #endif
+ #define FIX_HW_BRN_33920/* workaround in ukernel */
+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */
+ /* add BRNs here */
+ #else
+ #if SGX_CORE_REV == 213
+ #define FIX_HW_BRN_31272/* workaround in services (srvclient) and uKernel */
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31559/* workaround in services and uKernel */
+ #endif
+ #define FIX_HW_BRN_31671 /* workaround in uKernel */
+ #define FIX_HW_BRN_31780/* workaround in uKernel */
+ #define FIX_HW_BRN_32085 /* workaround in services: prefetch fix applied, investigating PT based fix */
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657/* workaround in ukernel*/
+ #endif
+ #define FIX_HW_BRN_33920/* workaround in ukernel */
+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */
+ /* add BRNs here */
+ #else
+ #if SGX_CORE_REV == 216
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657/* workaround in ukernel*/
+ #endif
+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */
+ #else
+ #if SGX_CORE_REV == 302
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657/* workaround in ukernel*/
+ #endif
+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */
+ #else
+ #if SGX_CORE_REV == 303
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657/* workaround in ukernel*/
+ #endif
+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */
+ #else
+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657/* workaround in ukernel*/
+ #endif
+ #else
+ #error "sgxerrata.h: SGX543 Core Revision unspecified"
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ /* signal that the Core Version has a valid definition */
+ #define SGX_CORE_DEFINED
+#endif
+
+#if defined(SGX544) && !defined(SGX_CORE_DEFINED)
+ /* define the _current_ SGX544 RTL head revision */
+ #define SGX_CORE_REV_HEAD 0
+ #if defined(USE_SGX_CORE_REV_HEAD)
+ /* build config selects Core Revision to be the Head */
+ #define SGX_CORE_REV SGX_CORE_REV_HEAD
+ #endif
+
+ #if SGX_CORE_REV == 104
+ #define FIX_HW_BRN_29954/* turns off regbank split feature */
+ #define FIX_HW_BRN_31093/* workaround in services */
+ #define FIX_HW_BRN_31195/* workaround in services */
+ #define FIX_HW_BRN_31272/* workaround in services (srvclient) and uKernel */
+ #define FIX_HW_BRN_31278/* disabled prefetching in MMU */
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31559/* workaround in services and uKernel */
+ #endif
+ #define FIX_HW_BRN_31542 /* workaround in uKernel and Services */
+ #define FIX_HW_BRN_31620/* workaround in services */
+ #define FIX_HW_BRN_31671 /* workaround in uKernel */
+ #define FIX_HW_BRN_31780/* workaround in uKernel */
+ #define FIX_HW_BRN_32044 /* workaround in uKernel, services and client drivers */
+ #define FIX_HW_BRN_32085 /* workaround in services: prefetch fix applied, investigating PT based fix */
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657/* workaround in ukernel*/
+ #endif
+ #define FIX_HW_BRN_33920/* workaround in ukernel */
+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */
+ #else
+ #if SGX_CORE_REV == 105
+ #if defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_31559/* workaround in services and uKernel */
+ #endif
+ #define FIX_HW_BRN_31780/* workaround in uKernel */
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657/* workaround in ukernel*/
+ #endif
+ #define FIX_HW_BRN_33920/* workaround in ukernel */
+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */
+ #else
+ #if SGX_CORE_REV == 112
+ #define FIX_HW_BRN_31272/* workaround in services (srvclient) and uKernel */
+ #define FIX_HW_BRN_33920/* workaround in ukernel */
+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */
+ #else
+ #if SGX_CORE_REV == 114
+ #define FIX_HW_BRN_31780/* workaround in uKernel */
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657/* workaround in ukernel*/
+ #endif
+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */
+ #else
+ #if SGX_CORE_REV == 115
+ #define FIX_HW_BRN_31780/* workaround in uKernel */
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657/* workaround in ukernel*/
+ #endif
+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */
+ #else
+ #if SGX_CORE_REV == 116
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657/* workaround in ukernel */
+ #endif
+ #define FIX_HW_BRN_33809/* workaround in kernel (enable burst combiner) */
+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */
+ #else
+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657/* workaround in ukernel*/
+ #endif
+ #else
+ #error "sgxerrata.h: SGX544 Core Revision unspecified"
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ /* signal that the Core Version has a valid definition */
+ #define SGX_CORE_DEFINED
+#endif
+
+#if defined(SGX545) && !defined(SGX_CORE_DEFINED)
+ /* define the _current_ SGX545 RTL head revision */
+ #define SGX_CORE_REV_HEAD 0
+ #if defined(USE_SGX_CORE_REV_HEAD)
+ /* build config selects Core Revision to be the Head */
+ #define SGX_CORE_REV SGX_CORE_REV_HEAD
+ #endif
+
+ #if SGX_CORE_REV == 109
+ #define FIX_HW_BRN_29702/* Workaround in services */
+ #define FIX_HW_BRN_29823/* Workaround in services */
+ #define FIX_HW_BRN_31939/* workaround in uKernel */
+ #else
+ #if SGX_CORE_REV == 10131
+ #else
+ #if SGX_CORE_REV == 1014
+ #else
+ #if SGX_CORE_REV == 10141
+ #else
+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD
+ /* RTL head - no BRNs to apply */
+ #else
+ #error "sgxerrata.h: SGX545 Core Revision unspecified"
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ /* signal that the Core Version has a valid definition */
+ #define SGX_CORE_DEFINED
+#endif
+
+#if defined(SGX554) && !defined(SGX_CORE_DEFINED)
+ /* define the _current_ SGX554 RTL head revision */
+ #define SGX_CORE_REV_HEAD 0
+ #if defined(USE_SGX_CORE_REV_HEAD)
+ /* build config selects Core Revision to be the Head */
+ #define SGX_CORE_REV SGX_CORE_REV_HEAD
+ #endif
+
+ #if SGX_CORE_REV == 1251
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657/* workaround in ukernel*/
+ #endif
+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */
+ /* add BRNs here */
+ #else
+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP)
+ #define FIX_HW_BRN_33657/* workaround in ukernel*/
+ #endif
+ #else
+ #error "sgxerrata.h: SGX554 Core Revision unspecified"
+ #endif
+ #endif
+ /* signal that the Core Version has a valid definition */
+ #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
+
+/* restore warning */
+/* PRQA S 3115 -- */
+
+#endif /* _SGXERRATA_KM_H_ */
+
+/******************************************************************************
+ End of file (sgxerrata.h)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/hwdefs/sgxfeaturedefs.h b/pvr-source/services4/srvkm/hwdefs/sgxfeaturedefs.h
new file mode 100644
index 0000000..3e3a116
--- /dev/null
+++ b/pvr-source/services4/srvkm/hwdefs/sgxfeaturedefs.h
@@ -0,0 +1,274 @@
+/*************************************************************************/ /*!
+@Title SGX fexture definitions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#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_NUM_USE_PIPES (1)
+ #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_NUM_USE_PIPES (2)
+ #define SGX_FEATURE_AUTOCLOCKGATING
+#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_NUM_USE_PIPES (2)
+ #define SGX_FEATURE_AUTOCLOCKGATING
+ #define SGX_FEATURE_MULTI_EVENT_KICK
+#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_NUM_USE_PIPES (2)
+ #define SGX_FEATURE_AUTOCLOCKGATING
+ #define SUPPORT_SGX_GENERAL_MAPPING_HEAP
+ #define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE
+#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_NUM_USE_PIPES (4)
+ #define SGX_FEATURE_AUTOCLOCKGATING
+ #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_NUM_USE_PIPES (4)
+ #define SGX_FEATURE_AUTOCLOCKGATING
+ #define SGX_FEATURE_MONOLITHIC_UKERNEL
+ #define SGX_FEATURE_MULTI_EVENT_KICK
+ #define SGX_FEATURE_DATA_BREAKPOINTS
+ #define SGX_FEATURE_PERPIPE_BKPT_REGS
+ #define SGX_FEATURE_PERPIPE_BKPT_REGS_NUMPIPES (2)
+ #define SGX_FEATURE_2D_HARDWARE
+ #define SGX_FEATURE_PTLA
+ #define SGX_FEATURE_EXTENDED_PERF_COUNTERS
+ #define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING)
+ #if defined(SGX_FEATURE_MP)
+ #define SGX_FEATURE_MASTER_VDM_CONTEXT_SWITCH
+ #endif
+ #define SGX_FEATURE_SLAVE_VDM_CONTEXT_SWITCH
+ #define SGX_FEATURE_SW_ISP_CONTEXT_SWITCH
+ #endif
+#else
+#if defined(SGX544)
+ #define SGX_CORE_FRIENDLY_NAME "SGX544"
+ #define SGX_CORE_ID SGX_CORE_ID_544
+ #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_NUM_USE_PIPES (4)
+ #define SGX_FEATURE_AUTOCLOCKGATING
+ #define SGX_FEATURE_MONOLITHIC_UKERNEL
+ #define SGX_FEATURE_MULTI_EVENT_KICK
+// #define SGX_FEATURE_DATA_BREAKPOINTS
+// #define SGX_FEATURE_PERPIPE_BKPT_REGS
+// #define SGX_FEATURE_PERPIPE_BKPT_REGS_NUMPIPES (2)
+// #define SGX_FEATURE_2D_HARDWARE
+// #define SGX_FEATURE_PTLA
+ #define SGX_FEATURE_EXTENDED_PERF_COUNTERS
+ #define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING)
+ #if defined(SGX_FEATURE_MP)
+ #define SGX_FEATURE_MASTER_VDM_CONTEXT_SWITCH
+ #define SGX_FEATURE_SLAVE_VDM_CONTEXT_SWITCH
+ #endif
+ #define SGX_FEATURE_SW_ISP_CONTEXT_SWITCH
+ #endif
+#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_VOLUME_TEXTURES
+ #define SGX_FEATURE_HOST_ALLOC_FROM_DPM
+ #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_NUM_PDS_PIPES (2)
+ #define SGX_FEATURE_NATIVE_BACKWARD_BLIT
+ #define SGX_FEATURE_MAX_TA_RENDER_TARGETS (512)
+ #define SGX_FEATURE_SECONDARY_REQUIRES_USE_KICK
+ #define SGX_FEATURE_WRITEBACK_DCU
+ //FIXME: this is defined in the build config for now
+ //#define SGX_FEATURE_36BIT_MMU
+ #define SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS
+ #define SGX_FEATURE_MULTI_EVENT_KICK
+ #define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING)
+ #define SGX_FEATURE_SW_ISP_CONTEXT_SWITCH
+ #endif
+#else
+#if defined(SGX554)
+ #define SGX_CORE_FRIENDLY_NAME "SGX554"
+ #define SGX_CORE_ID SGX_CORE_ID_554
+ #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_NUM_USE_PIPES (8)
+ #define SGX_FEATURE_AUTOCLOCKGATING
+ #define SGX_FEATURE_MONOLITHIC_UKERNEL
+ #define SGX_FEATURE_MULTI_EVENT_KICK
+// #define SGX_FEATURE_DATA_BREAKPOINTS
+// #define SGX_FEATURE_PERPIPE_BKPT_REGS
+// #define SGX_FEATURE_PERPIPE_BKPT_REGS_NUMPIPES (2)
+ #define SGX_FEATURE_2D_HARDWARE
+ #define SGX_FEATURE_PTLA
+ #define SGX_FEATURE_EXTENDED_PERF_COUNTERS
+ #define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE
+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING)
+ #if defined(SGX_FEATURE_MP)
+ #define SGX_FEATURE_MASTER_VDM_CONTEXT_SWITCH
+ #endif
+ #define SGX_FEATURE_SLAVE_VDM_CONTEXT_SWITCH
+ #define SGX_FEATURE_SW_ISP_CONTEXT_SWITCH
+ #endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+
+#if defined(SGX_FEATURE_SLAVE_VDM_CONTEXT_SWITCH) \
+ || defined(SGX_FEATURE_MASTER_VDM_CONTEXT_SWITCH)
+/* Enable the define so common code for HW VDMCS code is compiled */
+#define SGX_FEATURE_VDM_CONTEXT_SWITCH
+#endif
+
+/*
+ 'switch-off' features if defined BRNs affect the feature
+*/
+
+#if defined(FIX_HW_BRN_27266)
+#undef SGX_FEATURE_36BIT_MMU
+#endif
+
+#if defined(FIX_HW_BRN_22934) \
+ || defined(FIX_HW_BRN_25499)
+#undef SGX_FEATURE_MULTI_EVENT_KICK
+#endif
+
+#if defined(SGX_FEATURE_SYSTEM_CACHE)
+ #if defined(SGX_FEATURE_36BIT_MMU)
+ #error SGX_FEATURE_SYSTEM_CACHE is incompatible with SGX_FEATURE_36BIT_MMU
+ #endif
+ #if defined(FIX_HW_BRN_26620) && !defined(SGX_FEATURE_MULTI_EVENT_KICK)
+ #define SGX_BYPASS_SYSTEM_CACHE
+ #endif
+#endif
+
+#if defined(FIX_HW_BRN_29954)
+#undef SGX_FEATURE_PERPIPE_BKPT_REGS
+#endif
+
+#if defined(FIX_HW_BRN_31620)
+#undef SGX_FEATURE_MULTIPLE_MEM_CONTEXTS
+#undef SGX_FEATURE_BIF_NUM_DIRLISTS
+#endif
+
+/*
+ Derive other definitions:
+*/
+
+/* define default MP core count */
+#if defined(SGX_FEATURE_MP)
+#if defined(SGX_FEATURE_MP_CORE_COUNT_TA) && defined(SGX_FEATURE_MP_CORE_COUNT_3D)
+#if (SGX_FEATURE_MP_CORE_COUNT_TA > SGX_FEATURE_MP_CORE_COUNT_3D)
+#error Number of TA cores larger than number of 3D cores not supported in current driver
+#endif /* (SGX_FEATURE_MP_CORE_COUNT_TA > SGX_FEATURE_MP_CORE_COUNT_3D) */
+#else
+#if defined(SGX_FEATURE_MP_CORE_COUNT)
+#define SGX_FEATURE_MP_CORE_COUNT_TA (SGX_FEATURE_MP_CORE_COUNT)
+#define SGX_FEATURE_MP_CORE_COUNT_3D (SGX_FEATURE_MP_CORE_COUNT)
+#else
+#error Either SGX_FEATURE_MP_CORE_COUNT or \
+both SGX_FEATURE_MP_CORE_COUNT_TA and SGX_FEATURE_MP_CORE_COUNT_3D \
+must be defined when SGX_FEATURE_MP is defined
+#endif /* SGX_FEATURE_MP_CORE_COUNT */
+#endif /* defined(SGX_FEATURE_MP_CORE_COUNT_TA) && defined(SGX_FEATURE_MP_CORE_COUNT_3D) */
+#else
+#define SGX_FEATURE_MP_CORE_COUNT (1)
+#define SGX_FEATURE_MP_CORE_COUNT_TA (1)
+#define SGX_FEATURE_MP_CORE_COUNT_3D (1)
+#endif /* SGX_FEATURE_MP */
+
+#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && !defined(SUPPORT_SGX_PRIORITY_SCHEDULING)
+#define SUPPORT_SGX_PRIORITY_SCHEDULING
+#endif
+
+#include "img_types.h"
+
+/******************************************************************************
+ End of file (sgxfeaturedefs.h)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/hwdefs/sgxmmu.h b/pvr-source/services4/srvkm/hwdefs/sgxmmu.h
new file mode 100644
index 0000000..a6a907a
--- /dev/null
+++ b/pvr-source/services4/srvkm/hwdefs/sgxmmu.h
@@ -0,0 +1,99 @@
+/*************************************************************************/ /*!
+@Title SGX MMU defines
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Provides SGX MMU declarations and macros
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__SGXMMU_KM_H__)
+#define __SGXMMU_KM_H__
+
+/* to be implemented */
+
+/* SGX MMU maps 4Kb pages */
+#define SGX_MMU_PAGE_SHIFT (12)
+#define SGX_MMU_PAGE_SIZE (1U<<SGX_MMU_PAGE_SHIFT)
+#define SGX_MMU_PAGE_MASK (SGX_MMU_PAGE_SIZE - 1U)
+
+/* PD details */
+#define SGX_MMU_PD_SHIFT (10)
+#define SGX_MMU_PD_SIZE (1U<<SGX_MMU_PD_SHIFT)
+#define SGX_MMU_PD_MASK (0xFFC00000U)
+
+/* PD Entry details */
+#if defined(SGX_FEATURE_36BIT_MMU)
+ #define SGX_MMU_PDE_ADDR_MASK (0xFFFFFF00U)
+ #define SGX_MMU_PDE_ADDR_ALIGNSHIFT (4)
+#else
+ #define SGX_MMU_PDE_ADDR_MASK (0xFFFFF000U)
+ #define SGX_MMU_PDE_ADDR_ALIGNSHIFT (0)
+#endif
+#define SGX_MMU_PDE_VALID (0x00000001U)
+/* variable page size control field */
+#define SGX_MMU_PDE_PAGE_SIZE_4K (0x00000000U)
+#define SGX_MMU_PDE_PAGE_SIZE_16K (0x00000002U)
+#define SGX_MMU_PDE_PAGE_SIZE_64K (0x00000004U)
+#define SGX_MMU_PDE_PAGE_SIZE_256K (0x00000006U)
+#define SGX_MMU_PDE_PAGE_SIZE_1M (0x00000008U)
+#define SGX_MMU_PDE_PAGE_SIZE_4M (0x0000000AU)
+#define SGX_MMU_PDE_PAGE_SIZE_MASK (0x0000000EU)
+
+/* PT details */
+#define SGX_MMU_PT_SHIFT (10)
+#define SGX_MMU_PT_SIZE (1U<<SGX_MMU_PT_SHIFT)
+#define SGX_MMU_PT_MASK (0x003FF000U)
+
+/* PT Entry details */
+#if defined(SGX_FEATURE_36BIT_MMU)
+ #define SGX_MMU_PTE_ADDR_MASK (0xFFFFFF00U)
+ #define SGX_MMU_PTE_ADDR_ALIGNSHIFT (4)
+#else
+ #define SGX_MMU_PTE_ADDR_MASK (0xFFFFF000U)
+ #define SGX_MMU_PTE_ADDR_ALIGNSHIFT (0)
+#endif
+#define SGX_MMU_PTE_VALID (0x00000001U)
+#define SGX_MMU_PTE_WRITEONLY (0x00000002U)
+#define SGX_MMU_PTE_READONLY (0x00000004U)
+#define SGX_MMU_PTE_CACHECONSISTENT (0x00000008U)
+#define SGX_MMU_PTE_EDMPROTECT (0x00000010U)
+
+#endif /* __SGXMMU_KM_H__ */
+
+/*****************************************************************************
+ End of file (sgxmmu.h)
+*****************************************************************************/
diff --git a/pvr-source/services4/srvkm/hwdefs/sgxmpdefs.h b/pvr-source/services4/srvkm/hwdefs/sgxmpdefs.h
new file mode 100644
index 0000000..4b9649f
--- /dev/null
+++ b/pvr-source/services4/srvkm/hwdefs/sgxmpdefs.h
@@ -0,0 +1,365 @@
+/*************************************************************************/ /*!
+@Title Hardware defs for SGXMP.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _SGXMPDEFS_KM_H_
+#define _SGXMPDEFS_KM_H_
+
+/* Register EUR_CR_MASTER_BIF_CTRL */
+#define EUR_CR_MASTER_BIF_CTRL 0x4C00
+#define EUR_CR_MASTER_BIF_CTRL_NOREORDER_MASK 0x00000001U
+#define EUR_CR_MASTER_BIF_CTRL_NOREORDER_SHIFT 0
+#define EUR_CR_MASTER_BIF_CTRL_NOREORDER_SIGNED 0
+#define EUR_CR_MASTER_BIF_CTRL_PAUSE_MASK 0x00000002U
+#define EUR_CR_MASTER_BIF_CTRL_PAUSE_SHIFT 1
+#define EUR_CR_MASTER_BIF_CTRL_PAUSE_SIGNED 0
+#define EUR_CR_MASTER_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U
+#define EUR_CR_MASTER_BIF_CTRL_CLEAR_FAULT_SHIFT 4
+#define EUR_CR_MASTER_BIF_CTRL_CLEAR_FAULT_SIGNED 0
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_PTLA_MASK 0x00010000U
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_PTLA_SHIFT 16
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_PTLA_SIGNED 0
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_VDM_MASK 0x00020000U
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_VDM_SHIFT 17
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_VDM_SIGNED 0
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_IPF_MASK 0x00040000U
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_IPF_SHIFT 18
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_IPF_SIGNED 0
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_DPM_MASK 0x00080000U
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_DPM_SHIFT 19
+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_DPM_SIGNED 0
+/* Register EUR_CR_MASTER_BIF_CTRL_INVAL */
+#define EUR_CR_MASTER_BIF_CTRL_INVAL 0x4C34
+#define EUR_CR_MASTER_BIF_CTRL_INVAL_PTE_MASK 0x00000004U
+#define EUR_CR_MASTER_BIF_CTRL_INVAL_PTE_SHIFT 2
+#define EUR_CR_MASTER_BIF_CTRL_INVAL_PTE_SIGNED 0
+#define EUR_CR_MASTER_BIF_CTRL_INVAL_ALL_MASK 0x00000008U
+#define EUR_CR_MASTER_BIF_CTRL_INVAL_ALL_SHIFT 3
+#define EUR_CR_MASTER_BIF_CTRL_INVAL_ALL_SIGNED 0
+/* Register EUR_CR_MASTER_BIF_MMU_CTRL */
+#define EUR_CR_MASTER_BIF_MMU_CTRL 0x4CD0
+#define EUR_CR_MASTER_BIF_MMU_CTRL_PREFETCHING_ON_MASK 0x00000001U
+#define EUR_CR_MASTER_BIF_MMU_CTRL_PREFETCHING_ON_SHIFT 0
+#define EUR_CR_MASTER_BIF_MMU_CTRL_PREFETCHING_ON_SIGNED 0
+#define EUR_CR_MASTER_BIF_MMU_CTRL_ADDR_HASH_MODE_MASK 0x00000006U
+#define EUR_CR_MASTER_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT 1
+#define EUR_CR_MASTER_BIF_MMU_CTRL_ADDR_HASH_MODE_SIGNED 0
+#define EUR_CR_MASTER_BIF_MMU_CTRL_ENABLE_DC_TLB_MASK 0x00000010U
+#define EUR_CR_MASTER_BIF_MMU_CTRL_ENABLE_DC_TLB_SHIFT 4
+#define EUR_CR_MASTER_BIF_MMU_CTRL_ENABLE_DC_TLB_SIGNED 0
+/* Register EUR_CR_MASTER_SLC_CTRL */
+#define EUR_CR_MASTER_SLC_CTRL 0x4D00
+#define EUR_CR_MASTER_SLC_CTRL_DISABLE_REORDERING_MASK 0x00800000U
+#define EUR_CR_MASTER_SLC_CTRL_DISABLE_REORDERING_SHIFT 23
+#define EUR_CR_MASTER_SLC_CTRL_DISABLE_REORDERING_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_DISABLE_BURST_EXP_MASK 0x00400000U
+#define EUR_CR_MASTER_SLC_CTRL_DISABLE_BURST_EXP_SHIFT 22
+#define EUR_CR_MASTER_SLC_CTRL_DISABLE_BURST_EXP_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ3_MASK 0x00200000U
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ3_SHIFT 21
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ3_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ2_MASK 0x00100000U
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ2_SHIFT 20
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ2_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ1_MASK 0x00080000U
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ1_SHIFT 19
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ1_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ0_MASK 0x00040000U
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ0_SHIFT 18
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ0_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_DM_REF_SET_ALL_MASK 0x00010000U
+#define EUR_CR_MASTER_SLC_CTRL_DM_REF_SET_ALL_SHIFT 16
+#define EUR_CR_MASTER_SLC_CTRL_DM_REF_SET_ALL_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_ARB_PAGE_SIZE_MASK 0x0000F000U
+#define EUR_CR_MASTER_SLC_CTRL_ARB_PAGE_SIZE_SHIFT 12
+#define EUR_CR_MASTER_SLC_CTRL_ARB_PAGE_SIZE_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_ADDR_DECODE_MODE_MASK 0x00000E00U
+#define EUR_CR_MASTER_SLC_CTRL_ADDR_DECODE_MODE_SHIFT 9
+#define EUR_CR_MASTER_SLC_CTRL_ADDR_DECODE_MODE_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_PAUSE_MASK 0x00000100U
+#define EUR_CR_MASTER_SLC_CTRL_PAUSE_SHIFT 8
+#define EUR_CR_MASTER_SLC_CTRL_PAUSE_SIGNED 0
+/* Register EUR_CR_MASTER_SLC_CTRL_BYPASS */
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS 0x4D04
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_N_MASK 0x08000000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_N_SHIFT 27
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_N_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_MASK 0x04000000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_SHIFT 26
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE4_MASK 0x02000000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE4_SHIFT 25
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE4_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE3_MASK 0x01000000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE3_SHIFT 24
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE3_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE2_MASK 0x00800000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE2_SHIFT 23
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE2_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE1_MASK 0x00400000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE1_SHIFT 22
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE1_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE0_MASK 0x00200000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE0_SHIFT 21
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE0_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PTLA_MASK 0x00100000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PTLA_SHIFT 20
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PTLA_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_ISP2_RCIF_MASK 0x00080000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_ISP2_RCIF_SHIFT 19
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_ISP2_RCIF_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_ZLS_MASK 0x00040000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_ZLS_SHIFT 18
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_ZLS_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PBE_MASK 0x00020000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PBE_SHIFT 17
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PBE_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_VDM_MASK 0x00010000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_VDM_SHIFT 16
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_VDM_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_IPF_MASK 0x00008000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_IPF_SHIFT 15
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_IPF_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PDS_MASK 0x00004000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PDS_SHIFT 14
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PDS_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USEC_MASK 0x00002000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USEC_SHIFT 13
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USEC_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE3_MASK 0x00001000U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE3_SHIFT 12
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE3_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE2_MASK 0x00000800U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE2_SHIFT 11
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE2_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE1_MASK 0x00000400U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE1_SHIFT 10
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE1_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE0_MASK 0x00000200U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE0_SHIFT 9
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE0_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_IPF_OBJ_MASK 0x00000100U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_IPF_OBJ_SHIFT 8
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_IPF_OBJ_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TPF_MASK 0x00000080U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TPF_SHIFT 7
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TPF_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TA_MASK 0x00000040U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TA_SHIFT 6
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TA_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_CACHE_MASK 0x00000020U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_CACHE_SHIFT 5
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_CACHE_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_MMU_MASK 0x00000010U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_MMU_SHIFT 4
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_MMU_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_EVENT_MASK 0x00000008U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_EVENT_SHIFT 3
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_EVENT_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_PIXEL_MASK 0x00000004U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_PIXEL_SHIFT 2
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_PIXEL_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_VERTEX_MASK 0x00000002U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_VERTEX_SHIFT 1
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_VERTEX_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_ALL_MASK 0x00000001U
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_ALL_SHIFT 0
+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_ALL_SIGNED 0
+/* Register EUR_CR_MASTER_SLC_CTRL_USSE_INVAL */
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL 0x4D08
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_ADDR_MASK 0xFFFFFFFFU
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_ADDR_SHIFT 0
+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_ADDR_SIGNED 0
+/* Register EUR_CR_MASTER_SLC_CTRL_INVAL */
+#define EUR_CR_MASTER_SLC_CTRL_INVAL 0x4D28
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_EVENT_MASK 0x00000008U
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_EVENT_SHIFT 3
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_EVENT_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_PIXEL_MASK 0x00000004U
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_PIXEL_SHIFT 2
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_PIXEL_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_VERTEX_MASK 0x00000002U
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_VERTEX_SHIFT 1
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_VERTEX_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_ALL_MASK 0x00000001U
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_ALL_SHIFT 0
+#define EUR_CR_MASTER_SLC_CTRL_INVAL_ALL_SIGNED 0
+/* Register EUR_CR_MASTER_SLC_CTRL_FLUSH */
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH 0x4D2C
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_EVENT_MASK 0x00000080U
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_EVENT_SHIFT 7
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_EVENT_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_PIXEL_MASK 0x00000040U
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_PIXEL_SHIFT 6
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_PIXEL_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_VERTEX_MASK 0x00000020U
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_VERTEX_SHIFT 5
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_VERTEX_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_ALL_MASK 0x00000010U
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_ALL_SHIFT 4
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_ALL_SIGNED 0
+/* Register EUR_CR_MASTER_SLC_CTRL_FLUSH_INV */
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV 0x4D34
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_EVENT_MASK 0x00000080U
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_EVENT_SHIFT 7
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_EVENT_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_PIXEL_MASK 0x00000040U
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_PIXEL_SHIFT 6
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_PIXEL_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_VERTEX_MASK 0x00000020U
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_VERTEX_SHIFT 5
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_VERTEX_SIGNED 0
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_ALL_MASK 0x00000010U
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_ALL_SHIFT 4
+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_ALL_SIGNED 0
+/* Register EUR_CR_MASTER_BREAKPOINT_READ */
+#define EUR_CR_MASTER_BREAKPOINT_READ 0x4F18
+#define EUR_CR_MASTER_BREAKPOINT_READ_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_MASTER_BREAKPOINT_READ_ADDRESS_SHIFT 4
+#define EUR_CR_MASTER_BREAKPOINT_READ_ADDRESS_SIGNED 0
+/* Register EUR_CR_MASTER_BREAKPOINT_TRAP */
+#define EUR_CR_MASTER_BREAKPOINT_TRAP 0x4F1C
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_CONTINUE_MASK 0x00000002U
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_CONTINUE_SHIFT 1
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_CONTINUE_SIGNED 0
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_WRNOTIFY_MASK 0x00000001U
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_WRNOTIFY_SHIFT 0
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_WRNOTIFY_SIGNED 0
+/* Register EUR_CR_MASTER_BREAKPOINT */
+#define EUR_CR_MASTER_BREAKPOINT 0x4F20
+#define EUR_CR_MASTER_BREAKPOINT_ID_MASK 0x00000030U
+#define EUR_CR_MASTER_BREAKPOINT_ID_SHIFT 4
+#define EUR_CR_MASTER_BREAKPOINT_ID_SIGNED 0
+#define EUR_CR_MASTER_BREAKPOINT_UNTRAPPED_MASK 0x00000008U
+#define EUR_CR_MASTER_BREAKPOINT_UNTRAPPED_SHIFT 3
+#define EUR_CR_MASTER_BREAKPOINT_UNTRAPPED_SIGNED 0
+#define EUR_CR_MASTER_BREAKPOINT_TRAPPED_MASK 0x00000004U
+#define EUR_CR_MASTER_BREAKPOINT_TRAPPED_SHIFT 2
+#define EUR_CR_MASTER_BREAKPOINT_TRAPPED_SIGNED 0
+/* Register EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0 */
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0 0x4F24
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK 0xFFFFFFF0U
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0_ADDRESS_SHIFT 4
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0_ADDRESS_SIGNED 0
+/* Register EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1 */
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1 0x4F28
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_SIZE_MASK 0x00007C00U
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT 10
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_SIZE_SIGNED 0
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_NUMBER_MASK 0x00000300U
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT 8
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_NUMBER_SIGNED 0
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_TAG_MASK 0x000000F8U
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_TAG_SHIFT 3
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_TAG_SIGNED 0
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK 0x00000006U
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT 1
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SIGNED 0
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_RNW_MASK 0x00000001U
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_RNW_SHIFT 0
+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_RNW_SIGNED 0
+/* Register EUR_CR_MASTER_CORE */
+#define EUR_CR_MASTER_CORE 0x4000
+#define EUR_CR_MASTER_CORE_ENABLE_MASK 0x00000003U
+#define EUR_CR_MASTER_CORE_ENABLE_SHIFT 0
+#define EUR_CR_MASTER_CORE_ENABLE_SIGNED 0
+/* Register EUR_CR_MASTER_CORE_ID */
+#define EUR_CR_MASTER_CORE_ID 0x4010
+#define EUR_CR_MASTER_CORE_ID_CONFIG_MULTI_MASK 0x00000001U
+#define EUR_CR_MASTER_CORE_ID_CONFIG_MULTI_SHIFT 0
+#define EUR_CR_MASTER_CORE_ID_CONFIG_MULTI_SIGNED 0
+#define EUR_CR_MASTER_CORE_ID_CONFIG_BASE_MASK 0x00000002U
+#define EUR_CR_MASTER_CORE_ID_CONFIG_BASE_SHIFT 1
+#define EUR_CR_MASTER_CORE_ID_CONFIG_BASE_SIGNED 0
+#define EUR_CR_MASTER_CORE_ID_CONFIG_MASK 0x000000FCU
+#define EUR_CR_MASTER_CORE_ID_CONFIG_SHIFT 2
+#define EUR_CR_MASTER_CORE_ID_CONFIG_SIGNED 0
+#define EUR_CR_MASTER_CORE_ID_CONFIG_CORES_MASK 0x00000F00U
+#define EUR_CR_MASTER_CORE_ID_CONFIG_CORES_SHIFT 8
+#define EUR_CR_MASTER_CORE_ID_CONFIG_CORES_SIGNED 0
+#define EUR_CR_MASTER_CORE_ID_CONFIG_SLC_MASK 0x0000F000U
+#define EUR_CR_MASTER_CORE_ID_CONFIG_SLC_SHIFT 12
+#define EUR_CR_MASTER_CORE_ID_CONFIG_SLC_SIGNED 0
+#define EUR_CR_MASTER_CORE_ID_ID_MASK 0xFFFF0000U
+#define EUR_CR_MASTER_CORE_ID_ID_SHIFT 16
+#define EUR_CR_MASTER_CORE_ID_ID_SIGNED 0
+/* Register EUR_CR_MASTER_CORE_REVISION */
+#define EUR_CR_MASTER_CORE_REVISION 0x4014
+#define EUR_CR_MASTER_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU
+#define EUR_CR_MASTER_CORE_REVISION_MAINTENANCE_SHIFT 0
+#define EUR_CR_MASTER_CORE_REVISION_MAINTENANCE_SIGNED 0
+#define EUR_CR_MASTER_CORE_REVISION_MINOR_MASK 0x0000FF00U
+#define EUR_CR_MASTER_CORE_REVISION_MINOR_SHIFT 8
+#define EUR_CR_MASTER_CORE_REVISION_MINOR_SIGNED 0
+#define EUR_CR_MASTER_CORE_REVISION_MAJOR_MASK 0x00FF0000U
+#define EUR_CR_MASTER_CORE_REVISION_MAJOR_SHIFT 16
+#define EUR_CR_MASTER_CORE_REVISION_MAJOR_SIGNED 0
+#define EUR_CR_MASTER_CORE_REVISION_DESIGNER_MASK 0xFF000000U
+#define EUR_CR_MASTER_CORE_REVISION_DESIGNER_SHIFT 24
+#define EUR_CR_MASTER_CORE_REVISION_DESIGNER_SIGNED 0
+/* Register EUR_CR_MASTER_SOFT_RESET */
+#define EUR_CR_MASTER_SOFT_RESET 0x4080
+#define EUR_CR_MASTER_SOFT_RESET_CORE_RESET_MASK(i) (0x00000001U << (0 + ((i) * 1)))
+#define EUR_CR_MASTER_SOFT_RESET_CORE_RESET_SHIFT(i) (0 + ((i) * 1))
+#define EUR_CR_MASTER_SOFT_RESET_CORE_RESET_REGNUM(i) 0x4080
+#define EUR_CR_MASTER_SOFT_RESET_IPF_RESET_MASK 0x00000010U
+#define EUR_CR_MASTER_SOFT_RESET_IPF_RESET_SHIFT 4
+#define EUR_CR_MASTER_SOFT_RESET_IPF_RESET_SIGNED 0
+#define EUR_CR_MASTER_SOFT_RESET_DPM_RESET_MASK 0x00000020U
+#define EUR_CR_MASTER_SOFT_RESET_DPM_RESET_SHIFT 5
+#define EUR_CR_MASTER_SOFT_RESET_DPM_RESET_SIGNED 0
+#define EUR_CR_MASTER_SOFT_RESET_VDM_RESET_MASK 0x00000040U
+#define EUR_CR_MASTER_SOFT_RESET_VDM_RESET_SHIFT 6
+#define EUR_CR_MASTER_SOFT_RESET_VDM_RESET_SIGNED 0
+#define EUR_CR_MASTER_SOFT_RESET_SLC_RESET_MASK 0x00000080U
+#define EUR_CR_MASTER_SOFT_RESET_SLC_RESET_SHIFT 7
+#define EUR_CR_MASTER_SOFT_RESET_SLC_RESET_SIGNED 0
+#define EUR_CR_MASTER_SOFT_RESET_BIF_RESET_MASK 0x00000100U
+#define EUR_CR_MASTER_SOFT_RESET_BIF_RESET_SHIFT 8
+#define EUR_CR_MASTER_SOFT_RESET_BIF_RESET_SIGNED 0
+#define EUR_CR_MASTER_SOFT_RESET_MCI_RESET_MASK 0x00000200U
+#define EUR_CR_MASTER_SOFT_RESET_MCI_RESET_SHIFT 9
+#define EUR_CR_MASTER_SOFT_RESET_MCI_RESET_SIGNED 0
+#define EUR_CR_MASTER_SOFT_RESET_PTLA_RESET_MASK 0x00000400U
+#define EUR_CR_MASTER_SOFT_RESET_PTLA_RESET_SHIFT 10
+#define EUR_CR_MASTER_SOFT_RESET_PTLA_RESET_SIGNED 0
+
+#endif /* _SGXMPDEFS_KM_H_ */
+
diff --git a/pvr-source/services4/srvkm/include/buffer_manager.h b/pvr-source/services4/srvkm/include/buffer_manager.h
new file mode 100644
index 0000000..c16efaa
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/buffer_manager.h
@@ -0,0 +1,674 @@
+/*************************************************************************/ /*!
+@Title Buffer Management.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Manages buffers mapped into two virtual memory spaces, host and
+ device and referenced by handles.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _BUFFER_MANAGER_H_
+#define _BUFFER_MANAGER_H_
+
+#include "img_types.h"
+#include "ra.h"
+#include "perproc.h"
+
+#if defined(__cplusplus)
+extern "C"{
+#endif
+
+/* forward reference */
+typedef struct _BM_HEAP_ BM_HEAP;
+
+/*
+ * The mapping structure is used to record relations between CPU virtual,
+ * CPU physical and device virtual addresses for large chunks of memory
+ * from which we have resource-allocator draw our buffers.
+ *
+ * There is one per contiguous pool and one per import from the host OS.
+ */
+struct _BM_MAPPING_
+{
+ enum
+ {
+ hm_wrapped = 1, /*!< wrapped user supplied contiguous*/
+ hm_wrapped_scatter, /*!< wrapped user supplied scattered */
+ hm_wrapped_virtaddr, /*!< wrapped user supplied contiguous with virtual address*/
+ hm_wrapped_scatter_virtaddr, /*!< wrapped user supplied scattered with virtual address*/
+ hm_env, /*!< obtained from environment */
+ hm_contiguous /*!< contigous arena */
+ } eCpuMemoryOrigin;
+
+ BM_HEAP *pBMHeap; /* which BM heap */
+ RA_ARENA *pArena; /* whence the memory comes */
+
+ IMG_CPU_VIRTADDR CpuVAddr;
+ IMG_CPU_PHYADDR CpuPAddr;
+ IMG_DEV_VIRTADDR DevVAddr;
+ IMG_SYS_PHYADDR *psSysAddr;
+ IMG_SIZE_T uSize;
+ IMG_SIZE_T uSizeVM;
+ IMG_HANDLE hOSMemHandle;
+ IMG_UINT32 ui32Flags;
+
+ /* Sparse mapping data */
+ IMG_UINT32 ui32ChunkSize;
+ IMG_UINT32 ui32NumVirtChunks;
+ IMG_UINT32 ui32NumPhysChunks;
+ IMG_BOOL *pabMapChunk;
+
+ /* GPU mapping reference count
+ * When goes down to 0 GPU mapping
+ * gets removed */
+ IMG_UINT32 ui32MappingCount;
+
+ /* need to track the original required alignment to make sure
+ * that an unmapped buffer which is later remapped to device
+ * is remapped with the original alignment restrictions.
+ */
+ IMG_UINT32 ui32DevVAddrAlignment;
+};
+
+/*
+ * The buffer structure handles individual allocations from the user; thus
+ * there is one allocated per call to BM_Alloc and one per call to BM_Wrap.
+ * We record a mapping reference so we know where to return allocated
+ * resources at BM_Free time.
+ */
+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;
+ IMG_UINT32 ui32ExportCount;
+} 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;
+ PDUMP_MMU_ATTRIB *psMMUAttrib;
+
+ struct _BM_HEAP_ *psNext;
+ struct _BM_HEAP_ **ppsThis;
+ /* BIF tile stride for this heap */
+ IMG_UINT32 ui32XTileStride;
+};
+
+/*
+ * The bm-context structure
+ */
+struct _BM_CONTEXT_
+{
+ MMU_CONTEXT *psMMUContext;
+
+ /*
+ * Resource allocation arena of dual mapped pages. For devices
+ * where the hardware imposes different constraints on the valid
+ * device virtual address range depending on the use of the buffer
+ * we maintain two allocation arenas, one low address range, the
+ * other high. For devices without such a constrain we do not
+ * create the high arena, instead all allocations come from the
+ * low arena.
+ */
+ BM_HEAP *psBMHeap;
+
+ /*
+ * The Shared Heaps
+ */
+ BM_HEAP *psBMSharedHeap;
+
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+
+ /*
+ * Hash table management.
+ */
+ HASH_TABLE *pBufferHash;
+
+ /*
+ * Resman item handle
+ */
+ IMG_HANDLE hResItem;
+
+ IMG_UINT32 ui32RefCount;
+
+ /*
+ linked list next pointer
+ */
+ struct _BM_CONTEXT_ *psNext;
+ struct _BM_CONTEXT_ **ppsThis;
+};
+
+/* refcount.c needs to know the internals of this structure */
+typedef struct _XPROC_DATA_{
+ IMG_UINT32 ui32RefCount;
+ IMG_UINT32 ui32AllocFlags;
+ IMG_UINT32 ui32Size;
+ IMG_UINT32 ui32PageSize;
+ RA_ARENA *psArena;
+ IMG_SYS_PHYADDR sSysPAddr;
+ IMG_VOID *pvCpuVAddr;
+ IMG_HANDLE hOSMemHandle;
+} XPROC_DATA;
+
+extern XPROC_DATA gXProcWorkaroundShareData[];
+/*
+ Buffer handle.
+*/
+typedef IMG_VOID *BM_HANDLE;
+
+/** Buffer manager allocation flags.
+ *
+ * Flags passed to BM_Alloc to specify buffer capabilities.
+ *
+ * @defgroup BP Buffer Manager Allocation Flags
+ * @{
+ */
+
+/** Pool number mask. */
+#define BP_POOL_MASK 0x7
+
+/* Request physically contiguous pages of memory */
+#define BP_CONTIGUOUS (1 << 3)
+#define BP_PARAMBUFFER (1 << 4)
+
+#define BM_MAX_DEVMEM_ARENAS 2
+
+/** @} */
+
+/**
+ * @Function BM_CreateContext
+ *
+ * @Description
+ *
+ * @Input
+
+ * @Return
+ */
+
+IMG_HANDLE
+BM_CreateContext(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_DEV_PHYADDR *psPDDevPAddr,
+ PVRSRV_PER_PROCESS_DATA *psPerProc,
+ IMG_BOOL *pbCreated);
+
+
+/**
+ * @Function BM_DestroyContext
+ *
+ * @Description
+ *
+ * @Input
+ *
+ * @Return PVRSRV_ERROR
+ */
+PVRSRV_ERROR
+BM_DestroyContext (IMG_HANDLE hBMContext,
+ IMG_BOOL *pbCreated);
+
+
+/**
+ * @Function BM_CreateHeap
+ *
+ * @Description
+ *
+ * @Input
+ *
+ * @Return
+ */
+IMG_HANDLE
+BM_CreateHeap (IMG_HANDLE hBMContext,
+ DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo);
+
+/**
+ * @Function BM_DestroyHeap
+ *
+ * @Description
+ *
+ * @Input
+ *
+ * @Return
+ */
+IMG_VOID
+BM_DestroyHeap (IMG_HANDLE hDevMemHeap);
+
+
+/**
+ * @Function BM_Reinitialise
+ *
+ * @Description
+ *
+ * Reinitialises the buffer manager after a power event. Calling this
+ * function will reprogram MMU registers and renable the MMU.
+ *
+ * @Input None
+ * @Return None
+ */
+
+IMG_BOOL
+BM_Reinitialise (PVRSRV_DEVICE_NODE *psDeviceNode);
+
+/**
+ * @Function BM_Alloc
+ *
+ * @Description
+ *
+ * Allocate a buffer mapped into both host and device virtual memory
+ * maps.
+ *
+ * @Input uSize - require size in bytes of the buffer.
+ * @Input/Output pui32Flags - bit mask of buffer property flags + recieves heap flags.
+ * @Input uDevVAddrAlignment - required alignment in bytes, or 0.
+ * @Input pvPrivData - private data passed to OS allocator
+ * @Input ui32PrivDataLength - length of private data
+ * @Input ui32ChunkSize - Chunk size
+ * @Input ui32NumVirtChunks - Number of virtual chunks
+ * @Input ui32NumPhysChunks - Number of physical chunks
+ * @Input pabMapChunk - Chunk mapping array
+ * @Output phBuf - receives the buffer handle.
+ * @Return IMG_TRUE - Success, IMG_FALSE - Failed.
+ */
+IMG_BOOL
+BM_Alloc (IMG_HANDLE hDevMemHeap,
+ IMG_DEV_VIRTADDR *psDevVAddr,
+ IMG_SIZE_T uSize,
+ IMG_UINT32 *pui32Flags,
+ IMG_UINT32 uDevVAddrAlignment,
+ IMG_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_UINT32 ui32ChunkSize,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_BOOL *pabMapChunk,
+ BM_HANDLE *phBuf);
+
+/**
+ * @Function BM_Wrap
+ *
+ * @Description
+ *
+ * Create a buffer which wraps user provided host physical memory.
+ * The wrapped memory must be page aligned. BM_Wrap will roundup the
+ * size to a multiple of host pages.
+ *
+ * @Input ui32Size - size of memory to wrap.
+ * @Input ui32Offset - Offset into page of memory to wrap.
+ * @Input bPhysContig - Is the wrap physically contiguous.
+ * @Input psSysAddr - list of system physical page addresses of memory to wrap.
+ * @Input pvCPUVAddr - optional CPU kernel virtual address (Page aligned) of memory to wrap.
+ * @Input uFlags - bit mask of buffer property flags.
+ * @Input phBuf - receives the buffer handle.
+ * @Return IMG_TRUE - Success, IMG_FALSE - Failed
+ */
+IMG_BOOL
+BM_Wrap ( IMG_HANDLE hDevMemHeap,
+ IMG_SIZE_T ui32Size,
+ IMG_SIZE_T ui32Offset,
+ IMG_BOOL bPhysContig,
+ IMG_SYS_PHYADDR *psSysAddr,
+ IMG_VOID *pvCPUVAddr,
+ IMG_UINT32 *pui32Flags,
+ BM_HANDLE *phBuf);
+
+/**
+ * @Function BM_Free
+ *
+ * @Description
+ *
+ * Free a buffer previously allocated via BM_Alloc.
+ *
+ * @Input hBuf - buffer handle.
+ * @Return None.
+ */
+IMG_VOID
+BM_Free (BM_HANDLE hBuf,
+ IMG_UINT32 ui32Flags);
+
+
+/**
+ * @Function BM_HandleToCpuVaddr
+ *
+ * @Description
+ *
+ * Retrieve the host virtual address associated with a buffer.
+ *
+ * @Input hBuf - buffer handle.
+ *
+ * @Return buffers host virtual address.
+ */
+IMG_CPU_VIRTADDR
+BM_HandleToCpuVaddr (BM_HANDLE hBuf);
+
+/**
+ * @Function BM_HandleToDevVaddr
+ *
+ * @Description
+ *
+ * Retrieve the device virtual address associated with a buffer.
+ *
+ * @Input hBuf - buffer handle.
+ * @Return buffers device virtual address.
+ */
+IMG_DEV_VIRTADDR
+BM_HandleToDevVaddr (BM_HANDLE hBuf);
+
+/**
+ * @Function BM_HandleToSysPaddr
+ *
+ * @Description
+ *
+ * Retrieve the system physical address associated with a buffer.
+ *
+ * @Input hBuf - buffer handle.
+ * @Return buffers device virtual address.
+ */
+IMG_SYS_PHYADDR
+BM_HandleToSysPaddr (BM_HANDLE hBuf);
+
+/**
+ * @Function BM_HandleToMemOSHandle
+ *
+ * @Description
+ *
+ * Retrieve the underlying memory handle associated with a buffer.
+ *
+ * @Input hBuf - buffer handle.
+ * @Return An OS Specific memory handle
+ */
+IMG_HANDLE
+BM_HandleToOSMemHandle (BM_HANDLE hBuf);
+
+/**
+ * @Function BM_RemapToDev
+ *
+ * @Description
+ *
+ * Remaps the device Virtual Mapping.
+ *
+ * @Input hBuf - buffer handle.
+ * @Return ref count on success
+ */
+IMG_INT32
+BM_RemapToDev(BM_HANDLE hBuf);
+
+/**
+ * @Function BM_UnmapFromDev
+ *
+ * @Description
+ *
+ * Removes the device Virtual Mapping.
+ *
+ * @Input hBuf - buffer handle.
+ * @Return Ref count on success
+ */
+IMG_INT32
+BM_UnmapFromDev(BM_HANDLE hBuf);
+
+/**
+ * @Function BM_GetPhysPageAddr
+ *
+ * @Description
+ *
+ * Retreive physical address backing dev V address
+ *
+ * @Input psMemInfo
+ * @Input sDevVPageAddr
+ * @Output psDevPAddr
+ * @Return PVRSRV_ERROR
+ */
+IMG_VOID BM_GetPhysPageAddr(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_DEV_VIRTADDR sDevVPageAddr,
+ IMG_DEV_PHYADDR *psDevPAddr);
+
+/*!
+******************************************************************************
+ @Function BM_GetMMUContext
+
+ @Description
+ utility function to return the MMU context
+
+ @inputs hDevMemHeap - the Dev mem heap handle
+
+ @Return MMU context, else NULL
+**************************************************************************/
+MMU_CONTEXT* BM_GetMMUContext(IMG_HANDLE hDevMemHeap);
+
+/*!
+******************************************************************************
+ @Function BM_GetMMUContextFromMemContext
+
+ @Description
+ utility function to return the MMU context
+
+ @inputs hDevMemHeap - the Dev mem heap handle
+
+ @Return MMU context, else NULL
+**************************************************************************/
+MMU_CONTEXT* BM_GetMMUContextFromMemContext(IMG_HANDLE hDevMemContext);
+
+/*!
+******************************************************************************
+ @Function BM_GetMMUHeap
+
+ @Description
+ utility function to return the MMU heap handle
+
+ @inputs hDevMemHeap - the Dev mem heap handle
+
+ @Return MMU heap handle, else NULL
+**************************************************************************/
+IMG_HANDLE BM_GetMMUHeap(IMG_HANDLE hDevMemHeap);
+
+/*!
+******************************************************************************
+ @Function BM_GetDeviceNode
+
+ @Description utility function to return the devicenode from the BM Context
+
+ @inputs hDevMemContext - the Dev Mem Context
+
+ @Return MMU heap handle, else NULL
+**************************************************************************/
+PVRSRV_DEVICE_NODE* BM_GetDeviceNode(IMG_HANDLE hDevMemContext);
+
+
+/*!
+******************************************************************************
+ @Function BM_GetMappingHandle
+
+ @Description utility function to return the mapping handle from a meminfo
+
+ @inputs psMemInfo - kernel meminfo
+
+ @Return mapping handle, else NULL
+**************************************************************************/
+IMG_HANDLE BM_GetMappingHandle(PVRSRV_KERNEL_MEM_INFO *psMemInfo);
+
+/*!
+******************************************************************************
+ @Function BM_Export
+
+ @Description Export a buffer previously allocated via BM_Alloc.
+
+ @inputs hBuf - buffer handle.
+
+ @Return None.
+**************************************************************************/
+IMG_VOID BM_Export(BM_HANDLE hBuf);
+
+/*!
+******************************************************************************
+ @Function BM_FreeExport
+
+ @Description Free a buffer previously exported via BM_Export.
+
+ @inputs hBuf - buffer handle.
+ ui32Flags - flags
+
+ @Return None.
+**************************************************************************/
+IMG_VOID BM_FreeExport(BM_HANDLE hBuf, IMG_UINT32 ui32Flags);
+
+/*!
+******************************************************************************
+ @Function BM_MappingHandleFromBuffer
+
+ @Description utility function to get the BM mapping handle from a BM buffer
+
+ @Input hBuffer - Handle to BM buffer
+
+ @Return BM mapping handle
+**************************************************************************/
+IMG_HANDLE BM_MappingHandleFromBuffer(IMG_HANDLE hBuffer);
+
+/*!
+******************************************************************************
+ @Function BM_GetVirtualSize
+
+ @Description utility function to get the VM size of a BM mapping
+
+ @Input hBMHandle - Handle to BM mapping
+
+ @Return VM size of mapping
+**************************************************************************/
+IMG_UINT32 BM_GetVirtualSize(IMG_HANDLE hBMHandle);
+
+/*!
+******************************************************************************
+ @Function BM_MapPageAtOffset
+
+ @Description utility function check if the specificed offset in a BM mapping
+ is a page that needs tp be mapped
+
+ @Input hBMHandle - Handle to BM mapping
+
+ @Input ui32Offset - Offset into import
+
+ @Return IMG_TRUE if the page should be mapped
+**************************************************************************/
+IMG_BOOL BM_MapPageAtOffset(IMG_HANDLE hBMHandle, IMG_UINT32 ui32Offset);
+
+/*!
+******************************************************************************
+ @Function BM_VirtOffsetToPhyscial
+
+ @Description utility function find of physical offset of a sparse allocation
+ from it's virtual offset.
+
+ @Input hBMHandle - Handle to BM mapping
+
+ @Input ui32VirtOffset - Virtual offset into allocation
+
+ @Output pui32PhysOffset - Physical offset
+
+ @Return IMG_TRUE if the virtual offset is physically backed
+**************************************************************************/
+IMG_BOOL BM_VirtOffsetToPhysical(IMG_HANDLE hBMHandle,
+ IMG_UINT32 ui32VirtOffset,
+ IMG_UINT32 *pui32PhysOffset);
+
+/* The following are present for the "share mem" workaround for
+ cross-process mapping. This is only valid for a specific
+ use-case, and only tested on Linux (Android) and only
+ superficially at that. Do not rely on this API! */
+/* The two "Set" functions set a piece of "global" state in the buffer
+ manager, and "Unset" removes this global state. Therefore, there
+ is no thread-safety here and it's the caller's responsibility to
+ ensure that a mutex is acquired before using these functions or any
+ device memory allocation functions, including, especially,
+ callbacks from RA. */
+/* Once a "Share Index" is set by this means, any requests from the RA
+ to import a block of physical memory shall cause the physical
+ memory allocation to be refcounted, and shared iff the IDs chosen
+ match */
+/* This API is difficult to use, but saves a lot of plumbing in other
+ APIs. The next generation of this library should have this functionality
+ plumbed in properly */
+PVRSRV_ERROR BM_XProcWorkaroundSetShareIndex(IMG_UINT32 ui32Index);
+PVRSRV_ERROR BM_XProcWorkaroundUnsetShareIndex(IMG_UINT32 ui32Index);
+PVRSRV_ERROR BM_XProcWorkaroundFindNewBufferAndSetShareIndex(IMG_UINT32 *pui32Index);
+IMG_INT32 BM_XProcGetShareDataRefCount(IMG_UINT32 ui32Index);
+
+#if defined(PVRSRV_REFCOUNT_DEBUG)
+IMG_VOID _BM_XProcIndexAcquireDebug(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index);
+IMG_VOID _BM_XProcIndexReleaseDebug(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index);
+
+#define BM_XProcIndexAcquire(x...) \
+ _BM_XProcIndexAcquireDebug(__FILE__, __LINE__, x)
+#define BM_XProcIndexRelease(x...) \
+ _BM_XProcIndexReleaseDebug(__FILE__, __LINE__, x)
+
+#else
+IMG_VOID _BM_XProcIndexAcquire(IMG_UINT32 ui32Index);
+IMG_VOID _BM_XProcIndexRelease(IMG_UINT32 ui32Index);
+
+#define BM_XProcIndexAcquire(x) \
+ _BM_XProcIndexAcquire( x)
+#define BM_XProcIndexRelease(x) \
+ _BM_XProcIndexRelease( x)
+#endif
+
+static INLINE IMG_CHAR *
+_BMMappingType (IMG_INT eCpuMemoryOrigin)
+{
+ switch (eCpuMemoryOrigin)
+ {
+ case hm_wrapped: return "hm_wrapped";
+ case hm_wrapped_scatter: return "hm_wrapped_scatter";
+ case hm_wrapped_virtaddr: return "hm_wrapped_virtaddr";
+ case hm_wrapped_scatter_virtaddr: return "hm_wrapped_scatter_virtaddr";
+ case hm_env: return "hm_env";
+ case hm_contiguous: return "hm_contiguous";
+ }
+ return "junk";
+}
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/pvr-source/services4/srvkm/include/device.h b/pvr-source/services4/srvkm/include/device.h
new file mode 100644
index 0000000..6ddee5d
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/device.h
@@ -0,0 +1,409 @@
+/*************************************************************************/ /*!
+@Title Common Device header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Device related function templates and defines
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __DEVICE_H__
+#define __DEVICE_H__
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "ra.h" /* RA_ARENA */
+#include "resman.h" /* PRESMAN_ITEM */
+
+/* BM context forward reference */
+typedef struct _BM_CONTEXT_ BM_CONTEXT;
+
+/* pre-defined MMU structure forward references */
+typedef struct _MMU_HEAP_ MMU_HEAP;
+typedef struct _MMU_CONTEXT_ MMU_CONTEXT;
+
+/* physical resource types: */
+/* contiguous system memory */
+#define PVRSRV_BACKINGSTORE_SYSMEM_CONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+0))
+/* non-contiguous system memory */
+#define PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+1))
+/* contiguous local device memory */
+#define PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+2))
+/* non-contiguous local device memory */
+#define PVRSRV_BACKINGSTORE_LOCALMEM_NONCONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+3))
+
+/* heap types: */
+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 /* FIXME : Optimal Invalidation is not default */
+
+typedef struct _DEVICE_MEMORY_HEAP_INFO_
+{
+ /* heap identifier */
+ IMG_UINT32 ui32HeapID;
+
+ /* heap identifier string */
+ IMG_CHAR *pszName;
+
+ /* backing store identifier string */
+ IMG_CHAR *pszBSName;
+
+ /* Device virtual address of base of heap */
+ IMG_DEV_VIRTADDR sDevVAddrBase;
+
+ /* heapsize in bytes */
+ IMG_UINT32 ui32HeapSize;
+
+ /* Flags, includes physical resource (backing store type). Must be available to SOC */
+ IMG_UINT32 ui32Attribs;
+
+ /* Heap type: per device, kernel only, shared, shared_exported */
+ DEVICE_MEMORY_HEAP_TYPE DevMemHeapType;
+
+ /* kernel heap handle */
+ IMG_HANDLE hDevMemHeap;
+
+ /* ptr to local memory allocator for this heap */
+ RA_ARENA *psLocalDevMemArena;
+
+ /* MMU data page size (4kb, 16kb, 256kb, 1Mb, 4Mb) */
+ IMG_UINT32 ui32DataPageSize;
+
+ IMG_UINT32 ui32XTileStride;
+
+} DEVICE_MEMORY_HEAP_INFO;
+
+typedef struct _DEVICE_MEMORY_INFO_
+{
+ /* size of address space, as log2 */
+ IMG_UINT32 ui32AddressSpaceSizeLog2;
+
+ /*
+ flags, includes physical memory resource types available to the system.
+ Allows for validation at heap creation, define PVRSRV_BACKINGSTORE_XXX
+ */
+ IMG_UINT32 ui32Flags;
+
+ /* heap count. Doesn't include additional heaps from PVRSRVCreateDeviceMemHeap */
+ IMG_UINT32 ui32HeapCount;
+
+ /* the sync heap id - common code needs to know */
+ IMG_UINT32 ui32SyncHeapID;
+
+ /* heap for buffer mappings */
+ IMG_UINT32 ui32MappingHeapID;
+
+ /* heap for ion buffers */
+ IMG_UINT32 ui32IonHeapID;
+
+ /* device memory heap info about each heap in a device address space */
+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+
+ /* BM kernel context for the device */
+ BM_CONTEXT *pBMKernelContext;
+
+ /* BM context list for the device*/
+ BM_CONTEXT *pBMContext;
+
+} DEVICE_MEMORY_INFO;
+
+
+/*!
+ ****************************************************************************
+ Device memory descriptor for a given system
+ ****************************************************************************/
+typedef struct DEV_ARENA_DESCRIPTOR_TAG
+{
+ IMG_UINT32 ui32HeapID; /*!< memory pool has a unique id for diagnostic purposes */
+
+ IMG_CHAR *pszName; /*!< memory pool has a unique string for diagnostic purposes */
+
+ IMG_DEV_VIRTADDR BaseDevVAddr; /*!< Device virtual base address of the managed memory pool. */
+
+ IMG_UINT32 ui32Size; /*!< Size in bytes of the managed memory pool. */
+
+ DEVICE_MEMORY_HEAP_TYPE DevMemHeapType;/*!< heap type */
+
+ /* MMU data page size (4kb, 16kb, 256kb, 1Mb, 4Mb) */
+ IMG_UINT32 ui32DataPageSize;
+
+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeapInfo;
+
+} DEV_ARENA_DESCRIPTOR;
+
+
+/*
+ PDUMP MMU atttributes
+*/
+typedef struct _PDUMP_MMU_ATTRIB_
+{
+ PVRSRV_DEVICE_IDENTIFIER sDevId;
+
+ IMG_CHAR *pszPDRegRegion;
+
+ /* data page info */
+ IMG_UINT32 ui32DataPageMask;
+
+ /* page table info */
+ IMG_UINT32 ui32PTEValid;
+ IMG_UINT32 ui32PTSize;
+ IMG_UINT32 ui32PTEAlignShift;
+
+ /* page directory info */
+ IMG_UINT32 ui32PDEMask;
+ IMG_UINT32 ui32PDEAlignShift;
+
+} PDUMP_MMU_ATTRIB;
+
+/* forward reference to _SYS_DATA_ */
+typedef struct _SYS_DATA_TAG_ *PSYS_DATA;
+
+typedef struct _PVRSRV_DEVICE_NODE_
+{
+ PVRSRV_DEVICE_IDENTIFIER sDevId;
+ IMG_UINT32 ui32RefCount;
+
+ /*
+ callbacks the device must support:
+ */
+ /* device initialiser */
+ PVRSRV_ERROR (*pfnInitDevice) (IMG_VOID*);
+ /* device deinitialiser */
+ PVRSRV_ERROR (*pfnDeInitDevice) (IMG_VOID*);
+
+ /* device post-finalise compatibility check */
+ PVRSRV_ERROR (*pfnInitDeviceCompatCheck) (struct _PVRSRV_DEVICE_NODE_*);
+
+ /* device MMU interface */
+ 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**,PDUMP_MMU_ATTRIB **ppsMMUAttrib);
+ 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 (*pfnMMUMapPagesSparse)(MMU_HEAP *pMMU,
+ IMG_DEV_VIRTADDR devVAddr,
+ IMG_SYS_PHYADDR SysPAddr,
+ IMG_UINT32 ui32ChunkSize,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_BOOL *pabMapChunk,
+ 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 (*pfnMMUMapShadowSparse)(MMU_HEAP *pMMU,
+ IMG_DEV_VIRTADDR MapBaseDevVAddr,
+ IMG_UINT32 ui32ChunkSize,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_BOOL *pabMapChunk,
+ 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);
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ IMG_BOOL (*pfnMMUIsHeapShared)(MMU_HEAP *);
+#endif
+ IMG_DEV_PHYADDR (*pfnMMUGetPhysPageAddr)(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr);
+ IMG_DEV_PHYADDR (*pfnMMUGetPDDevPAddr)(MMU_CONTEXT *pMMUContext);
+ IMG_VOID (*pfnMMUGetCacheFlushRange)(MMU_CONTEXT *pMMUContext, IMG_UINT32 *pui32RangeMask);
+ IMG_VOID (*pfnMMUGetPDPhysAddr)(MMU_CONTEXT *pMMUContext, IMG_DEV_PHYADDR *psDevPAddr);
+
+ /* tiling range control functions */
+ PVRSRV_ERROR (*pfnAllocMemTilingRange)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32TilingStride,
+ IMG_UINT32 *pui32RangeIndex);
+ PVRSRV_ERROR (*pfnFreeMemTilingRange)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+ IMG_UINT32 ui32RangeIndex);
+
+ /* LISR handler for device */
+ IMG_BOOL (*pfnDeviceISR)(IMG_VOID*);
+ /* ISR data */
+ IMG_VOID *pvISRData;
+ /* System/SOC specific interrupt bit relating to this device */
+ IMG_UINT32 ui32SOCInterruptBit;
+ /* MISR handler for device */
+ IMG_VOID (*pfnDeviceMISR)(IMG_VOID*);
+
+ /* Software command complete callback for device */
+ IMG_VOID (*pfnDeviceCommandComplete)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
+ /* Flag indicating that command complete callback needs to be reprocessed */
+ IMG_BOOL bReProcessDeviceCommandComplete;
+
+ IMG_VOID (*pfnCacheInvalidate)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
+
+ /* information about the device's address space and heaps */
+ DEVICE_MEMORY_INFO sDevMemoryInfo;
+
+ /* private device information */
+ IMG_VOID *pvDevice;
+ IMG_UINT32 ui32pvDeviceSize; /* required by GetClassDeviceInfo API */
+
+ /* Resource Manager Context */
+ PRESMAN_CONTEXT hResManContext;
+
+ /* pointer back to parent sysdata */
+ PSYS_DATA psSysData;
+
+ /* default MMU PT/PD backing store to use for the device */
+ RA_ARENA *psLocalDevMemArena;
+
+ IMG_UINT32 ui32Flags;
+
+ struct _PVRSRV_DEVICE_NODE_ *psNext;
+ struct _PVRSRV_DEVICE_NODE_ **ppsThis;
+
+#if defined(PDUMP)
+ /* device-level callback which is called when pdump.exe starts.
+ * Should be implemented in device-specific init code, e.g. sgxinit.c
+ */
+ PVRSRV_ERROR (*pfnPDumpInitDevice)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
+ /* device-level callback to return pdump ID associated to a memory context */
+ IMG_UINT32 (*pfnMMUGetContextID)(IMG_HANDLE hDevMemContext);
+#endif
+} 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)
+
+/*!
+******************************************************************************
+
+ @Function PollForValueKM
+
+ @Description
+ Polls for a value to match a masked read of sysmem
+
+ @Input pui32LinMemAddr : CPU linear address of the mem to poll
+ @Input ui32Value : req'd value
+ @Input ui32Mask : Mask
+ @Input ui32Timeoutus : maximum total time to wait (us)
+ @Input ui32PollPeriodus : minimum delay between consecutive polls (us)
+ @Input bAllowPreemption : allow the polling loop to be preempted
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PollForValueKM(volatile IMG_UINT32* pui32LinMemAddr,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ IMG_UINT32 ui32Timeoutus,
+ IMG_UINT32 ui32PollPeriodus,
+ IMG_BOOL bAllowPreemption);
+
+#endif /* !defined(USE_CODE) */
+
+
+#if defined (USING_ISR_INTERRUPTS)
+PVRSRV_ERROR IMG_CALLCONV PollForInterruptKM(IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ IMG_UINT32 ui32Waitus,
+ IMG_UINT32 ui32Tries);
+
+#endif /* #if defined (USING_ISR_INTERRUPTS) */
+
+/* The following functions don't really belong here (srvkm.h might be a better
+ * place), but as they use the device data structures, this is the most convenient
+ * place for them. */
+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 /* __DEVICE_H__ */
+
+/******************************************************************************
+ End of file (device.h)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/include/handle.h b/pvr-source/services4/srvkm/include/handle.h
new file mode 100644
index 0000000..157d209
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/handle.h
@@ -0,0 +1,567 @@
+/*************************************************************************/ /*!
+@Title Handle Manager API
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Provide handle management
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef __HANDLE_H__
+#define __HANDLE_H__
+
+/*
+ * Handle API
+ * ----------
+ * The handle API is intended to provide handles for kernel resources,
+ * which can then be passed back to user space processes.
+ *
+ * The following functions comprise the API. Each function takes a
+ * pointer to a PVRSRV_HANDLE_BASE strcture, one of which is allocated
+ * for each process, and stored in the per-process data area. Use
+ * KERNEL_HANDLE_BASE for handles not allocated for a particular process,
+ * or for handles that need to be allocated before the PVRSRV_HANDLE_BASE
+ * structure for the process is available.
+ *
+ * PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase,
+ * IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType,
+ * PVRSRV_HANDLE_ALLOC_FLAG eFlag);
+ *
+ * Allocate a handle phHandle, for the resource of type eType pointed to by
+ * pvData.
+ *
+ * For handles that have a definite lifetime, where the corresponding
+ * resource is explicitly created and destroyed, eFlag should be zero.
+ *
+ * If the resource is not explicitly created and destroyed, eFlag should be
+ * set to PVRSRV_HANDLE_ALLOC_FLAG_SHARED. For a given process, the same
+ * handle will be returned each time a handle for the resource is allocated
+ * with the PVRSRV_HANDLE_ALLOC_FLAG_SHARED flag.
+ *
+ * If a particular resource may be referenced multiple times by a
+ * given process, setting eFlag to PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+ * will allow multiple handles to be allocated for the resource.
+ * Such handles cannot be found with PVRSRVFindHandle.
+ *
+ * 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);
+ *
+ * This function is similar to PVRSRVAllocHandle, except that the allocated
+ * handles are associated with a parent handle, hParent, that has been
+ * allocated previously. Subhandles are automatically deallocated when their
+ * parent handle is dealloacted.
+ * Subhandles can be treated as ordinary handles. For example, they may
+ * have subhandles of their own, and may be explicity deallocated using
+ * PVRSRVReleaseHandle (see below).
+ *
+ * PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase,
+ * IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType);
+ *
+ * Find the handle previously allocated for the resource pointed to by
+ * pvData, of type eType. Handles allocated with the flag
+ * PVRSRV_HANDLE_ALLOC_FLAG_MULTI cannot be found using this
+ * function.
+ *
+ * PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase,
+ * IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+ *
+ * Given a handle for a resource of type eType, return the pointer to the
+ * resource.
+ *
+ * PVRSRV_ERROR PVRSRVLookuSubHandle(PVRSRV_HANDLE_BASE *psBase,
+ * IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType,
+ * IMH_HANDLE hAncestor);
+ *
+ * Similar to PVRSRVLookupHandle, but checks the handle is a descendent
+ * of hAncestor.
+ *
+ * PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase,
+ * IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle);
+ *
+ * This function returns the resource pointer corresponding to the
+ * given handle, and the resource type in peType. This function is
+ * intended for situations where a handle may be one of several types,
+ * but the type isn't known beforehand.
+ *
+ * PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase,
+ * IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+ *
+ * Deallocate a handle of given type.
+ *
+ * PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase,
+ * IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+ *
+ * This function combines the functionality of PVRSRVLookupHandle and
+ * PVRSRVReleaseHandle, deallocating the handle after looking it up.
+ *
+ * PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase,
+ * IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+ *
+ * Return the parent of a handle in *phParent, or IMG_NULL if the handle has
+ * no parent.
+ *
+ * PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase,
+ * IMG_UINT32 ui32BatchSize)
+ *
+ * Allocate a new handle batch. This preallocates ui32BatchSize handles.
+ * Batch mode simplifies the handling of handle allocation failures.
+ * The handle API is unchanged in batch mode, except that handles freed
+ * in batch mode will not be available for reallocation until the batch
+ * is committed or released (see below).
+ *
+ * PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase)
+ * void PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase)
+ *
+ * When handle allocation from a handle batch is complete, the
+ * batch must be committed by calling PVRSRVCommitHandleBatch. If
+ * an error occurred, and none of the handles in the batch are no
+ * longer needed, PVRSRVReleaseHandleBatch must be called.
+ * The macros PVRSRVAllocHandleNR, and PVRSRVAllocSubHandleNR
+ * are defined for use in batch mode. These work the same way
+ * as PVRSRVAllocHandle and PVRSRVAllocSubHandle, except that
+ * they don't return a value, relying on the fact that
+ * PVRSRVCommitHandleBatch will not commit any of the handles
+ * in a batch if there was an error allocating one of the
+ * handles in the batch.
+ *
+ * PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase,
+ * IMG_UINT32 ui32MaxHandle)
+ * Set the maximum handle number. This is intended to restrict the
+ * handle range so that it will fit within a given field width. For
+ * example, setting the maximum handle number to 0x7fffffff, would
+ * ensure the handles would fit within a 31 bit width field. This
+ * facility should be used with caution, as it restricts the number of
+ * handles that can be allocated.
+ *
+ * IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase)
+ * Return the maximum handle number, or 0 if the setting of a limit
+ * is not supported.
+ *
+ * PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase)
+ * Allows unused handle space to be reclaimed, by calling
+ * PVRSRVPurgeHandles. Note that allocating handles may have a
+ * higher overhead if purging is enabled.
+ *
+ * PVRSRV_ERROR PVRSRVPurgeHandles((PVRSRV_HANDLE_BASE *psBase)
+ * Purge handles for a handle base that has purging enabled.
+ */
+
+#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_SYNC_INFO_MOD_OBJ,
+ PVRSRV_HANDLE_TYPE_RESITEM_INFO
+} PVRSRV_HANDLE_TYPE;
+
+typedef enum
+{
+ /* No flags */
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE = 0,
+ /* Share a handle that already exists for a given data pointer */
+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED = 0x01,
+ /* Muliple handles can point at the given data pointer */
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI = 0x02,
+ /* Subhandles are allocated in a private handle space */
+ PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE = 0x04
+} PVRSRV_HANDLE_ALLOC_FLAG;
+
+struct _PVRSRV_HANDLE_BASE_;
+typedef struct _PVRSRV_HANDLE_BASE_ PVRSRV_HANDLE_BASE;
+
+#if defined (PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
+extern PVRSRV_HANDLE_BASE *gpsKernelHandleBase;
+
+#define KERNEL_HANDLE_BASE (gpsKernelHandleBase)
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag);
+
+PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_SID hParent);
+
+PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_SID hHandle);
+
+PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType, IMG_SID hAncestor);
+
+PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phParent, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType);
+#else
+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);
+#endif /* #if defined (SUPPORT_SID_INTERFACE) */
+
+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 /* #if defined (PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)*/
+
+#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);
+ /*
+ * Unlike the other functions here, the returned results will need
+ * to be handled differently for the secure and non-secure cases.
+ */
+ *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 /* #if defined (PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)*/
+
+/*
+ * Versions of PVRSRVAllocHandle and PVRSRVAllocSubHandle with no return
+ * values. Intended for use with batched handle allocation, relying on
+ * CommitHandleBatch to detect handle allocation errors.
+ */
+#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 /* __HANDLE_H__ */
+
+/******************************************************************************
+ End of file (handle.h)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/include/hash.h b/pvr-source/services4/srvkm/include/hash.h
new file mode 100644
index 0000000..1ed6fd0
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/hash.h
@@ -0,0 +1,277 @@
+/*************************************************************************/ /*!
+@Title Self scaling hash tables
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Implements simple self scaling hash tables.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _HASH_H_
+#define _HASH_H_
+
+#include "img_types.h"
+#include "osfunc.h"
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * Keys passed to the comparsion function are only guaranteed to
+ * be aligned on an IMG_UINTPTR_T boundary.
+ */
+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;
+
+typedef PVRSRV_ERROR (*HASH_pfnCallback) (
+ IMG_UINTPTR_T k,
+ IMG_UINTPTR_T v
+);
+
+/*!
+******************************************************************************
+ @Function HASH_Func_Default
+
+ @Description Hash function intended for hashing keys composed of
+ IMG_UINTPTR_T arrays.
+
+ @Input uKeySize - the size of the hash key, in bytes.
+ @Input pKey - a pointer to the key to hash.
+ @Input uHashTabLen - the length of the hash table.
+
+ @Return The hash value.
+******************************************************************************/
+IMG_UINT32 HASH_Func_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen);
+
+/*!
+******************************************************************************
+ @Function HASH_Key_Comp_Default
+
+ @Description Compares keys composed of IMG_UINTPTR_T arrays.
+
+ @Input uKeySize - the size of the hash key, in bytes.
+ @Input pKey1 - pointer to first hash key to compare.
+ @Input pKey2 - pointer to second hash key to compare.
+
+ @Return IMG_TRUE - the keys match.
+ IMG_FALSE - the keys don't match.
+******************************************************************************/
+IMG_BOOL HASH_Key_Comp_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2);
+
+/*!
+******************************************************************************
+ @Function HASH_Create_Extended
+
+ @Description Create a self scaling hash table, using the supplied
+ key size, and the supllied hash and key comparsion
+ functions.
+
+ @Input uInitialLen - initial and minimum length of the
+ hash table, where the length refers to the number
+ of entries in the hash table, not its size in
+ bytes.
+ @Input uKeySize - the size of the key, in bytes.
+ @Input pfnHashFunc - pointer to hash function.
+ @Input pfnKeyComp - pointer to key comparsion function.
+
+ @Return IMG_NULL or hash table handle.
+******************************************************************************/
+HASH_TABLE * HASH_Create_Extended (IMG_UINT32 uInitialLen, IMG_SIZE_T uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp);
+
+/*!
+******************************************************************************
+ @Function HASH_Create
+
+ @Description Create a self scaling hash table with a key
+ consisting of a single IMG_UINTPTR_T, and using
+ the default hash and key comparison functions.
+
+ @Input uInitialLen - initial and minimum length of the
+ hash table, where the length refers to the
+ number of entries in the hash table, not its size
+ in bytes.
+
+ @Return IMG_NULL or hash table handle.
+******************************************************************************/
+HASH_TABLE * HASH_Create (IMG_UINT32 uInitialLen);
+
+/*!
+******************************************************************************
+ @Function HASH_Delete
+
+ @Description Delete a hash table created by HASH_Create_Extended or
+ HASH_Create. All entries in the table must have been
+ removed before calling this function.
+
+ @Input pHash - hash table
+
+ @Return None
+******************************************************************************/
+IMG_VOID HASH_Delete (HASH_TABLE *pHash);
+
+/*!
+******************************************************************************
+ @Function HASH_Insert_Extended
+
+ @Description Insert a key value pair into a hash table created
+ with HASH_Create_Extended.
+
+ @Input pHash - the hash table.
+ @Input pKey - pointer to the key.
+ @Input v - the value associated with the key.
+
+ @Return IMG_TRUE - success.
+ IMG_FALSE - failure.
+******************************************************************************/
+IMG_BOOL HASH_Insert_Extended (HASH_TABLE *pHash, IMG_VOID *pKey, IMG_UINTPTR_T v);
+
+/*!
+******************************************************************************
+ @Function HASH_Insert
+
+ @Description Insert a key value pair into a hash table created with
+ HASH_Create.
+
+ @Input pHash - the hash table.
+ @Input k - the key value.
+ @Input v - the value associated with the key.
+
+ @Return IMG_TRUE - success.
+ IMG_FALSE - failure.
+******************************************************************************/
+IMG_BOOL HASH_Insert (HASH_TABLE *pHash, IMG_UINTPTR_T k, IMG_UINTPTR_T v);
+
+/*!
+******************************************************************************
+ @Function HASH_Remove_Extended
+
+ @Description Remove a key from a hash table created with
+ HASH_Create_Extended.
+
+ @Input pHash - the hash table.
+ @Input pKey - pointer to key.
+
+ @Return 0 if the key is missing, or the value associated
+ with the key.
+******************************************************************************/
+IMG_UINTPTR_T HASH_Remove_Extended(HASH_TABLE *pHash, IMG_VOID *pKey);
+
+/*!
+******************************************************************************
+ @Function HASH_Remove
+
+ @Description Remove a key value pair from a hash table created
+ with HASH_Create.
+
+ @Input pHash - the hash table
+ @Input k - the key
+
+ @Return 0 if the key is missing, or the value associated
+ with the key.
+******************************************************************************/
+IMG_UINTPTR_T HASH_Remove (HASH_TABLE *pHash, IMG_UINTPTR_T k);
+
+/*!
+******************************************************************************
+ @Function HASH_Retrieve_Extended
+
+ @Description Retrieve a value from a hash table created with
+ HASH_Create_Extended.
+
+ @Input pHash - the hash table.
+ @Input pKey - pointer to the key.
+
+ @Return 0 if the key is missing, or the value associated with
+ the key.
+******************************************************************************/
+IMG_UINTPTR_T HASH_Retrieve_Extended (HASH_TABLE *pHash, IMG_VOID *pKey);
+
+/*!
+******************************************************************************
+ @Function HASH_Retrieve
+
+ @Description Retrieve a value from a hash table created with
+ HASH_Create.
+
+ @Input pHash - the hash table
+ @Input k - the key
+
+ @Return 0 if the key is missing, or the value associated with
+ the key.
+******************************************************************************/
+IMG_UINTPTR_T HASH_Retrieve (HASH_TABLE *pHash, IMG_UINTPTR_T k);
+
+/*!
+******************************************************************************
+ @Function HASH_Interate
+
+ @Description Iterate over every entry in the hash table
+
+ @Input pHash - the old hash table
+ @Input HASH_pfnCallback - the size of the old hash table
+
+ @Return Callback error if any, otherwise PVRSRV_OK
+******************************************************************************/
+PVRSRV_ERROR HASH_Iterate(HASH_TABLE *pHash, HASH_pfnCallback pfnCallback);
+
+#ifdef HASH_TRACE
+/*!
+******************************************************************************
+ @Function HASH_Dump
+
+ @Description Dump out some information about a hash table.
+
+ @Input pHash - the hash table
+
+ @Return None
+******************************************************************************/
+IMG_VOID HASH_Dump (HASH_TABLE *pHash);
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* _HASH_H_ */
+
+/******************************************************************************
+ End of file (hash.h)
+******************************************************************************/
+
+
diff --git a/pvr-source/services4/srvkm/include/lists.h b/pvr-source/services4/srvkm/include/lists.h
new file mode 100644
index 0000000..81205de
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/lists.h
@@ -0,0 +1,349 @@
+/*************************************************************************/ /*!
+@Title Linked list shared functions templates.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Definition of the linked list function templates.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __LISTS_UTILS__
+#define __LISTS_UTILS__
+
+/* instruct QAC to ignore warnings about the following custom formatted macros */
+/* PRQA S 0881,3410 ++ */
+#include <stdarg.h>
+#include "img_types.h"
+
+/*
+ - USAGE -
+
+ The list functions work with any structure that provides the fields psNext and
+ ppsThis. In order to make a function available for a given type, it is required
+ to use the funcion template macro that creates the actual code.
+
+ There are 4 main types of functions:
+ - INSERT : given a pointer to the head pointer of the list and a pointer to
+ the node, inserts it as the new head.
+ - REMOVE : given a pointer to a node, removes it from its list.
+ - FOR EACH : apply a function over all the elements of a list.
+ - ANY : apply a function over the elements of a list, until one of them
+ return a non null value, and then returns it.
+
+ The two last functions can have a variable argument form, with allows to pass
+ additional parameters to the callback function. In order to do this, the
+ callback function must take two arguments, the first is the current node and
+ the second is a list of variable arguments (va_list).
+
+ The ANY functions have also another for wich specifies the return type of the
+ callback function and the default value returned by the callback function.
+
+*/
+
+/*!
+******************************************************************************
+ @Function List_##TYPE##_ForEach
+
+ @Description Apply a callback function to all the elements of a list.
+
+ @Input psHead - the head of the list to be processed.
+ @Input pfnCallBack - the function to be applied to each element
+ of the list.
+
+ @Return None
+******************************************************************************/
+#define DECLARE_LIST_FOR_EACH(TYPE) \
+IMG_VOID List_##TYPE##_ForEach(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode))
+
+#define IMPLEMENT_LIST_FOR_EACH(TYPE) \
+IMG_VOID List_##TYPE##_ForEach(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode))\
+{\
+ while(psHead)\
+ {\
+ pfnCallBack(psHead);\
+ psHead = psHead->psNext;\
+ }\
+}
+
+
+#define DECLARE_LIST_FOR_EACH_VA(TYPE) \
+IMG_VOID List_##TYPE##_ForEach_va(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode, va_list va), ...)
+
+#define IMPLEMENT_LIST_FOR_EACH_VA(TYPE) \
+IMG_VOID List_##TYPE##_ForEach_va(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode, va_list va), ...) \
+{\
+ va_list ap;\
+ while(psHead)\
+ {\
+ va_start(ap, pfnCallBack);\
+ pfnCallBack(psHead, ap);\
+ psHead = psHead->psNext;\
+ va_end(ap);\
+ }\
+}
+
+
+/*!
+******************************************************************************
+ @Function List_##TYPE##_Any
+
+ @Description Applies a callback function to the elements of a list until
+ the function returns a non null value, then returns it.
+
+ @Input psHead - the head of the list to be processed.
+ @Input pfnCallBack - the function to be applied to each element
+ of the list.
+
+ @Return None
+******************************************************************************/
+#define DECLARE_LIST_ANY(TYPE) \
+IMG_VOID* List_##TYPE##_Any(TYPE *psHead, IMG_VOID* (*pfnCallBack)(TYPE* psNode))
+
+#define IMPLEMENT_LIST_ANY(TYPE) \
+IMG_VOID* List_##TYPE##_Any(TYPE *psHead, IMG_VOID* (*pfnCallBack)(TYPE* psNode))\
+{ \
+ IMG_VOID *pResult;\
+ TYPE *psNextNode;\
+ pResult = IMG_NULL;\
+ psNextNode = psHead;\
+ while(psHead && !pResult)\
+ {\
+ psNextNode = psNextNode->psNext;\
+ pResult = pfnCallBack(psHead);\
+ psHead = psNextNode;\
+ }\
+ return pResult;\
+}
+
+
+/*with variable arguments, that will be passed as a va_list to the callback function*/
+
+#define DECLARE_LIST_ANY_VA(TYPE) \
+IMG_VOID* List_##TYPE##_Any_va(TYPE *psHead, IMG_VOID*(*pfnCallBack)(TYPE* psNode, va_list va), ...)
+
+#define IMPLEMENT_LIST_ANY_VA(TYPE) \
+IMG_VOID* List_##TYPE##_Any_va(TYPE *psHead, IMG_VOID*(*pfnCallBack)(TYPE* psNode, va_list va), ...)\
+{\
+ va_list ap;\
+ TYPE *psNextNode;\
+ IMG_VOID* pResult = IMG_NULL;\
+ while(psHead && !pResult)\
+ {\
+ psNextNode = psHead->psNext;\
+ va_start(ap, pfnCallBack);\
+ pResult = pfnCallBack(psHead, ap);\
+ va_end(ap);\
+ psHead = psNextNode;\
+ }\
+ return pResult;\
+}
+
+/*those ones are for extra type safety, so there's no need to use castings for the results*/
+
+#define DECLARE_LIST_ANY_2(TYPE, RTYPE, CONTINUE) \
+RTYPE List_##TYPE##_##RTYPE##_Any(TYPE *psHead, RTYPE (*pfnCallBack)(TYPE* psNode))
+
+#define IMPLEMENT_LIST_ANY_2(TYPE, RTYPE, CONTINUE) \
+RTYPE List_##TYPE##_##RTYPE##_Any(TYPE *psHead, RTYPE (*pfnCallBack)(TYPE* psNode))\
+{ \
+ RTYPE result;\
+ TYPE *psNextNode;\
+ result = CONTINUE;\
+ psNextNode = psHead;\
+ while(psHead && result == CONTINUE)\
+ {\
+ psNextNode = psNextNode->psNext;\
+ result = pfnCallBack(psHead);\
+ psHead = psNextNode;\
+ }\
+ return result;\
+}
+
+
+#define DECLARE_LIST_ANY_VA_2(TYPE, RTYPE, CONTINUE) \
+RTYPE List_##TYPE##_##RTYPE##_Any_va(TYPE *psHead, RTYPE(*pfnCallBack)(TYPE* psNode, va_list va), ...)
+
+#define IMPLEMENT_LIST_ANY_VA_2(TYPE, RTYPE, CONTINUE) \
+RTYPE List_##TYPE##_##RTYPE##_Any_va(TYPE *psHead, RTYPE(*pfnCallBack)(TYPE* psNode, va_list va), ...)\
+{\
+ va_list ap;\
+ TYPE *psNextNode;\
+ RTYPE result = CONTINUE;\
+ while(psHead && result == CONTINUE)\
+ {\
+ psNextNode = psHead->psNext;\
+ va_start(ap, pfnCallBack);\
+ result = pfnCallBack(psHead, ap);\
+ va_end(ap);\
+ psHead = psNextNode;\
+ }\
+ return result;\
+}
+
+
+/*!
+******************************************************************************
+ @Function List_##TYPE##_Remove
+
+ @Description Removes a given node from the list.
+
+ @Input psNode - the pointer to the node to be removed.
+
+ @Return None
+******************************************************************************/
+#define DECLARE_LIST_REMOVE(TYPE) \
+IMG_VOID List_##TYPE##_Remove(TYPE *psNode)
+
+#define IMPLEMENT_LIST_REMOVE(TYPE) \
+IMG_VOID List_##TYPE##_Remove(TYPE *psNode)\
+{\
+ (*psNode->ppsThis)=psNode->psNext;\
+ if(psNode->psNext)\
+ {\
+ psNode->psNext->ppsThis = psNode->ppsThis;\
+ }\
+}
+
+/*!
+******************************************************************************
+ @Function List_##TYPE##_Insert
+
+ @Description Inserts a given node at the beginnning of the list.
+
+ @Input psHead - The pointer to the pointer to the head node.
+ @Input psNode - The pointer to the node to be inserted.
+
+ @Return None
+******************************************************************************/
+#define DECLARE_LIST_INSERT(TYPE) \
+IMG_VOID List_##TYPE##_Insert(TYPE **ppsHead, TYPE *psNewNode)
+
+#define IMPLEMENT_LIST_INSERT(TYPE) \
+IMG_VOID List_##TYPE##_Insert(TYPE **ppsHead, TYPE *psNewNode)\
+{\
+ psNewNode->ppsThis = ppsHead;\
+ psNewNode->psNext = *ppsHead;\
+ *ppsHead = psNewNode;\
+ if(psNewNode->psNext)\
+ {\
+ psNewNode->psNext->ppsThis = &(psNewNode->psNext);\
+ }\
+}
+
+/*!
+******************************************************************************
+ @Function List_##TYPE##_Reverse
+
+ @Description Reverse a list in place
+
+ @Input ppsHead - The pointer to the pointer to the head node.
+
+ @Return None
+******************************************************************************/
+#define DECLARE_LIST_REVERSE(TYPE) \
+IMG_VOID List_##TYPE##_Reverse(TYPE **ppsHead)
+
+#define IMPLEMENT_LIST_REVERSE(TYPE) \
+IMG_VOID List_##TYPE##_Reverse(TYPE **ppsHead)\
+{\
+ TYPE *psTmpNode1; \
+ TYPE *psTmpNode2; \
+ TYPE *psCurNode; \
+ psTmpNode1 = IMG_NULL; \
+ psCurNode = *ppsHead; \
+ while(psCurNode) { \
+ psTmpNode2 = psCurNode->psNext; \
+ psCurNode->psNext = psTmpNode1; \
+ psTmpNode1 = psCurNode; \
+ psCurNode = psTmpNode2; \
+ if(psCurNode) \
+ { \
+ psTmpNode1->ppsThis = &(psCurNode->psNext); \
+ } \
+ else \
+ { \
+ psTmpNode1->ppsThis = ppsHead; \
+ } \
+ } \
+ *ppsHead = psTmpNode1; \
+}
+
+#define IS_LAST_ELEMENT(x) ((x)->psNext == IMG_NULL)
+
+#include "services_headers.h"
+
+DECLARE_LIST_ANY_VA(BM_HEAP);
+DECLARE_LIST_ANY_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK);
+DECLARE_LIST_ANY_VA_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK);
+DECLARE_LIST_FOR_EACH_VA(BM_HEAP);
+DECLARE_LIST_REMOVE(BM_HEAP);
+DECLARE_LIST_INSERT(BM_HEAP);
+
+DECLARE_LIST_ANY_VA(BM_CONTEXT);
+DECLARE_LIST_ANY_VA_2(BM_CONTEXT, IMG_HANDLE, IMG_NULL);
+DECLARE_LIST_ANY_VA_2(BM_CONTEXT, PVRSRV_ERROR, PVRSRV_OK);
+DECLARE_LIST_FOR_EACH(BM_CONTEXT);
+DECLARE_LIST_REMOVE(BM_CONTEXT);
+DECLARE_LIST_INSERT(BM_CONTEXT);
+
+DECLARE_LIST_ANY_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK);
+DECLARE_LIST_ANY_VA(PVRSRV_DEVICE_NODE);
+DECLARE_LIST_ANY_VA_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK);
+DECLARE_LIST_FOR_EACH(PVRSRV_DEVICE_NODE);
+DECLARE_LIST_FOR_EACH_VA(PVRSRV_DEVICE_NODE);
+DECLARE_LIST_INSERT(PVRSRV_DEVICE_NODE);
+DECLARE_LIST_REMOVE(PVRSRV_DEVICE_NODE);
+
+DECLARE_LIST_ANY_VA(PVRSRV_POWER_DEV);
+DECLARE_LIST_ANY_VA_2(PVRSRV_POWER_DEV, PVRSRV_ERROR, PVRSRV_OK);
+DECLARE_LIST_INSERT(PVRSRV_POWER_DEV);
+DECLARE_LIST_REMOVE(PVRSRV_POWER_DEV);
+
+#undef DECLARE_LIST_ANY_2
+#undef DECLARE_LIST_ANY_VA
+#undef DECLARE_LIST_ANY_VA_2
+#undef DECLARE_LIST_FOR_EACH
+#undef DECLARE_LIST_FOR_EACH_VA
+#undef DECLARE_LIST_INSERT
+#undef DECLARE_LIST_REMOVE
+
+IMG_VOID* MatchDeviceKM_AnyVaCb(PVRSRV_DEVICE_NODE* psDeviceNode, va_list va);
+IMG_VOID* MatchPowerDeviceIndex_AnyVaCb(PVRSRV_POWER_DEV *psPowerDev, va_list va);
+
+#endif
+
+/* re-enable warnings */
+/* PRQA S 0881,3410 -- */
diff --git a/pvr-source/services4/srvkm/include/metrics.h b/pvr-source/services4/srvkm/include/metrics.h
new file mode 100644
index 0000000..18079cb
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/metrics.h
@@ -0,0 +1,146 @@
+/*************************************************************************/ /*!
+@Title Time measurement interface.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#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)) // timer start register
+
+#define TCOR_2 ((volatile IMG_UINT *) (psDevInfo->pvSOCRegsBaseKM+28)) // timer constant register_2
+#define TCNT_2 ((volatile IMG_UINT *) (psDevInfo->pvSOCRegsBaseKM+32)) // timer counter register_2
+#define TCR_2 ((volatile IMG_UINT16 *)(psDevInfo->pvSOCRegsBaseKM+36)) // timer control register_2
+
+#define TIMER_DIVISOR 4
+
+#endif /* defined(__sh__) */
+
+
+
+#else /* defined(DEBUG) || defined(TIMING) */
+
+
+
+#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 /* defined(DEBUG) || defined(TIMING) */
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif /* _METRICS_ */
+
+/**************************************************************************
+ End of file (metrics.h)
+**************************************************************************/
diff --git a/pvr-source/services4/srvkm/include/osfunc.h b/pvr-source/services4/srvkm/include/osfunc.h
new file mode 100644
index 0000000..dcaa58a
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/osfunc.h
@@ -0,0 +1,799 @@
+/*************************************************************************/ /*!
+@Title OS functions header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description OS specific API definitions
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#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>
+#include <asm/system.h>
+#if defined(__arm__)
+#include <asm/memory.h>
+#endif
+#endif
+
+
+/* setup conditional pageable / non-pageable select */
+ /* Other OSs only need pageable */
+ #define PVRSRV_PAGEABLE_SELECT PVRSRV_OS_PAGEABLE_HEAP
+
+/******************************************************************************
+ * Static defines
+ *****************************************************************************/
+#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_PAGEMASK) & ~HOST_PAGEMASK)
+
+/******************************************************************************
+ * Host memory heaps
+ *****************************************************************************/
+#define PVRSRV_OS_HEAP_MASK 0xf /* host heap flags mask */
+#define PVRSRV_OS_PAGEABLE_HEAP 0x1 /* allocation pageable */
+#define PVRSRV_OS_NON_PAGEABLE_HEAP 0x2 /* allocation non pageable */
+
+
+IMG_UINT32 OSClockus(IMG_VOID);
+IMG_SIZE_T 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_HANDLE, IMG_VOID* pvLinAddr);
+IMG_VOID OSMemCopy(IMG_VOID *pvDst, IMG_VOID *pvSrc, IMG_SIZE_T ui32Size);
+IMG_VOID *OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE *phOSMemHandle);
+IMG_BOOL OSUnMapPhysToLin(IMG_VOID *pvLinAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle);
+
+PVRSRV_ERROR OSReservePhys(IMG_CPU_PHYADDR BasePAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hBMHandle, IMG_VOID **ppvCpuVAddr, IMG_HANDLE *phOSMemHandle);
+PVRSRV_ERROR OSUnReservePhys(IMG_VOID *pvCpuVAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle);
+
+/* Some terminology:
+ *
+ * FLUSH Flush w/ invalidate
+ * CLEAN Flush w/o invalidate
+ * INVALIDATE Invalidate w/o flush
+ */
+
+#if defined(__linux__) && defined(__KERNEL__)
+
+IMG_VOID OSFlushCPUCacheKM(IMG_VOID);
+
+IMG_VOID OSCleanCPUCacheKM(IMG_VOID);
+
+IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length);
+IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length);
+IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length);
+
+#else /* defined(__linux__) && defined(__KERNEL__) */
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSFlushCPUCacheKM)
+#endif
+static INLINE IMG_VOID OSFlushCPUCacheKM(IMG_VOID) {}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSCleanCPUCacheKM)
+#endif
+static INLINE IMG_VOID OSCleanCPUCacheKM(IMG_VOID) {}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSFlushCPUCacheRangeKM)
+#endif
+static INLINE IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+ PVR_UNREFERENCED_PARAMETER(ui32ByteOffset);
+ PVR_UNREFERENCED_PARAMETER(pvRangeAddrStart);
+ PVR_UNREFERENCED_PARAMETER(ui32Length);
+ return IMG_FALSE;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSCleanCPUCacheRangeKM)
+#endif
+static INLINE IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+ PVR_UNREFERENCED_PARAMETER(ui32ByteOffset);
+ PVR_UNREFERENCED_PARAMETER(pvRangeAddrStart);
+ PVR_UNREFERENCED_PARAMETER(ui32Length);
+ return IMG_FALSE;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSInvalidateCPUCacheRangeKM)
+#endif
+static INLINE IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32ByteOffset,
+ IMG_VOID *pvRangeAddrStart,
+ IMG_UINT32 ui32Length)
+{
+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+ PVR_UNREFERENCED_PARAMETER(ui32ByteOffset);
+ PVR_UNREFERENCED_PARAMETER(pvRangeAddrStart);
+ PVR_UNREFERENCED_PARAMETER(ui32Length);
+ return IMG_FALSE;
+}
+
+#endif /* defined(__linux__) && defined(__KERNEL__) */
+
+#if defined(__linux__) || defined(__QNXNTO__)
+PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr,
+ IMG_VOID *pvCpuVAddr,
+ IMG_SIZE_T ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE *phOSMemHandle);
+PVRSRV_ERROR OSUnRegisterDiscontigMem(IMG_VOID *pvCpuVAddr,
+ IMG_SIZE_T ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hOSMemHandle);
+#else /* defined(__linux__) */
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSRegisterDiscontigMem)
+#endif
+static INLINE PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr,
+ IMG_VOID *pvCpuVAddr,
+ IMG_SIZE_T 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_SIZE_T 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 /* defined(__linux__) */
+
+
+#if defined(__linux__) || defined(__QNXNTO__)
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSReserveDiscontigPhys)
+#endif
+static INLINE PVRSRV_ERROR OSReserveDiscontigPhys(IMG_SYS_PHYADDR *pBasePAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_VOID **ppvCpuVAddr, IMG_HANDLE *phOSMemHandle)
+{
+#if defined(__linux__) || defined(__QNXNTO__)
+ *ppvCpuVAddr = IMG_NULL;
+ return OSRegisterDiscontigMem(pBasePAddr, *ppvCpuVAddr, ui32Bytes, ui32Flags, phOSMemHandle);
+#else
+ extern IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr(IMG_SYS_PHYADDR SysPAddr);
+
+ /*
+ * On uITRON we know:
+ * 1. We will only be called with a non-contig physical if we
+ * already have a contiguous CPU linear
+ * 2. There is a one->one mapping of CpuPAddr -> CpuVAddr
+ * 3. Looking up the first CpuPAddr will find the first CpuVAddr
+ * 4. We don't need to unmap
+ */
+
+ return OSReservePhys(SysSysPAddrToCpuPAddr(pBasePAddr[0]), ui32Bytes, ui32Flags, IMG_NULL, ppvCpuVAddr, phOSMemHandle);
+#endif
+}
+
+static INLINE PVRSRV_ERROR OSUnReserveDiscontigPhys(IMG_VOID *pvCpuVAddr, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle)
+{
+#if defined(__linux__) || defined(__QNXNTO__)
+ OSUnRegisterDiscontigMem(pvCpuVAddr, ui32Bytes, ui32Flags, hOSMemHandle);
+#endif
+ /* We don't need to unmap */
+ return PVRSRV_OK;
+}
+#else /* defined(__linux__) */
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSReserveDiscontigPhys)
+#endif
+static INLINE PVRSRV_ERROR OSReserveDiscontigPhys(IMG_SYS_PHYADDR *pBasePAddr, IMG_SIZE_T 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_SIZE_T 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 /* defined(__linux__) */
+
+PVRSRV_ERROR OSRegisterMem(IMG_CPU_PHYADDR BasePAddr,
+ IMG_VOID *pvCpuVAddr,
+ IMG_SIZE_T ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE *phOSMemHandle);
+PVRSRV_ERROR OSUnRegisterMem(IMG_VOID *pvCpuVAddr,
+ IMG_SIZE_T ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hOSMemHandle);
+
+
+
+#if defined(__linux__) || defined(__QNXNTO__)
+PVRSRV_ERROR OSGetSubMemHandle(IMG_HANDLE hOSMemHandle,
+ IMG_UINTPTR_T ui32ByteOffset,
+ IMG_SIZE_T 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_UINTPTR_T ui32ByteOffset,
+ IMG_SIZE_T 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);
+int OSGetProcCmdline(IMG_UINT32 ui32PID, char * buffer, int buff_size);
+const char* OSGetPathBaseName(char * buffer, int buff_size);
+IMG_UINTPTR_T OSGetCurrentThreadID( IMG_VOID );
+IMG_VOID OSMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_SIZE_T ui32Size);
+
+PVRSRV_ERROR OSAllocPages_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_UINT32 ui32PageSize,
+ IMG_PVOID pvPrivData, IMG_UINT32 ui32PrivDataLength, IMG_HANDLE hBMHandle, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phPageAlloc);
+PVRSRV_ERROR OSFreePages(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID pvLinAddr, IMG_HANDLE hPageAlloc);
+
+IMG_INT32
+OSGetMemMultiPlaneInfo(IMG_HANDLE hOSMemHandle, IMG_UINT32* pui32AddressOffsets,
+ IMG_UINT32* ui32NumAddrOffsets);
+
+
+/*---------------------
+The set of macros below follows this pattern:
+
+f(x) = if F -> f2(g(x))
+ else -> g(x)
+
+g(x) = if G -> g2(h(x))
+ else -> h(x)
+
+h(x) = ...
+
+-----------------------*/
+
+/*If level 3 wrapper is enabled, we add a PVR_TRACE and call the next level, else just call the next level*/
+#ifdef PVRSRV_LOG_MEMORY_ALLOCS
+ #define OSAllocMem(flags, size, linAddr, blockAlloc, logStr) \
+ (PVR_TRACE(("OSAllocMem(" #flags ", " #size ", " #linAddr ", " #blockAlloc "): " logStr " (size = 0x%lx)", size)), \
+ OSAllocMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__))
+
+ #define OSAllocPages(flags, size, pageSize, privdata, privdatalength, bmhandle, linAddr, pageAlloc) \
+ (PVR_TRACE(("OSAllocPages(" #flags ", " #size ", " #pageSize ", " #linAddr ", " #pageAlloc "): (size = 0x%lx)", size)), \
+ OSAllocPages_Impl(flags, size, pageSize, linAddr, privdata, privdatalength, bmhandle, pageAlloc))
+
+ #define OSFreeMem(flags, size, linAddr, blockAlloc) \
+ (PVR_TRACE(("OSFreeMem(" #flags ", " #size ", " #linAddr ", " #blockAlloc "): (pointer = 0x%X)", linAddr)), \
+ OSFreeMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__))
+#else
+ #define OSAllocMem(flags, size, linAddr, blockAlloc, logString) \
+ OSAllocMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__)
+
+ #define OSAllocPages OSAllocPages_Impl
+
+ #define OSFreeMem(flags, size, linAddr, blockAlloc) \
+ OSFreeMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__)
+#endif
+
+/*If level 2 wrapper is enabled declare the function,
+else alias to level 1 wrapper, else the wrapper function will be used*/
+#ifdef PVRSRV_DEBUG_OS_MEMORY
+
+ PVRSRV_ERROR OSAllocMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
+ IMG_UINT32 ui32Size,
+ IMG_PVOID *ppvCpuVAddr,
+ IMG_HANDLE *phBlockAlloc,
+ IMG_CHAR *pszFilename,
+ IMG_UINT32 ui32Line);
+
+ PVRSRV_ERROR OSFreeMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
+ IMG_UINT32 ui32Size,
+ IMG_PVOID pvCpuVAddr,
+ IMG_HANDLE hBlockAlloc,
+ IMG_CHAR *pszFilename,
+ IMG_UINT32 ui32Line);
+
+
+ typedef struct
+ {
+ IMG_UINT8 sGuardRegionBefore[8];
+ IMG_CHAR sFileName[128];
+ IMG_UINT32 uLineNo;
+ IMG_SIZE_T uSize;
+ IMG_SIZE_T uSizeParityCheck;
+ enum valid_tag
+ { isFree = 0x277260FF,
+ isAllocated = 0x260511AA
+ } eValid;
+ } OSMEM_DEBUG_INFO;
+
+ #define TEST_BUFFER_PADDING_STATUS (sizeof(OSMEM_DEBUG_INFO))
+ #define TEST_BUFFER_PADDING_AFTER (8)
+ #define TEST_BUFFER_PADDING (TEST_BUFFER_PADDING_STATUS + TEST_BUFFER_PADDING_AFTER)
+#else
+ #define OSAllocMem_Debug_Wrapper OSAllocMem_Debug_Linux_Memory_Allocations
+ #define OSFreeMem_Debug_Wrapper OSFreeMem_Debug_Linux_Memory_Allocations
+#endif
+
+/*If level 1 wrapper is enabled declare the functions with extra parameters
+else alias to level 0 and declare the functions without the extra debugging parameters*/
+#if (defined(__linux__) || defined(__QNXNTO__)) && defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
+ PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line);
+ PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID pvLinAddr, IMG_HANDLE hBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line);
+
+ #define OSAllocMem_Debug_Linux_Memory_Allocations OSAllocMem_Impl
+ #define OSFreeMem_Debug_Linux_Memory_Allocations OSFreeMem_Impl
+#else
+ PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phBlockAlloc);
+ PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T ui32Size, IMG_PVOID pvLinAddr, IMG_HANDLE hBlockAlloc);
+
+ #define OSAllocMem_Debug_Linux_Memory_Allocations(flags, size, addr, blockAlloc, file, line) \
+ OSAllocMem_Impl(flags, size, addr, blockAlloc)
+ #define OSFreeMem_Debug_Linux_Memory_Allocations(flags, size, addr, blockAlloc, file, line) \
+ OSFreeMem_Impl(flags, size, addr, blockAlloc)
+#endif
+
+
+#if defined(__linux__) || defined(__QNXNTO__)
+IMG_CPU_PHYADDR OSMemHandleToCpuPAddr(IMG_VOID *hOSMemHandle, IMG_SIZE_T ui32ByteOffset);
+#else
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSMemHandleToCpuPAddr)
+#endif
+static INLINE IMG_CPU_PHYADDR OSMemHandleToCpuPAddr(IMG_HANDLE hOSMemHandle, IMG_SIZE_T ui32ByteOffset)
+{
+ IMG_CPU_PHYADDR sCpuPAddr;
+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+ PVR_UNREFERENCED_PARAMETER(ui32ByteOffset);
+ sCpuPAddr.uiAddr = 0;
+ return sCpuPAddr;
+}
+#endif
+
+#if defined(__linux__)
+IMG_BOOL OSMemHandleIsPhysContig(IMG_VOID *hOSMemHandle);
+#else
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSMemHandleIsPhysContig)
+#endif
+static INLINE IMG_BOOL OSMemHandleIsPhysContig(IMG_HANDLE hOSMemHandle)
+{
+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
+ return IMG_FALSE;
+}
+#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_SIZE_T ui32Size, const IMG_CHAR *pszFormat, ...) IMG_FORMAT_PRINTF(3, 4);
+#define OSStringLength(pszString) strlen(pszString)
+
+#if defined (SUPPORT_SID_INTERFACE)
+PVRSRV_ERROR OSEventObjectCreateKM(const IMG_CHAR *pszName,
+ PVRSRV_EVENTOBJECT_KM *psEventObject);
+PVRSRV_ERROR OSEventObjectDestroyKM(PVRSRV_EVENTOBJECT_KM *psEventObject);
+PVRSRV_ERROR OSEventObjectSignalKM(IMG_HANDLE hOSEventKM);
+PVRSRV_ERROR OSEventObjectWaitKM(IMG_HANDLE hOSEventKM);
+PVRSRV_ERROR OSEventObjectOpenKM(PVRSRV_EVENTOBJECT_KM *psEventObject,
+ IMG_HANDLE *phOSEvent);
+PVRSRV_ERROR OSEventObjectCloseKM(PVRSRV_EVENTOBJECT_KM *psEventObject,
+ IMG_HANDLE hOSEventKM);
+#else
+PVRSRV_ERROR OSEventObjectCreateKM(const IMG_CHAR *pszName,
+ PVRSRV_EVENTOBJECT *psEventObject);
+PVRSRV_ERROR OSEventObjectDestroyKM(PVRSRV_EVENTOBJECT *psEventObject);
+PVRSRV_ERROR OSEventObjectSignalKM(IMG_HANDLE hOSEventKM);
+PVRSRV_ERROR OSEventObjectWaitKM(IMG_HANDLE hOSEventKM);
+PVRSRV_ERROR OSEventObjectOpenKM(PVRSRV_EVENTOBJECT *psEventObject,
+ IMG_HANDLE *phOSEvent);
+PVRSRV_ERROR OSEventObjectCloseKM(PVRSRV_EVENTOBJECT *psEventObject,
+ IMG_HANDLE hOSEventKM);
+#endif /* #if defined (SUPPORT_SID_INTERFACE) */
+
+
+PVRSRV_ERROR OSBaseAllocContigMemory(IMG_SIZE_T ui32Size, IMG_CPU_VIRTADDR *pLinAddr, IMG_CPU_PHYADDR *pPhysAddr);
+PVRSRV_ERROR OSBaseFreeContigMemory(IMG_SIZE_T ui32Size, IMG_CPU_VIRTADDR LinAddr, IMG_CPU_PHYADDR PhysAddr);
+
+IMG_PVOID MapUserFromKernel(IMG_PVOID pvLinAddrKM,IMG_SIZE_T 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_SIZE_T ui32Size, IMG_HANDLE hMemBlock);
+
+PVRSRV_ERROR OSMapPhysToUserSpace(IMG_HANDLE hDevCookie,
+ IMG_SYS_PHYADDR sCPUPhysAddr,
+ IMG_SIZE_T uiSizeInBytes,
+ IMG_UINT32 ui32CacheFlags,
+ IMG_PVOID *ppvUserAddr,
+ IMG_SIZE_T *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);
+
+#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
+#define OSPowerLockWrap SysPowerLockWrap
+#define OSPowerLockUnwrap SysPowerLockUnwrap
+#else
+/******************************************************************************
+ @Function OSPowerLockWrap
+
+ @Description OS-specific wrapper around the power lock
+
+ @Input bTryLock - don't block on lock contention
+
+ @Return PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR OSPowerLockWrap(IMG_BOOL bTryLock);
+
+/******************************************************************************
+ @Function OSPowerLockUnwrap
+
+ @Description OS-specific wrapper around the power unlock
+
+ @Return IMG_VOID
+******************************************************************************/
+IMG_VOID OSPowerLockUnwrap(IMG_VOID);
+#endif /* SYS_CUSTOM_POWERLOCK_WRAP */
+
+/*!
+******************************************************************************
+
+ @Function OSWaitus
+
+ @Description
+ This function implements a busy wait of the specified microseconds
+ This function does NOT release thread quanta
+
+ @Input ui32Timeus - (us)
+
+ @Return IMG_VOID
+
+******************************************************************************/
+IMG_VOID OSWaitus(IMG_UINT32 ui32Timeus);
+
+/*!
+******************************************************************************
+
+ @Function OSSleepms
+
+ @Description
+ This function implements a sleep of the specified milliseconds
+ This function may allow pre-emption if implemented
+
+ @Input ui32Timems - (ms)
+
+ @Return IMG_VOID
+
+******************************************************************************/
+IMG_VOID OSSleepms(IMG_UINT32 ui32Timems);
+
+IMG_HANDLE OSFuncHighResTimerCreate(IMG_VOID);
+IMG_UINT32 OSFuncHighResTimerGetus(IMG_HANDLE hTimer);
+IMG_VOID OSFuncHighResTimerDestroy(IMG_HANDLE hTimer);
+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);
+
+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);
+
+#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_SIZE_T *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);
+
+/******************************************************************************
+
+ @Function OSPanic
+
+ @Description Take action in response to an unrecoverable driver error
+
+ @Input IMG_VOID
+
+ @Return IMG_VOID
+
+******************************************************************************/
+IMG_VOID OSPanic(IMG_VOID);
+
+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_SIZE_T ui32Bytes);
+
+PVRSRV_ERROR OSCopyToUser(IMG_PVOID pvProcess, IMG_VOID *pvDest, IMG_VOID *pvSrc, IMG_SIZE_T ui32Bytes);
+PVRSRV_ERROR OSCopyFromUser(IMG_PVOID pvProcess, IMG_VOID *pvDest, IMG_VOID *pvSrc, IMG_SIZE_T ui32Bytes);
+
+#if defined(__linux__) || defined(__QNXNTO__)
+PVRSRV_ERROR OSAcquirePhysPageAddr(IMG_VOID* pvCPUVAddr,
+ IMG_SIZE_T 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_SIZE_T 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)
+{
+ PVR_UNREFERENCED_PARAMETER(pvSysData);
+ return (in_irq()) ? IMG_TRUE : IMG_FALSE;
+}
+
+static inline IMG_VOID OSWriteMemoryBarrier(IMG_VOID)
+{
+ wmb();
+}
+
+static inline IMG_VOID OSMemoryBarrier(IMG_VOID)
+{
+ mb();
+}
+
+#else /* defined(__linux__) && defined(__KERNEL__) */
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSWriteMemoryBarrier)
+#endif
+static INLINE IMG_VOID OSWriteMemoryBarrier(IMG_VOID) { }
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSMemoryBarrier)
+#endif
+static INLINE IMG_VOID OSMemoryBarrier(IMG_VOID) { }
+
+#endif /* defined(__linux__) && defined(__KERNEL__) */
+
+/* Atomic functions */
+PVRSRV_ERROR OSAtomicAlloc(IMG_PVOID *ppvRefCount);
+IMG_VOID OSAtomicFree(IMG_PVOID pvRefCount);
+IMG_VOID OSAtomicInc(IMG_PVOID pvRefCount);
+IMG_BOOL OSAtomicDecAndTest(IMG_PVOID pvRefCount);
+IMG_UINT32 OSAtomicRead(IMG_PVOID pvRefCount);
+
+PVRSRV_ERROR OSTimeCreateWithUSOffset(IMG_PVOID *pvRet, IMG_UINT32 ui32MSOffset);
+IMG_BOOL OSTimeHasTimePassed(IMG_PVOID pvData);
+IMG_VOID OSTimeDestroy(IMG_PVOID pvData);
+
+#if defined(__linux__)
+IMG_VOID OSReleaseBridgeLock(IMG_VOID);
+IMG_VOID OSReacquireBridgeLock(IMG_VOID);
+#else
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSReleaseBridgeLock)
+#endif
+static INLINE IMG_VOID OSReleaseBridgeLock(IMG_VOID) { }
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSReacquireBridgeLock)
+#endif
+static INLINE IMG_VOID OSReacquireBridgeLock(IMG_VOID) { }
+
+#endif
+
+#if defined(__linux__)
+IMG_VOID OSGetCurrentProcessNameKM(IMG_CHAR *pszName, IMG_UINT32 ui32Size);
+#else
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(OSGetCurrentProcessNameKM)
+#endif
+static INLINE IMG_VOID OSGetCurrentProcessNameKM(IMG_CHAR *pszName, IMG_UINT32 ui32Size)
+{
+ PVR_UNREFERENCED_PARAMETER(pszName);
+ PVR_UNREFERENCED_PARAMETER(ui32Size);
+}
+
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* __OSFUNC_H__ */
+
+/******************************************************************************
+ End of file (osfunc.h)
+******************************************************************************/
+
diff --git a/pvr-source/services4/srvkm/include/osperproc.h b/pvr-source/services4/srvkm/include/osperproc.h
new file mode 100644
index 0000000..0b962b4
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/osperproc.h
@@ -0,0 +1,94 @@
+/*************************************************************************/ /*!
+@Title OS specific per process data interface
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description OS specific per process data interface
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef __OSPERPROC_H__
+#define __OSPERPROC_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#if defined(__linux__) || defined(__QNXNTO__)
+PVRSRV_ERROR OSPerProcessPrivateDataInit(IMG_HANDLE *phOsPrivateData);
+PVRSRV_ERROR OSPerProcessPrivateDataDeInit(IMG_HANDLE hOsPrivateData);
+
+PVRSRV_ERROR OSPerProcessSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase);
+#else /* defined(__linux__) */
+#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 /* defined(__linux__) */
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* __OSPERPROC_H__ */
+
+/******************************************************************************
+ End of file (osperproc.h)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/include/pdump_int.h b/pvr-source/services4/srvkm/include/pdump_int.h
new file mode 100644
index 0000000..a76fed0
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/pdump_int.h
@@ -0,0 +1,100 @@
+/*************************************************************************/ /*!
+@Title Parameter dump internal common functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+
+#ifndef __PDUMP_INT_H__
+#define __PDUMP_INT_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * This file contains internal pdump utility functions which may be accessed
+ * from OS-specific code. The header should not be included outside of srvkm
+ * pdump files.
+ */
+
+#if !defined(_UITRON)
+/*
+ * No dbgdriver on uitron, so ignore any common functions for communicating
+ * with dbgdriver.
+ */
+#include "dbgdrvif.h"
+
+/* Callbacks which are registered with the debug driver. */
+IMG_EXPORT IMG_VOID PDumpConnectionNotify(IMG_VOID);
+
+#endif /* !defined(_UITRON) */
+
+typedef enum
+{
+ /* Continuous writes are always captured in the dbgdrv; the buffer will
+ * expand if no client/sink process is running.
+ */
+ PDUMP_WRITE_MODE_CONTINUOUS = 0,
+ /* Last frame capture */
+ PDUMP_WRITE_MODE_LASTFRAME,
+ /* Capture frame, binary data */
+ PDUMP_WRITE_MODE_BINCM,
+ /* Persistent capture, append data to init phase */
+ PDUMP_WRITE_MODE_PERSISTENT
+} PDUMP_DDWMODE;
+
+
+IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags);
+
+IMG_UINT32 PDumpOSDebugDriverWrite( PDBG_STREAM psStream,
+ PDUMP_DDWMODE eDbgDrvWriteMode,
+ IMG_UINT8 *pui8Data,
+ IMG_UINT32 ui32BCount,
+ IMG_UINT32 ui32Level,
+ IMG_UINT32 ui32DbgDrvFlags);
+
+#if defined (__cplusplus)
+}
+#endif
+#endif /* __PDUMP_INT_H__ */
+
+/******************************************************************************
+ End of file (pdump_int.h)
+******************************************************************************/
+
diff --git a/pvr-source/services4/srvkm/include/pdump_km.h b/pvr-source/services4/srvkm/include/pdump_km.h
new file mode 100644
index 0000000..e4325cc
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/pdump_km.h
@@ -0,0 +1,441 @@
+/*************************************************************************/ /*!
+@Title pdump functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Main APIs for pdump functions
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef _PDUMP_KM_H_
+#define _PDUMP_KM_H_
+
+
+/*
+ * Include the OS abstraction APIs
+ */
+#include "pdump_osfunc.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * Pull in pdump flags from services include
+ */
+#include "pdump.h"
+
+#define PDUMP_PD_UNIQUETAG (IMG_HANDLE)0
+#define PDUMP_PT_UNIQUETAG (IMG_HANDLE)0
+
+/*
+ * PDump streams (common to all OSes)
+ */
+#define PDUMP_STREAM_PARAM2 0
+#define PDUMP_STREAM_SCRIPT2 1
+#define PDUMP_STREAM_DRIVERINFO 2
+#define PDUMP_NUM_STREAMS 3
+
+#if defined(PDUMP_DEBUG_OUTFILES)
+/* counter increments each time debug write is called */
+extern IMG_UINT32 g_ui32EveryLineCounter;
+#endif
+
+#ifndef PDUMP
+#define MAKEUNIQUETAG(hMemInfo) (0)
+#endif
+
+#ifdef PDUMP
+
+#define MAKEUNIQUETAG(hMemInfo) (((BM_BUF *)(((PVRSRV_KERNEL_MEM_INFO *)(hMemInfo))->sMemBlk.hBuffer))->pMapping)
+
+ IMG_IMPORT PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 ui32Offset,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ PDUMP_POLL_OPERATOR eOperator,
+ IMG_UINT32 ui32Flags,
+ 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_IDENTIFIER *psDevID,
+ 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 PDumpMemPDEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib,
+ IMG_HANDLE hOSMemHandle,
+ IMG_CPU_VIRTADDR pvLinAddr,
+ IMG_UINT32 ui32Bytes,
+ IMG_UINT32 ui32Flags,
+ IMG_BOOL bInitialisePages,
+ IMG_HANDLE hUniqueTag1,
+ IMG_HANDLE hUniqueTag2);
+
+ PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib,
+ IMG_HANDLE hOSMemHandle,
+ 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);
+ IMG_BOOL PDumpIsSuspended(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_CHAR *pszPDumpRegName,
+ IMG_UINT32 ui32RegAddr,
+ IMG_UINT32 ui32RegValue,
+ IMG_UINT32 ui32Flags);
+ PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_CHAR *pszPDumpRegName,
+ IMG_UINT32 ui32RegAddr,
+ IMG_UINT32 ui32RegValue,
+ IMG_UINT32 ui32Mask,
+ IMG_UINT32 ui32Flags,
+ PDUMP_POLL_OPERATOR eOperator);
+ PVRSRV_ERROR PDumpRegPolKM(IMG_CHAR *pszPDumpRegName,
+ IMG_UINT32 ui32RegAddr,
+ IMG_UINT32 ui32RegValue,
+ IMG_UINT32 ui32Mask,
+ PDUMP_POLL_OPERATOR eOperator);
+
+ IMG_IMPORT PVRSRV_ERROR PDumpBitmapKM(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_UINT32 ui32Width,
+ IMG_UINT32 ui32Height,
+ IMG_UINT32 ui32StrideInBytes,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+ IMG_HANDLE hDevMemContext,
+ IMG_UINT32 ui32Size,
+ PDUMP_PIXEL_FORMAT ePixelFormat,
+ PDUMP_MEM_FORMAT eMemFormat,
+ IMG_UINT32 ui32PDumpFlags);
+ IMG_IMPORT PVRSRV_ERROR PDumpReadRegKM(IMG_CHAR *pszPDumpRegName,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_UINT32 ui32Address,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32PDumpFlags);
+
+ PVRSRV_ERROR PDumpRegKM(IMG_CHAR* pszPDumpRegName,
+ IMG_UINT32 dwReg,
+ IMG_UINT32 dwData);
+
+ PVRSRV_ERROR PDumpComment(IMG_CHAR* pszFormat, ...) IMG_FORMAT_PRINTF(1, 2);
+ PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32 ui32Flags,
+ IMG_CHAR* pszFormat,
+ ...) IMG_FORMAT_PRINTF(2, 3);
+
+ PVRSRV_ERROR PDumpPDReg(PDUMP_MMU_ATTRIB *psMMUAttrib,
+ IMG_UINT32 ui32Reg,
+ IMG_UINT32 ui32dwData,
+ IMG_HANDLE hUniqueTag);
+ PVRSRV_ERROR PDumpPDRegWithFlags(PDUMP_MMU_ATTRIB *psMMUAttrib,
+ IMG_UINT32 ui32Reg,
+ IMG_UINT32 ui32Data,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag);
+
+ IMG_BOOL PDumpIsLastCaptureFrameKM(IMG_VOID);
+ IMG_IMPORT IMG_BOOL PDumpIsCaptureFrameKM(IMG_VOID);
+
+ IMG_VOID PDumpMallocPagesPhys(PVRSRV_DEVICE_IDENTIFIER *psDevID,
+ IMG_UINT32 ui32DevVAddr,
+ IMG_PUINT32 pui32PhysPages,
+ IMG_UINT32 ui32NumPages,
+ IMG_HANDLE hUniqueTag);
+ PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
+ IMG_CHAR *pszMemSpace,
+ IMG_UINT32 *pui32MMUContextID,
+ IMG_UINT32 ui32MMUType,
+ IMG_HANDLE hUniqueTag1,
+ IMG_HANDLE hOSMemHandle,
+ IMG_VOID *pvPDCPUAddr);
+ PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
+ IMG_CHAR *pszMemSpace,
+ IMG_UINT32 ui32MMUContextID,
+ IMG_UINT32 ui32MMUType);
+
+ 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);
+
+ PVRSRV_ERROR PDumpSaveMemKM (PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32DataMaster,
+ IMG_UINT32 ui32PDumpFlags);
+
+ PVRSRV_ERROR PDumpTASignatureRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_UINT32 ui32DumpFrameNum,
+ IMG_UINT32 ui32TAKickCount,
+ IMG_BOOL bLastFrame,
+ IMG_UINT32 *pui32Registers,
+ IMG_UINT32 ui32NumRegisters);
+
+ PVRSRV_ERROR PDump3DSignatureRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_UINT32 ui32DumpFrameNum,
+ IMG_BOOL bLastFrame,
+ IMG_UINT32 *pui32Registers,
+ IMG_UINT32 ui32NumRegisters);
+
+ PVRSRV_ERROR PDumpCounterRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_UINT32 ui32DumpFrameNum,
+ IMG_BOOL bLastFrame,
+ IMG_UINT32 *pui32Registers,
+ IMG_UINT32 ui32NumRegisters);
+
+ PVRSRV_ERROR PDumpRegRead(IMG_CHAR *pszPDumpRegName,
+ const IMG_UINT32 dwRegOffset,
+ IMG_UINT32 ui32Flags);
+
+ PVRSRV_ERROR PDumpCycleCountRegRead(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ const IMG_UINT32 dwRegOffset,
+ IMG_BOOL bLastFrame);
+
+ PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags);
+ PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks);
+
+ PVRSRV_ERROR PDumpMallocPages(PVRSRV_DEVICE_IDENTIFIER *psDevID,
+ IMG_UINT32 ui32DevVAddr,
+ IMG_CPU_VIRTADDR pvLinAddr,
+ IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32NumBytes,
+ IMG_UINT32 ui32PageSize,
+ IMG_BOOL bShared,
+ IMG_HANDLE hUniqueTag);
+ PVRSRV_ERROR PDumpMallocPageTable(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32Offset,
+ IMG_CPU_VIRTADDR pvLinAddr,
+ IMG_UINT32 ui32NumBytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag);
+ PVRSRV_ERROR PDumpFreePages(struct _BM_HEAP_ *psBMHeap,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_UINT32 ui32NumBytes,
+ IMG_UINT32 ui32PageSize,
+ IMG_HANDLE hUniqueTag,
+ IMG_BOOL bInterleaved,
+ IMG_BOOL bSparse);
+ PVRSRV_ERROR PDumpFreePageTable(PVRSRV_DEVICE_IDENTIFIER *psDevID,
+ IMG_HANDLE hOSMemHandle,
+ IMG_CPU_VIRTADDR pvLinAddr,
+ IMG_UINT32 ui32NumBytes,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag);
+
+ IMG_IMPORT PVRSRV_ERROR PDumpHWPerfCBKM(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32MMUContextID,
+ IMG_UINT32 ui32PDumpFlags);
+
+ PVRSRV_ERROR PDumpSignatureBuffer(PVRSRV_DEVICE_IDENTIFIER *psDevId,
+ IMG_CHAR *pszFileName,
+ IMG_CHAR *pszBufferType,
+ IMG_UINT32 ui32FileOffset,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32MMUContextID,
+ IMG_UINT32 ui32PDumpFlags);
+
+ PVRSRV_ERROR PDumpCBP(PPVRSRV_KERNEL_MEM_INFO psROffMemInfo,
+ IMG_UINT32 ui32ROffOffset,
+ IMG_UINT32 ui32WPosVal,
+ IMG_UINT32 ui32PacketSize,
+ IMG_UINT32 ui32BufferSize,
+ IMG_UINT32 ui32Flags,
+ IMG_HANDLE hUniqueTag);
+
+ PVRSRV_ERROR PDumpRegBasedCBP(IMG_CHAR *pszPDumpRegName,
+ IMG_UINT32 ui32RegOffset,
+ IMG_UINT32 ui32WPosVal,
+ IMG_UINT32 ui32PacketSize,
+ IMG_UINT32 ui32BufferSize,
+ IMG_UINT32 ui32Flags);
+
+ IMG_VOID PDumpVGXMemToFile(IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 uiAddr,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32PDumpFlags,
+ IMG_HANDLE hUniqueTag);
+
+ IMG_VOID PDumpSuspendKM(IMG_VOID);
+ IMG_VOID PDumpResumeKM(IMG_VOID);
+
+ /* New pdump common functions */
+ PVRSRV_ERROR PDumpStoreMemToFile(PDUMP_MMU_ATTRIB *psMMUAttrib,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ PVRSRV_KERNEL_MEM_INFO *psMemInfo,
+ IMG_UINT32 uiAddr,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32PDumpFlags,
+ IMG_HANDLE hUniqueTag);
+
+ #define PDUMPMEMPOL PDumpMemPolKM
+ #define PDUMPMEM PDumpMemKM
+ #define PDUMPMEMPTENTRIES PDumpMemPTEntriesKM
+ #define PDUMPPDENTRIES PDumpMemPDEntriesKM
+ #define PDUMPMEMUM PDumpMemUM
+ #define PDUMPINIT PDumpInitCommon
+ #define PDUMPDEINIT PDumpDeInitCommon
+ #define PDUMPISLASTFRAME PDumpIsLastCaptureFrameKM
+ #define PDUMPTESTFRAME PDumpIsCaptureFrameKM
+ #define PDUMPTESTNEXTFRAME PDumpTestNextFrame
+ #define PDUMPREGWITHFLAGS PDumpRegWithFlagsKM
+ #define PDUMPREG PDumpRegKM
+ #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 PDUMPPDDEVPADDR PDumpPDDevPAddrKM
+ #define PDUMPFREEPAGES PDumpFreePages
+ #define PDUMPFREEPAGETABLE PDumpFreePageTable
+ #define PDUMPPDREG PDumpPDReg
+ #define PDUMPPDREGWITHFLAGS PDumpPDRegWithFlags
+ #define PDUMPCBP PDumpCBP
+ #define PDUMPREGBASEDCBP PDumpRegBasedCBP
+ #define PDUMPMALLOCPAGESPHYS PDumpMallocPagesPhys
+ #define PDUMPENDINITPHASE PDumpStopInitPhaseKM
+ #define PDUMPBITMAPKM PDumpBitmapKM
+ #define PDUMPDRIVERINFO PDumpDriverInfoKM
+ #define PDUMPIDLWITHFLAGS PDumpIDLWithFlags
+ #define PDUMPIDL PDumpIDL
+ #define PDUMPSUSPEND PDumpSuspendKM
+ #define PDUMPRESUME PDumpResumeKM
+
+#else
+#if defined LINUX || defined (__QNXNTO__) || defined GCC_IA32 || defined GCC_ARM
+ #define PDUMPMEMPOL(args...)
+ #define PDUMPMEM(args...)
+ #define PDUMPMEMPTENTRIES(args...)
+ #define PDUMPPDENTRIES(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 PDUMPPDDEVPADDR(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 PDUMPREGBASEDCBP(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 /* _PDUMP_KM_H_ */
+
+/******************************************************************************
+ End of file (pdump_km.h)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/include/pdump_osfunc.h b/pvr-source/services4/srvkm/include/pdump_osfunc.h
new file mode 100644
index 0000000..0f2e103
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/pdump_osfunc.h
@@ -0,0 +1,337 @@
+/*************************************************************************/ /*!
+@Title OS-independent interface to helper functions for pdump
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stdarg.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/*
+ * Some OSes (WinXP,CE) allocate the string on the stack, but some
+ * (Linux,Symbian) use a global variable/lock instead.
+ * Would be good to use the same across all OSes.
+ *
+ * A handle is returned which represents IMG_CHAR* type on all OSes except
+ * Symbian when it represents PDumpState* type.
+ *
+ * The allocated buffer length is also returned on OSes where it's
+ * supported (e.g. Linux).
+ */
+#define MAX_PDUMP_STRING_LENGTH (256)
+#if defined(__QNXNTO__)
+#define PDUMP_GET_SCRIPT_STRING() \
+ IMG_CHAR pszScript[MAX_PDUMP_STRING_LENGTH]; \
+ IMG_UINT32 ui32MaxLen = MAX_PDUMP_STRING_LENGTH-1; \
+ IMG_HANDLE hScript = (IMG_HANDLE)pszScript;
+
+#define PDUMP_GET_MSG_STRING() \
+ IMG_CHAR pszMsg[MAX_PDUMP_STRING_LENGTH]; \
+ IMG_UINT32 ui32MaxLen = MAX_PDUMP_STRING_LENGTH-1;
+
+#define PDUMP_GET_FILE_STRING() \
+ IMG_CHAR pszFileName[MAX_PDUMP_STRING_LENGTH]; \
+ IMG_UINT32 ui32MaxLen = MAX_PDUMP_STRING_LENGTH-1;
+
+#define PDUMP_GET_SCRIPT_AND_FILE_STRING() \
+ IMG_CHAR pszScript[MAX_PDUMP_STRING_LENGTH]; \
+ IMG_CHAR pszFileName[MAX_PDUMP_STRING_LENGTH]; \
+ IMG_UINT32 ui32MaxLenScript = MAX_PDUMP_STRING_LENGTH-1; \
+ IMG_UINT32 ui32MaxLenFileName = MAX_PDUMP_STRING_LENGTH-1; \
+ IMG_HANDLE hScript = (IMG_HANDLE)pszScript;
+
+#else /* WIN32 or QNX */
+
+
+ /*
+ * Linux
+ */
+#define PDUMP_GET_SCRIPT_STRING() \
+ IMG_HANDLE hScript; \
+ IMG_UINT32 ui32MaxLen; \
+ PVRSRV_ERROR eError; \
+ eError = PDumpOSGetScriptString(&hScript, &ui32MaxLen);\
+ if(eError != PVRSRV_OK) return eError;
+
+#define PDUMP_GET_MSG_STRING() \
+ IMG_CHAR *pszMsg; \
+ IMG_UINT32 ui32MaxLen; \
+ PVRSRV_ERROR eError; \
+ eError = PDumpOSGetMessageString(&pszMsg, &ui32MaxLen);\
+ if(eError != PVRSRV_OK) return eError;
+
+#define PDUMP_GET_FILE_STRING() \
+ IMG_CHAR *pszFileName; \
+ IMG_UINT32 ui32MaxLen; \
+ PVRSRV_ERROR eError; \
+ eError = PDumpOSGetFilenameString(&pszFileName, &ui32MaxLen);\
+ if(eError != PVRSRV_OK) return eError;
+
+#define PDUMP_GET_SCRIPT_AND_FILE_STRING() \
+ IMG_HANDLE hScript; \
+ IMG_CHAR *pszFileName; \
+ IMG_UINT32 ui32MaxLenScript; \
+ IMG_UINT32 ui32MaxLenFileName; \
+ PVRSRV_ERROR eError; \
+ eError = PDumpOSGetScriptString(&hScript, &ui32MaxLenScript);\
+ if(eError != PVRSRV_OK) return eError; \
+ eError = PDumpOSGetFilenameString(&pszFileName, &ui32MaxLenFileName);\
+ if(eError != PVRSRV_OK) return eError;
+
+ /*!
+ * @name PDumpOSGetScriptString
+ * @brief Get the "script" buffer
+ * @param phScript - buffer handle for pdump script
+ * @param pui32MaxLen - max length of the script buffer
+ * FIXME: the max length should be internal to the OS-specific code
+ * @return error (always PVRSRV_OK on some OSes)
+ */
+ PVRSRV_ERROR PDumpOSGetScriptString(IMG_HANDLE *phScript, IMG_UINT32 *pui32MaxLen);
+
+ /*!
+ * @name PDumpOSGetMessageString
+ * @brief Get the "message" buffer
+ * @param pszMsg - buffer pointer for pdump messages
+ * @param pui32MaxLen - max length of the message buffer
+ * FIXME: the max length should be internal to the OS-specific code
+ * @return error (always PVRSRV_OK on some OSes)
+ */
+ PVRSRV_ERROR PDumpOSGetMessageString(IMG_CHAR **ppszMsg, IMG_UINT32 *pui32MaxLen);
+
+ /*!
+ * @name PDumpOSGetFilenameString
+ * @brief Get the "filename" buffer
+ * @param ppszFile - buffer pointer for filename
+ * @param pui32MaxLen - max length of the filename buffer
+ * FIXME: the max length should be internal to the OS-specific code
+ * @return error (always PVRSRV_OK on some OSes)
+ */
+ PVRSRV_ERROR PDumpOSGetFilenameString(IMG_CHAR **ppszFile, IMG_UINT32 *pui32MaxLen);
+
+#endif /* WIN32 or QNX */
+
+
+/*
+ * Define macro for processing variable args list in OS-independent
+ * manner. See e.g. PDumpComment().
+ */
+
+#define PDUMP_va_list va_list
+#define PDUMP_va_start va_start
+#define PDUMP_va_end va_end
+
+
+
+/*!
+ * @name PDumpOSGetStream
+ * @brief Get a handle to the labelled stream (cast the handle to PDBG_STREAM to use it)
+ * @param ePDumpStream - stream label
+ */
+IMG_HANDLE PDumpOSGetStream(IMG_UINT32 ePDumpStream);
+
+/*!
+ * @name PDumpOSGetStreamOffset
+ * @brief Return current offset within the labelled stream
+ * @param ePDumpStream - stream label
+ */
+IMG_UINT32 PDumpOSGetStreamOffset(IMG_UINT32 ePDumpStream);
+
+/*!
+ * @name PDumpOSGetParamFileNum
+ * @brief Return file number of the 'script' stream, in the case that the file was split
+ * @param ePDumpStream - stream label
+ */
+IMG_UINT32 PDumpOSGetParamFileNum(IMG_VOID);
+
+/*!
+ * @name PDumpOSCheckForSplitting
+ * @brief Check if the requested pdump params are too large for a single file
+ * @param hStream - pdump stream
+ * @param ui32Size - size of params to dump (bytes)
+ * @param ui32Flags - pdump flags
+ */
+IMG_VOID PDumpOSCheckForSplitting(IMG_HANDLE hStream, IMG_UINT32 ui32Size, IMG_UINT32 ui32Flags);
+
+/*!
+ * @name PDumpOSIsSuspended
+ * @brief Is the pdump stream busy?
+ * @return IMG_BOOL
+ */
+IMG_BOOL PDumpOSIsSuspended(IMG_VOID);
+
+/*!
+ * @name PDumpOSIsSuspended
+ * @brief Is the pdump jump table initialised?
+ * @return IMG_BOOL
+ */
+IMG_BOOL PDumpOSJTInitialised(IMG_VOID);
+
+/*!
+ * @name PDumpOSWriteString
+ * @brief General function for writing to pdump stream.
+ * Usually more convenient to use PDumpOSWriteString2 below.
+ * @param hDbgStream - pdump stream handle
+ * @param psui8Data - data to write
+ * @param ui32Size - size of write
+ * @param ui32Flags - pdump flags
+ * @return error
+ */
+IMG_BOOL PDumpOSWriteString(IMG_HANDLE hDbgStream,
+ IMG_UINT8 *psui8Data,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32Flags);
+
+/*!
+ * @name PDumpOSWriteString2
+ * @brief Write a string to the "script" output stream
+ * @param pszScript - buffer to write (ptr to state structure on Symbian)
+ * @param ui32Flags - pdump flags
+ * @return error
+ */
+IMG_BOOL PDumpOSWriteString2(IMG_HANDLE hScript, IMG_UINT32 ui32Flags);
+
+/*!
+ * @name PDumpOSBufprintf
+ * @brief Printf to OS-specific pdump state buffer
+ * @param hBuf - buffer handle to write into (ptr to state structure on Symbian)
+ * @param ui32ScriptSizeMax - maximum size of data to write (not supported on all OSes)
+ * @param pszFormat - format string
+ */
+PVRSRV_ERROR PDumpOSBufprintf(IMG_HANDLE hBuf, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, ...) IMG_FORMAT_PRINTF(3, 4);
+
+/*!
+ * @name PDumpOSDebugPrintf
+ * @brief Debug message during pdumping
+ * @param pszFormat - format string
+ */
+IMG_VOID PDumpOSDebugPrintf(IMG_CHAR* pszFormat, ...) IMG_FORMAT_PRINTF(1, 2);
+
+/*
+ * Write into a IMG_CHAR* on all OSes. Can be allocated on the stack or heap.
+ */
+/*!
+ * @name PDumpOSSprintf
+ * @brief Printf to IMG char array
+ * @param pszComment - char array to print into
+ * @param pszFormat - format string
+ */
+PVRSRV_ERROR PDumpOSSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR *pszFormat, ...) IMG_FORMAT_PRINTF(3, 4);
+
+/*!
+ * @name PDumpOSVSprintf
+ * @brief Printf to IMG string using variable args (see stdarg.h). This is necessary
+ * because the ... notation does not support nested function calls.
+ * @param pszMsg - char array to print into
+ * @param ui32ScriptSizeMax - maximum size of data to write (not supported on all OSes)
+ * @param pszFormat - format string
+ * @param vaArgs - variable args structure (from stdarg.h)
+ */
+PVRSRV_ERROR PDumpOSVSprintf(IMG_CHAR *pszMsg, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, PDUMP_va_list vaArgs) IMG_FORMAT_PRINTF(3, 0);
+
+/*!
+ * @name PDumpOSBuflen
+ * @param hBuffer - handle to buffer (ptr to state structure on Symbian)
+ * @param ui32BuffeRSizeMax - max size of buffer (chars)
+ * @return length of buffer, will always be <= ui32BufferSizeMax
+ */
+IMG_UINT32 PDumpOSBuflen(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax);
+
+/*!
+ * @name PDumpOSVerifyLineEnding
+ * @brief Put \r\n sequence at the end if it isn't already there
+ * @param hBuffer - handle to buffer
+ * @param ui32BufferSizeMax - max size of buffer (chars)
+ */
+IMG_VOID PDumpOSVerifyLineEnding(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax);
+
+/*!
+ * @name PDumpOSCPUVAddrToDevPAddr
+ * @brief OS function to convert CPU virtual to device physical for dumping pages
+ * @param hOSMemHandle mem allocation handle (used if kernel virtual mem space is limited, e.g. linux)
+ * @param ui32Offset dword offset into allocation (for use with mem handle, e.g. linux)
+ * @param pui8LinAddr CPU linear addr (usually a kernel virtual address)
+ * @param ui32PageSize page size, used for assertion check
+ * @return psDevPAddr device physical addr
+ */
+IMG_VOID PDumpOSCPUVAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType,
+ IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32Offset,
+ IMG_UINT8 *pui8LinAddr,
+ IMG_UINT32 ui32PageSize,
+ IMG_DEV_PHYADDR *psDevPAddr);
+
+/*!
+ * @name PDumpOSCPUVAddrToPhysPages
+ * @brief OS function to convert CPU virtual to backing physical pages
+ * @param hOSMemHandle mem allocation handle (used if kernel virtual mem space is limited, e.g. linux)
+ * @param ui32Offset offset within mem allocation block
+ * @param pui8LinAddr CPU linear addr
+ * @param ui32DataPageMask mask for data page (= data page size -1)
+ * @return pui32PageOffset CPU page offset (same as device page offset if page sizes equal)
+ */
+IMG_VOID PDumpOSCPUVAddrToPhysPages(IMG_HANDLE hOSMemHandle,
+ IMG_UINT32 ui32Offset,
+ IMG_PUINT8 pui8LinAddr,
+ IMG_UINT32 ui32DataPageMask,
+ IMG_UINT32 *pui32PageOffset);
+
+/*!
+ * @name PDumpOSReleaseExecution
+ * @brief OS function to switch to another process, to clear pdump buffers
+ */
+IMG_VOID PDumpOSReleaseExecution(IMG_VOID);
+
+/*!
+ * @name PDumpOSIsCaptureFrameKM
+ * @brief Is the current frame a capture frame?
+ */
+IMG_BOOL PDumpOSIsCaptureFrameKM(IMG_VOID);
+
+/*!
+ * @name PDumpOSSetFrameKM
+ * @brief Set frame counter
+ */
+PVRSRV_ERROR PDumpOSSetFrameKM(IMG_UINT32 ui32Frame);
+
+#if defined (__cplusplus)
+}
+#endif
diff --git a/pvr-source/services4/srvkm/include/perfkm.h b/pvr-source/services4/srvkm/include/perfkm.h
new file mode 100644
index 0000000..458a29b
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/perfkm.h
@@ -0,0 +1,53 @@
+/*************************************************************************/ /*!
+@Title Perf initialisation
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef _PERFKM_H_
+#define _PERFKM_H_
+
+#include "img_types.h"
+
+#define PERFINIT()
+#define PERFDEINIT()
+
+#endif /* _PERFKM_H_ */
+
+/******************************************************************************
+ End of file (perfkm.h)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/include/perproc.h b/pvr-source/services4/srvkm/include/perproc.h
new file mode 100644
index 0000000..d603613
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/perproc.h
@@ -0,0 +1,150 @@
+/*************************************************************************/ /*!
+@Title Handle Manager API
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Perprocess data
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#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;
+#if defined (SUPPORT_SID_INTERFACE)
+ IMG_SID hPerProcData;
+#else
+ IMG_HANDLE hPerProcData;
+#endif
+ PVRSRV_HANDLE_BASE *psHandleBase;
+#if defined (SUPPORT_SID_INTERFACE)
+ /* Handles are being allocated in batches */
+ IMG_BOOL bHandlesBatched;
+#else
+#if defined (PVR_SECURE_HANDLES)
+ /* Handles are being allocated in batches */
+ IMG_BOOL bHandlesBatched;
+#endif /* PVR_SECURE_HANDLES */
+#endif /* SUPPORT_SID_INTERFACE */
+ IMG_UINT32 ui32RefCount;
+
+ /* True if the process is the initialisation server. */
+ IMG_BOOL bInitProcess;
+#if defined(PDUMP)
+ /* True if pdump data from the process is 'persistent' */
+ IMG_BOOL bPDumpPersistent;
+#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
+ /* True if this process is marked for pdumping. This flag is
+ * significant in a multi-app environment.
+ */
+ IMG_BOOL bPDumpActive;
+#endif /* SUPPORT_PDUMP_MULTI_PROCESS */
+#endif
+ /*
+ * OS specific data can be stored via this handle.
+ * See osperproc.h for a generic mechanism for initialising
+ * this field.
+ */
+ IMG_HANDLE hOsPrivateData;
+} PVRSRV_PER_PROCESS_DATA;
+
+PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(IMG_UINT32 ui32PID);
+
+PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32 ui32PID, IMG_UINT32 ui32Flags);
+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 /* __PERPROC_H__ */
+
+/******************************************************************************
+ End of file (perproc.h)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/include/power.h b/pvr-source/services4/srvkm/include/power.h
new file mode 100644
index 0000000..0abaf75
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/power.h
@@ -0,0 +1,140 @@
+/*************************************************************************/ /*!
+@Title Power Management Functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Main APIs for power management functions
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef POWER_H
+#define POWER_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/*!
+ *****************************************************************************
+ * Power management
+ *****************************************************************************/
+
+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;
+ PVRSRV_DEV_POWER_STATE eDefaultPowerState;
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState;
+ struct _PVRSRV_POWER_DEV_TAG_ *psNext;
+ struct _PVRSRV_POWER_DEV_TAG_ **ppsThis;
+
+} 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,
+ PVRSRV_DEV_POWER_STATE eNewPowerState);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSystemPrePowerStateKM(PVRSRV_SYS_POWER_STATE eNewPowerState);
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSystemPostPowerStateKM(PVRSRV_SYS_POWER_STATE eNewPowerState);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVSetPowerStateKM (PVRSRV_SYS_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,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState,
+ PVRSRV_DEV_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 /* POWER_H */
+
+/******************************************************************************
+ End of file (power.h)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/include/queue.h b/pvr-source/services4/srvkm/include/queue.h
new file mode 100644
index 0000000..58f8093
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/queue.h
@@ -0,0 +1,145 @@
+/*************************************************************************/ /*!
+@Title Command Queue API
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Internal structures and definitions for command queues
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef QUEUE_H
+#define QUEUE_H
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ * Macro to Read Offset in given command queue
+ */
+#define UPDATE_QUEUE_ROFF(psQueue, ui32Size) \
+ (psQueue)->ui32ReadOffset = ((psQueue)->ui32ReadOffset + (ui32Size)) \
+ & ((psQueue)->ui32QueueSize - 1);
+
+/*!
+ generic cmd complete structure.
+ This structure represents the storage required between starting and finishing
+ a given cmd and is required to hold the generic sync object update data.
+ note: for any given system we know what command types we support and
+ therefore how much storage is required for any number of commands in progress
+ */
+ typedef struct _COMMAND_COMPLETE_DATA_
+ {
+ IMG_BOOL bInUse;
+ /* <arg(s) to PVRSRVProcessQueues>; */ /*!< TBD */
+ IMG_UINT32 ui32DstSyncCount; /*!< number of dst sync objects */
+ IMG_UINT32 ui32SrcSyncCount; /*!< number of src sync objects */
+ PVRSRV_SYNC_OBJECT *psDstSync; /*!< dst sync ptr list,
+ allocated on back of this structure */
+ PVRSRV_SYNC_OBJECT *psSrcSync; /*!< src sync ptr list,
+ allocated on back of this structure */
+ IMG_UINT32 ui32AllocSize; /*!< allocated size*/
+ PFN_QUEUE_COMMAND_COMPLETE pfnCommandComplete; /*!< Command complete callback */
+ IMG_HANDLE hCallbackData; /*!< Command complete callback data */
+ }COMMAND_COMPLETE_DATA, *PCOMMAND_COMPLETE_DATA;
+
+#if !defined(USE_CODE)
+IMG_VOID QueueDumpDebugInfo(IMG_VOID);
+
+IMG_IMPORT
+PVRSRV_ERROR PVRSRVProcessQueues (IMG_BOOL bFlush);
+
+#if defined(__linux__) && defined(__KERNEL__)
+#include <linux/types.h>
+#include <linux/seq_file.h>
+void* ProcSeqOff2ElementQueue(struct seq_file * sfile, loff_t off);
+void ProcSeqShowQueue(struct seq_file *sfile,void* el);
+#endif
+
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T 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_SIZE_T ui32DataByteSize,
+ PFN_QUEUE_COMMAND_COMPLETE pfnCommandComplete,
+ IMG_HANDLE hCallbackData);
+
+IMG_IMPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetQueueSpaceKM(PVRSRV_QUEUE_INFO *psQueue,
+ IMG_SIZE_T 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_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 /* !defined(USE_CODE) */
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* QUEUE_H */
+
+/******************************************************************************
+ End of file (queue.h)
+******************************************************************************/
diff --git a/pvr-source/services4/srvkm/include/ra.h b/pvr-source/services4/srvkm/include/ra.h
new file mode 100644
index 0000000..b84a8e5
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/ra.h
@@ -0,0 +1,293 @@
+/*************************************************************************/ /*!
+@Title Resource Allocator API
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _RA_H_
+#define _RA_H_
+
+#include "img_types.h"
+#include "hash.h"
+#include "osfunc.h"
+
+/** Resource arena.
+ * struct _RA_ARENA_ deliberately opaque
+ */
+typedef struct _RA_ARENA_ RA_ARENA; //PRQA S 3313
+typedef struct _BM_MAPPING_ BM_MAPPING;
+
+
+
+/** Enable support for arena statistics. */
+#define RA_STATS
+
+
+/** Resource arena statistics. */
+struct _RA_STATISTICS_
+{
+ /** total number of segments add to the arena */
+ IMG_SIZE_T uSpanCount;
+
+ /** number of current live segments within the arena */
+ IMG_SIZE_T uLiveSegmentCount;
+
+ /** number of current free segments within the arena */
+ IMG_SIZE_T uFreeSegmentCount;
+
+ /** total number of resource within the arena */
+ IMG_SIZE_T uTotalResourceCount;
+
+ /** number of free resource within the arena */
+ IMG_SIZE_T uFreeResourceCount;
+
+ /** total number of resources allocated from the arena */
+ IMG_SIZE_T uCumulativeAllocs;
+
+ /** total number of resources returned to the arena */
+ IMG_SIZE_T uCumulativeFrees;
+
+ /** total number of spans allocated by the callback mechanism */
+ IMG_SIZE_T uImportCount;
+
+ /** total number of spans deallocated by the callback mechanism */
+ IMG_SIZE_T uExportCount;
+
+ IMG_SIZE_T uFailedAllocCount;
+
+};
+typedef struct _RA_STATISTICS_ RA_STATISTICS;
+
+struct _RA_SEGMENT_DETAILS_
+{
+ IMG_SIZE_T uiSize;
+ IMG_CPU_PHYADDR sCpuPhyAddr;
+ IMG_HANDLE hSegment;
+};
+typedef struct _RA_SEGMENT_DETAILS_ RA_SEGMENT_DETAILS;
+
+/**
+ * @Function RA_Create
+ *
+ * @Description
+ *
+ * To create a resource arena.
+ *
+ * @Input name - the name of the arena for diagnostic purposes.
+ * @Input base - the base of an initial resource span or 0.
+ * @Input uSize - the size of an initial resource span or 0.
+ * @Input pRef - the reference to return for the initial resource or 0.
+ * @Input uQuantum - the arena allocation quantum.
+ * @Input alloc - a resource allocation callback or 0.
+ * @Input free - a resource de-allocation callback or 0.
+ * @Input import_handle - handle passed to alloc and free or 0.
+ * @Return arena handle, or IMG_NULL.
+ */
+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_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_UINTPTR_T *pBase),
+ IMG_VOID (*imp_free) (IMG_VOID *,
+ IMG_UINTPTR_T,
+ BM_MAPPING *),
+ IMG_VOID (*backingstore_free) (IMG_VOID *,
+ IMG_SIZE_T,
+ IMG_SIZE_T,
+ IMG_HANDLE),
+ IMG_VOID *import_handle);
+
+/**
+ * @Function RA_Delete
+ *
+ * @Description
+ *
+ * To delete a resource arena. All resources allocated from the arena
+ * must be freed before deleting the arena.
+ *
+ * @Input pArena - the arena to delete.
+ * @Return None
+ */
+IMG_VOID
+RA_Delete (RA_ARENA *pArena);
+
+/**
+ * @Function RA_TestDelete
+ *
+ * @Description
+ *
+ * To test whether it is safe to delete a resource arena. If any allocations
+ * have not been freed, the RA must not be deleted.
+ *
+ * @Input pArena - the arena to test.
+ * @Return IMG_BOOL - IMG_TRUE if is safe to go on and call RA_Delete.
+ */
+IMG_BOOL
+RA_TestDelete (RA_ARENA *pArena);
+
+/**
+ * @Function RA_Add
+ *
+ * @Description
+ *
+ * To add a resource span to an arena. The span must not overlap with
+ * any span previously added to the arena.
+ *
+ * @Input pArena - the arena to add a span into.
+ * @Input base - the base of the span.
+ * @Input uSize - the extent of the span.
+ * @Return IMG_TRUE - success, IMG_FALSE - failure
+ */
+IMG_BOOL
+RA_Add (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize);
+
+/**
+ * @Function RA_Alloc
+ *
+ * @Description
+ *
+ * To allocate resource from an arena.
+ *
+ * @Input pArena - the arena
+ * @Input uRequestSize - the size of resource segment requested.
+ * @Output pActualSize - the actual_size of resource segment allocated,
+ * typcially rounded up by quantum.
+ * @Output ppsMapping - the user reference associated with allocated
+ * resource span.
+ * @Input uFlags - flags influencing allocation policy.
+ * @Input uAlignment - the alignment constraint required for the
+ * allocated segment, use 0 if alignment not required.
+ * @Input uAlignmentOffset - the required alignment offset
+ * @Input pvPrivData - private data passed to OS allocator
+ * @Input ui32PrivData - length of private data
+ *
+ * @Output pBase - allocated base resource
+ * @Return IMG_TRUE - success, IMG_FALSE - failure
+ */
+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_PVOID pvPrivData,
+ IMG_UINT32 ui32PrivDataLength,
+ IMG_UINTPTR_T *pBase);
+
+/**
+ * @Function RA_Free
+ *
+ * @Description To free a resource segment.
+ *
+ * @Input pArena - the arena the segment was originally allocated from.
+ * @Input base - the base of the resource span to free.
+ * @Input bFreeBackingStore - Should backing store memory be freed?
+ *
+ * @Return None
+ */
+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); \
+ } \
+}
+
+
+/**
+ * @Function RA_GetNextLiveSegment
+ *
+ * @Description Returns details of the next live resource segments
+ *
+ * @Input pArena - the arena the segment was originally allocated from.
+ * @Output psSegDetails - rtn details of segments
+ *
+ * @Return IMG_TRUE if operation succeeded
+ */
+IMG_BOOL RA_GetNextLiveSegment(IMG_HANDLE hArena, RA_SEGMENT_DETAILS *psSegDetails);
+
+
+/**
+ * @Function RA_GetStats
+ *
+ * @Description gets stats on a given arena
+ *
+ * @Input pArena - the arena the segment was originally allocated from.
+ * @Input ppszStr - string to write stats to
+ * @Input pui32StrLen - length of string
+ *
+ * @Return PVRSRV_ERROR
+ */
+PVRSRV_ERROR RA_GetStats(RA_ARENA *pArena,
+ IMG_CHAR **ppszStr,
+ IMG_UINT32 *pui32StrLen);
+
+PVRSRV_ERROR RA_GetStatsFreeMem(RA_ARENA *pArena,
+ IMG_CHAR **ppszStr,
+ IMG_UINT32 *pui32StrLen);
+
+#endif /* #ifdef RA_STATS */
+
+#endif
+
diff --git a/pvr-source/services4/srvkm/include/refcount.h b/pvr-source/services4/srvkm/include/refcount.h
new file mode 100644
index 0000000..0e3479d
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/refcount.h
@@ -0,0 +1,203 @@
+/*************************************************************************/ /*!
+@Title Services reference count debugging
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __REFCOUNT_H__
+#define __REFCOUNT_H__
+
+#include "pvr_bridge_km.h"
+
+#if defined(PVRSRV_REFCOUNT_DEBUG)
+
+void PVRSRVDumpRefCountCCB(void);
+
+#define PVRSRVKernelSyncInfoIncRef(x...) \
+ PVRSRVKernelSyncInfoIncRef2(__FILE__, __LINE__, x)
+#define PVRSRVKernelSyncInfoDecRef(x...) \
+ PVRSRVKernelSyncInfoDecRef2(__FILE__, __LINE__, x)
+#define PVRSRVKernelMemInfoIncRef(x...) \
+ PVRSRVKernelMemInfoIncRef2(__FILE__, __LINE__, x)
+#define PVRSRVKernelMemInfoDecRef(x...) \
+ PVRSRVKernelMemInfoDecRef2(__FILE__, __LINE__, x)
+#define PVRSRVBMBufIncRef(x...) \
+ PVRSRVBMBufIncRef2(__FILE__, __LINE__, x)
+#define PVRSRVBMBufDecRef(x...) \
+ PVRSRVBMBufDecRef2(__FILE__, __LINE__, x)
+#define PVRSRVBMBufIncExport(x...) \
+ PVRSRVBMBufIncExport2(__FILE__, __LINE__, x)
+#define PVRSRVBMBufDecExport(x...) \
+ PVRSRVBMBufDecExport2(__FILE__, __LINE__, x)
+
+void PVRSRVKernelSyncInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
+void PVRSRVKernelSyncInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
+void PVRSRVKernelMemInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
+void PVRSRVKernelMemInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
+void PVRSRVBMBufIncRef2(const IMG_CHAR *pszFile,
+ IMG_INT iLine, BM_BUF *pBuf);
+void PVRSRVBMBufDecRef2(const IMG_CHAR *pszFile,
+ IMG_INT iLine, BM_BUF *pBuf);
+void PVRSRVBMBufIncExport2(const IMG_CHAR *pszFile,
+ IMG_INT iLine, BM_BUF *pBuf);
+void PVRSRVBMBufDecExport2(const IMG_CHAR *pszFile,
+ IMG_INT iLine, BM_BUF *pBuf);
+void PVRSRVBMXProcIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ IMG_UINT32 ui32Index);
+void PVRSRVBMXProcDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ IMG_UINT32 ui32Index);
+
+#if defined(__linux__)
+
+/* mmap refcounting is Linux specific */
+#include "mmap.h"
+
+#define PVRSRVOffsetStructIncRef(x...) \
+ PVRSRVOffsetStructIncRef2(__FILE__, __LINE__, x)
+#define PVRSRVOffsetStructDecRef(x...) \
+ PVRSRVOffsetStructDecRef2(__FILE__, __LINE__, x)
+#define PVRSRVOffsetStructIncMapped(x...) \
+ PVRSRVOffsetStructIncMapped2(__FILE__, __LINE__, x)
+#define PVRSRVOffsetStructDecMapped(x...) \
+ PVRSRVOffsetStructDecMapped2(__FILE__, __LINE__, x)
+
+void PVRSRVOffsetStructIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct);
+void PVRSRVOffsetStructDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct);
+void PVRSRVOffsetStructIncMapped2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct);
+void PVRSRVOffsetStructDecMapped2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct);
+
+#endif /* defined(__linux__) */
+
+#else /* defined(PVRSRV_REFCOUNT_DEBUG) */
+
+static INLINE void PVRSRVDumpRefCountCCB(void) { }
+
+static INLINE void PVRSRVKernelSyncInfoIncRef(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ PVR_UNREFERENCED_PARAMETER(psKernelMemInfo);
+ PVRSRVAcquireSyncInfoKM(psKernelSyncInfo);
+}
+
+static INLINE void PVRSRVKernelSyncInfoDecRef(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ PVR_UNREFERENCED_PARAMETER(psKernelMemInfo);
+ PVRSRVReleaseSyncInfoKM(psKernelSyncInfo);
+}
+
+static INLINE void PVRSRVKernelMemInfoIncRef(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ psKernelMemInfo->ui32RefCount++;
+}
+
+static INLINE void PVRSRVKernelMemInfoDecRef(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ psKernelMemInfo->ui32RefCount--;
+}
+
+static INLINE void PVRSRVBMBufIncRef(BM_BUF *pBuf)
+{
+ pBuf->ui32RefCount++;
+}
+
+static INLINE void PVRSRVBMBufDecRef(BM_BUF *pBuf)
+{
+ pBuf->ui32RefCount--;
+}
+
+static INLINE void PVRSRVBMBufIncExport(BM_BUF *pBuf)
+{
+ pBuf->ui32ExportCount++;
+}
+
+static INLINE void PVRSRVBMBufDecExport(BM_BUF *pBuf)
+{
+ pBuf->ui32ExportCount--;
+}
+
+static INLINE void PVRSRVBMXProcIncRef(IMG_UINT32 ui32Index)
+{
+ gXProcWorkaroundShareData[ui32Index].ui32RefCount++;
+}
+
+static INLINE void PVRSRVBMXProcDecRef(IMG_UINT32 ui32Index)
+{
+ gXProcWorkaroundShareData[ui32Index].ui32RefCount--;
+}
+
+#if defined(__linux__)
+
+/* mmap refcounting is Linux specific */
+#include "mmap.h"
+
+static INLINE void PVRSRVOffsetStructIncRef(PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ psOffsetStruct->ui32RefCount++;
+}
+
+static INLINE void PVRSRVOffsetStructDecRef(PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ psOffsetStruct->ui32RefCount--;
+}
+
+static INLINE void PVRSRVOffsetStructIncMapped(PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ psOffsetStruct->ui32Mapped++;
+}
+
+static INLINE void PVRSRVOffsetStructDecMapped(PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ psOffsetStruct->ui32Mapped--;
+}
+
+#endif /* defined(__linux__) */
+
+#endif /* defined(PVRSRV_REFCOUNT_DEBUG) */
+
+#endif /* __REFCOUNT_H__ */
diff --git a/pvr-source/services4/srvkm/include/resman.h b/pvr-source/services4/srvkm/include/resman.h
new file mode 100644
index 0000000..92659d9
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/resman.h
@@ -0,0 +1,152 @@
+/*************************************************************************/ /*!
+@Title Resource Manager API
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Provide resource management
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __RESMAN_H__
+#define __RESMAN_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/******************************************************************************
+ * resman definitions
+ *****************************************************************************/
+
+enum {
+ /* SGX: */
+ RESMAN_TYPE_SHARED_PB_DESC = 1, /*!< Parameter buffer kernel stubs */
+ RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK, /*!< Shared parameter buffer creation lock */
+ RESMAN_TYPE_HW_RENDER_CONTEXT, /*!< Hardware Render Context Resource */
+ RESMAN_TYPE_HW_TRANSFER_CONTEXT, /*!< Hardware transfer Context Resource */
+ RESMAN_TYPE_HW_2D_CONTEXT, /*!< Hardware 2D Context Resource */
+ RESMAN_TYPE_TRANSFER_CONTEXT, /*!< Transfer Queue context */
+
+ /* VGX: */
+ RESMAN_TYPE_DMA_CLIENT_FIFO_DATA, /*!< VGX DMA Client FIFO data */
+
+ /* DISPLAY CLASS: */
+ RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF, /*!< Display Class Swapchain Reference Resource */
+ RESMAN_TYPE_DISPLAYCLASS_DEVICE, /*!< Display Class Device Resource */
+
+ /* BUFFER CLASS: */
+ RESMAN_TYPE_BUFFERCLASS_DEVICE, /*!< Buffer Class Device Resource */
+
+ /* OS specific User mode Mappings: */
+ RESMAN_TYPE_OS_USERMODE_MAPPING, /*!< OS specific User mode mappings */
+
+ /* COMMON: */
+ RESMAN_TYPE_DEVICEMEM_CONTEXT, /*!< Device Memory Context Resource */
+ RESMAN_TYPE_DEVICECLASSMEM_MAPPING, /*!< Device Memory Mapping Resource */
+ RESMAN_TYPE_DEVICEMEM_MAPPING, /*!< Device Memory Mapping Resource */
+ RESMAN_TYPE_DEVICEMEM_WRAP, /*!< Device Memory Wrap Resource */
+ RESMAN_TYPE_DEVICEMEM_ALLOCATION, /*!< Device Memory Allocation Resource */
+ RESMAN_TYPE_DEVICEMEM_ION, /*!< Device Memory Ion Resource */
+ RESMAN_TYPE_EVENT_OBJECT, /*!< Event Object */
+ RESMAN_TYPE_SHARED_MEM_INFO, /*!< Shared system memory meminfo */
+ RESMAN_TYPE_MODIFY_SYNC_OPS, /*!< Syncobject synchronisation Resource*/
+ RESMAN_TYPE_SYNC_INFO, /*!< Syncobject Resource*/
+
+ /* KERNEL: */
+ RESMAN_TYPE_KERNEL_DEVICEMEM_ALLOCATION /*!< Device Memory Allocation Resource */
+};
+
+#define RESMAN_CRITERIA_ALL 0x00000000 /*!< match by criteria all */
+#define RESMAN_CRITERIA_RESTYPE 0x00000001 /*!< match by criteria type */
+#define RESMAN_CRITERIA_PVOID_PARAM 0x00000002 /*!< match by criteria param1 */
+#define RESMAN_CRITERIA_UI32_PARAM 0x00000004 /*!< match by criteria param2 */
+
+typedef PVRSRV_ERROR (*RESMAN_FREE_FN)(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bForceCleanup);
+
+typedef struct _RESMAN_ITEM_ *PRESMAN_ITEM;
+typedef struct _RESMAN_CONTEXT_ *PRESMAN_CONTEXT;
+
+/******************************************************************************
+ * resman functions
+ *****************************************************************************/
+
+/*
+ Note:
+ Resource cleanup can fail with retry in which case we don't remove
+ it from resman's list and either UM or KM will try to release the
+ resource at a later date (and will keep trying until a non-retry
+ error is returned)
+*/
+
+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,
+ IMG_BOOL bForceCleanup);
+
+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 /* __RESMAN_H__ */
+
+/******************************************************************************
+ End of file (resman.h)
+******************************************************************************/
+
diff --git a/pvr-source/services4/srvkm/include/services_headers.h b/pvr-source/services4/srvkm/include/services_headers.h
new file mode 100644
index 0000000..d09b8a8
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/services_headers.h
@@ -0,0 +1,68 @@
+/*************************************************************************/ /*!
+@Title Command queues and synchronisation
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Internal structures and definitions for command queues and
+ synchronisation
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+
+#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"
+#include "refcount.h"
+
+#endif /* SERVICES_HEADERS_H */
+
diff --git a/pvr-source/services4/srvkm/include/srvkm.h b/pvr-source/services4/srvkm/include/srvkm.h
new file mode 100644
index 0000000..5d396f8
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/srvkm.h
@@ -0,0 +1,129 @@
+/*************************************************************************/ /*!
+@Title Services kernel module internal header file
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef SRVKM_H
+#define SRVKM_H
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+ /** Use PVR_DPF() unless message is necessary in release build
+ */
+ #ifdef PVR_DISABLE_LOGGING
+ #define PVR_LOG(X)
+ #else
+ /* PRQA S 3410 1 */ /* this macro requires no brackets in order to work */
+ #define PVR_LOG(X) PVRSRVReleasePrintf X;
+ #endif
+
+ IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVReleasePrintf(const IMG_CHAR *pszFormat, ...) IMG_FORMAT_PRINTF(1, 2);
+
+ IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVProcessConnect(IMG_UINT32 ui32PID, IMG_UINT32 ui32Flags);
+ IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVProcessDisconnect(IMG_UINT32 ui32PID);
+
+ IMG_IMPORT IMG_VOID PVRSRVScheduleDevicesKM(IMG_VOID);
+
+ IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State);
+
+ PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer, IMG_SIZE_T *puiBufSize, IMG_BOOL bSave);
+
+ IMG_VOID PVRSRVScheduleDeviceCallbacks(IMG_VOID);
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+/******************
+HIGHER LEVEL MACROS
+*******************/
+
+/*----------------------------------------------------------------------------
+Repeats the body of the loop for a certain minimum time, or until the body
+exits by its own means (break, return, goto, etc.)
+
+Example of usage:
+
+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();
+
+-----------------------------------------------------------------------------*/
+
+/* uiNotLastLoop will remain at 1 until the timeout has expired, at which time
+ * it will be decremented and the loop executed one final time. This is necessary
+ * when preemption is enabled.
+ */
+/* PRQA S 3411,3431 12 */ /* critical format, leave alone */
+#define LOOP_UNTIL_TIMEOUT(TIMEOUT) \
+{\
+ IMG_UINT32 uiOffset, uiStart, uiCurrent; \
+ IMG_INT32 iNotLastLoop; \
+ for(uiOffset = 0, uiStart = OSClockus(), uiCurrent = uiStart + 1, iNotLastLoop = 1;\
+ ((uiCurrent - uiStart + uiOffset) < (TIMEOUT)) || iNotLastLoop--; \
+ uiCurrent = OSClockus(), \
+ uiOffset = uiCurrent < uiStart ? IMG_UINT32_MAX - uiStart : uiOffset, \
+ uiStart = uiCurrent < uiStart ? 0 : uiStart)
+
+#define END_LOOP_UNTIL_TIMEOUT() \
+}
+
+/*!
+ ******************************************************************************
+
+ @Function PVRSRVGetErrorStringKM
+
+ @Description Returns a text string relating to the PVRSRV_ERROR enum.
+
+ ******************************************************************************/
+IMG_IMPORT
+const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError);
+
+#endif /* SRVKM_H */
diff --git a/pvr-source/services4/srvkm/include/ttrace.h b/pvr-source/services4/srvkm/include/ttrace.h
new file mode 100644
index 0000000..cb70ff8
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/ttrace.h
@@ -0,0 +1,200 @@
+/*************************************************************************/ /*!
+@Title Timed Trace header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Timed Trace header. Contines structures and functions used
+ in the timed trace subsystem.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#include "services_headers.h"
+#include "ttrace_common.h"
+#include "ttrace_tokens.h"
+
+#ifndef __TTRACE_H__
+#define __TTRACE_H__
+
+#if defined(TTRACE)
+
+ #define PVR_TTRACE(group, class, token) \
+ PVRSRVTimeTrace(group, class, token)
+ #define PVR_TTRACE_UI8(group, class, token, val) \
+ PVRSRVTimeTraceUI8(group, class, token, val)
+ #define PVR_TTRACE_UI16(group, class, token, val) \
+ PVRSRVTimeTraceUI16(group, class, token, val)
+ #define PVR_TTRACE_UI32(group, class, token, val) \
+ PVRSRVTimeTraceUI32(group, class, token, val)
+ #define PVR_TTRACE_UI64(group, class, token, val) \
+ PVRSRVTimeTraceUI64(group, class, token, val)
+ #define PVR_TTRACE_DEV_VIRTADDR(group, class, token, val) \
+ PVRSRVTimeTraceDevVirtAddr(group, class, token, val)
+ #define PVR_TTRACE_CPU_PHYADDR(group, class, token, val) \
+ PVRSRVTimeTraceCpuPhyAddr(group, class, token, val)
+ #define PVR_TTRACE_DEV_PHYADDR(group, class, token, val) \
+ PVRSRVTimeTraceDevPhysAddr(group, class, token, val)
+ #define PVR_TTRACE_SYS_PHYADDR(group, class, token, val) \
+ PVRSRVTimeTraceSysPhysAddr(group, class, token, val)
+ #define PVR_TTRACE_SYNC_OBJECT(group, token, syncobj, op) \
+ PVRSRVTimeTraceSyncObject(group, token, syncobj, op)
+
+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVTimeTraceArray(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+ IMG_UINT32 ui32Token, IMG_UINT32 ui32TypeSize,
+ IMG_UINT32 ui32Count, IMG_UINT8 *ui8Data);
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTrace)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTrace(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+ IMG_UINT32 ui32Token)
+{
+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, 0, 0, NULL);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceUI8)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceUI8(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+ IMG_UINT32 ui32Token, IMG_UINT8 ui8Value)
+{
+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI8,
+ 1, &ui8Value);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceUI16)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceUI16(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+ IMG_UINT32 ui32Token, IMG_UINT16 ui16Value)
+{
+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI16,
+ 1, (IMG_UINT8 *) &ui16Value);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceUI32)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceUI32(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+ IMG_UINT32 ui32Token, IMG_UINT32 ui32Value)
+{
+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI32,
+ 1, (IMG_UINT8 *) &ui32Value);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceUI64)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceUI64(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+ IMG_UINT32 ui32Token, IMG_UINT64 ui64Value)
+{
+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI64,
+ 1, (IMG_UINT8 *) &ui64Value);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceDevVirtAddr)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceDevVirtAddr(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+ IMG_UINT32 ui32Token, IMG_DEV_VIRTADDR psVAddr)
+{
+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI32,
+ 1, (IMG_UINT8 *) &psVAddr.uiAddr);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceCpuPhyAddr)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceCpuPhyAddr(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+ IMG_UINT32 ui32Token, IMG_CPU_PHYADDR psPAddr)
+{
+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI32,
+ 1, (IMG_UINT8 *) &psPAddr.uiAddr);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceDevPhysAddr)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceDevPhysAddr(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+ IMG_UINT32 ui32Token, IMG_DEV_PHYADDR psPAddr)
+{
+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI32,
+ 1, (IMG_UINT8 *) &psPAddr.uiAddr);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVTimeTraceSysPhysAddr)
+#endif
+static INLINE IMG_VOID PVRSRVTimeTraceSysPhysAddr(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class,
+ IMG_UINT32 ui32Token, IMG_SYS_PHYADDR psPAddr)
+{
+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, sizeof(psPAddr.uiAddr),
+ 1, (IMG_UINT8 *) &psPAddr.uiAddr);
+}
+
+#else /* defined(PVRSRV_NEED_PVR_TIME_TRACE) */
+
+ #define PVR_TTRACE(group, class, token) \
+ ((void) 0)
+ #define PVR_TTRACE_UI8(group, class, token, val) \
+ ((void) 0)
+ #define PVR_TTRACE_UI16(group, class, token, val) \
+ ((void) 0)
+ #define PVR_TTRACE_UI32(group, class, token, val) \
+ ((void) 0)
+ #define PVR_TTRACE_UI64(group, class, token, val) \
+ ((void) 0)
+ #define PVR_TTRACE_DEV_VIRTADDR(group, class, token, val) \
+ ((void) 0)
+ #define PVR_TTRACE_CPU_PHYADDR(group, class, token, val) \
+ ((void) 0)
+ #define PVR_TTRACE_DEV_PHYADDR(group, class, token, val) \
+ ((void) 0)
+ #define PVR_TTRACE_SYS_PHYADDR(group, class, token, val) \
+ ((void) 0)
+ #define PVR_TTRACE_SYNC_OBJECT(group, token, syncobj, op) \
+ ((void) 0)
+
+#endif /* defined(PVRSRV_NEED_PVR_TIME_TRACE) */
+
+IMG_IMPORT PVRSRV_ERROR PVRSRVTimeTraceInit(IMG_VOID);
+IMG_IMPORT IMG_VOID PVRSRVTimeTraceDeinit(IMG_VOID);
+
+IMG_IMPORT IMG_VOID PVRSRVTimeTraceSyncObject(IMG_UINT32 ui32Group, IMG_UINT32 ui32Token,
+ PVRSRV_KERNEL_SYNC_INFO *psSync, IMG_UINT8 ui8SyncOp);
+IMG_IMPORT PVRSRV_ERROR PVRSRVTimeTraceBufferCreate(IMG_UINT32 ui32PID);
+IMG_IMPORT PVRSRV_ERROR PVRSRVTimeTraceBufferDestroy(IMG_UINT32 ui32PID);
+
+IMG_IMPORT IMG_VOID PVRSRVDumpTimeTraceBuffers(IMG_VOID);
+#endif /* __TTRACE_H__ */
diff --git a/pvr-source/services4/srvkm/include/ttrace_common.h b/pvr-source/services4/srvkm/include/ttrace_common.h
new file mode 100644
index 0000000..b14f256
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/ttrace_common.h
@@ -0,0 +1,146 @@
+/*************************************************************************/ /*!
+@Title Timed Trace header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Timed Trace common header. Contains shared defines and
+ structures which are shared with the post processing tool.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#include "img_types.h"
+
+#ifndef __TTRACE_COMMON_H__
+#define __TTRACE_COMMON_H__
+
+/*
+ * Trace item
+ * ==========
+ *
+ * A trace item contains a trace header, a timestamp, a UID and a
+ * data header all of which are 32-bit and mandatory. If there
+ * is no data then the data header size is set to 0.
+ *
+ * Trace header
+ * ------------
+ * 31 27 23 19 15 11 7 3
+ * GGGG GGGG CCCC CCCC TTTT TTTT TTTT TTTT
+ *
+ * G = group
+ * Note:
+ * Group 0xff means the message is padding
+ *
+ * C = class
+ * T = Token
+ *
+ * Data header
+ *-----------
+ * 31 27 23 19 15 11 7 3
+ * SSSS SSSS SSSS SSSS TTTT CCCC CCCC CCCC
+ *
+ * S = data packet size
+ * T = Type
+ * 0000 - 8 bit
+ * 0001 - 16 bit
+ * 0010 - 32 bit
+ * 0011 - 64 bit
+ *
+ * C = data item count
+ *
+ * Note: It might look strange having both the packet
+ * size and the data item count, but the idea
+ * is the you might have a "special" data type
+ * who's size might not be known by the post
+ * processing program and rather then fail
+ * processing the buffer after that point if we
+ * know the size we can just skip it and move to
+ * the next item.
+ */
+
+
+#define PVRSRV_TRACE_HEADER 0
+#define PVRSRV_TRACE_TIMESTAMP 1
+#define PVRSRV_TRACE_HOSTUID 2
+#define PVRSRV_TRACE_DATA_HEADER 3
+#define PVRSRV_TRACE_DATA_PAYLOAD 4
+
+#define PVRSRV_TRACE_ITEM_SIZE 16
+
+#define PVRSRV_TRACE_GROUP_MASK 0xff
+#define PVRSRV_TRACE_CLASS_MASK 0xff
+#define PVRSRV_TRACE_TOKEN_MASK 0xffff
+
+#define PVRSRV_TRACE_GROUP_SHIFT 24
+#define PVRSRV_TRACE_CLASS_SHIFT 16
+#define PVRSRV_TRACE_TOKEN_SHIFT 0
+
+#define PVRSRV_TRACE_SIZE_MASK 0xffff
+#define PVRSRV_TRACE_TYPE_MASK 0xf
+#define PVRSRV_TRACE_COUNT_MASK 0xfff
+
+#define PVRSRV_TRACE_SIZE_SHIFT 16
+#define PVRSRV_TRACE_TYPE_SHIFT 12
+#define PVRSRV_TRACE_COUNT_SHIFT 0
+
+
+#define WRITE_HEADER(n,m) \
+ ((m & PVRSRV_TRACE_##n##_MASK) << PVRSRV_TRACE_##n##_SHIFT)
+
+#define READ_HEADER(n,m) \
+ ((m & (PVRSRV_TRACE_##n##_MASK << PVRSRV_TRACE_##n##_SHIFT)) >> PVRSRV_TRACE_##n##_SHIFT)
+
+#define TIME_TRACE_BUFFER_SIZE 4096
+
+/* Type defines for trace items */
+#define PVRSRV_TRACE_TYPE_UI8 0
+#define PVRSRV_TRACE_TYPE_UI16 1
+#define PVRSRV_TRACE_TYPE_UI32 2
+#define PVRSRV_TRACE_TYPE_UI64 3
+
+#define PVRSRV_TRACE_TYPE_SYNC 15
+ #define PVRSRV_TRACE_SYNC_UID 0
+ #define PVRSRV_TRACE_SYNC_WOP 1
+ #define PVRSRV_TRACE_SYNC_WOC 2
+ #define PVRSRV_TRACE_SYNC_ROP 3
+ #define PVRSRV_TRACE_SYNC_ROC 4
+ #define PVRSRV_TRACE_SYNC_WO_DEV_VADDR 5
+ #define PVRSRV_TRACE_SYNC_RO_DEV_VADDR 6
+ #define PVRSRV_TRACE_SYNC_OP 7
+ #define PVRSRV_TRACE_SYNC_RO2P 8
+ #define PVRSRV_TRACE_SYNC_RO2C 9
+ #define PVRSRV_TRACE_SYNC_RO2_DEV_VADDR 10
+#define PVRSRV_TRACE_TYPE_SYNC_SIZE ((PVRSRV_TRACE_SYNC_RO2_DEV_VADDR + 1) * sizeof(IMG_UINT32))
+
+#endif /* __TTRACE_COMMON_H__*/
diff --git a/pvr-source/services4/srvkm/include/ttrace_tokens.h b/pvr-source/services4/srvkm/include/ttrace_tokens.h
new file mode 100644
index 0000000..24bc484
--- /dev/null
+++ b/pvr-source/services4/srvkm/include/ttrace_tokens.h
@@ -0,0 +1,119 @@
+/*************************************************************************/ /*!
+@Title Timed Trace header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Timed Trace token header. Contains defines for all the tokens
+ used.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __TTRACE_TOKENS_H__
+#define __TTRACE_TOKENS_H__
+
+/* All defines should use decimal so to not confuse the post processing tool */
+
+/* Trace groups */
+#define PVRSRV_TRACE_GROUP_KICK 0
+#define PVRSRV_TRACE_GROUP_TRANSFER 1
+#define PVRSRV_TRACE_GROUP_QUEUE 2
+#define PVRSRV_TRACE_GROUP_POWER 3
+#define PVRSRV_TRACE_GROUP_MKSYNC 4
+
+#define PVRSRV_TRACE_GROUP_PADDING 255
+
+/* Trace classes */
+#define PVRSRV_TRACE_CLASS_FUNCTION_ENTER 0
+#define PVRSRV_TRACE_CLASS_FUNCTION_EXIT 1
+#define PVRSRV_TRACE_CLASS_SYNC 2
+#define PVRSRV_TRACE_CLASS_CCB 3
+#define PVRSRV_TRACE_CLASS_CMD_START 4
+#define PVRSRV_TRACE_CLASS_CMD_END 5
+#define PVRSRV_TRACE_CLASS_CMD_COMP_START 6
+#define PVRSRV_TRACE_CLASS_CMD_COMP_END 7
+#define PVRSRV_TRACE_CLASS_FLAGS 8
+
+#define PVRSRV_TRACE_CLASS_NONE 255
+
+/* Operation about to happen on the sync object */
+#define PVRSRV_SYNCOP_SAMPLE 0
+#define PVRSRV_SYNCOP_COMPLETE 1
+#define PVRSRV_SYNCOP_DUMP 2
+
+/*
+ * Trace tokens
+ * ------------
+ * These only need to unique within a group.
+ */
+
+/* Kick group tokens */
+#define KICK_TOKEN_DOKICK 0
+#define KICK_TOKEN_CCB_OFFSET 1
+#define KICK_TOKEN_TA3D_SYNC 2
+#define KICK_TOKEN_TA_SYNC 3
+#define KICK_TOKEN_3D_SYNC 4
+#define KICK_TOKEN_SRC_SYNC 5
+#define KICK_TOKEN_DST_SYNC 6
+#define KICK_TOKEN_FIRST_KICK 7
+#define KICK_TOKEN_LAST_KICK 8
+
+/* Transfer Queue group tokens */
+#define TRANSFER_TOKEN_SUBMIT 0
+#define TRANSFER_TOKEN_TA_SYNC 1
+#define TRANSFER_TOKEN_3D_SYNC 2
+#define TRANSFER_TOKEN_SRC_SYNC 3
+#define TRANSFER_TOKEN_DST_SYNC 4
+#define TRANSFER_TOKEN_CCB_OFFSET 5
+
+/* Queue group tokens */
+#define QUEUE_TOKEN_GET_SPACE 0
+#define QUEUE_TOKEN_INSERTKM 1
+#define QUEUE_TOKEN_SUBMITKM 2
+#define QUEUE_TOKEN_PROCESS_COMMAND 3
+#define QUEUE_TOKEN_PROCESS_QUEUES 4
+#define QUEUE_TOKEN_COMMAND_COMPLETE 5
+#define QUEUE_TOKEN_UPDATE_DST 6
+#define QUEUE_TOKEN_UPDATE_SRC 7
+#define QUEUE_TOKEN_SRC_SYNC 8
+#define QUEUE_TOKEN_DST_SYNC 9
+#define QUEUE_TOKEN_COMMAND_TYPE 10
+
+/* uKernel Sync tokens */
+#define MKSYNC_TOKEN_KERNEL_CCB_OFFSET 0
+#define MKSYNC_TOKEN_CORE_CLK 1
+#define MKSYNC_TOKEN_UKERNEL_CLK 2
+
+#endif /* __TTRACE_TOKENS_H__ */
diff --git a/pvr-source/services4/system/include/syscommon.h b/pvr-source/services4/system/include/syscommon.h
new file mode 100644
index 0000000..4fd3512
--- /dev/null
+++ b/pvr-source/services4/system/include/syscommon.h
@@ -0,0 +1,397 @@
+/*************************************************************************/ /*!
+@Title Common System APIs and structures
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description This header provides common system-specific declarations and macros
+ that are supported by all system's
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _SYSCOMMON_H
+#define _SYSCOMMON_H
+
+#include "sysconfig.h" /* System specific system defines */
+#include "sysinfo.h" /* globally accessible system info */
+#include "servicesint.h"
+#include "queue.h"
+#include "power.h"
+#include "resman.h"
+#include "ra.h"
+#include "device.h"
+#include "buffer_manager.h"
+#include "pvr_debug.h"
+#include "services.h"
+
+#if defined(NO_HARDWARE) && defined(__linux__) && defined(__KERNEL__)
+#include <asm/io.h>
+#endif
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ ****************************************************************************
+ device id management structure
+ ****************************************************************************/
+typedef struct _SYS_DEVICE_ID_TAG
+{
+ IMG_UINT32 uiID;
+ IMG_BOOL bInUse;
+
+} SYS_DEVICE_ID;
+
+
+/*
+ the max number of independent local backing stores services supports
+ (grow this number if ever required)
+*/
+#define SYS_MAX_LOCAL_DEVMEM_ARENAS 4
+
+typedef IMG_HANDLE (*PFN_HTIMER_CREATE) (IMG_VOID);
+typedef IMG_UINT32 (*PFN_HTIMER_GETUS) (IMG_HANDLE);
+typedef IMG_VOID (*PFN_HTIMER_DESTROY) (IMG_HANDLE);
+/*!
+ ****************************************************************************
+ Top level system data structure
+ ****************************************************************************/
+typedef struct _SYS_DATA_TAG_
+{
+ IMG_UINT32 ui32NumDevices; /*!< number of devices in system */
+ SYS_DEVICE_ID sDeviceID[SYS_DEVICE_COUNT];
+ PVRSRV_DEVICE_NODE *psDeviceNodeList; /*!< list of private device info structures */
+ PVRSRV_POWER_DEV *psPowerDeviceList; /*!< list of devices registered with the power manager */
+ PVRSRV_RESOURCE sPowerStateChangeResource; /*!< lock for power state transitions */
+ PVRSRV_SYS_POWER_STATE eCurrentPowerState; /*!< current Kernel services power state */
+ PVRSRV_SYS_POWER_STATE eFailedPowerState; /*!< Kernel services power state (Failed to transition to) */
+ IMG_UINT32 ui32CurrentOSPowerState; /*!< current OS specific power state */
+ PVRSRV_QUEUE_INFO *psQueueList; /*!< list of all command queues in the system */
+ PVRSRV_KERNEL_SYNC_INFO *psSharedSyncInfoList; /*!< list of cross process syncinfos */
+ IMG_PVOID pvEnvSpecificData; /*!< Environment specific data */
+ IMG_PVOID pvSysSpecificData; /*!< Unique to system, accessible at system layer only */
+ PVRSRV_RESOURCE sQProcessResource; /*!< Command Q processing access lock */
+ IMG_VOID *pvSOCRegsBase; /*!< SOC registers base linear address */
+ IMG_HANDLE hSOCTimerRegisterOSMemHandle; /*!< SOC Timer register (if present) */
+ IMG_UINT32 *pvSOCTimerRegisterKM; /*!< SOC Timer register (if present) */
+ IMG_VOID *pvSOCClockGateRegsBase; /*!< SOC Clock gating registers (if present) */
+ IMG_UINT32 ui32SOCClockGateRegsSize;
+
+ struct _DEVICE_COMMAND_DATA_ *apsDeviceCommandData[SYS_DEVICE_COUNT];
+ /*!< command complete data and callback function store for every command for every device */
+
+ RA_ARENA *apsLocalDevMemArena[SYS_MAX_LOCAL_DEVMEM_ARENAS]; /*!< RA Arenas for local device memory heap management */
+
+ IMG_CHAR *pszVersionString; /*!< Human readable string showing relevent system version info */
+#if defined (SUPPORT_SID_INTERFACE)
+ PVRSRV_EVENTOBJECT_KM *psGlobalEventObject; /*!< OS Global Event Object */
+#else
+ PVRSRV_EVENTOBJECT *psGlobalEventObject; /*!< OS Global Event Object */
+#endif
+
+ PVRSRV_MISC_INFO_CPUCACHEOP_TYPE ePendingCacheOpType; /*!< Deferred CPU cache op control */
+
+ PFN_HTIMER_CREATE pfnHighResTimerCreate;
+ PFN_HTIMER_GETUS pfnHighResTimerGetus;
+ PFN_HTIMER_DESTROY pfnHighResTimerDestroy;
+} SYS_DATA;
+
+
+/****************************************************************************
+ * common function prototypes
+ ****************************************************************************/
+
+#if defined (CUSTOM_DISPLAY_SEGMENT)
+PVRSRV_ERROR SysGetDisplaySegmentAddress (IMG_VOID *pvDevInfo, IMG_VOID *pvPhysicalAddress, IMG_UINT32 *pui32Length);
+#endif
+
+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(PVRSRV_SYS_POWER_STATE eNewPowerState);
+PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState);
+PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState);
+
+IMG_VOID SysSGXIdleEntered(IMG_VOID);
+IMG_VOID SysSGXCommandPending(IMG_BOOL bSGXIdle);
+
+#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
+PVRSRV_ERROR SysPowerLockWrap(IMG_BOOL bTryLock);
+IMG_VOID SysPowerLockUnwrap(IMG_VOID);
+#endif
+
+IMG_VOID SysLockSystemSuspend(IMG_VOID);
+IMG_VOID SysUnlockSystemSuspend(IMG_VOID);
+
+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)
+
+/*!
+******************************************************************************
+
+ @Function SysAcquireData
+
+ @Description returns reference to to sysdata
+ creating one on first call
+
+ @Input ppsSysData - pointer to copy reference into
+
+ @Return ppsSysData updated
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysAcquireData)
+#endif
+static INLINE IMG_VOID SysAcquireData(SYS_DATA **ppsSysData)
+{
+ /* Copy pointer back system information pointer */
+ *ppsSysData = gpsSysData;
+
+ /*
+ Verify we've not been called before being initialised. Instinctively
+ we should do this check first, but in the failing case we'll just write
+ null back and the compiler won't warn about an uninitialised varible.
+ */
+ PVR_ASSERT (gpsSysData != IMG_NULL);
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SysAcquireDataNoCheck
+
+ @Description returns reference to to sysdata
+ creating one on first call
+
+ @Input none
+
+ @Return psSysData - pointer to copy reference into
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysAcquireDataNoCheck)
+#endif
+static INLINE SYS_DATA * SysAcquireDataNoCheck(IMG_VOID)
+{
+ /* return pointer back system information pointer */
+ return gpsSysData;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SysInitialiseCommon
+
+ @Description Performs system initialisation common to all systems
+
+ @Input psSysData - pointer to system data
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysInitialiseCommon)
+#endif
+static INLINE PVRSRV_ERROR SysInitialiseCommon(SYS_DATA *psSysData)
+{
+ PVRSRV_ERROR eError;
+
+ /* Initialise Services */
+ eError = PVRSRVInit(psSysData);
+
+ return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function SysDeinitialiseCommon
+
+ @Description Performs system deinitialisation common to all systems
+
+ @Input psSysData - pointer to system data
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysDeinitialiseCommon)
+#endif
+static INLINE IMG_VOID SysDeinitialiseCommon(SYS_DATA *psSysData)
+{
+ /* De-initialise Services */
+ PVRSRVDeInit(psSysData);
+
+ OSDestroyResource(&psSysData->sPowerStateChangeResource);
+}
+#endif /* !defined(USE_CODE) */
+
+
+/*
+ * SysReadHWReg and SysWriteHWReg differ from OSReadHWReg and OSWriteHWReg
+ * in that they are always intended for use with real hardware, even on
+ * NO_HARDWARE systems.
+ */
+#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 /* !(defined(NO_HARDWARE) && defined(__linux__)) */
+/*!
+******************************************************************************
+
+ @Function SysReadHWReg
+
+ @Description
+
+ register read function
+
+ @input pvLinRegBaseAddr : lin addr of register block base
+
+ @input ui32Offset :
+
+ @Return register value
+
+******************************************************************************/
+static inline IMG_UINT32 SysReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
+{
+ return (IMG_UINT32) readl(pvLinRegBaseAddr + ui32Offset);
+}
+
+/*!
+******************************************************************************
+
+ @Function SysWriteHWReg
+
+ @Description
+
+ register write function
+
+ @input pvLinRegBaseAddr : lin addr of register block base
+
+ @input ui32Offset :
+
+ @input ui32Value :
+
+ @Return none
+
+******************************************************************************/
+static inline IMG_VOID SysWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
+{
+ writel(ui32Value, pvLinRegBaseAddr + ui32Offset);
+}
+#endif /* !(defined(NO_HARDWARE) && defined(__linux__)) */
+
+#if defined(__cplusplus)
+}
+#endif
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysHighResTimerCreate)
+#endif
+static INLINE IMG_HANDLE SysHighResTimerCreate(IMG_VOID)
+{
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+ return psSysData->pfnHighResTimerCreate();
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysHighResTimerGetus)
+#endif
+static INLINE IMG_UINT32 SysHighResTimerGetus(IMG_HANDLE hTimer)
+{
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+ return psSysData->pfnHighResTimerGetus(hTimer);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysHighResTimerDestroy)
+#endif
+static INLINE IMG_VOID SysHighResTimerDestroy(IMG_HANDLE hTimer)
+{
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+ psSysData->pfnHighResTimerDestroy(hTimer);
+}
+#endif
+
+/*****************************************************************************
+ End of file (syscommon.h)
+*****************************************************************************/
diff --git a/pvr-source/services4/system/omap4/oemfuncs.h b/pvr-source/services4/system/omap4/oemfuncs.h
new file mode 100644
index 0000000..0902042
--- /dev/null
+++ b/pvr-source/services4/system/omap4/oemfuncs.h
@@ -0,0 +1,80 @@
+/*************************************************************************/ /*!
+@Title SGX kernel/client driver interface structures and prototypes
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__OEMFUNCS_H__)
+#define __OEMFUNCS_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/* function in/out data structures: */
+typedef IMG_UINT32 (*PFN_SRV_BRIDGEDISPATCH)( IMG_UINT32 Ioctl,
+ IMG_BYTE *pInBuf,
+ IMG_UINT32 InBufLen,
+ IMG_BYTE *pOutBuf,
+ IMG_UINT32 OutBufLen,
+ IMG_UINT32 *pdwBytesTransferred);
+/*
+ Function table for kernel 3rd party driver to kernel services
+*/
+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 /* __OEMFUNCS_H__ */
+
+/*****************************************************************************
+ End of file (oemfuncs.h)
+*****************************************************************************/
+
+
diff --git a/pvr-source/services4/system/omap4/sgxfreq.c b/pvr-source/services4/system/omap4/sgxfreq.c
new file mode 100644
index 0000000..7e8e8fd
--- /dev/null
+++ b/pvr-source/services4/system/omap4/sgxfreq.c
@@ -0,0 +1,590 @@
+/*
+ * Copyright (C) 2012 Texas Instruments, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/opp.h>
+#include <plat/gpu.h>
+#include "sgxfreq.h"
+
+static struct sgxfreq_data {
+ int freq_cnt;
+ unsigned long *freq_list;
+ unsigned long freq;
+ unsigned long freq_request;
+ unsigned long freq_limit;
+ unsigned long total_idle_time;
+ unsigned long total_active_time;
+ struct mutex freq_mutex;
+ struct list_head gov_list;
+ struct sgxfreq_governor *gov;
+ struct mutex gov_mutex;
+ struct sgxfreq_sgx_data sgx_data;
+ struct device *dev;
+ struct gpu_platform_data *pdata;
+} sfd;
+
+/* Governor init/deinit functions */
+int onoff_init(void);
+int onoff_deinit(void);
+int activeidle_init(void);
+int activeidle_deinit(void);
+int on3demand_init(void);
+int on3demand_deinit(void);
+int userspace_init(void);
+int userspace_deinit(void);
+
+
+typedef int sgxfreq_gov_init_t(void);
+sgxfreq_gov_init_t *sgxfreq_gov_init[] = {
+ onoff_init,
+ activeidle_init,
+ on3demand_init,
+ userspace_init,
+ NULL,
+};
+
+typedef int sgxfreq_gov_deinit_t(void);
+sgxfreq_gov_deinit_t *sgxfreq_gov_deinit[] = {
+ onoff_deinit,
+ activeidle_deinit,
+ on3demand_deinit,
+ userspace_deinit,
+ NULL,
+};
+
+#define SGXFREQ_DEFAULT_GOV_NAME "on3demand"
+static unsigned long _idle_curr_time;
+static unsigned long _idle_prev_time;
+static unsigned long _active_curr_time;
+static unsigned long _active_prev_time;
+
+#if defined(CONFIG_THERMAL_FRAMEWORK)
+int cool_init(void);
+void cool_deinit(void);
+#endif
+
+/*********************** begin sysfs interface ***********************/
+
+struct kobject *sgxfreq_kobj;
+
+static ssize_t show_frequency_list(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int i;
+ ssize_t count = 0;
+
+ for (i = 0; i < sfd.freq_cnt; i++)
+ count += sprintf(&buf[count], "%lu ", sfd.freq_list[i]);
+ count += sprintf(&buf[count], "\n");
+
+ return count;
+}
+
+static ssize_t show_frequency_request(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%lu\n", sfd.freq_request);
+}
+
+static ssize_t show_frequency_limit(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%lu\n", sfd.freq_limit);
+}
+
+static ssize_t show_frequency(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%lu\n", sfd.freq);
+}
+
+static ssize_t show_stat(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "gpu %lu %lu\n",
+ sfd.total_active_time, sfd.total_idle_time);
+}
+
+static ssize_t show_governor_list(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ ssize_t i = 0;
+ struct sgxfreq_governor *t;
+
+ list_for_each_entry(t, &sfd.gov_list, governor_list) {
+ if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
+ - (SGXFREQ_NAME_LEN + 2)))
+ goto out;
+ i += scnprintf(&buf[i], SGXFREQ_NAME_LEN, "%s ", t->name);
+ }
+out:
+ i += sprintf(&buf[i], "\n");
+ return i;
+}
+
+static ssize_t show_governor(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ if (sfd.gov)
+ return scnprintf(buf, SGXFREQ_NAME_LEN, "%s\n", sfd.gov->name);
+
+ return sprintf(buf, "\n");
+}
+
+static ssize_t store_governor(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ int ret;
+ char name[16];
+
+ ret = sscanf(buf, "%15s", name);
+ if (ret != 1)
+ return -EINVAL;
+
+ ret = sgxfreq_set_governor(name);
+ if (ret)
+ return ret;
+ else
+ return count;
+}
+
+static DEVICE_ATTR(frequency_list, 0444, show_frequency_list, NULL);
+static DEVICE_ATTR(frequency_request, 0444, show_frequency_request, NULL);
+static DEVICE_ATTR(frequency_limit, 0444, show_frequency_limit, NULL);
+static DEVICE_ATTR(frequency, 0444, show_frequency, NULL);
+static DEVICE_ATTR(governor_list, 0444, show_governor_list, NULL);
+static DEVICE_ATTR(governor, 0644, show_governor, store_governor);
+static DEVICE_ATTR(stat, 0444, show_stat, NULL);
+
+static const struct attribute *sgxfreq_attributes[] = {
+ &dev_attr_frequency_list.attr,
+ &dev_attr_frequency_request.attr,
+ &dev_attr_frequency_limit.attr,
+ &dev_attr_frequency.attr,
+ &dev_attr_governor_list.attr,
+ &dev_attr_governor.attr,
+ &dev_attr_stat.attr,
+ NULL
+};
+
+/************************ end sysfs interface ************************/
+
+static void __set_freq(void)
+{
+ unsigned long freq;
+
+ freq = min(sfd.freq_request, sfd.freq_limit);
+ if (freq != sfd.freq) {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
+ sfd.pdata->device_scale(sfd.dev, sfd.dev, freq);
+#else
+ sfd.pdata->device_scale(sfd.dev, freq);
+#endif
+ sfd.freq = freq;
+ }
+}
+
+static struct sgxfreq_governor *__find_governor(const char *name)
+{
+ struct sgxfreq_governor *t;
+
+ list_for_each_entry(t, &sfd.gov_list, governor_list)
+ if (!strnicmp(name, t->name, SGXFREQ_NAME_LEN))
+ return t;
+
+ return NULL;
+}
+
+static void __update_timing_info(bool active)
+{
+ struct timeval tv;
+ do_gettimeofday(&tv);
+ if(active)
+ {
+ if(sfd.sgx_data.active == true) {
+ _active_curr_time = __tv2msec(tv);
+ sfd.total_active_time += __delta32(
+ _active_curr_time, _active_prev_time);
+ SGXFREQ_TRACE("A->A TA:= %lums \tdA: %lums \tTI: %lums \tdI: %lums\n",
+ sfd.total_active_time,
+ __delta32(_active_curr_time, _active_prev_time),
+ sfd.total_active_time,
+ (unsigned long)0);
+ _active_prev_time = _active_curr_time;
+ } else {
+ _idle_curr_time = __tv2msec(tv);
+ _active_prev_time = _idle_curr_time;
+ sfd.total_idle_time +=
+ __delta32(_idle_curr_time, _idle_prev_time);
+ SGXFREQ_TRACE("I->A TA:= %lums \tdA: %lums \tTI: %lums \tdI: %lums\n",
+ sfd.total_active_time,
+ (unsigned long)0,
+ sfd.total_idle_time,
+ __delta32(_idle_curr_time, _idle_prev_time));
+ }
+ } else {
+ if(sfd.sgx_data.active == true)
+ {
+ _idle_prev_time = _active_curr_time = __tv2msec(tv);
+ sfd.total_active_time +=
+ __delta32(_active_curr_time, _active_prev_time);
+ SGXFREQ_TRACE("A->I TA:= %lums \tdA: %lums \tTI: %lums \tdI: %lums\n",
+ sfd.total_active_time,
+ __delta32(_active_curr_time, _active_prev_time),
+ sfd.total_active_time,
+ (unsigned long)0);
+ }
+ else
+ {
+ _idle_curr_time = __tv2msec(tv);
+ sfd.total_idle_time += __delta32(
+ _idle_curr_time, _idle_prev_time);
+ SGXFREQ_TRACE("I->I TA:= %lums \tdA: %lums \tTI: %lums \tdI: %lums\n",
+ sfd.total_active_time,
+ (unsigned long)0,
+ sfd.total_idle_time,
+ __delta32(_idle_curr_time, _idle_prev_time));
+ _idle_prev_time = _idle_curr_time;
+ }
+ }
+}
+
+int sgxfreq_init(struct device *dev)
+{
+ int i, ret;
+ unsigned long freq;
+ struct opp *opp;
+ struct timeval tv;
+
+ sfd.dev = dev;
+ if (!sfd.dev)
+ return -EINVAL;
+
+ sfd.pdata = (struct gpu_platform_data *)dev->platform_data;
+ if (!sfd.pdata ||
+ !sfd.pdata->opp_get_opp_count ||
+ !sfd.pdata->opp_find_freq_ceil ||
+ !sfd.pdata->device_scale)
+ return -EINVAL;
+
+ rcu_read_lock();
+
+ sfd.freq_cnt = sfd.pdata->opp_get_opp_count(dev);
+ if (sfd.freq_cnt < 1) {
+ rcu_read_unlock();
+ return -ENODEV;
+ }
+
+ sfd.freq_list = kmalloc(sfd.freq_cnt * sizeof(unsigned long), GFP_ATOMIC);
+ if (!sfd.freq_list) {
+ rcu_read_unlock();
+ return -ENOMEM;
+ }
+
+ freq = 0;
+ for (i = 0; i < sfd.freq_cnt; i++) {
+ opp = sfd.pdata->opp_find_freq_ceil(dev, &freq);
+ if (IS_ERR_OR_NULL(opp)) {
+ rcu_read_unlock();
+ kfree(sfd.freq_list);
+ return -ENODEV;
+ }
+ sfd.freq_list[i] = freq;
+ freq++;
+ }
+ rcu_read_unlock();
+
+ mutex_init(&sfd.freq_mutex);
+ sfd.freq_limit = sfd.freq_list[sfd.freq_cnt - 1];
+ sgxfreq_set_freq_request(sfd.freq_list[sfd.freq_cnt - 1]);
+ sfd.sgx_data.clk_on = false;
+ sfd.sgx_data.active = false;
+
+ mutex_init(&sfd.gov_mutex);
+ INIT_LIST_HEAD(&sfd.gov_list);
+
+ sgxfreq_kobj = kobject_create_and_add("sgxfreq", &sfd.dev->kobj);
+ ret = sysfs_create_files(sgxfreq_kobj, sgxfreq_attributes);
+ if (ret) {
+ kfree(sfd.freq_list);
+ return ret;
+ }
+
+#if defined(CONFIG_THERMAL_FRAMEWORK)
+ cool_init();
+#endif
+
+ for (i = 0; sgxfreq_gov_init[i] != NULL; i++)
+ sgxfreq_gov_init[i]();
+
+ if (sgxfreq_set_governor(SGXFREQ_DEFAULT_GOV_NAME)) {
+ kfree(sfd.freq_list);
+ return -ENODEV;
+ }
+ do_gettimeofday(&tv);
+ _idle_prev_time = _active_curr_time = _idle_curr_time =
+ _active_prev_time = __tv2msec(tv);
+
+ return 0;
+}
+
+int sgxfreq_deinit(void)
+{
+ int i;
+
+ sgxfreq_set_governor(NULL);
+
+ sgxfreq_set_freq_request(sfd.freq_list[0]);
+
+#if defined(CONFIG_THERMAL_FRAMEWORK)
+ cool_deinit();
+#endif
+
+ for (i = 0; sgxfreq_gov_deinit[i] != NULL; i++)
+ sgxfreq_gov_deinit[i]();
+
+ sysfs_remove_files(sgxfreq_kobj, sgxfreq_attributes);
+ kobject_put(sgxfreq_kobj);
+
+ kfree(sfd.freq_list);
+
+ return 0;
+}
+
+int sgxfreq_register_governor(struct sgxfreq_governor *governor)
+{
+ if (!governor)
+ return -EINVAL;
+
+ list_add(&governor->governor_list, &sfd.gov_list);
+
+ return 0;
+}
+
+void sgxfreq_unregister_governor(struct sgxfreq_governor *governor)
+{
+ if (!governor)
+ return;
+
+ list_del(&governor->governor_list);
+}
+
+int sgxfreq_set_governor(const char *name)
+{
+ int ret = 0;
+ struct sgxfreq_governor *new_gov = 0;
+
+ if (name) {
+ new_gov = __find_governor(name);
+ if (!new_gov)
+ return -EINVAL;
+ }
+
+ mutex_lock(&sfd.gov_mutex);
+
+ if (sfd.gov && sfd.gov->gov_stop)
+ sfd.gov->gov_stop();
+
+ if (new_gov && new_gov->gov_start)
+ ret = new_gov->gov_start(&sfd.sgx_data);
+
+ if (ret) {
+ if (sfd.gov && sfd.gov->gov_start)
+ sfd.gov->gov_start(&sfd.sgx_data);
+ return -ENODEV;
+ }
+ sfd.gov = new_gov;
+
+ mutex_unlock(&sfd.gov_mutex);
+
+ return 0;
+}
+
+int sgxfreq_get_freq_list(unsigned long **pfreq_list)
+{
+ *pfreq_list = sfd.freq_list;
+
+ return sfd.freq_cnt;
+}
+
+unsigned long sgxfreq_get_freq_min(void)
+{
+ return sfd.freq_list[0];
+}
+
+unsigned long sgxfreq_get_freq_max(void)
+{
+ return sfd.freq_list[sfd.freq_cnt - 1];
+}
+
+unsigned long sgxfreq_get_freq_floor(unsigned long freq)
+{
+ int i;
+ unsigned long f = 0;
+
+ for (i = sfd.freq_cnt - 1; i >= 0; i--) {
+ f = sfd.freq_list[i];
+ if (f <= freq)
+ return f;
+ }
+
+ return f;
+}
+
+unsigned long sgxfreq_get_freq_ceil(unsigned long freq)
+{
+ int i;
+ unsigned long f = 0;
+
+ for (i = 0; i < sfd.freq_cnt; i++) {
+ f = sfd.freq_list[i];
+ if (f >= freq)
+ return f;
+ }
+
+ return f;
+}
+
+unsigned long sgxfreq_get_freq(void)
+{
+ return sfd.freq;
+}
+
+unsigned long sgxfreq_get_freq_request(void)
+{
+ return sfd.freq_request;
+}
+
+unsigned long sgxfreq_get_freq_limit(void)
+{
+ return sfd.freq_limit;
+}
+
+unsigned long sgxfreq_set_freq_request(unsigned long freq_request)
+{
+ freq_request = sgxfreq_get_freq_ceil(freq_request);
+
+ mutex_lock(&sfd.freq_mutex);
+
+ sfd.freq_request = freq_request;
+ __set_freq();
+
+ mutex_unlock(&sfd.freq_mutex);
+
+ return freq_request;
+}
+
+unsigned long sgxfreq_set_freq_limit(unsigned long freq_limit)
+{
+ freq_limit = sgxfreq_get_freq_ceil(freq_limit);
+
+ mutex_lock(&sfd.freq_mutex);
+
+ sfd.freq_limit = freq_limit;
+ __set_freq();
+
+ mutex_unlock(&sfd.freq_mutex);
+
+ return freq_limit;
+}
+
+unsigned long sgxfreq_get_total_active_time(void)
+{
+ __update_timing_info(sfd.sgx_data.active);
+ return sfd.total_active_time;
+}
+
+unsigned long sgxfreq_get_total_idle_time(void)
+{
+ __update_timing_info(sfd.sgx_data.active);
+ return sfd.total_idle_time;
+}
+
+/*
+ * sgx_clk_on, sgx_clk_off, sgx_active, and sgx_idle notifications are
+ * serialized by power lock. governor notif calls need sync with governor
+ * setting.
+ */
+void sgxfreq_notif_sgx_clk_on(void)
+{
+ sfd.sgx_data.clk_on = true;
+
+ mutex_lock(&sfd.gov_mutex);
+
+ if (sfd.gov && sfd.gov->sgx_clk_on)
+ sfd.gov->sgx_clk_on();
+
+ mutex_unlock(&sfd.gov_mutex);
+}
+
+void sgxfreq_notif_sgx_clk_off(void)
+{
+ sfd.sgx_data.clk_on = false;
+
+ mutex_lock(&sfd.gov_mutex);
+
+ if (sfd.gov && sfd.gov->sgx_clk_off)
+ sfd.gov->sgx_clk_off();
+
+ mutex_unlock(&sfd.gov_mutex);
+}
+
+
+void sgxfreq_notif_sgx_active(void)
+{
+ __update_timing_info(true);
+
+ sfd.sgx_data.active = true;
+
+ mutex_lock(&sfd.gov_mutex);
+
+ if (sfd.gov && sfd.gov->sgx_active)
+ sfd.gov->sgx_active();
+
+ mutex_unlock(&sfd.gov_mutex);
+
+}
+
+void sgxfreq_notif_sgx_idle(void)
+{
+
+ __update_timing_info(false);
+
+ sfd.sgx_data.active = false;
+
+ mutex_lock(&sfd.gov_mutex);
+
+ if (sfd.gov && sfd.gov->sgx_idle)
+ sfd.gov->sgx_idle();
+
+ mutex_unlock(&sfd.gov_mutex);
+}
+
+void sgxfreq_notif_sgx_frame_done(void)
+{
+ mutex_lock(&sfd.gov_mutex);
+
+ if (sfd.gov && sfd.gov->sgx_frame_done)
+ sfd.gov->sgx_frame_done();
+
+ mutex_unlock(&sfd.gov_mutex);
+}
diff --git a/pvr-source/services4/system/omap4/sgxfreq.h b/pvr-source/services4/system/omap4/sgxfreq.h
new file mode 100644
index 0000000..ff6fc88
--- /dev/null
+++ b/pvr-source/services4/system/omap4/sgxfreq.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2012 Texas Instruments, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SGXFREQ_H
+#define SGXFREQ_H
+
+#include <linux/device.h>
+#include <linux/time.h>
+
+#define SGXFREQ_NAME_LEN 16
+
+//#define SGXFREQ_DEBUG_FTRACE
+#if defined(SGXFREQ_DEBUG_FTRACE)
+#define SGXFREQ_TRACE(...) trace_printk(__VA_ARGS__)
+#else
+#define SGXFREQ_TRACE(...)
+#endif
+
+struct sgxfreq_sgx_data {
+ bool clk_on;
+ bool active;
+};
+
+struct sgxfreq_governor {
+ char name[SGXFREQ_NAME_LEN];
+ int (*gov_start) (struct sgxfreq_sgx_data *data);
+ void (*gov_stop) (void);
+ void (*sgx_clk_on) (void);
+ void (*sgx_clk_off) (void);
+ void (*sgx_active) (void);
+ void (*sgx_idle) (void);
+ void (*sgx_frame_done) (void);
+ struct list_head governor_list;
+};
+
+/* sgxfreq_init must be called before any other api */
+int sgxfreq_init(struct device *dev);
+int sgxfreq_deinit(void);
+
+int sgxfreq_register_governor(struct sgxfreq_governor *governor);
+void sgxfreq_unregister_governor(struct sgxfreq_governor *governor);
+
+int sgxfreq_set_governor(const char *name);
+
+int sgxfreq_get_freq_list(unsigned long **pfreq_list);
+
+unsigned long sgxfreq_get_freq_min(void);
+unsigned long sgxfreq_get_freq_max(void);
+
+unsigned long sgxfreq_get_freq_floor(unsigned long freq);
+unsigned long sgxfreq_get_freq_ceil(unsigned long freq);
+
+unsigned long sgxfreq_get_freq(void);
+unsigned long sgxfreq_get_freq_request(void);
+unsigned long sgxfreq_get_freq_limit(void);
+
+unsigned long sgxfreq_set_freq_request(unsigned long freq_request);
+unsigned long sgxfreq_set_freq_limit(unsigned long freq_limit);
+
+unsigned long sgxfreq_get_total_active_time(void);
+unsigned long sgxfreq_get_total_idle_time(void);
+
+/* Helper functions */
+static inline unsigned long __tv2msec(struct timeval tv)
+{
+ return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
+}
+
+static inline unsigned long __delta32(unsigned long a, unsigned long b)
+{
+ if (a >= b)
+ return a - b;
+ else
+ return 1 + (0xFFFFFFFF - b) + a;
+}
+
+/* External notifications to sgxfreq */
+void sgxfreq_notif_sgx_clk_on(void);
+void sgxfreq_notif_sgx_clk_off(void);
+void sgxfreq_notif_sgx_active(void);
+void sgxfreq_notif_sgx_idle(void);
+void sgxfreq_notif_sgx_frame_done(void);
+
+#endif
diff --git a/pvr-source/services4/system/omap4/sgxfreq_activeidle.c b/pvr-source/services4/system/omap4/sgxfreq_activeidle.c
new file mode 100644
index 0000000..45159d7
--- /dev/null
+++ b/pvr-source/services4/system/omap4/sgxfreq_activeidle.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2012 Texas Instruments, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/sysfs.h>
+#include "sgxfreq.h"
+
+static int activeidle_start(struct sgxfreq_sgx_data *data);
+static void activeidle_stop(void);
+static void activeidle_sgx_active(void);
+static void activeidle_sgx_idle(void);
+
+static struct activeidle_data {
+ unsigned long freq_active;
+ unsigned long freq_idle;
+ struct mutex mutex;
+ bool sgx_active;
+} aid;
+
+static struct sgxfreq_governor activeidle_gov = {
+ .name = "activeidle",
+ .gov_start = activeidle_start,
+ .gov_stop = activeidle_stop,
+ .sgx_active = activeidle_sgx_active,
+ .sgx_idle = activeidle_sgx_idle,
+};
+
+/*********************** begin sysfs interface ***********************/
+
+extern struct kobject *sgxfreq_kobj;
+
+static ssize_t show_freq_active(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%lu\n", aid.freq_active);
+}
+
+static ssize_t store_freq_active(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+ unsigned long freq;
+
+ ret = sscanf(buf, "%lu", &freq);
+ if (ret != 1)
+ return -EINVAL;
+
+ freq = sgxfreq_get_freq_ceil(freq);
+
+ mutex_lock(&aid.mutex);
+
+ aid.freq_active = freq;
+ if (aid.sgx_active)
+ sgxfreq_set_freq_request(aid.freq_active);
+
+ mutex_unlock(&aid.mutex);
+
+ return count;
+}
+
+static ssize_t show_freq_idle(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%lu\n", aid.freq_idle);
+}
+
+static ssize_t store_freq_idle(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+ unsigned long freq;
+
+ ret = sscanf(buf, "%lu", &freq);
+ if (ret != 1)
+ return -EINVAL;
+
+ freq = sgxfreq_get_freq_floor(freq);
+
+ mutex_lock(&aid.mutex);
+
+ aid.freq_idle = freq;
+ if (!aid.sgx_active)
+ sgxfreq_set_freq_request(aid.freq_idle);
+
+ mutex_unlock(&aid.mutex);
+
+ return count;
+}
+static DEVICE_ATTR(freq_active, 0644, show_freq_active, store_freq_active);
+static DEVICE_ATTR(freq_idle, 0644, show_freq_idle, store_freq_idle);
+
+static struct attribute *activeidle_attributes[] = {
+ &dev_attr_freq_active.attr,
+ &dev_attr_freq_idle.attr,
+ NULL
+};
+
+static struct attribute_group activeidle_attr_group = {
+ .attrs = activeidle_attributes,
+ .name = "activeidle",
+};
+
+/************************ end sysfs interface ************************/
+
+int activeidle_init(void)
+{
+ int ret;
+
+ mutex_init(&aid.mutex);
+
+ ret = sgxfreq_register_governor(&activeidle_gov);
+ if (ret)
+ return ret;
+
+ aid.freq_idle = sgxfreq_get_freq_min();
+ aid.freq_active = sgxfreq_get_freq_max();
+
+ return 0;
+}
+
+int activeidle_deinit(void)
+{
+ return 0;
+}
+
+static int activeidle_start(struct sgxfreq_sgx_data *data)
+{
+ int ret;
+
+ aid.sgx_active = data->active;
+
+ ret = sysfs_create_group(sgxfreq_kobj, &activeidle_attr_group);
+ if (ret)
+ return ret;
+
+ if (aid.sgx_active)
+ sgxfreq_set_freq_request(aid.freq_active);
+ else
+ sgxfreq_set_freq_request(aid.freq_idle);
+
+ return 0;
+}
+
+static void activeidle_stop(void)
+{
+ sysfs_remove_group(sgxfreq_kobj, &activeidle_attr_group);
+}
+
+static void activeidle_sgx_active(void)
+{
+ mutex_lock(&aid.mutex);
+
+ aid.sgx_active = true;
+ sgxfreq_set_freq_request(aid.freq_active);
+
+ mutex_unlock(&aid.mutex);
+}
+
+static void activeidle_sgx_idle(void)
+{
+ mutex_lock(&aid.mutex);
+
+ aid.sgx_active = false;
+ sgxfreq_set_freq_request(aid.freq_idle);
+
+ mutex_unlock(&aid.mutex);
+}
diff --git a/pvr-source/services4/system/omap4/sgxfreq_cool.c b/pvr-source/services4/system/omap4/sgxfreq_cool.c
new file mode 100644
index 0000000..9233def
--- /dev/null
+++ b/pvr-source/services4/system/omap4/sgxfreq_cool.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2012 Texas Instruments, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/thermal_framework.h>
+
+static int cool_device(struct thermal_dev *dev, int cooling_level);
+
+static struct cool_data {
+ int freq_cnt;
+ unsigned long *freq_list;
+} cd;
+
+static struct thermal_dev_ops cool_dev_ops = {
+ .cool_device = cool_device,
+};
+
+static struct thermal_dev cool_dev = {
+ .name = "gpu_cooling.0",
+ .domain_name = "gpu",
+ .dev_ops = &cool_dev_ops,
+};
+
+static struct thermal_dev case_cool_dev = {
+ .name = "gpu_cooling.1",
+ .domain_name = "case",
+ .dev_ops = &cool_dev_ops,
+};
+
+static unsigned int gpu_cooling_level;
+#if defined(CONFIG_CASE_TEMP_GOVERNOR)
+static unsigned int case_cooling_level;
+#endif
+
+int cool_init(void)
+{
+ int ret;
+ cd.freq_cnt = sgxfreq_get_freq_list(&cd.freq_list);
+ if (!cd.freq_cnt || !cd.freq_list)
+ return -EINVAL;
+
+ ret = thermal_cooling_dev_register(&cool_dev);
+ if (ret)
+ return ret;
+
+ return thermal_cooling_dev_register(&case_cool_dev);
+}
+
+void cool_deinit(void)
+{
+ thermal_cooling_dev_unregister(&cool_dev);
+ thermal_cooling_dev_unregister(&case_cool_dev);
+}
+
+static int cool_device(struct thermal_dev *dev, int cooling_level)
+{
+ int freq_max_index, freq_limit_index;
+
+#if defined(CONFIG_CASE_TEMP_GOVERNOR)
+ if (!strcmp(dev->domain_name, "case"))
+ {
+ int tmp = 0;
+ tmp = cooling_level - case_subzone_number;
+ if (tmp < 0)
+ tmp = 0;
+ case_cooling_level = tmp;
+ }
+ else
+#endif
+ {
+ gpu_cooling_level = cooling_level;
+ }
+
+ freq_max_index = cd.freq_cnt - 1;
+#if defined(CONFIG_CASE_TEMP_GOVERNOR)
+ if (case_cooling_level > gpu_cooling_level)
+ {
+ freq_limit_index = freq_max_index - case_cooling_level;
+ }
+ else
+#endif
+ {
+ freq_limit_index = freq_max_index - gpu_cooling_level;
+ }
+
+ if (freq_limit_index < 0)
+ freq_limit_index = 0;
+
+ sgxfreq_set_freq_limit(cd.freq_list[freq_limit_index]);
+
+ return 0;
+}
diff --git a/pvr-source/services4/system/omap4/sgxfreq_on3demand.c b/pvr-source/services4/system/omap4/sgxfreq_on3demand.c
new file mode 100644
index 0000000..c4e4bd9
--- /dev/null
+++ b/pvr-source/services4/system/omap4/sgxfreq_on3demand.c
@@ -0,0 +1,324 @@
+/*
+ * Copyright (C) 2012 Texas Instruments, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/sysfs.h>
+#include <linux/vmalloc.h>
+#include <asm/io.h>
+#include "sgxfreq.h"
+
+static int on3demand_start(struct sgxfreq_sgx_data *data);
+static void on3demand_stop(void);
+static void on3demand_predict(void);
+static void on3demand_frame_done(void);
+static void on3demand_active(void);
+static void on3demand_timeout(struct work_struct *work);
+
+
+static struct sgxfreq_governor on3demand_gov = {
+ .name = "on3demand",
+ .gov_start = on3demand_start,
+ .gov_stop = on3demand_stop,
+ .sgx_frame_done = on3demand_frame_done,
+ .sgx_active = on3demand_active,
+};
+
+static struct on3demand_data {
+ unsigned int load;
+ unsigned int up_threshold;
+ unsigned int down_threshold;
+ unsigned int history_size;
+ unsigned long prev_total_idle;
+ unsigned long prev_total_active;
+ unsigned int low_load_cnt;
+ unsigned int poll_interval;
+ unsigned long delta_active;
+ unsigned long delta_idle;
+ bool polling_enabled;
+ struct delayed_work work;
+ struct mutex mutex;
+} odd;
+
+#define ON3DEMAND_DEFAULT_UP_THRESHOLD 80
+#define ON3DEMAND_DEFAULT_DOWN_THRESHOLD 30
+#define ON3DEMAND_DEFAULT_HISTORY_SIZE_THRESHOLD 5
+/* For Live wallpaper frame done at interval of ~64ms */
+#define ON3DEMAND_DEFAULT_POLL_INTERVAL 75
+
+/*FIXME: This should be dynamic and queried from platform */
+#define ON3DEMAND_FRAME_DONE_DEADLINE_MS 16
+
+
+/*********************** begin sysfs interface ***********************/
+
+extern struct kobject *sgxfreq_kobj;
+
+static ssize_t show_down_threshold(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%u\n", odd.down_threshold);
+}
+
+static ssize_t store_down_threshold(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int ret;
+ unsigned int thres;
+
+ ret = sscanf(buf, "%u", &thres);
+ if (ret != 1)
+ return -EINVAL;
+
+ mutex_lock(&odd.mutex);
+
+ if (thres <= 100) {
+ odd.down_threshold = thres;
+ odd.low_load_cnt = 0;
+ } else {
+ return -EINVAL;
+ }
+
+ mutex_unlock(&odd.mutex);
+
+ return count;
+}
+
+static ssize_t show_up_threshold(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%u\n", odd.up_threshold);
+}
+
+static ssize_t store_up_threshold(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int ret;
+ unsigned int thres;
+
+ ret = sscanf(buf, "%u", &thres);
+ if (ret != 1)
+ return -EINVAL;
+
+ mutex_lock(&odd.mutex);
+
+ if (thres <= 100) {
+ odd.up_threshold = thres;
+ odd.low_load_cnt = 0;
+ } else {
+ return -EINVAL;
+ }
+
+ mutex_unlock(&odd.mutex);
+
+ return count;
+}
+
+static ssize_t show_history_size(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%u\n", odd.history_size);
+}
+
+static ssize_t store_history_size(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int ret;
+ unsigned int size;
+
+ ret = sscanf(buf, "%u", &size);
+ if (ret != 1)
+ return -EINVAL;
+
+ mutex_lock(&odd.mutex);
+
+ if (size >= 1) {
+ odd.history_size = size;
+ odd.low_load_cnt = 0;
+ } else {
+ return -EINVAL;
+ }
+
+ mutex_unlock(&odd.mutex);
+
+ return count;
+}
+
+static ssize_t show_load(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%u\n", odd.load);
+}
+
+static DEVICE_ATTR(down_threshold, 0644,
+ show_down_threshold, store_down_threshold);
+static DEVICE_ATTR(up_threshold, 0644,
+ show_up_threshold, store_up_threshold);
+static DEVICE_ATTR(history_size, 0644,
+ show_history_size, store_history_size);
+static DEVICE_ATTR(load, 0444,
+ show_load, NULL);
+
+static struct attribute *on3demand_attributes[] = {
+ &dev_attr_down_threshold.attr,
+ &dev_attr_up_threshold.attr,
+ &dev_attr_history_size.attr,
+ &dev_attr_load.attr,
+ NULL
+};
+
+static struct attribute_group on3demand_attr_group = {
+ .attrs = on3demand_attributes,
+ .name = "on3demand",
+};
+/************************ end sysfs interface ************************/
+
+int on3demand_init(void)
+{
+ int ret;
+
+ mutex_init(&odd.mutex);
+
+ ret = sgxfreq_register_governor(&on3demand_gov);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+int on3demand_deinit(void)
+{
+ return 0;
+}
+
+static int on3demand_start(struct sgxfreq_sgx_data *data)
+{
+ int ret;
+
+ odd.load = 0;
+ odd.up_threshold = ON3DEMAND_DEFAULT_UP_THRESHOLD;
+ odd.down_threshold = ON3DEMAND_DEFAULT_DOWN_THRESHOLD;
+ odd.history_size = ON3DEMAND_DEFAULT_HISTORY_SIZE_THRESHOLD;
+ odd.prev_total_active = 0;
+ odd.prev_total_idle = 0;
+ odd.low_load_cnt = 0;
+ odd.poll_interval = ON3DEMAND_DEFAULT_POLL_INTERVAL;
+ odd.polling_enabled = false;
+
+ INIT_DELAYED_WORK(&odd.work, on3demand_timeout);
+
+ ret = sysfs_create_group(sgxfreq_kobj, &on3demand_attr_group);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static void on3demand_stop(void)
+{
+ cancel_delayed_work_sync(&odd.work);
+ sysfs_remove_group(sgxfreq_kobj, &on3demand_attr_group);
+}
+
+static void on3demand_predict(void)
+{
+ static unsigned short first_sample = 1;
+ unsigned long total_active, total_idle;
+ unsigned long freq;
+
+ if (first_sample == 1) {
+ first_sample = 0;
+ odd.prev_total_active = sgxfreq_get_total_active_time();
+ odd.prev_total_idle = sgxfreq_get_total_idle_time();
+ return;
+ }
+
+ /* Sample new active and idle times */
+ total_active = sgxfreq_get_total_active_time();
+ total_idle = sgxfreq_get_total_idle_time();
+
+ /* Compute load */
+ odd.delta_active = __delta32(total_active, odd.prev_total_active);
+ odd.delta_idle = __delta32(total_idle, odd.prev_total_idle);
+
+ /*
+ * If SGX was active for longer than frame display time (1/fps),
+ * scale to highest possible frequency.
+ */
+ if (odd.delta_active > ON3DEMAND_FRAME_DONE_DEADLINE_MS) {
+ odd.low_load_cnt = 0;
+ sgxfreq_set_freq_request(sgxfreq_get_freq_max());
+ }
+
+ if ((odd.delta_active + odd.delta_idle))
+ odd.load = (100 * odd.delta_active / (odd.delta_active + odd.delta_idle));
+
+ odd.prev_total_active = total_active;
+ odd.prev_total_idle = total_idle;
+
+ /* Scale GPU frequency on purpose */
+ if (odd.load >= odd.up_threshold) {
+ odd.low_load_cnt = 0;
+ sgxfreq_set_freq_request(sgxfreq_get_freq_max());
+ } else if (odd.load <= odd.down_threshold) {
+ if (odd.low_load_cnt == odd.history_size) {
+ /* Convert load to frequency */
+ freq = (sgxfreq_get_freq() * odd.load) / 100;
+ sgxfreq_set_freq_request(freq);
+ odd.low_load_cnt = 0;
+ } else {
+ odd.low_load_cnt++;
+ }
+ } else {
+ odd.low_load_cnt = 0;
+ }
+}
+
+
+static void on3demand_active(void)
+{
+ if (!odd.polling_enabled) {
+ sgxfreq_set_freq_request(sgxfreq_get_freq_max());
+ odd.low_load_cnt = 0;
+ odd.polling_enabled = true;
+ schedule_delayed_work(&odd.work, odd.poll_interval * HZ/1000);
+ }
+
+}
+
+static void on3demand_frame_done(void)
+{
+ if (odd.polling_enabled) {
+ cancel_delayed_work_sync(&odd.work);
+ schedule_delayed_work(&odd.work, odd.poll_interval * HZ/1000);
+ }
+ on3demand_predict();
+}
+
+static void on3demand_timeout(struct work_struct *work)
+{
+ /*
+ * If sgx was idle all throughout timer disable polling and
+ * enable it on next sgx active event
+ */
+ if (!odd.delta_active) {
+ sgxfreq_set_freq_request(sgxfreq_get_freq_min());
+ odd.low_load_cnt = 0;
+ odd.polling_enabled = false;
+ } else {
+ on3demand_predict();
+ odd.polling_enabled = true;
+ schedule_delayed_work(&odd.work, odd.poll_interval * HZ/1000);
+ }
+}
diff --git a/pvr-source/services4/system/omap4/sgxfreq_onoff.c b/pvr-source/services4/system/omap4/sgxfreq_onoff.c
new file mode 100644
index 0000000..39dd3fc
--- /dev/null
+++ b/pvr-source/services4/system/omap4/sgxfreq_onoff.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2012 Texas Instruments, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/sysfs.h>
+#include "sgxfreq.h"
+
+static int onoff_start(struct sgxfreq_sgx_data *data);
+static void onoff_stop(void);
+static void onoff_sgx_clk_on(void);
+static void onoff_sgx_clk_off(void);
+
+static struct onoff_data {
+ unsigned long freq_off;
+ unsigned long freq_on;
+ struct mutex mutex;
+ bool sgx_clk_on;
+} ood;
+
+static struct sgxfreq_governor onoff_gov = {
+ .name = "onoff",
+ .gov_start = onoff_start,
+ .gov_stop = onoff_stop,
+ .sgx_clk_on = onoff_sgx_clk_on,
+ .sgx_clk_off = onoff_sgx_clk_off,
+};
+
+/*********************** begin sysfs interface ***********************/
+
+extern struct kobject *sgxfreq_kobj;
+
+static ssize_t show_freq_on(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%lu\n", ood.freq_on);
+}
+
+static ssize_t store_freq_on(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+ unsigned long freq;
+
+ ret = sscanf(buf, "%lu", &freq);
+ if (ret != 1)
+ return -EINVAL;
+
+ freq = sgxfreq_get_freq_ceil(freq);
+
+ mutex_lock(&ood.mutex);
+
+ ood.freq_on = freq;
+ if (ood.sgx_clk_on)
+ sgxfreq_set_freq_request(ood.freq_on);
+
+ mutex_unlock(&ood.mutex);
+
+ return count;
+}
+
+static ssize_t show_freq_off(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%lu\n", ood.freq_off);
+}
+
+static ssize_t store_freq_off(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+ unsigned long freq;
+
+ ret = sscanf(buf, "%lu", &freq);
+ if (ret != 1)
+ return -EINVAL;
+
+ freq = sgxfreq_get_freq_floor(freq);
+
+ mutex_lock(&ood.mutex);
+
+ ood.freq_off = freq;
+ if (!ood.sgx_clk_on)
+ sgxfreq_set_freq_request(ood.freq_off);
+
+ mutex_unlock(&ood.mutex);
+
+ return count;
+}
+static DEVICE_ATTR(freq_on, 0644, show_freq_on, store_freq_on);
+static DEVICE_ATTR(freq_off, 0644, show_freq_off, store_freq_off);
+
+static struct attribute *onoff_attributes[] = {
+ &dev_attr_freq_on.attr,
+ &dev_attr_freq_off.attr,
+ NULL
+};
+
+static struct attribute_group onoff_attr_group = {
+ .attrs = onoff_attributes,
+ .name = "onoff",
+};
+
+/************************ end sysfs interface ************************/
+
+int onoff_init(void)
+{
+ int ret;
+
+ mutex_init(&ood.mutex);
+
+ ret = sgxfreq_register_governor(&onoff_gov);
+ if (ret)
+ return ret;
+
+ ood.freq_off = sgxfreq_get_freq_min();
+ ood.freq_on = sgxfreq_get_freq_max();
+
+ return 0;
+}
+
+int onoff_deinit(void)
+{
+ return 0;
+}
+
+static int onoff_start(struct sgxfreq_sgx_data *data)
+{
+ int ret;
+
+ ood.sgx_clk_on = data->clk_on;
+
+ ret = sysfs_create_group(sgxfreq_kobj, &onoff_attr_group);
+ if (ret)
+ return ret;
+
+ if (ood.sgx_clk_on)
+ sgxfreq_set_freq_request(ood.freq_on);
+ else
+ sgxfreq_set_freq_request(ood.freq_off);
+
+ return 0;
+}
+
+static void onoff_stop(void)
+{
+ sysfs_remove_group(sgxfreq_kobj, &onoff_attr_group);
+}
+
+static void onoff_sgx_clk_on(void)
+{
+ mutex_lock(&ood.mutex);
+
+ ood.sgx_clk_on = true;
+ sgxfreq_set_freq_request(ood.freq_on);
+
+ mutex_unlock(&ood.mutex);
+}
+
+static void onoff_sgx_clk_off(void)
+{
+ mutex_lock(&ood.mutex);
+
+ ood.sgx_clk_on = false;
+ sgxfreq_set_freq_request(ood.freq_off);
+
+ mutex_unlock(&ood.mutex);
+}
+
diff --git a/pvr-source/services4/system/omap4/sgxfreq_userspace.c b/pvr-source/services4/system/omap4/sgxfreq_userspace.c
new file mode 100644
index 0000000..5ff0dd0
--- /dev/null
+++ b/pvr-source/services4/system/omap4/sgxfreq_userspace.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2012 Texas Instruments, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/sysfs.h>
+#include "sgxfreq.h"
+
+
+static int userspace_start(struct sgxfreq_sgx_data *data);
+static void userspace_stop(void);
+static void userspace_sgx_clk_on(void);
+static void userspace_sgx_clk_off(void);
+static void userspace_sgx_active(void);
+static void userspace_sgx_idle(void);
+
+
+static struct sgxfreq_governor userspace_gov = {
+ .name = "userspace",
+ .gov_start = userspace_start,
+ .gov_stop = userspace_stop,
+ .sgx_clk_on = userspace_sgx_clk_on,
+ .sgx_clk_off = userspace_sgx_clk_off,
+ .sgx_active = userspace_sgx_active,
+ .sgx_idle = userspace_sgx_idle,
+};
+
+
+static struct userspace_data {
+ unsigned long freq_user; /* in KHz */
+ struct mutex mutex;
+} usd;
+
+
+/*********************** begin sysfs interface ***********************/
+
+extern struct kobject *sgxfreq_kobj;
+
+
+static ssize_t show_frequency_set(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%lu\n", usd.freq_user);
+}
+
+
+static ssize_t store_frequency_set(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int ret;
+ unsigned long freq;
+
+ ret = sscanf(buf, "%lu", &freq);
+ if (ret != 1)
+ return -EINVAL;
+
+ mutex_lock(&odd.mutex);
+
+ if (freq > sgxfreq_get_freq_max())
+ freq = sgxfreq_get_freq_max();
+ usd.freq_user = sgxfreq_set_freq_request(freq);
+ trace_printk("USERSPACE: new freq=%luHz.\n", usd.freq_user);
+
+ mutex_unlock(&odd.mutex);
+
+ return count;
+}
+
+
+static DEVICE_ATTR(frequency_set, 0644,
+ show_frequency_set, store_frequency_set);
+
+
+static struct attribute *userspace_attributes[] = {
+ &dev_attr_frequency_set.attr,
+ NULL
+};
+
+
+static struct attribute_group userspace_attr_group = {
+ .attrs = userspace_attributes,
+ .name = "userspace",
+};
+
+/************************ end sysfs interface ************************/
+
+
+int userspace_init(void)
+{
+ int ret;
+
+ mutex_init(&odd.mutex);
+
+ ret = sgxfreq_register_governor(&userspace_gov);
+ if (ret)
+ return ret;
+ return 0;
+}
+
+
+int userspace_deinit(void)
+{
+ return 0;
+}
+
+
+static int userspace_start(struct sgxfreq_sgx_data *data)
+{
+ int ret;
+
+ usd.freq_user = sgxfreq_get_freq();
+
+ ret = sysfs_create_group(sgxfreq_kobj, &userspace_attr_group);
+ if (ret)
+ return ret;
+
+ trace_printk("USERSPACE: started.\n");
+
+ return 0;
+}
+
+
+static void userspace_stop(void)
+{
+ usd.freq_user = sgxfreq_set_freq_request(sgxfreq_get_freq_min());
+ sysfs_remove_group(sgxfreq_kobj, &userspace_attr_group);
+
+ trace_printk("USERSPACE: stopped.\n");
+}
+
+
+static void userspace_sgx_clk_on(void)
+{
+ mutex_lock(&ood.mutex);
+
+ sgxfreq_set_freq_request(usd.freq_user);
+
+ mutex_unlock(&ood.mutex);
+}
+
+
+static void userspace_sgx_clk_off(void)
+{
+ mutex_lock(&ood.mutex);
+
+ sgxfreq_set_freq_request(sgxfreq_get_freq_min());
+
+ mutex_unlock(&ood.mutex);
+}
+
+
+static void userspace_sgx_active(void)
+{
+ mutex_lock(&aid.mutex);
+
+ sgxfreq_set_freq_request(usd.freq_user);
+
+ mutex_unlock(&aid.mutex);
+}
+
+
+static void userspace_sgx_idle(void)
+{
+ mutex_lock(&aid.mutex);
+
+ sgxfreq_set_freq_request(sgxfreq_get_freq_min());
+
+ mutex_unlock(&aid.mutex);
+}
diff --git a/pvr-source/services4/system/omap4/sysconfig.c b/pvr-source/services4/system/omap4/sysconfig.c
new file mode 100644
index 0000000..e9fd069
--- /dev/null
+++ b/pvr-source/services4/system/omap4/sysconfig.c
@@ -0,0 +1,1329 @@
+/*************************************************************************/ /*!
+@Title System Configuration
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description System Configuration functions
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "sysconfig.h"
+#include "services_headers.h"
+#include "kerneldisplay.h"
+#include "oemfuncs.h"
+#include "sgxinfo.h"
+#include "sgxinfokm.h"
+#include "syslocal.h"
+
+#include "ocpdefs.h"
+
+#define OMAP5430_CORE_REV 0x10005
+
+/* top level system data anchor point*/
+SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL;
+SYS_DATA gsSysData;
+
+static SYS_SPECIFIC_DATA gsSysSpecificData;
+SYS_SPECIFIC_DATA *gpsSysSpecificData;
+
+/* SGX structures */
+static IMG_UINT32 gui32SGXDeviceID;
+static SGX_DEVICE_MAP gsSGXDeviceMap;
+static PVRSRV_DEVICE_NODE *gpsSGXDevNode;
+
+
+#if defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED)
+static IMG_CPU_VIRTADDR gsSGXRegsCPUVAddr;
+#endif
+
+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO)
+extern struct platform_device *gpsPVRLDMDev;
+#endif
+
+IMG_UINT32 PVRSRV_BridgeDispatchKM(IMG_UINT32 Ioctl,
+ IMG_BYTE *pInBuf,
+ IMG_UINT32 InBufLen,
+ IMG_BYTE *pOutBuf,
+ IMG_UINT32 OutBufLen,
+ IMG_UINT32 *pdwBytesTransferred);
+
+#if defined(SGX_OCP_REGS_ENABLED)
+
+static IMG_CPU_VIRTADDR gpvOCPRegsLinAddr;
+
+static PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData)
+{
+ PVRSRV_ERROR eError = EnableSGXClocks(psSysData);
+
+#if !defined(SGX_OCP_NO_INT_BYPASS)
+ if(eError == PVRSRV_OK)
+ {
+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_SYSCONFIG, 0x14);
+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_DEBUG_CONFIG, EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_MASK);
+ }
+#endif
+ return eError;
+}
+
+#else /* defined(SGX_OCP_REGS_ENABLED) */
+
+static INLINE PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData)
+{
+ return EnableSGXClocks(psSysData);
+}
+
+#endif /* defined(SGX_OCP_REGS_ENABLED) */
+
+static INLINE PVRSRV_ERROR EnableSystemClocksWrap(SYS_DATA *psSysData)
+{
+ PVRSRV_ERROR eError = EnableSystemClocks(psSysData);
+
+#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
+ if(eError == PVRSRV_OK)
+ {
+ /*
+ * The SGX Clocks are enabled separately if active power
+ * management is enabled.
+ */
+ eError = EnableSGXClocksWrap(psSysData);
+ if (eError != PVRSRV_OK)
+ {
+ DisableSystemClocks(psSysData);
+ }
+ }
+#endif
+
+ return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function SysLocateDevices
+
+ @Description Specifies devices in the systems memory map
+
+ @Input psSysData - sys data
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData)
+{
+#if defined(NO_HARDWARE)
+ PVRSRV_ERROR eError;
+ IMG_CPU_PHYADDR sCpuPAddr;
+#else
+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO)
+ struct resource *dev_res;
+ int dev_irq;
+#endif
+#endif
+
+ PVR_UNREFERENCED_PARAMETER(psSysData);
+
+ /* SGX Device: */
+ gsSGXDeviceMap.ui32Flags = 0x0;
+
+#if defined(NO_HARDWARE)
+ /*
+ * For no hardware, allocate some contiguous memory for the
+ * register block.
+ */
+
+ /* Registers */
+ gsSGXDeviceMap.ui32RegsSize = SYS_OMAP4430_SGX_REGS_SIZE;
+
+ eError = OSBaseAllocContigMemory(gsSGXDeviceMap.ui32RegsSize,
+ &gsSGXRegsCPUVAddr,
+ &sCpuPAddr);
+ if(eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr;
+ gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase);
+#if defined(__linux__)
+ /* Indicate the registers are already mapped */
+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr;
+#else
+ /*
+ * FIXME: Could we just use the virtual address returned by
+ * OSBaseAllocContigMemory?
+ */
+ gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL;
+#endif
+
+ OSMemSet(gsSGXRegsCPUVAddr, 0, gsSGXDeviceMap.ui32RegsSize);
+
+ /*
+ device interrupt IRQ
+ Note: no interrupts available on no hardware system
+ */
+ gsSGXDeviceMap.ui32IRQ = 0;
+
+#else /* defined(NO_HARDWARE) */
+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO)
+ /* get the resource and IRQ through platform resource API */
+ dev_res = platform_get_resource(gpsPVRLDMDev, IORESOURCE_MEM, 0);
+ if (dev_res == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_resource failed", __FUNCTION__));
+ return PVRSRV_ERROR_INVALID_DEVICE;
+ }
+
+ dev_irq = platform_get_irq(gpsPVRLDMDev, 0);
+ if (dev_irq < 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_irq failed (%d)", __FUNCTION__, -dev_irq));
+ return PVRSRV_ERROR_INVALID_DEVICE;
+ }
+
+ gsSGXDeviceMap.sRegsSysPBase.uiAddr = dev_res->start;
+ gsSGXDeviceMap.sRegsCpuPBase =
+ SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase);
+ PVR_TRACE(("SGX register base: 0x%lx", (unsigned long)gsSGXDeviceMap.sRegsCpuPBase.uiAddr));
+
+#if defined(SGX544) && defined(SGX_FEATURE_MP)
+ /* Workaround: Due to the change in the HWMOD, the driver is only detecting the
+ size of the first memory section. For the moment, set the size with a macro
+ until a better solution found */
+ gsSGXDeviceMap.ui32RegsSize = SYS_OMAP4430_SGX_REGS_SIZE;
+#else
+ gsSGXDeviceMap.ui32RegsSize = (unsigned int)(dev_res->end - dev_res->start);
+#endif
+
+ PVR_TRACE(("SGX register size: %d",gsSGXDeviceMap.ui32RegsSize));
+
+ gsSGXDeviceMap.ui32IRQ = dev_irq;
+ PVR_TRACE(("SGX IRQ: %d", gsSGXDeviceMap.ui32IRQ));
+#else /* defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) */
+ gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_OMAP4430_SGX_REGS_SYS_PHYS_BASE;
+ gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase);
+ gsSGXDeviceMap.ui32RegsSize = SYS_OMAP4430_SGX_REGS_SIZE;
+
+ gsSGXDeviceMap.ui32IRQ = SYS_OMAP4430_SGX_IRQ;
+
+#endif /* defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) */
+#if defined(SGX_OCP_REGS_ENABLED)
+ gsSGXRegsCPUVAddr = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase,
+ gsSGXDeviceMap.ui32RegsSize,
+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
+ IMG_NULL);
+
+ if (gsSGXRegsCPUVAddr == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysLocateDevices: Failed to map SGX registers"));
+ return PVRSRV_ERROR_BAD_MAPPING;
+ }
+
+ /* Indicate the registers are already mapped */
+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr;
+ gpvOCPRegsLinAddr = gsSGXRegsCPUVAddr;
+#endif
+#endif /* defined(NO_HARDWARE) */
+
+#if defined(PDUMP)
+ {
+ /* initialise memory region name for pdumping */
+ static IMG_CHAR pszPDumpDevName[] = "SGXMEM";
+ gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName;
+ }
+#endif
+
+ /* add other devices here: */
+
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SysCreateVersionString
+
+ @Description Read the version string
+
+ @Return IMG_CHAR * : Version string
+
+******************************************************************************/
+static IMG_CHAR *SysCreateVersionString(void)
+{
+ static IMG_CHAR aszVersionString[100];
+ SYS_DATA *psSysData;
+ IMG_UINT32 ui32SGXRevision;
+ IMG_INT32 i32Count;
+#if !defined(NO_HARDWARE)
+ IMG_VOID *pvRegsLinAddr;
+
+ pvRegsLinAddr = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase,
+ gsSGXDeviceMap.ui32RegsSize,
+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
+ IMG_NULL);
+ if(!pvRegsLinAddr)
+ {
+ return IMG_NULL;
+ }
+
+#if defined(SGX544) && defined(SGX_FEATURE_MP)
+ ui32SGXRevision = OMAP5430_CORE_REV;
+#else
+ ui32SGXRevision = OSReadHWReg((IMG_PVOID)((IMG_PBYTE)pvRegsLinAddr),
+ EUR_CR_CORE_REVISION);
+#endif
+
+#else
+ ui32SGXRevision = 0;
+#endif
+
+ SysAcquireData(&psSysData);
+
+ 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_OMAP4430_SGX_REGS_SIZE,
+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
+ IMG_NULL);
+#endif
+
+ if(i32Count == -1)
+ {
+ return IMG_NULL;
+ }
+
+ return aszVersionString;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SysInitialise
+
+ @Description Initialises kernel services at 'driver load' time
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR SysInitialise(IMG_VOID)
+{
+ IMG_UINT32 i;
+ PVRSRV_ERROR eError;
+ PVRSRV_DEVICE_NODE *psDeviceNode;
+#if !defined(PVR_NO_OMAP_TIMER)
+ IMG_CPU_PHYADDR TimerRegPhysBase;
+#endif
+#if !defined(SGX_DYNAMIC_TIMING_INFO)
+ SGX_TIMING_INFORMATION* psTimingInfo;
+#endif
+ gpsSysData = &gsSysData;
+ OSMemSet(gpsSysData, 0, sizeof(SYS_DATA));
+
+ gpsSysSpecificData = &gsSysSpecificData;
+ OSMemSet(gpsSysSpecificData, 0, sizeof(SYS_SPECIFIC_DATA));
+
+ gpsSysData->pvSysSpecificData = gpsSysSpecificData;
+
+ eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure"));
+ (IMG_VOID)SysDeinitialise(gpsSysData);
+ gpsSysData = IMG_NULL;
+ return eError;
+ }
+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA);
+
+ gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT;
+
+ /* init device ID's */
+ 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"));
+ (IMG_VOID)SysDeinitialise(gpsSysData);
+ gpsSysData = IMG_NULL;
+ return eError;
+ }
+
+#if !defined(SGX_DYNAMIC_TIMING_INFO)
+ /* Set up timing information*/
+ psTimingInfo = &gsSGXDeviceMap.sTimingInfo;
+ psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED;
+ psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ;
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
+ psTimingInfo->bEnableActivePM = IMG_TRUE;
+#else
+ psTimingInfo->bEnableActivePM = IMG_FALSE;
+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */
+ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS;
+ psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ;
+#endif
+
+ /*
+ Setup the Source Clock Divider value
+ */
+ gpsSysSpecificData->ui32SrcClockDiv = 3;
+
+ /*
+ Locate the devices within the system, specifying
+ the physical addresses of each devices components
+ (regs, mem, ports etc.)
+ */
+ eError = SysLocateDevices(gpsSysData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices"));
+ (IMG_VOID)SysDeinitialise(gpsSysData);
+ gpsSysData = IMG_NULL;
+ return eError;
+ }
+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV);
+
+ eError = SysPMRuntimeRegister(gpsSysSpecificData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register with OSPM!"));
+ (IMG_VOID)SysDeinitialise(gpsSysData);
+ gpsSysData = IMG_NULL;
+ return eError;
+ }
+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME);
+
+ eError = SysDvfsInitialize(gpsSysSpecificData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialize DVFS"));
+ (IMG_VOID)SysDeinitialise(gpsSysData);
+ gpsSysData = IMG_NULL;
+ return eError;
+ }
+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_DVFS_INIT);
+
+ /*
+ Register devices with the system
+ This also sets up their memory maps/heaps
+ */
+ eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice,
+ DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!"));
+ (IMG_VOID)SysDeinitialise(gpsSysData);
+ gpsSysData = IMG_NULL;
+ return eError;
+ }
+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV);
+
+ /*
+ Once all devices are registered, specify the backing store
+ and, if required, customise the memory heap config
+ */
+ psDeviceNode = gpsSysData->psDeviceNodeList;
+ while(psDeviceNode)
+ {
+ /* perform any OEM SOC address space customisations here */
+ switch(psDeviceNode->sDevId.eDeviceType)
+ {
+ case PVRSRV_DEVICE_TYPE_SGX:
+ {
+ DEVICE_MEMORY_INFO *psDevMemoryInfo;
+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+
+ /*
+ specify the backing store to use for the devices MMU PT/PDs
+ - the PT/PDs are always UMA in this system
+ */
+ psDeviceNode->psLocalDevMemArena = IMG_NULL;
+
+ /* useful pointers */
+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
+ psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
+
+ /* specify the backing store for all SGX heaps */
+ 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;
+ }
+
+ /* advance to next device */
+ psDeviceNode = psDeviceNode->psNext;
+ }
+
+ eError = EnableSystemClocksWrap(gpsSysData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable system clocks (%d)", eError));
+ (IMG_VOID)SysDeinitialise(gpsSysData);
+ gpsSysData = IMG_NULL;
+ return eError;
+ }
+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS);
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
+ eError = EnableSGXClocksWrap(gpsSysData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError));
+ (IMG_VOID)SysDeinitialise(gpsSysData);
+ gpsSysData = IMG_NULL;
+ return eError;
+ }
+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */
+
+ eError = PVRSRVInitialiseDevice(gui32SGXDeviceID);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!"));
+ (IMG_VOID)SysDeinitialise(gpsSysData);
+ gpsSysData = IMG_NULL;
+ return eError;
+ }
+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV);
+
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
+ /* SGX defaults to D3 power state */
+ DisableSGXClocks(gpsSysData);
+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */
+
+#if !defined(PVR_NO_OMAP_TIMER)
+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA)
+ TimerRegPhysBase = gsSysSpecificData.sTimerRegPhysBase;
+#else
+ TimerRegPhysBase.uiAddr = SYS_OMAP4430_GP11TIMER_REGS_SYS_PHYS_BASE;
+#endif
+ gpsSysData->pvSOCTimerRegisterKM = IMG_NULL;
+ gpsSysData->hSOCTimerRegisterOSMemHandle = 0;
+ if (TimerRegPhysBase.uiAddr != 0)
+ {
+ OSReservePhys(TimerRegPhysBase,
+ 4,
+ PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED,
+ IMG_NULL,
+ (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM,
+ &gpsSysData->hSOCTimerRegisterOSMemHandle);
+ }
+#endif /* !defined(PVR_NO_OMAP_TIMER) */
+
+
+ return PVRSRV_OK;
+}
+
+#if defined(CONFIG_OMAPLFB)
+int OMAPLFBRegisterPVRDriver(void * pfnFuncTable);
+#endif
+
+/*!
+******************************************************************************
+
+ @Function SysFinalise
+
+ @Description Final part of initialisation at 'driver load' time
+
+ @Return PVRSRV_ERROR :
+
+******************************************************************************/
+PVRSRV_ERROR SysFinalise(IMG_VOID)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
+ eError = EnableSGXClocksWrap(gpsSysData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to Enable SGX clocks (%d)", eError));
+ return eError;
+ }
+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */
+
+ eError = OSInstallMISR(gpsSysData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install MISR"));
+ return eError;
+ }
+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR);
+
+#if defined(SYS_USING_INTERRUPTS)
+ /* install a Device ISR */
+ eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install ISR"));
+ return eError;
+ }
+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR);
+#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
+ SysEnableSGXInterrupts(gpsSysData);
+#endif
+#endif /* defined(SYS_USING_INTERRUPTS) */
+#if defined(__linux__)
+ /* Create a human readable version string for this system */
+ gpsSysData->pszVersionString = SysCreateVersionString();
+ if (!gpsSysData->pszVersionString)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to create a system version string"));
+ }
+ else
+ {
+ PVR_TRACE(("SysFinalise: Version string: %s", gpsSysData->pszVersionString));
+ }
+#endif
+
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
+ /* SGX defaults to D3 power state */
+ DisableSGXClocks(gpsSysData);
+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */
+
+#if defined(CONFIG_OMAPLFB)
+ if (OMAPLFBRegisterPVRDriver((void *)&PVRGetDisplayClassJTable) != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to register PVR driver with omaplfb"));
+ return PVRSRV_ERROR_INIT_FAILURE;
+ }
+#endif
+
+ gpsSysSpecificData->bSGXInitComplete = IMG_TRUE;
+
+ return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SysDeinitialise
+
+ @Description De-initialises kernel services at 'driver unload' time
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData)
+{
+ PVRSRV_ERROR eError;
+
+ PVR_UNREFERENCED_PARAMETER(psSysData);
+
+ if(gpsSysData->pvSOCTimerRegisterKM)
+ {
+ OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM,
+ 4,
+ PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED,
+ gpsSysData->hSOCTimerRegisterOSMemHandle);
+ }
+
+
+#if defined(SYS_USING_INTERRUPTS)
+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR))
+ {
+ eError = OSUninstallDeviceLISR(gpsSysData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallDeviceLISR failed"));
+ return eError;
+ }
+ }
+#endif
+
+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR))
+ {
+ eError = OSUninstallMISR(gpsSysData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed"));
+ return eError;
+ }
+ }
+
+ 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));
+ /* Reenable SGX clocks whilst SGX is being deinitialised. */
+ eError = EnableSGXClocksWrap(gpsSysData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: EnableSGXClocks failed"));
+ return eError;
+ }
+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */
+
+ /* Deinitialise SGX */
+ 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_DVFS_INIT))
+ {
+ eError = SysDvfsDeinitialize(gpsSysSpecificData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: Failed to de-init DVFS"));
+ gpsSysData = IMG_NULL;
+ return eError;
+ }
+ }
+
+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME))
+ {
+ eError = SysPMRuntimeUnregister(gpsSysSpecificData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: Failed to unregister with OSPM!"));
+ gpsSysData = IMG_NULL;
+ return eError;
+ }
+ }
+
+ /*
+ Disable system clocks - must happen after last access to hardware.
+ */
+ 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;
+ }
+ }
+
+ SysDeinitialiseCommon(gpsSysData);
+
+#if defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED)
+ if(gsSGXRegsCPUVAddr != IMG_NULL)
+ {
+#if defined(NO_HARDWARE)
+ /* Free hardware resources. */
+ OSBaseFreeContigMemory(SYS_OMAP4430_SGX_REGS_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase);
+#else
+#if defined(SGX_OCP_REGS_ENABLED)
+ OSUnMapPhysToLin(gsSGXRegsCPUVAddr,
+ gsSGXDeviceMap.ui32RegsSize,
+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
+ IMG_NULL);
+
+ gpvOCPRegsLinAddr = IMG_NULL;
+#endif
+#endif /* defined(NO_HARDWARE) */
+ gsSGXRegsCPUVAddr = IMG_NULL;
+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr;
+ }
+#endif /* defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) */
+
+
+ gpsSysSpecificData->ui32SysSpecificData = 0;
+ gpsSysSpecificData->bSGXInitComplete = IMG_FALSE;
+
+ gpsSysData = IMG_NULL;
+
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SysGetDeviceMemoryMap
+
+ @Description returns a device address map for the specified device
+
+ @Input eDeviceType - device type
+ @Input ppvDeviceMap - void ptr to receive device specific info.
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType,
+ IMG_VOID **ppvDeviceMap)
+{
+
+ switch(eDeviceType)
+ {
+ case PVRSRV_DEVICE_TYPE_SGX:
+ {
+ /* just return a pointer to the structure */
+ *ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap;
+
+ break;
+ }
+ default:
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysGetDeviceMemoryMap: unsupported device type"));
+ }
+ }
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+ @Function SysCpuPAddrToDevPAddr
+
+ @Description Compute a device physical address from a cpu physical
+ address. Relevant when
+
+ @Input cpu_paddr - cpu physical address.
+ @Input eDeviceType - device type required if DevPAddr
+ address spaces vary across devices
+ in the same system
+ @Return device physical address.
+
+******************************************************************************/
+IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType,
+ IMG_CPU_PHYADDR CpuPAddr)
+{
+ IMG_DEV_PHYADDR DevPAddr;
+
+ PVR_UNREFERENCED_PARAMETER(eDeviceType);
+
+ /* Note: for UMA system we assume DevP == CpuP */
+ DevPAddr.uiAddr = CpuPAddr.uiAddr;
+
+ return DevPAddr;
+}
+
+/*!
+******************************************************************************
+ @Function SysSysPAddrToCpuPAddr
+
+ @Description Compute a cpu physical address from a system physical
+ address.
+
+ @Input sys_paddr - system physical address.
+ @Return cpu physical address.
+
+******************************************************************************/
+IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR sys_paddr)
+{
+ IMG_CPU_PHYADDR cpu_paddr;
+
+ /* This would only be an inequality if the CPU's MMU did not point to
+ sys address 0, ie. multi CPU system */
+ cpu_paddr.uiAddr = sys_paddr.uiAddr;
+ return cpu_paddr;
+}
+
+/*!
+******************************************************************************
+ @Function SysCpuPAddrToSysPAddr
+
+ @Description Compute a system physical address from a cpu physical
+ address.
+
+ @Input cpu_paddr - cpu physical address.
+ @Return device physical address.
+
+******************************************************************************/
+IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr)
+{
+ IMG_SYS_PHYADDR sys_paddr;
+
+ /* This would only be an inequality if the CPU's MMU did not point to
+ sys address 0, ie. multi CPU system */
+ sys_paddr.uiAddr = cpu_paddr.uiAddr;
+ return sys_paddr;
+}
+
+
+/*!
+******************************************************************************
+ @Function SysSysPAddrToDevPAddr
+
+ @Description Compute a device physical address from a system physical
+ address.
+
+ @Input SysPAddr - system physical address.
+ @Input eDeviceType - device type required if DevPAddr
+ address spaces vary across devices
+ in the same system
+
+ @Return Device physical address.
+
+******************************************************************************/
+IMG_DEV_PHYADDR SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr)
+{
+ IMG_DEV_PHYADDR DevPAddr;
+
+ PVR_UNREFERENCED_PARAMETER(eDeviceType);
+
+ /* Note: for UMA system we assume DevP == CpuP */
+ DevPAddr.uiAddr = SysPAddr.uiAddr;
+
+ return DevPAddr;
+}
+
+
+/*!
+******************************************************************************
+ @Function SysDevPAddrToSysPAddr
+
+ @Description Compute a device physical address from a system physical
+ address.
+
+ @Input DevPAddr - device physical address.
+ @Input eDeviceType - device type required if DevPAddr
+ address spaces vary across devices
+ in the same system
+
+ @Return System physical address.
+
+******************************************************************************/
+IMG_SYS_PHYADDR SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR DevPAddr)
+{
+ IMG_SYS_PHYADDR SysPAddr;
+
+ PVR_UNREFERENCED_PARAMETER(eDeviceType);
+
+ /* Note: for UMA system we assume DevP == SysP */
+ SysPAddr.uiAddr = DevPAddr.uiAddr;
+
+ return SysPAddr;
+}
+
+
+/*****************************************************************************
+ @Function SysRegisterExternalDevice
+
+ @Description Called when a 3rd party device registers with services
+
+ @Input psDeviceNode - the new device node.
+
+ @Return IMG_VOID
+*****************************************************************************/
+IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+}
+
+
+/*****************************************************************************
+ @Function SysRemoveExternalDevice
+
+ @Description Called when a 3rd party device unregisters from services
+
+ @Input psDeviceNode - the device node being removed.
+
+ @Return IMG_VOID
+*****************************************************************************/
+IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+}
+
+/*!
+******************************************************************************
+ @Function SysGetInterruptSource
+
+ @Description Returns System specific information about the device(s) that
+ generated the interrupt in the system
+
+ @Input psSysData
+ @Input psDeviceNode
+
+ @Return System specific information indicating which device(s)
+ generated the interrupt
+
+******************************************************************************/
+IMG_UINT32 SysGetInterruptSource(SYS_DATA *psSysData,
+ PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVR_UNREFERENCED_PARAMETER(psSysData);
+#if defined(NO_HARDWARE)
+ /* no interrupts in no_hw system just return all bits */
+ return 0xFFFFFFFF;
+#else
+ /* Not a shared irq, so we know this is an interrupt for this device */
+ return psDeviceNode->ui32SOCInterruptBit;
+#endif
+}
+
+
+/*!
+******************************************************************************
+ @Function SysClearInterrupts
+
+ @Description Clears specified system interrupts
+
+ @Input psSysData
+ @Input ui32ClearBits
+
+ @Return IMG_VOID
+
+******************************************************************************/
+IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits)
+{
+ PVR_UNREFERENCED_PARAMETER(ui32ClearBits);
+ PVR_UNREFERENCED_PARAMETER(psSysData);
+#if !defined(NO_HARDWARE)
+#if defined(SGX_OCP_NO_INT_BYPASS)
+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1);
+#endif
+ /* Flush posted writes */
+ OSReadHWReg(((PVRSRV_SGXDEV_INFO *)gpsSGXDevNode->pvDevice)->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR);
+#endif /* defined(NO_HARDWARE) */
+}
+
+#if defined(SGX_OCP_NO_INT_BYPASS)
+/*!
+******************************************************************************
+ @Function SysEnableSGXInterrupts
+
+ @Description Enables SGX interrupts
+
+ @Input psSysData
+
+ @Return IMG_VOID
+
+******************************************************************************/
+IMG_VOID SysEnableSGXInterrupts(SYS_DATA *psSysData)
+{
+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData;
+ if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_ENABLE_LISR) && !SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED))
+ {
+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1);
+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_SET_2, 0x1);
+ SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED);
+ }
+}
+
+/*!
+******************************************************************************
+ @Function SysDisableSGXInterrupts
+
+ @Description Disables SGX interrupts
+
+ @Input psSysData
+
+ @Return IMG_VOID
+
+******************************************************************************/
+IMG_VOID SysDisableSGXInterrupts(SYS_DATA *psSysData)
+{
+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData;
+
+ if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED))
+ {
+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_CLR_2, 0x1);
+ SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED);
+ }
+}
+#endif /* defined(SGX_OCP_NO_INT_BYPASS) */
+
+/*!
+******************************************************************************
+
+ @Function SysSystemPrePowerState
+
+ @Description Perform system-level processing required before a power transition
+
+ @Input eNewPowerState :
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ if (eNewPowerState == PVRSRV_SYS_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;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SysSystemPostPowerState
+
+ @Description Perform system-level processing required after a power transition
+
+ @Input eNewPowerState :
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D0)
+ {
+ PVR_TRACE(("SysSystemPostPowerState: Entering state D0"));
+
+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS))
+ {
+ eError = EnableSystemClocksWrap(gpsSysData);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: EnableSystemClocksWrap 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;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SysDevicePrePowerState
+
+ @Description Perform system level processing required before a device power
+ transition
+
+ @Input ui32DeviceIndex :
+ @Input eNewPowerState :
+ @Input eCurrentPowerState :
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ PVRSRV_DEV_POWER_STATE eCurrentPowerState)
+{
+ PVR_UNREFERENCED_PARAMETER(eCurrentPowerState);
+
+ if (ui32DeviceIndex != gui32SGXDeviceID)
+ {
+ return PVRSRV_OK;
+ }
+
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePrePowerState: SGX Entering state D3"));
+ DisableSGXClocks(gpsSysData);
+ }
+#else /* SUPPORT_ACTIVE_POWER_MANAGEMENT */
+ PVR_UNREFERENCED_PARAMETER(eNewPowerState );
+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function SysDevicePostPowerState
+
+ @Description Perform system level processing required after a device power
+ transition
+
+ @Input ui32DeviceIndex :
+ @Input eNewPowerState :
+ @Input eCurrentPowerState :
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex,
+ PVRSRV_DEV_POWER_STATE eNewPowerState,
+ PVRSRV_DEV_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_DEV_POWER_STATE_OFF)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePostPowerState: SGX Leaving state D3"));
+ eError = EnableSGXClocksWrap(gpsSysData);
+ }
+#else /* SUPPORT_ACTIVE_POWER_MANAGEMENT */
+ PVR_UNREFERENCED_PARAMETER(eCurrentPowerState);
+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */
+
+ return eError;
+}
+
+IMG_VOID SysLockSystemSuspend(IMG_VOID)
+{
+#if defined(CONFIG_HAS_WAKELOCK)
+ wake_lock(&gpsSysSpecificData->wake_lock);
+#endif
+}
+
+IMG_VOID SysUnlockSystemSuspend(IMG_VOID)
+{
+#if defined(CONFIG_HAS_WAKELOCK)
+ wake_unlock(&gpsSysSpecificData->wake_lock);
+#endif
+}
+
+/*****************************************************************************
+ @Function SysOEMFunction
+
+ @Description marshalling function for custom OEM functions
+
+ @Input ui32ID - function ID
+ @Input pvIn - in data
+ @Output pvOut - out data
+
+ @Return PVRSRV_ERROR
+*****************************************************************************/
+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;
+}
+/******************************************************************************
+ End of file (sysconfig.c)
+******************************************************************************/
diff --git a/pvr-source/services4/system/omap4/sysconfig.h b/pvr-source/services4/system/omap4/sysconfig.h
new file mode 100644
index 0000000..64f3187
--- /dev/null
+++ b/pvr-source/services4/system/omap4/sysconfig.h
@@ -0,0 +1,110 @@
+/*************************************************************************/ /*!
+@Title System Description Header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description This header provides system-specific declarations and macros
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__SOCCONFIG_H__)
+#define __SOCCONFIG_H__
+
+#define VS_PRODUCT_NAME "OMAP4"
+
+#if defined(SGX540) && (SGX_CORE_REV == 120)
+#define SYS_SGX_CLOCK_SPEED 307200000
+#else
+#define SYS_SGX_CLOCK_SPEED 304742400
+#endif
+
+#define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ (100) // 10ms (100hz)
+#define SYS_SGX_PDS_TIMER_FREQ (1000) // 1ms (1000hz)
+
+/* Allow the AP latency to be overridden in the build config */
+#if !defined(SYS_SGX_ACTIVE_POWER_LATENCY_MS)
+#define SYS_SGX_ACTIVE_POWER_LATENCY_MS (2)
+#endif
+
+
+#define SYS_OMAP4430_SGX_REGS_SYS_PHYS_BASE 0x56000000
+#define SYS_OMAP4430_SGX_REGS_SIZE 0xFFFF
+
+#define SYS_OMAP4430_SGX_IRQ 53 /* OMAP4 IRQ's are offset by 32 */
+
+#define SYS_OMAP4430_DSS_REGS_SYS_PHYS_BASE 0x58000000
+#define SYS_OMAP4430_DSS_REGS_SIZE 0x7000
+
+#define SYS_OMAP4430_DSS_HDMI_INTERRUPT_STATUS_REG 0x6028
+#define SYS_OMAP4430_DSS_HDMI_INTERRUPT_ENABLE_REG 0x602c
+
+#define SYS_OMAP4430_DSS_HDMI_INTERRUPT_VSYNC_ENABLE_MASK 0x10000
+#define SYS_OMAP4430_DSS_HDMI_INTERRUPT_VSYNC_STATUS_MASK 0x10000
+
+#define SYS_OMAP4430_DSS_LCD_INTERRUPT_STATUS_REG 0x1018
+#define SYS_OMAP4430_DSS_LCD_INTERRUPT_ENABLE_REG 0x101c
+
+#define SYS_OMAP4430_DSS_LCD_INTERRUPT_VSYNC_ENABLE_MASK 0x40002
+#define SYS_OMAP4430_DSS_LCD_INTERRUPT_VSYNC_STATUS_MASK 0x40002
+
+
+#define SYS_OMAP4430_GP11TIMER_ENABLE_SYS_PHYS_BASE 0x48088038
+#define SYS_OMAP4430_GP11TIMER_REGS_SYS_PHYS_BASE 0x4808803C
+#define SYS_OMAP4430_GP11TIMER_TSICR_SYS_PHYS_BASE 0x48088054
+
+/* Interrupt bits */
+#define DEVICE_SGX_INTERRUPT (1<<0)
+#define DEVICE_MSVDX_INTERRUPT (1<<1)
+#define DEVICE_DISP_INTERRUPT (1<<2)
+
+#if defined(__linux__)
+/*
+ * Recent OMAP4 kernels register SGX as platform device "omap_gpu".
+ * This device must be used with the Linux power management calls
+ * in sysutils_linux.c, in order for SGX to be powered on.
+ */
+#if defined(PVR_LDM_PLATFORM_PRE_REGISTERED_DEV)
+#define SYS_SGX_DEV_NAME PVR_LDM_PLATFORM_PRE_REGISTERED_DEV
+#else
+#define SYS_SGX_DEV_NAME "omap_gpu"
+#endif /* defined(PVR_LDM_PLATFORM_PRE_REGISTERED_DEV) */
+#endif /* defined(__linux__) */
+
+/*****************************************************************************
+ * system specific data structures
+ *****************************************************************************/
+
+#endif /* __SYSCONFIG_H__ */
diff --git a/pvr-source/services4/system/omap4/sysinfo.h b/pvr-source/services4/system/omap4/sysinfo.h
new file mode 100644
index 0000000..70ae148
--- /dev/null
+++ b/pvr-source/services4/system/omap4/sysinfo.h
@@ -0,0 +1,64 @@
+/*************************************************************************/ /*!
+@Title System Description Header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description This header provides system-specific declarations and macros
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__SYSINFO_H__)
+#define __SYSINFO_H__
+
+/*!< System specific poll/timeout details */
+#if defined(PVR_LINUX_USING_WORKQUEUES)
+/*
+ * The workqueue based 3rd party display driver may be blocked for up
+ * to 500ms waiting for a vsync when the screen goes blank, so we
+ * need to wait longer for the hardware if a flush of the swap chain is
+ * required.
+ */
+#define MAX_HW_TIME_US (1000000)
+#define WAIT_TRY_COUNT (20000)
+#else
+#define MAX_HW_TIME_US (500000)
+#define WAIT_TRY_COUNT (10000)
+#endif
+
+
+#define SYS_DEVICE_COUNT 15 /* SGX, DISPLAYCLASS (external), BUFFERCLASS (external) */
+
+#endif /* __SYSINFO_H__ */
diff --git a/pvr-source/services4/system/omap4/syslocal.h b/pvr-source/services4/system/omap4/syslocal.h
new file mode 100644
index 0000000..5fd36b3
--- /dev/null
+++ b/pvr-source/services4/system/omap4/syslocal.h
@@ -0,0 +1,265 @@
+/*************************************************************************/ /*!
+@Title Local system definitions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description This header provides local system declarations and macros
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__SYSLOCAL_H__)
+#define __SYSLOCAL_H__
+
+#if defined(__linux__)
+
+#include <linux/version.h>
+#include <linux/clk.h>
+#if defined(PVR_LINUX_USING_WORKQUEUES)
+#include <linux/mutex.h>
+#else
+#include <linux/spinlock.h>
+#endif
+#include <asm/atomic.h>
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
+#include <linux/semaphore.h>
+#include <linux/resource.h>
+#else /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) */
+#include <asm/semaphore.h>
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22))
+#include <asm/arch/resource.h>
+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) */
+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) */
+
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+#if !defined(LDM_PLATFORM)
+#error "LDM_PLATFORM must be set"
+#endif
+#define PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO
+#include <linux/platform_device.h>
+#endif
+
+#if ((defined(DEBUG) || defined(TIMING)) && \
+ (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,34))) && \
+ !defined(PVR_NO_OMAP_TIMER)
+/*
+ * We need to explicitly enable the GPTIMER11 clocks, or we'll get an
+ * abort when we try to access the timer registers.
+ */
+#define PVR_OMAP4_TIMING_PRCM
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+#include <plat/gpu.h>
+#if !defined(PVR_NO_OMAP_TIMER)
+#define PVR_OMAP_USE_DM_TIMER_API
+#include <plat/dmtimer.h>
+#endif
+#endif
+
+#if defined(CONFIG_HAS_WAKELOCK)
+#include <linux/wakelock.h>
+#endif
+
+#if !defined(PVR_NO_OMAP_TIMER)
+#define PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA
+#endif
+#endif /* defined(__linux__) */
+
+#if !defined(NO_HARDWARE) && \
+ defined(SYS_USING_INTERRUPTS)
+#define SGX_OCP_REGS_ENABLED
+#endif
+
+#if defined(__linux__)
+#if defined(SGX_OCP_REGS_ENABLED)
+#define SGX_OCP_NO_INT_BYPASS
+#endif
+#endif
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/*****************************************************************************
+ * system specific data structures
+ *****************************************************************************/
+
+/*****************************************************************************
+ * system specific function prototypes
+ *****************************************************************************/
+
+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData);
+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData);
+
+IMG_VOID DisableSGXClocks(SYS_DATA *psSysData);
+PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData);
+
+/*
+ * Various flags to indicate what has been initialised, and what
+ * has been temporarily deinitialised for power management purposes.
+ */
+#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_ENABLE_OCPREGS 0x00000800
+#define SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME 0x00001000
+#define SYS_SPECIFIC_DATA_IRQ_ENABLED 0x00002000
+#define SYS_SPECIFIC_DATA_DVFS_INIT 0x00004000
+
+#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(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA)
+ IMG_CPU_PHYADDR sTimerRegPhysBase;
+#endif
+#if !defined(__linux__)
+ IMG_BOOL bSGXClocksEnabled;
+#endif
+ IMG_UINT32 ui32SrcClockDiv;
+#if defined(__linux__)
+ IMG_BOOL bSysClocksOneTimeInit;
+ atomic_t sSGXClocksEnabled;
+#if defined(PVR_LINUX_USING_WORKQUEUES)
+ struct mutex sPowerLock;
+#else
+ IMG_BOOL bConstraintNotificationsEnabled;
+ spinlock_t sPowerLock;
+ atomic_t sPowerLockCPU;
+ spinlock_t sNotifyLock;
+ atomic_t sNotifyLockCPU;
+ IMG_BOOL bCallVDD2PostFunc;
+#endif
+#if defined(DEBUG) || defined(TIMING)
+ struct clk *psGPT11_FCK;
+ struct clk *psGPT11_ICK;
+#endif
+#if defined(PVR_OMAP_USE_DM_TIMER_API)
+ struct omap_dm_timer *psGPTimer;
+#endif
+#if defined(CONFIG_HAS_WAKELOCK)
+ struct wake_lock wake_lock;
+#endif /* CONFIG_HAS_WAKELOCK */
+#endif /* defined(__linux__) */
+} SYS_SPECIFIC_DATA;
+
+extern SYS_SPECIFIC_DATA *gpsSysSpecificData;
+
+#if defined(SGX_OCP_REGS_ENABLED) && defined(SGX_OCP_NO_INT_BYPASS)
+IMG_VOID SysEnableSGXInterrupts(SYS_DATA* psSysData);
+IMG_VOID SysDisableSGXInterrupts(SYS_DATA* psSysData);
+#else
+#define SysEnableSGXInterrupts(psSysData)
+#define SysDisableSGXInterrupts(psSysData)
+#endif
+
+#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
+IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData);
+IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData);
+#endif
+
+#if defined(__linux__)
+
+PVRSRV_ERROR SysPMRuntimeRegister(SYS_SPECIFIC_DATA *psSysSpecificData);
+PVRSRV_ERROR SysPMRuntimeUnregister(SYS_SPECIFIC_DATA *psSysSpecificData);
+
+PVRSRV_ERROR SysDvfsInitialize(SYS_SPECIFIC_DATA *psSysSpecificData);
+PVRSRV_ERROR SysDvfsDeinitialize(SYS_SPECIFIC_DATA *psSysSpecificData);
+int pvr_access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
+
+#else /* defined(__linux__) */
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysPMRuntimeRegister)
+#endif
+static INLINE PVRSRV_ERROR SysPMRuntimeRegister(void)
+{
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysPMRuntimeUnregister)
+#endif
+static INLINE PVRSRV_ERROR SysPMRuntimeUnregister(void)
+{
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysDvfsInitialize)
+#endif
+static INLINE PVRSRV_ERROR SysDvfsInitialize(void)
+{
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysDvfsDeinitialize)
+#endif
+static INLINE PVRSRV_ERROR SysDvfsDeinitialize(void)
+{
+ return PVRSRV_OK;
+}
+
+#define pvr_access_process_vm(tsk, addr, buf, len, write) -1
+
+#endif /* defined(__linux__) */
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __SYSLOCAL_H__ */
+
+
diff --git a/pvr-source/services4/system/omap4/sysutils.c b/pvr-source/services4/system/omap4/sysutils.c
new file mode 100644
index 0000000..20baad2
--- /dev/null
+++ b/pvr-source/services4/system/omap4/sysutils.c
@@ -0,0 +1,59 @@
+/*************************************************************************/ /*!
+@Title Shared (User/kernel) and System dependent utilities
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Provides system-specific functions
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/* Pull in the correct system dependent sysutils source */
+
+#if defined(__linux__)
+#include "sysutils_linux.c"
+#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK)
+#include "sgxfreq.c"
+#include "sgxfreq_onoff.c"
+#include "sgxfreq_activeidle.c"
+#include "sgxfreq_on3demand.c"
+#include "sgxfreq_userspace.c"
+#if defined(CONFIG_THERMAL_FRAMEWORK)
+#include "sgxfreq_cool.c"
+#endif
+#endif
+#endif
+
+
diff --git a/pvr-source/services4/system/omap4/sysutils_linux.c b/pvr-source/services4/system/omap4/sysutils_linux.c
new file mode 100644
index 0000000..1bef2ee
--- /dev/null
+++ b/pvr-source/services4/system/omap4/sysutils_linux.c
@@ -0,0 +1,745 @@
+/*************************************************************************/ /*!
+@Title System dependent utilities
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Provides system-specific functions
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#include <linux/version.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/hardirq.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+
+#include "sgxdefs.h"
+#include "services_headers.h"
+#include "sysinfo.h"
+#include "sgxapi_km.h"
+#include "sysconfig.h"
+#include "sgxinfokm.h"
+#include "syslocal.h"
+
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK)
+#include "sgxfreq.h"
+#endif
+
+#if defined(SUPPORT_DRI_DRM_PLUGIN)
+#include <drm/drmP.h>
+#include <drm/drm.h>
+
+#include <linux/omap_gpu.h>
+
+#include "pvr_drm.h"
+#endif
+
+#if defined(CONFIG_OMAP4_DPLL_CASCADING)
+#include <mach/omap4-common.h>
+#endif
+
+#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(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI)
+extern struct platform_device *gpsPVRLDMDev;
+#endif
+
+static PVRSRV_ERROR PowerLockWrap(SYS_SPECIFIC_DATA *psSysSpecData, IMG_BOOL bTryLock)
+{
+ if (!in_interrupt())
+ {
+ if (bTryLock)
+ {
+ int locked = mutex_trylock(&psSysSpecData->sPowerLock);
+ if (locked == 0)
+ {
+ return PVRSRV_ERROR_RETRY;
+ }
+ }
+ else
+ {
+ mutex_lock(&psSysSpecData->sPowerLock);
+ }
+ }
+
+ return PVRSRV_OK;
+}
+
+static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA *psSysSpecData)
+{
+ if (!in_interrupt())
+ {
+ mutex_unlock(&psSysSpecData->sPowerLock);
+ }
+}
+
+PVRSRV_ERROR SysPowerLockWrap(IMG_BOOL bTryLock)
+{
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+
+ return PowerLockWrap(psSysData->pvSysSpecificData, bTryLock);
+}
+
+IMG_VOID SysPowerLockUnwrap(IMG_VOID)
+{
+ SYS_DATA *psSysData;
+
+ SysAcquireData(&psSysData);
+
+ PowerLockUnwrap(psSysData->pvSysSpecificData);
+}
+
+/*
+ * This function should be called to unwrap the Services power lock, prior
+ * to calling any function that might sleep.
+ * This function shouldn't be called prior to calling EnableSystemClocks
+ * or DisableSystemClocks, as those functions perform their own power lock
+ * unwrapping.
+ * If the function returns IMG_TRUE, UnwrapSystemPowerChange must be
+ * called to rewrap the power lock, prior to returning to Services.
+ */
+IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData)
+{
+ return IMG_TRUE;
+}
+
+IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData)
+{
+}
+
+/*
+ * Return SGX timining information to caller.
+ */
+IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psTimingInfo)
+{
+#if !defined(NO_HARDWARE)
+ PVR_ASSERT(atomic_read(&gpsSysSpecificData->sSGXClocksEnabled) != 0);
+#endif
+#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK)
+ /*
+ * The core SGX driver and ukernel code expects SGX frequency
+ * changes to occur only just prior to SGX initialization. We
+ * don't wish to constrain the DVFS implementation as such. So
+ * we let these components believe that frequency setting is
+ * always at maximum. This produces safe values for derived
+ * parameters such as APM and HWR timeouts.
+ */
+ psTimingInfo->ui32CoreClockSpeed = (IMG_UINT32)sgxfreq_get_freq_max();
+#else /* defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) */
+ psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED;
+#endif
+ psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ;
+ psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ;
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
+ psTimingInfo->bEnableActivePM = IMG_TRUE;
+#else
+ psTimingInfo->bEnableActivePM = IMG_FALSE;
+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */
+ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS;
+}
+
+/*!
+******************************************************************************
+
+ @Function EnableSGXClocks
+
+ @Description Enable SGX clocks
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData)
+{
+#if !defined(NO_HARDWARE)
+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
+
+ /* SGX clocks already enabled? */
+ if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0)
+ {
+ return PVRSRV_OK;
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks"));
+
+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI)
+ {
+ int res;
+
+#if defined(CONFIG_OMAP4_DPLL_CASCADING)
+ if (omap4_dpll_cascading_blocker_hold(&gpsPVRLDMDev->dev))
+ {
+ PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: "
+ "omap4_dpll_cascading_blocker_hold failed"));
+ }
+#endif
+ /*
+ * pm_runtime_get_sync returns 1 after the module has
+ * been reloaded.
+ */
+ res = pm_runtime_get_sync(&gpsPVRLDMDev->dev);
+ if (res < 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: pm_runtime_get_sync failed (%d)", -res));
+ return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK;
+ }
+ }
+#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK)
+ sgxfreq_notif_sgx_clk_on();
+#endif /* defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) */
+#endif /* defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) */
+
+ SysEnableSGXInterrupts(psSysData);
+
+ /* Indicate that the SGX clocks are enabled */
+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 1);
+
+#else /* !defined(NO_HARDWARE) */
+ PVR_UNREFERENCED_PARAMETER(psSysData);
+#endif /* !defined(NO_HARDWARE) */
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function DisableSGXClocks
+
+ @Description Disable SGX clocks.
+
+ @Return none
+
+******************************************************************************/
+IMG_VOID DisableSGXClocks(SYS_DATA *psSysData)
+{
+#if !defined(NO_HARDWARE)
+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
+
+ /* SGX clocks already disabled? */
+ if (atomic_read(&psSysSpecData->sSGXClocksEnabled) == 0)
+ {
+ return;
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE, "DisableSGXClocks: Disabling SGX Clocks"));
+
+ SysDisableSGXInterrupts(psSysData);
+
+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI)
+ {
+ int res = pm_runtime_put_sync(&gpsPVRLDMDev->dev);
+ if (res < 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DisableSGXClocks: pm_runtime_put_sync failed (%d)", -res));
+ }
+#if defined(CONFIG_OMAP4_DPLL_CASCADING)
+ if (omap4_dpll_cascading_blocker_release(&gpsPVRLDMDev->dev))
+ {
+ PVR_DPF((PVR_DBG_WARNING, "DisableSGXClocks: "
+ "omap4_dpll_cascading_blocker_release failed"));
+ }
+#endif
+ }
+#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK)
+ sgxfreq_notif_sgx_clk_off();
+#endif /* defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) */
+#endif /* defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) */
+
+ /* Indicate that the SGX clocks are disabled */
+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 0);
+
+#else /* !defined(NO_HARDWARE) */
+ PVR_UNREFERENCED_PARAMETER(psSysData);
+#endif /* !defined(NO_HARDWARE) */
+}
+
+#if (defined(DEBUG) || defined(TIMING)) && !defined(PVR_NO_OMAP_TIMER)
+#if defined(PVR_OMAP_USE_DM_TIMER_API)
+#define GPTIMER_TO_USE 11
+/*!
+******************************************************************************
+
+ @Function AcquireGPTimer
+
+ @Description Acquire a GP timer
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData)
+{
+ PVR_ASSERT(psSysSpecData->psGPTimer == NULL);
+
+ /*
+ * This code could try requesting registers 9, 10, and 11,
+ * stopping at the first succesful request. We'll stick with
+ * 11 for now, as it avoids having to hard code yet more
+ * physical addresses into the code.
+ */
+ psSysSpecData->psGPTimer = omap_dm_timer_request_specific(GPTIMER_TO_USE);
+ if (psSysSpecData->psGPTimer == NULL)
+ {
+
+ PVR_DPF((PVR_DBG_WARNING, "%s: omap_dm_timer_request_specific failed", __FUNCTION__));
+ return PVRSRV_ERROR_CLOCK_REQUEST_FAILED;
+ }
+
+ /* Set timer source to system clock */
+ omap_dm_timer_set_source(psSysSpecData->psGPTimer, OMAP_TIMER_SRC_SYS_CLK);
+ omap_dm_timer_enable(psSysSpecData->psGPTimer);
+
+ /* Set autoreload, and start value of 0 */
+ omap_dm_timer_set_load_start(psSysSpecData->psGPTimer, 1, 0);
+
+ omap_dm_timer_start(psSysSpecData->psGPTimer);
+
+ /*
+ * The DM timer API doesn't have a mechansim for obtaining the
+ * physical address of the counter register.
+ */
+ psSysSpecData->sTimerRegPhysBase.uiAddr = SYS_OMAP4430_GP11TIMER_REGS_SYS_PHYS_BASE;
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function ReleaseGPTimer
+
+ @Description Release a GP timer
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData)
+{
+ if (psSysSpecData->psGPTimer != NULL)
+ {
+ /* Always returns 0 */
+ (void) omap_dm_timer_stop(psSysSpecData->psGPTimer);
+
+ omap_dm_timer_disable(psSysSpecData->psGPTimer);
+
+ omap_dm_timer_free(psSysSpecData->psGPTimer);
+
+ psSysSpecData->sTimerRegPhysBase.uiAddr = 0;
+
+ psSysSpecData->psGPTimer = NULL;
+ }
+
+}
+#else /* PVR_OMAP_USE_DM_TIMER_API */
+/*!
+******************************************************************************
+
+ @Function AcquireGPTimer
+
+ @Description Acquire a GP timer
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData)
+{
+#if defined(PVR_OMAP4_TIMING_PRCM)
+ struct clk *psCLK;
+ IMG_INT res;
+ struct clk *sys_ck;
+ IMG_INT rate;
+#endif
+ PVRSRV_ERROR eError;
+
+ IMG_CPU_PHYADDR sTimerRegPhysBase;
+ IMG_HANDLE hTimerEnable;
+ IMG_UINT32 *pui32TimerEnable;
+
+ PVR_ASSERT(psSysSpecData->sTimerRegPhysBase.uiAddr == 0);
+
+#if defined(PVR_OMAP4_TIMING_PRCM)
+ /* assert our dependence on the GPTIMER11 module */
+ psCLK = clk_get(NULL, "gpt11_fck");
+ if (IS_ERR(psCLK))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock"));
+ goto ExitError;
+ }
+ 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 ExitError;
+ }
+ psSysSpecData->psGPT11_ICK = psCLK;
+
+ sys_ck = clk_get(NULL, "sys_clkin_ck");
+ if (IS_ERR(sys_ck))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get System clock"));
+ goto ExitError;
+ }
+
+ 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 ExitError;
+ }
+ }
+
+ 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 ExitError;
+ }
+
+ 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;
+ }
+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */
+
+ /* Set the timer to non-posted mode */
+ sTimerRegPhysBase.uiAddr = SYS_OMAP4430_GP11TIMER_TSICR_SYS_PHYS_BASE;
+ pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase,
+ 4,
+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+ &hTimerEnable);
+
+ if (pui32TimerEnable == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed"));
+ goto ExitDisableGPT11ICK;
+ }
+
+ if(!(*pui32TimerEnable & 4))
+ {
+ PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)"));
+
+ /* Set posted mode */
+ *pui32TimerEnable |= 4;
+ }
+
+ OSUnMapPhysToLin(pui32TimerEnable,
+ 4,
+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+ hTimerEnable);
+
+ /* Enable the timer */
+ sTimerRegPhysBase.uiAddr = SYS_OMAP4430_GP11TIMER_ENABLE_SYS_PHYS_BASE;
+ pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase,
+ 4,
+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+ &hTimerEnable);
+
+ if (pui32TimerEnable == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed"));
+ goto ExitDisableGPT11ICK;
+ }
+
+ /* Enable and set autoreload on overflow */
+ *pui32TimerEnable = 3;
+
+ OSUnMapPhysToLin(pui32TimerEnable,
+ 4,
+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
+ hTimerEnable);
+
+ psSysSpecData->sTimerRegPhysBase = sTimerRegPhysBase;
+
+ eError = PVRSRV_OK;
+
+ goto Exit;
+
+ExitDisableGPT11ICK:
+#if defined(PVR_OMAP4_TIMING_PRCM)
+ clk_disable(psSysSpecData->psGPT11_ICK);
+ExitDisableGPT11FCK:
+ clk_disable(psSysSpecData->psGPT11_FCK);
+ExitError:
+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */
+ eError = PVRSRV_ERROR_CLOCK_REQUEST_FAILED;
+Exit:
+ return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function ReleaseGPTimer
+
+ @Description Release a GP timer
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData)
+{
+ IMG_HANDLE hTimerDisable;
+ IMG_UINT32 *pui32TimerDisable;
+
+ if (psSysSpecData->sTimerRegPhysBase.uiAddr == 0)
+ {
+ return;
+ }
+
+ /* Disable the timer */
+ pui32TimerDisable = OSMapPhysToLin(psSysSpecData->sTimerRegPhysBase,
+ 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);
+ }
+
+ psSysSpecData->sTimerRegPhysBase.uiAddr = 0;
+
+#if defined(PVR_OMAP4_TIMING_PRCM)
+ clk_disable(psSysSpecData->psGPT11_ICK);
+
+ clk_disable(psSysSpecData->psGPT11_FCK);
+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */
+}
+#endif /* PVR_OMAP_USE_DM_TIMER_API */
+#else /* (DEBUG || TIMING) && !PVR_NO_OMAP_TIMER */
+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData)
+{
+ PVR_UNREFERENCED_PARAMETER(psSysSpecData);
+
+ return PVRSRV_OK;
+}
+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData)
+{
+ PVR_UNREFERENCED_PARAMETER(psSysSpecData);
+}
+#endif /* (DEBUG || TIMING) && !PVR_NO_OMAP_TIMER */
+
+/*!
+******************************************************************************
+
+ @Function EnableSystemClocks
+
+ @Description Setup up the clocks for the graphics device to work.
+
+ @Return PVRSRV_ERROR
+
+******************************************************************************/
+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData)
+{
+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
+
+ PVR_TRACE(("EnableSystemClocks: Enabling System Clocks"));
+
+ if (!psSysSpecData->bSysClocksOneTimeInit)
+ {
+ mutex_init(&psSysSpecData->sPowerLock);
+
+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 0);
+
+ psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE;
+ }
+
+ return AcquireGPTimer(psSysSpecData);
+}
+
+/*!
+******************************************************************************
+
+ @Function DisableSystemClocks
+
+ @Description Disable the graphics clocks.
+
+ @Return none
+
+******************************************************************************/
+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData)
+{
+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
+
+ PVR_TRACE(("DisableSystemClocks: Disabling System Clocks"));
+
+ /*
+ * Always disable the SGX clocks when the system clocks are disabled.
+ * This saves having to make an explicit call to DisableSGXClocks if
+ * active power management is enabled.
+ */
+ DisableSGXClocks(psSysData);
+
+ ReleaseGPTimer(psSysSpecData);
+}
+
+PVRSRV_ERROR SysPMRuntimeRegister(SYS_SPECIFIC_DATA *psSysSpecificData)
+{
+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI)
+ pm_runtime_enable(&gpsPVRLDMDev->dev);
+#endif
+#if defined(CONFIG_HAS_WAKELOCK)
+ wake_lock_init(&psSysSpecificData->wake_lock, WAKE_LOCK_SUSPEND, "pvrsrvkm");
+#endif
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR SysPMRuntimeUnregister(SYS_SPECIFIC_DATA *psSysSpecificData)
+{
+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI)
+ pm_runtime_disable(&gpsPVRLDMDev->dev);
+#endif
+#if defined(CONFIG_HAS_WAKELOCK)
+ wake_lock_destroy(&psSysSpecificData->wake_lock);
+#endif
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR SysDvfsInitialize(SYS_SPECIFIC_DATA *psSysSpecificData)
+{
+ PVR_UNREFERENCED_PARAMETER(psSysSpecificData);
+#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK)
+ if (sgxfreq_init(&gpsPVRLDMDev->dev))
+ return PVRSRV_ERROR_NOT_SUPPORTED;
+#endif /* defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) */
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR SysDvfsDeinitialize(SYS_SPECIFIC_DATA *psSysSpecificData)
+{
+ PVR_UNREFERENCED_PARAMETER(psSysSpecificData);
+#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK)
+ if (sgxfreq_deinit())
+ return PVRSRV_ERROR_NOT_SUPPORTED;
+#endif /* defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) */
+
+ return PVRSRV_OK;
+}
+
+#if defined(SUPPORT_DRI_DRM_PLUGIN)
+static struct omap_gpu_plugin sOMAPGPUPlugin;
+
+#define SYS_DRM_SET_PLUGIN_FIELD(d, s, f) (d)->f = (s)->f
+int
+SysDRMRegisterPlugin(PVRSRV_DRM_PLUGIN *psDRMPlugin)
+{
+ int iRes;
+
+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, name);
+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, open);
+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, load);
+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, unload);
+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, release);
+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, mmap);
+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, ioctls);
+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, num_ioctls);
+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, ioctl_start);
+
+ iRes = omap_gpu_register_plugin(&sOMAPGPUPlugin);
+ if (iRes != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: omap_gpu_register_plugin failed (%d)", __FUNCTION__, iRes));
+ }
+
+ return iRes;
+}
+
+void
+SysDRMUnregisterPlugin(PVRSRV_DRM_PLUGIN *psDRMPlugin)
+{
+ int iRes = omap_gpu_unregister_plugin(&sOMAPGPUPlugin);
+ if (iRes != 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: omap_gpu_unregister_plugin failed (%d)", __FUNCTION__, iRes));
+ }
+}
+#endif
+
+int pvr_access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
+{
+ struct gpu_platform_data *pdata;
+ pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data;
+ if(!pdata || !pdata->access_process_vm)
+ return -1;
+ return pdata->access_process_vm(tsk, addr, buf, len, write);
+}
+
+IMG_VOID SysSGXIdleEntered(IMG_VOID)
+{
+#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK)
+ sgxfreq_notif_sgx_idle();
+#endif
+}
+
+IMG_VOID SysSGXCommandPending(IMG_BOOL bSGXIdle)
+{
+#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK)
+ sgxfreq_notif_sgx_active();
+#else
+ PVR_UNREFERENCED_PARAMETER(bSGXIdle);
+#endif
+}
diff --git a/pvr-source/tools/intern/debug/client/linuxsrv.h b/pvr-source/tools/intern/debug/client/linuxsrv.h
new file mode 100644
index 0000000..d9fd825
--- /dev/null
+++ b/pvr-source/tools/intern/debug/client/linuxsrv.h
@@ -0,0 +1,64 @@
+/*************************************************************************/ /*!
+@File linuxsrv.h
+@Title Module defs for pvr core drivers.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _LINUXSRV_H__
+#define _LINUXSRV_H__
+
+typedef struct tagIOCTL_PACKAGE
+{
+ IMG_UINT32 ui32Cmd; // ioctl command
+ IMG_UINT32 ui32Size; // needs to be correctly set
+ IMG_VOID *pInBuffer; // input data buffer
+ IMG_UINT32 ui32InBufferSize; // size of input data buffer
+ IMG_VOID *pOutBuffer; // output data buffer
+ IMG_UINT32 ui32OutBufferSize; // size of output data buffer
+} 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 /* _LINUXSRV_H__*/
diff --git a/pvr-source/tools/intern/debug/dbgdriv/Kbuild.mk b/pvr-source/tools/intern/debug/dbgdriv/Kbuild.mk
new file mode 100644
index 0000000..e1e8868
--- /dev/null
+++ b/pvr-source/tools/intern/debug/dbgdriv/Kbuild.mk
@@ -0,0 +1,51 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+ccflags-y += \
+ -I$(TOP)/tools/intern/debug/dbgdriv/common \
+ -I$(TOP)/tools/intern/debug/client
+
+dbgdrv-y += \
+ tools/intern/debug/dbgdriv/common/dbgdriv.o \
+ tools/intern/debug/dbgdriv/common/ioctl.o \
+ tools/intern/debug/dbgdriv/common/handle.o \
+ tools/intern/debug/dbgdriv/common/hotkey.o \
+ tools/intern/debug/dbgdriv/linux/main.o \
+ tools/intern/debug/dbgdriv/linux/hostfunc.o
diff --git a/pvr-source/tools/intern/debug/dbgdriv/Linux.mk b/pvr-source/tools/intern/debug/dbgdriv/Linux.mk
new file mode 100644
index 0000000..e050879
--- /dev/null
+++ b/pvr-source/tools/intern/debug/dbgdriv/Linux.mk
@@ -0,0 +1,45 @@
+########################################################################### ###
+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+#@License Dual MIT/GPLv2
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 ("GPL") in which case the provisions
+# of GPL are applicable instead of those above.
+#
+# If you wish to allow use of your version of this file only under the terms of
+# GPL, and not to allow others to use your version of this file under the terms
+# of the MIT license, indicate your decision by deleting the provisions above
+# and replace them with the notice and other provisions required by GPL as set
+# out in the file called "GPL-COPYING" included in this distribution. If you do
+# not delete the provisions above, a recipient may use your version of this file
+# under the terms of either the MIT license or GPL.
+#
+# This License is also included in this distribution in the file called
+# "MIT-COPYING".
+#
+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+### ###########################################################################
+
+modules := dbgdrv
+
+dbgdrv_type := kernel_module
+dbgdrv_target := dbgdrv.ko
+dbgdrv_makefile := $(THIS_DIR)/Kbuild.mk
diff --git a/pvr-source/tools/intern/debug/dbgdriv/common/dbgdriv.c b/pvr-source/tools/intern/debug/dbgdriv/common/dbgdriv.c
new file mode 100644
index 0000000..0b8d445
--- /dev/null
+++ b/pvr-source/tools/intern/debug/dbgdriv/common/dbgdriv.c
@@ -0,0 +1,2883 @@
+/*************************************************************************/ /*!
+@Title Debug Driver
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description 32 Bit kernel mode debug driver
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifdef LINUX
+#include <linux/string.h>
+#endif
+#ifdef __QNXNTO__
+#include <string.h>
+#endif
+
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "dbgdrvif.h"
+#include "dbgdriv.h"
+#include "hotkey.h"
+#include "hostfunc.h"
+#include "pvr_debug.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;
+} *PDBG_LASTFRAME_BUFFER;
+
+/******************************************************************************
+ Global vars
+******************************************************************************/
+
+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);
+
+/***************************************************************************
+ Declare kernel mode service table.
+***************************************************************************/
+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,
+ ExtDBGDrivSetConnectNotifier,
+ ExtDBGDrivWritePersist
+};
+
+
+/* Static function declarations */
+static IMG_UINT32 DBGDrivWritePersist(PDBG_STREAM psMainStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+static IMG_VOID InvalidateAllStreams(IMG_VOID);
+
+/*****************************************************************************
+ Code
+*****************************************************************************/
+
+
+
+DBGKM_CONNECT_NOTIFIER g_fnDBGKMNotifier;
+
+/*!
+ @name ExtDBGDrivSetConnectNotifier
+ @brief Registers one or more services callback functions which are called on events in the dbg driver
+ @param fn_notifier - services callbacks
+ @return none
+ */
+IMG_VOID IMG_CALLCONV ExtDBGDrivSetConnectNotifier(DBGKM_CONNECT_NOTIFIER fn_notifier)
+{
+ /* Set the callback function which enables the debug driver to
+ * communicate to services KM when pdump is connected.
+ */
+ g_fnDBGKMNotifier = fn_notifier;
+}
+
+/*!
+ @name ExtDBGDrivCreateStream
+ */
+IMG_VOID * IMG_CALLCONV ExtDBGDrivCreateStream(IMG_CHAR * pszName, IMG_UINT32 ui32CapMode, IMG_UINT32 ui32OutMode, IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size)
+{
+ IMG_VOID * pvRet;
+
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ pvRet=DBGDrivCreateStream(pszName, ui32CapMode, ui32OutMode, ui32Flags, ui32Size);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return pvRet;
+}
+
+/*!
+ @name ExtDBGDrivDestroyStream
+ */
+void IMG_CALLCONV ExtDBGDrivDestroyStream(PDBG_STREAM psStream)
+{
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivDestroyStream(psStream);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return;
+}
+
+/*!
+ @name ExtDBGDrivFindStream
+ */
+IMG_VOID * IMG_CALLCONV ExtDBGDrivFindStream(IMG_CHAR * pszName, IMG_BOOL bResetStream)
+{
+ IMG_VOID * pvRet;
+
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ pvRet=DBGDrivFindStream(pszName, bResetStream);
+ if(g_fnDBGKMNotifier.pfnConnectNotifier)
+ {
+ g_fnDBGKMNotifier.pfnConnectNotifier();
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "pfnConnectNotifier not initialised.\n"));
+ }
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return pvRet;
+}
+
+/*!
+ @name ExtDBGDrivWriteString
+ */
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level)
+{
+ IMG_UINT32 ui32Ret;
+
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret=DBGDrivWriteString(psStream, pszString, ui32Level);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+/*!
+ @name ExtDBGDrivReadString
+ */
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivReadString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Limit)
+{
+ IMG_UINT32 ui32Ret;
+
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret=DBGDrivReadString(psStream, pszString, ui32Limit);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+/*!
+ @name ExtDBGDrivWrite
+ */
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWrite(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+ IMG_UINT32 ui32Ret;
+
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret=DBGDrivWrite(psStream, pui8InBuf, ui32InBuffSize, ui32Level);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+/*!
+ @name ExtDBGDrivRead
+ */
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivRead(PDBG_STREAM psStream, IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBuffSize,IMG_UINT8 * pui8OutBuf)
+{
+ IMG_UINT32 ui32Ret;
+
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret=DBGDrivRead(psStream, bReadInitBuffer, ui32OutBuffSize, pui8OutBuf);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+/*!
+ @name ExtDBGDrivSetCaptureMode
+ */
+void IMG_CALLCONV ExtDBGDrivSetCaptureMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode,IMG_UINT32 ui32Start,IMG_UINT32 ui32End,IMG_UINT32 ui32SampleRate)
+{
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivSetCaptureMode(psStream, ui32Mode, ui32Start, ui32End, ui32SampleRate);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return;
+}
+
+/*!
+ @name ExtDBGDrivSetOutputMode
+ */
+void IMG_CALLCONV ExtDBGDrivSetOutputMode(PDBG_STREAM psStream,IMG_UINT32 ui32OutMode)
+{
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivSetOutputMode(psStream, ui32OutMode);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return;
+}
+
+/*!
+ @name ExtDBGDrivSetDebugLevel
+ */
+void IMG_CALLCONV ExtDBGDrivSetDebugLevel(PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel)
+{
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivSetDebugLevel(psStream, ui32DebugLevel);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return;
+}
+
+/*!
+ @name ExtDBGDrivSetFrame
+ */
+void IMG_CALLCONV ExtDBGDrivSetFrame(PDBG_STREAM psStream,IMG_UINT32 ui32Frame)
+{
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivSetFrame(psStream, ui32Frame);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return;
+}
+
+/*!
+ @name ExtDBGDrivGetFrame
+ */
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetFrame(PDBG_STREAM psStream)
+{
+ IMG_UINT32 ui32Ret;
+
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret=DBGDrivGetFrame(psStream);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+/*!
+ @name ExtDBGDrivIsLastCaptureFrame
+ */
+IMG_BOOL IMG_CALLCONV ExtDBGDrivIsLastCaptureFrame(PDBG_STREAM psStream)
+{
+ IMG_BOOL bRet;
+
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ bRet = DBGDrivIsLastCaptureFrame(psStream);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return bRet;
+}
+
+/*!
+ @name ExtDBGDrivIsCaptureFrame
+ */
+IMG_BOOL IMG_CALLCONV ExtDBGDrivIsCaptureFrame(PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame)
+{
+ IMG_BOOL bRet;
+
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ bRet = DBGDrivIsCaptureFrame(psStream, bCheckPreviousFrame);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return bRet;
+}
+
+/*!
+ @name ExtDBGDrivOverrideMode
+ */
+void IMG_CALLCONV ExtDBGDrivOverrideMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode)
+{
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivOverrideMode(psStream, ui32Mode);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return;
+}
+
+/*!
+ @name ExtDBGDrivDefaultMode
+ */
+void IMG_CALLCONV ExtDBGDrivDefaultMode(PDBG_STREAM psStream)
+{
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivDefaultMode(psStream);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return;
+}
+
+/*!
+ @name ExtDBGDrivWrite2
+ */
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWrite2(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+ IMG_UINT32 ui32Ret;
+
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret=DBGDrivWrite2(psStream, pui8InBuf, ui32InBuffSize, ui32Level);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+/*!
+ @name ExtDBGDrivWritePersist
+ */
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWritePersist(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+ IMG_UINT32 ui32Ret;
+
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret=DBGDrivWritePersist(psStream, pui8InBuf, ui32InBuffSize, ui32Level);
+ if(ui32Ret==0xFFFFFFFFU)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "An error occurred in DBGDrivWritePersist."));
+ }
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+/*!
+ @name ExtDBGDrivWriteStringCM
+ */
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteStringCM(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level)
+{
+ IMG_UINT32 ui32Ret;
+
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret=DBGDrivWriteStringCM(psStream, pszString, ui32Level);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+/*!
+ @name ExtDBGDrivWriteCM
+ */
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteCM(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+ IMG_UINT32 ui32Ret;
+
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret=DBGDrivWriteCM(psStream, pui8InBuf, ui32InBuffSize, ui32Level);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+/*!
+ @name ExtDBGDrivSetMarker
+ */
+void IMG_CALLCONV ExtDBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker)
+{
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivSetMarker(psStream, ui32Marker);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return;
+}
+
+/*!
+ @name ExtDBGDrivGetMarker
+ */
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetMarker(PDBG_STREAM psStream)
+{
+ IMG_UINT32 ui32Marker;
+
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Marker = DBGDrivGetMarker(psStream);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Marker;
+}
+
+/*!
+ @name ExtDBGDrivWriteLF
+ */
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteLF(PDBG_STREAM psStream, IMG_UINT8 * pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags)
+{
+ IMG_UINT32 ui32Ret;
+
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret = DBGDrivWriteLF(psStream, pui8InBuf, ui32InBuffSize, ui32Level, ui32Flags);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+/*!
+ @name ExtDBGDrivReadLF
+ */
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivReadLF(PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 * pui8OutBuf)
+{
+ IMG_UINT32 ui32Ret;
+
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret = DBGDrivReadLF(psStream, ui32OutBuffSize, pui8OutBuf);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+
+/*!
+ @name ExtDBGDrivStartInitPhase
+ */
+IMG_VOID IMG_CALLCONV ExtDBGDrivStartInitPhase(PDBG_STREAM psStream)
+{
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivStartInitPhase(psStream);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return;
+}
+
+/*!
+ @name ExtDBGDrivStopInitPhase
+ */
+IMG_VOID IMG_CALLCONV ExtDBGDrivStopInitPhase(PDBG_STREAM psStream)
+{
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivStopInitPhase(psStream);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return;
+}
+
+/*!
+ @name ExtDBGDrivGetStreamOffset
+ */
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetStreamOffset(PDBG_STREAM psStream)
+{
+ IMG_UINT32 ui32Ret;
+
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ ui32Ret = DBGDrivGetStreamOffset(psStream);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+
+ return ui32Ret;
+}
+
+/*!
+ @name ExtDBGDrivSetStreamOffset
+ */
+IMG_VOID IMG_CALLCONV ExtDBGDrivSetStreamOffset(PDBG_STREAM psStream, IMG_UINT32 ui32StreamOffset)
+{
+ /* Aquire API Mutex */
+ HostAquireMutex(g_pvAPIMutex);
+
+ DBGDrivSetStreamOffset(psStream, ui32StreamOffset);
+
+ /* Release API Mutex */
+ HostReleaseMutex(g_pvAPIMutex);
+}
+
+/*!
+ @name ExtDBGDrivWaitForEvent
+ */
+IMG_VOID IMG_CALLCONV ExtDBGDrivWaitForEvent(DBG_EVENT eEvent)
+{
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+ DBGDrivWaitForEvent(eEvent);
+#else /* defined(SUPPORT_DBGDRV_EVENT_OBJECTS) */
+ PVR_UNREFERENCED_PARAMETER(eEvent); /* PRQA S 3358 */
+#endif /* defined(SUPPORT_DBGDRV_EVENT_OBJECTS) */
+}
+
+/*!****************************************************************************
+ @name AtoI
+ @brief Returns the integer value of a decimal string
+ @param szIn - String with hexadecimal value
+ @return IMG_UINT32 integer value, 0 if string is null or not valid
+ Based on Max`s one, now copes with (only) hex ui32ords, upper or lower case a-f.
+*****************************************************************************/
+IMG_UINT32 AtoI(IMG_CHAR *szIn)
+{
+ IMG_INT iLen = 0;
+ IMG_UINT32 ui32Value = 0;
+ IMG_UINT32 ui32Digit=1;
+ IMG_UINT32 ui32Base=10;
+ IMG_INT iPos;
+ IMG_CHAR bc;
+
+ //get len of string
+ while (szIn[iLen] > 0)
+ {
+ iLen ++;
+ }
+
+ //nothing to do
+ if (iLen == 0)
+ {
+ return (0);
+ }
+
+ /* See if we have an 'x' or 'X' before the number to make it a hex number */
+ 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';
+ }
+
+ //go through string from right (least significant) to left
+ for (iPos = iLen - 1; iPos >= 0; iPos --)
+ {
+ bc = szIn[iPos];
+
+ if ( (bc >= 'a') && (bc <= 'f') && ui32Base == 16) //handle lower case a-f
+ {
+ bc -= 'a' - 0xa;
+ }
+ else
+ if ( (bc >= 'A') && (bc <= 'F') && ui32Base == 16) //handle upper case A-F
+ {
+ bc -= 'A' - 0xa;
+ }
+ else
+ if ((bc >= '0') && (bc <= '9')) //if char out of range, return 0
+ {
+ bc -= '0';
+ }
+ else
+ return (0);
+
+ ui32Value += (IMG_UINT32)bc * ui32Digit;
+
+ ui32Digit = ui32Digit * ui32Base;
+ }
+ return (ui32Value);
+}
+
+
+/*!****************************************************************************
+ @name StreamValid
+ @brief Validates supplied debug buffer.
+ @param psStream - debug stream
+ @return true if valid
+*****************************************************************************/
+static 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);
+}
+
+
+/*!****************************************************************************
+ @name StreamValidForRead
+ @brief Validates supplied debug buffer for read op.
+ @param psStream - debug stream
+ @return true if readable
+*****************************************************************************/
+static IMG_BOOL StreamValidForRead(PDBG_STREAM psStream)
+{
+ if( StreamValid(psStream) &&
+ ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_WRITEONLY) == 0) )
+ {
+ return(IMG_TRUE);
+ }
+
+ return(IMG_FALSE);
+}
+
+/*!****************************************************************************
+ @name StreamValidForWrite
+ @brief Validates supplied debug buffer for write op.
+ @param psStream - debug stream
+ @return true if writable
+*****************************************************************************/
+static IMG_BOOL StreamValidForWrite(PDBG_STREAM psStream)
+{
+ if( StreamValid(psStream) &&
+ ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_READONLY) == 0) )
+ {
+ return(IMG_TRUE);
+ }
+
+ return(IMG_FALSE);
+}
+
+
+/*!****************************************************************************
+ @name Write
+ @brief Copies data from a buffer into selected stream. Stream size is fixed.
+ @param psStream - stream for output
+ @param pui8Data - input buffer
+ @param ui32InBuffSize - size of input
+ @return none
+*****************************************************************************/
+static void Write(PDBG_STREAM psStream,IMG_PUINT8 pui8Data,IMG_UINT32 ui32InBuffSize)
+{
+ /*
+ Split copy into two bits as necessary (if we're allowed to wrap).
+ */
+ if (!psStream->bCircularAllowed)
+ {
+ //PVR_ASSERT( (psStream->ui32WPtr + ui32InBuffSize) < psStream->ui32Size );
+ }
+
+ if ((psStream->ui32WPtr + ui32InBuffSize) > psStream->ui32Size)
+ {
+ /* Yes we need two bits, calculate their sizes */
+ IMG_UINT32 ui32B1 = psStream->ui32Size - psStream->ui32WPtr;
+ IMG_UINT32 ui32B2 = ui32InBuffSize - ui32B1;
+
+ /* Copy first block to current location */
+ HostMemCopy((IMG_PVOID)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32WPtr),
+ (IMG_PVOID) pui8Data,
+ ui32B1);
+
+ /* Copy second block to start of buffer */
+ HostMemCopy(psStream->pvBase,
+ (IMG_PVOID)(pui8Data + ui32B1),
+ ui32B2);
+
+ /* Set pointer to be the new end point */
+ psStream->ui32WPtr = ui32B2;
+ }
+ else
+ { /* Can fit block in single chunk */
+ HostMemCopy((IMG_PVOID)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32WPtr),
+ (IMG_PVOID) pui8Data,
+ ui32InBuffSize);
+
+ psStream->ui32WPtr += ui32InBuffSize;
+
+ if (psStream->ui32WPtr == psStream->ui32Size)
+ {
+ psStream->ui32WPtr = 0;
+ }
+ }
+ psStream->ui32DataWritten += ui32InBuffSize;
+}
+
+
+/*!****************************************************************************
+ @name MonoOut
+ @brief Output data to mono display. [Possibly deprecated]
+ @param pszString - input
+ @param bNewLine - line wrapping
+ @return none
+*****************************************************************************/
+void MonoOut(IMG_CHAR * pszString,IMG_BOOL bNewLine)
+{
+#if defined (_WIN64)
+ PVR_UNREFERENCED_PARAMETER(pszString);
+ PVR_UNREFERENCED_PARAMETER(bNewLine);
+
+#else
+ IMG_UINT32 i;
+ IMG_CHAR * pScreen;
+
+ pScreen = (IMG_CHAR *) DBGDRIV_MONOBASE;
+
+ pScreen += g_ui32Line * 160;
+
+ /*
+ Write the string.
+ */
+ 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++;
+ }
+
+ /*
+ Scroll if necssary.
+ */
+ 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);
+ }
+#endif
+}
+
+/*!****************************************************************************
+ @name WriteExpandingBuffer
+ @brief Copies data from a buffer into selected stream. Stream size may be expandable.
+ @param psStream - stream for output
+ @param pui8InBuf - input buffer
+ @param ui32InBuffSize - size of input
+ @return bytes copied
+*****************************************************************************/
+static IMG_UINT32 WriteExpandingBuffer(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize)
+{
+ IMG_UINT ui32Space;
+
+ /*
+ How much space have we got in the buffer ?
+ */
+ ui32Space = SpaceInStream(psStream);
+
+ /*
+ Don't copy anything if we don't have space or buffers not enabled.
+ */
+ if ((psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_STREAMENABLE) == 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "WriteExpandingBuffer: buffer %x is disabled", (IMG_UINTPTR_T) psStream));
+ return(0);
+ }
+
+ /*
+ Check if we can expand the buffer
+ */
+ if (psStream->psCtrl->ui32Flags & DEBUG_FLAGS_NO_BUF_EXPANDSION)
+ {
+ /*
+ Don't do anything if we've got less that 32 ui8tes of space and
+ we're not allowing expansion of buffer space...
+ */
+ if (ui32Space < 32)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "WriteExpandingBuffer: buffer %x is full and isn't expandable", (IMG_UINTPTR_T) psStream));
+ return(0);
+ }
+ }
+ else
+ {
+ if ((ui32Space < 32) || (ui32Space <= (ui32InBuffSize + 4)))
+ {
+ IMG_UINT32 ui32NewBufSize;
+
+ /*
+ Find new buffer size
+ */
+ ui32NewBufSize = 2 * psStream->ui32Size;
+
+ PVR_DPF((PVR_DBGDRIV_MESSAGE, "Expanding buffer size = %x, new size = %x",
+ psStream->ui32Size, ui32NewBufSize));
+
+ if (ui32InBuffSize > psStream->ui32Size)
+ {
+ ui32NewBufSize += ui32InBuffSize;
+ }
+
+ /*
+ Attempt to expand the buffer
+ */
+ if (!ExpandStreamBuffer(psStream,ui32NewBufSize))
+ {
+ if (ui32Space < 32)
+ {
+ if(psStream->bCircularAllowed)
+ {
+ return(0);
+ }
+ else
+ {
+ /* out of memory */
+ PVR_DPF((PVR_DBG_ERROR, "WriteExpandingBuffer: Unable to expand %x. Out of memory.", (IMG_UINTPTR_T) psStream));
+ InvalidateAllStreams();
+ return (0xFFFFFFFFUL);
+ }
+ }
+ }
+
+ /*
+ Recalc the space in the buffer
+ */
+ ui32Space = SpaceInStream(psStream);
+ PVR_DPF((PVR_DBGDRIV_MESSAGE, "Expanded buffer, free space = %x",
+ ui32Space));
+ }
+ }
+
+ /*
+ Only copy what we can..
+ */
+ if (ui32Space <= (ui32InBuffSize + 4))
+ {
+ ui32InBuffSize = ui32Space - 4;
+ }
+
+ /*
+ Write the stuff...
+ */
+ Write(psStream,pui8InBuf,ui32InBuffSize);
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+ if (ui32InBuffSize)
+ {
+ HostSignalEvent(DBG_EVENT_STREAM_DATA);
+ }
+#endif
+ return(ui32InBuffSize);
+}
+
+/*****************************************************************************
+******************************************************************************
+******************************************************************************
+ THE ACTUAL FUNCTIONS
+******************************************************************************
+******************************************************************************
+*****************************************************************************/
+
+/*!****************************************************************************
+ @name DBGDrivCreateStream
+ @brief Creates a pdump/debug stream
+ @param pszName - stream name
+ @param ui32CapMode - capture mode (framed, continuous, hotkey)
+ @param ui32OutMode - output mode (see dbgdrvif.h)
+ @param ui32Flags - output flags, text stream bit is set for pdumping
+ @param ui32Size - size of stream buffer in pages
+ @return none
+*****************************************************************************/
+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;
+ PDBG_STREAM_CONTROL psCtrl;
+ IMG_UINT32 ui32Off;
+ IMG_VOID * pvBase;
+ static IMG_CHAR pszNameInitSuffix[] = "_Init";
+ IMG_UINT32 ui32OffSuffix;
+
+ /*
+ If we already have a buffer using this name just return
+ its handle.
+ */
+ psStream = (PDBG_STREAM) DBGDrivFindStream(pszName, IMG_FALSE);
+
+ if (psStream)
+ {
+ return ((IMG_VOID *) psStream);
+ }
+
+ /*
+ Allocate memory for control structures
+ */
+ psStream = HostNonPageablePageAlloc(1);
+ psInitStream = HostNonPageablePageAlloc(1);
+ psLFBuffer = HostNonPageablePageAlloc(1);
+ psCtrl = HostNonPageablePageAlloc(1);
+ if (
+ (!psStream) ||
+ (!psInitStream) ||
+ (!psLFBuffer) ||
+ (!psCtrl)
+ )
+ {
+ PVR_DPF((PVR_DBG_ERROR,"DBGDriv: Couldn't alloc control structs\n\r"));
+ return((IMG_VOID *) 0);
+ }
+
+ /* Allocate memory for buffer */
+ 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 alloc Stream buffer\n\r"));
+ HostNonPageablePageFree(psStream);
+ return((IMG_VOID *) 0);
+ }
+
+ /* Setup control state */
+ psCtrl->ui32Flags = ui32Flags;
+ psCtrl->ui32CapMode = ui32CapMode;
+ psCtrl->ui32OutMode = ui32OutMode;
+ psCtrl->ui32DebugLevel = DEBUG_LEVEL_0;
+ psCtrl->ui32DefaultMode = ui32CapMode;
+ psCtrl->ui32Start = 0;
+ psCtrl->ui32End = 0;
+ psCtrl->ui32Current = 0;
+ psCtrl->ui32SampleRate = 1;
+ psCtrl->bInitPhaseComplete = IMG_FALSE;
+
+ /*
+ Setup internal debug buffer state.
+ */
+ psStream->psNext = 0;
+ psStream->pvBase = pvBase;
+ psStream->psCtrl = psCtrl;
+ psStream->ui32Size = ui32Size * 4096UL;
+ psStream->ui32RPtr = 0;
+ psStream->ui32WPtr = 0;
+ psStream->ui32DataWritten = 0;
+ psStream->ui32Marker = 0;
+ psStream->bCircularAllowed = IMG_TRUE;
+ psStream->ui32InitPhaseWOff = 0;
+
+ /* Allocate memory for buffer */
+ 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 alloc InitStream buffer\n\r"));
+
+ if ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
+ {
+ HostNonPageablePageFree(psStream->pvBase);
+ }
+ else
+ {
+ HostPageablePageFree(psStream->pvBase);
+ }
+ HostNonPageablePageFree(psStream);
+ return((IMG_VOID *) 0);
+ }
+
+ /* Initialise the stream for the init phase */
+ psInitStream->psNext = 0;
+ psInitStream->pvBase = pvBase;
+ psInitStream->psCtrl = psCtrl;
+ psInitStream->ui32Size = ui32Size * 4096UL;
+ psInitStream->ui32RPtr = 0;
+ psInitStream->ui32WPtr = 0;
+ psInitStream->ui32DataWritten = 0;
+ psInitStream->ui32Marker = 0;
+ psInitStream->bCircularAllowed = IMG_FALSE;
+ psInitStream->ui32InitPhaseWOff = 0;
+ psStream->psInitStream = psInitStream;
+
+ /* Setup last frame buffer */
+ psLFBuffer->psStream = psStream;
+ psLFBuffer->ui32BufLen = 0UL;
+
+ g_bHotkeyMiddump = IMG_FALSE;
+ g_ui32HotkeyMiddumpStart = 0xffffffffUL;
+ g_ui32HotkeyMiddumpEnd = 0xffffffffUL;
+
+ /*
+ Copy buffer name.
+ */
+ ui32Off = 0;
+
+ do
+ {
+ psStream->szName[ui32Off] = pszName[ui32Off];
+ psInitStream->szName[ui32Off] = pszName[ui32Off];
+ ui32Off++;
+ }
+ while ((pszName[ui32Off] != 0) && (ui32Off < (4096UL - sizeof(DBG_STREAM))));
+ psStream->szName[ui32Off] = pszName[ui32Off]; /* PRQA S 3689 */
+
+ /*
+ Append suffix to init phase name
+ */
+ ui32OffSuffix = 0;
+ do
+ {
+ psInitStream->szName[ui32Off] = pszNameInitSuffix[ui32OffSuffix];
+ ui32Off++;
+ ui32OffSuffix++;
+ }
+ while ( (pszNameInitSuffix[ui32OffSuffix] != 0) &&
+ (ui32Off < (4096UL - sizeof(DBG_STREAM))));
+ psInitStream->szName[ui32Off] = pszNameInitSuffix[ui32OffSuffix]; /* PRQA S 3689 */
+
+ /*
+ Insert into list.
+ */
+ psStream->psNext = g_psStreamList;
+ g_psStreamList = psStream;
+
+ psLFBuffer->psNext = g_psLFBufferList;
+ g_psLFBufferList = psLFBuffer;
+
+ AddSIDEntry(psStream);
+
+ return((IMG_VOID *) psStream);
+}
+
+/*!****************************************************************************
+ @name DBGDrivDestroyStream
+ @brief Delete a stream and free its memory
+ @param psStream - stream to be removed
+ @return none
+*****************************************************************************/
+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 ));
+
+ /*
+ Validate buffer.
+ */
+ if (!StreamValid(psStream))
+ {
+ return;
+ }
+
+ RemoveSIDEntry(psStream);
+
+ psLFBuffer = FindLFBuf(psStream);
+
+ /*
+ Remove from linked list.
+ */
+ 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;
+ }
+ }
+ /*
+ Dectivate hotkey it the stream is of this type.
+ */
+ if (psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_HOTKEY)
+ {
+ DeactivateHotKeys();
+ }
+
+ /*
+ And free its memory.
+ */
+ if ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
+ {
+ HostNonPageablePageFree(psStream->psCtrl);
+ HostNonPageablePageFree(psStream->pvBase);
+ HostNonPageablePageFree(psStream->psInitStream->pvBase);
+ }
+ else
+ {
+ HostNonPageablePageFree(psStream->psCtrl);
+ HostPageablePageFree(psStream->pvBase);
+ HostPageablePageFree(psStream->psInitStream->pvBase);
+ }
+
+ HostNonPageablePageFree(psStream->psInitStream);
+ HostNonPageablePageFree(psStream);
+ HostNonPageablePageFree(psLFBuffer);
+
+ if (g_psStreamList == 0)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,"DBGDriv: Stream list now empty" ));
+ }
+
+ return;
+}
+
+/*!****************************************************************************
+ @name DBGDrivFindStream
+ @brief Finds/resets a named stream
+ @param pszName - stream name
+ @param bResetStream - whether to reset the stream, e.g. to end pdump init phase
+ @return none
+*****************************************************************************/
+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;
+
+ PVR_DPF((PVR_DBGDRIV_MESSAGE, "PDump client connecting to %s %s",
+ pszName,
+ (bResetStream == IMG_TRUE) ? "with reset" : "no reset"));
+
+ /*
+ Scan buffer names for supplied one.
+ */
+ 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 IMG_CHAR szComment[] = "-- Init phase terminated\r\n";
+ psStream->psInitStream->ui32RPtr = 0;
+ psStream->ui32RPtr = 0;
+ psStream->ui32WPtr = 0;
+ psStream->ui32DataWritten = psStream->psInitStream->ui32DataWritten;
+ if (psStream->psCtrl->bInitPhaseComplete == IMG_FALSE)
+ {
+ if (psStream->psCtrl->ui32Flags & DEBUG_FLAGS_TEXTSTREAM)
+ {
+ DBGDrivWrite2(psStream, (IMG_UINT8 *)szComment, sizeof(szComment) - 1, 0x01);
+ }
+ psStream->psCtrl->bInitPhaseComplete = IMG_TRUE;
+ }
+
+ {
+ /* mark init stream to prevent further reading by pdump client */
+ psStream->psInitStream->ui32InitPhaseWOff = psStream->psInitStream->ui32WPtr;
+ PVR_DPF((PVR_DBGDRIV_MESSAGE, "Set %s client marker bo %x, total bw %x",
+ psStream->szName,
+ psStream->psInitStream->ui32InitPhaseWOff,
+ psStream->psInitStream->ui32DataWritten ));
+ }
+ }
+
+ return((IMG_VOID *) psStream);
+}
+
+static void IMG_CALLCONV DBGDrivInvalidateStream(PDBG_STREAM psStream)
+{
+ IMG_CHAR pszErrorMsg[] = "**OUTOFMEM\n";
+ IMG_UINT32 ui32Space;
+ IMG_UINT32 ui32Off = 0;
+ IMG_UINT32 ui32WPtr = psStream->ui32WPtr;
+ IMG_PUINT8 pui8Buffer = (IMG_UINT8 *) psStream->pvBase;
+
+ PVR_DPF((PVR_DBG_ERROR, "DBGDrivInvalidateStream: An error occurred for stream %s\r\n", psStream->szName ));
+
+ /*
+ Validate buffer.
+ */
+ /*
+ if (!StreamValid(psStream))
+ {
+ return;
+ }
+*/
+ /* Write what we can of the error message */
+ ui32Space = SpaceInStream(psStream);
+
+ /* Make sure there's space for termination character */
+ if(ui32Space > 0)
+ {
+ ui32Space--;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DBGDrivInvalidateStream: Buffer full."));
+ }
+
+ while((pszErrorMsg[ui32Off] != 0) && (ui32Off < ui32Space))
+ {
+ pui8Buffer[ui32WPtr] = (IMG_UINT8)pszErrorMsg[ui32Off];
+ ui32Off++;
+ ui32WPtr++;
+ }
+ pui8Buffer[ui32WPtr++] = '\0';
+ psStream->ui32WPtr = ui32WPtr;
+
+ /* Buffer will accept no more params from Services/client driver */
+ psStream->psCtrl->ui32Flags |= DEBUG_FLAGS_READONLY;
+}
+
+/*!****************************************************************************
+ @name InvalidateAllStreams
+ @brief invalidate all streams in list
+ @return none
+*****************************************************************************/
+static IMG_VOID InvalidateAllStreams(IMG_VOID)
+{
+ PDBG_STREAM psStream = g_psStreamList;
+ while (psStream != IMG_NULL)
+ {
+ DBGDrivInvalidateStream(psStream);
+ psStream = psStream->psNext;
+ }
+ return;
+}
+
+
+
+/*!****************************************************************************
+ @name DBGDrivWriteStringCM
+ @brief Write capture mode data, wraps DBGDrivWriteString
+ @param psStream - stream
+ @param pszString - input buffer
+ @param ui32Level - debug level
+*****************************************************************************/
+IMG_UINT32 IMG_CALLCONV DBGDrivWriteStringCM(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level)
+{
+ /*
+ Validate buffer.
+ */
+ if (!StreamValidForWrite(psStream))
+ {
+ return(0xFFFFFFFFUL);
+ }
+
+ /*
+ Only write string if debug capture mode adds up...
+ */
+ if (psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED)
+ {
+ if ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE) == 0)
+ {
+ return(0);
+ }
+ }
+ else
+ {
+ if (psStream->psCtrl->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
+ {
+ if ((psStream->psCtrl->ui32Current != g_ui32HotKeyFrame) || (g_bHotKeyPressed == IMG_FALSE))
+ {
+ return(0);
+ }
+ }
+ }
+
+ return(DBGDrivWriteString(psStream,pszString,ui32Level));
+
+}
+
+/*!****************************************************************************
+ @name DBGDrivWriteString
+ @brief Write string to stream (note stream buffer size is assumed fixed)
+ @param psStream - stream
+ @param pszString - string to write
+ @param ui32Level - verbosity level
+ @return -1; invalid stream
+ 0; other error (e.g. stream not enabled)
+ else number of characters written
+*****************************************************************************/
+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;
+
+ /*
+ Validate buffer.
+ */
+ if (!StreamValidForWrite(psStream))
+ {
+ return(0xFFFFFFFFUL);
+ }
+
+ /*
+ Check debug level.
+ */
+ if ((psStream->psCtrl->ui32DebugLevel & ui32Level) == 0)
+ {
+ return(0xFFFFFFFFUL);
+ }
+
+ /*
+ Output to standard debug out ? (don't if async out
+ flag is set).
+ */
+ if ((psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_ASYNC) == 0)
+ {
+ if (psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_STANDARDDBG)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,"%s: %s\r\n",psStream->szName, pszString));
+ }
+
+ /*
+ Output to mono monitor ?
+ */
+ if (psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_MONO)
+ {
+ MonoOut(psStream->szName,IMG_FALSE);
+ MonoOut(": ",IMG_FALSE);
+ MonoOut(pszString,IMG_TRUE);
+ }
+ }
+
+ /*
+ Don't bother writing the string if it's not flagged
+ */
+ if (
+ !(
+ ((psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_STREAMENABLE) != 0) ||
+ ((psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_ASYNC) != 0)
+ )
+ )
+ {
+ return(0xFFFFFFFFUL);
+ }
+
+ /*
+ How much space have we got in the buffer ?
+ */
+ ui32Space=SpaceInStream(psStream);
+
+ /* Make sure there's space for termination character */
+ if(ui32Space > 0)
+ {
+ ui32Space--;
+ }
+
+ ui32Len = 0;
+ ui32WPtr = psStream->ui32WPtr;
+ pui8Buffer = (IMG_UINT8 *) psStream->pvBase;
+
+ while((pszString[ui32Len] != 0) && (ui32Len < ui32Space))
+ {
+ pui8Buffer[ui32WPtr] = (IMG_UINT8)pszString[ui32Len];
+ ui32Len++;
+ ui32WPtr++;
+ if (ui32WPtr == psStream->ui32Size)
+ {
+ ui32WPtr = 0;
+ }
+ }
+
+ if (ui32Len < ui32Space)
+ {
+ /* copy terminator */
+ pui8Buffer[ui32WPtr] = (IMG_UINT8)pszString[ui32Len];
+ ui32Len++;
+ ui32WPtr++;
+ if (ui32WPtr == psStream->ui32Size)
+ {
+ ui32WPtr = 0;
+ }
+
+ /* Write pointer, and length */
+ 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);
+}
+
+/*!****************************************************************************
+ @name DBGDrivReadString
+ @brief Reads string from debug stream
+ @param psStream - stream
+ @param pszString - string to read
+ @param ui32Limit - max size to read
+ @return -1; invalid stream
+ 0; other error (e.g. stream not enabled)
+ else number of characters read
+*****************************************************************************/
+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;
+
+ /*
+ Validate buffer.
+ */
+ if (!StreamValidForRead(psStream))
+ {
+ return(0);
+ }
+
+ /*
+ Stream appears to be in list so carry on.
+ */
+ pui8Buff = (IMG_UINT8 *)psStream->pvBase;
+ ui32Offset = psStream->ui32RPtr;
+
+ if (psStream->ui32RPtr == psStream->ui32WPtr)
+ {
+ return(0);
+ }
+
+ /*
+ Find length of string.
+ */
+ ui32Len = 0;
+ while((pui8Buff[ui32Offset] != 0) && (ui32Offset != psStream->ui32WPtr))
+ {
+ ui32Offset++;
+ ui32Len++;
+
+ /*
+ Reset offset if buffer wrapped.
+ */
+ if (ui32Offset == psStream->ui32Size)
+ {
+ ui32Offset = 0;
+ }
+ }
+
+ ui32OutLen = ui32Len + 1;
+
+ /*
+ Only copy string if target has enough space.
+ */
+ if (ui32Len > ui32Limit)
+ {
+ return(0);
+ }
+
+ /*
+ Copy it.
+ */
+ ui32Offset = psStream->ui32RPtr;
+ ui32Len = 0;
+
+ while ((pui8Buff[ui32Offset] != 0) && (ui32Len < ui32Limit))
+ {
+ pszString[ui32Len] = (IMG_CHAR)pui8Buff[ui32Offset];
+ ui32Offset++;
+ ui32Len++;
+
+ /*
+ If wrap as necessary
+ */
+ if (ui32Offset == psStream->ui32Size)
+ {
+ ui32Offset = 0;
+ }
+ }
+
+ pszString[ui32Len] = (IMG_CHAR)pui8Buff[ui32Offset];
+
+ psStream->ui32RPtr = ui32Offset + 1;
+
+ if (psStream->ui32RPtr == psStream->ui32Size)
+ {
+ psStream->ui32RPtr = 0;
+ }
+
+ return(ui32OutLen);
+}
+
+/*!****************************************************************************
+ @name DBGDrivWrite
+ @brief Write binary buffer to stream (fixed size)
+ @param psStream - stream
+ @param pui8InBuf - buffer to write
+ @param ui32InBuffSize - size
+ @param ui32Level - verbosity level
+ @return bytes written, 0 if recoverable error, -1 if unrecoverable error
+*****************************************************************************/
+IMG_UINT32 IMG_CALLCONV DBGDrivWrite(PDBG_STREAM psMainStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+ IMG_UINT32 ui32Space;
+ DBG_STREAM *psStream;
+
+ /*
+ Validate buffer.
+ */
+ if (!StreamValidForWrite(psMainStream))
+ {
+ return(0xFFFFFFFFUL);
+ }
+
+ /*
+ Check debug level.
+ */
+ if ((psMainStream->psCtrl->ui32DebugLevel & ui32Level) == 0)
+ {
+ return(0xFFFFFFFFUL);
+ }
+
+ /*
+ Only write data if debug mode adds up...
+ */
+ if (psMainStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED)
+ {
+ if ((psMainStream->psCtrl->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE) == 0)
+ {
+ /* throw away non-capturing data */
+ return(ui32InBuffSize);
+ }
+ }
+ else if (psMainStream->psCtrl->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
+ {
+ if ((psMainStream->psCtrl->ui32Current != g_ui32HotKeyFrame) || (g_bHotKeyPressed == IMG_FALSE))
+ {
+ /* throw away non-capturing data */
+ return(ui32InBuffSize);
+ }
+ }
+
+ if(psMainStream->psCtrl->bInitPhaseComplete)
+ {
+ psStream = psMainStream;
+ }
+ else
+ {
+ psStream = psMainStream->psInitStream;
+ }
+
+ /*
+ How much space have we got in the buffer ?
+ */
+ ui32Space=SpaceInStream(psStream);
+
+ PVR_DPF((PVR_DBGDRIV_MESSAGE, "Recv %d b for %s: Roff = %x, WOff = %x",
+ ui32InBuffSize,
+ psStream->szName,
+ psStream->ui32RPtr,
+ psStream->ui32WPtr));
+
+ /*
+ Don't copy anything if we don't have space or buffers not enabled.
+ */
+ if ((psStream->psCtrl->ui32OutMode & DEBUG_OUTMODE_STREAMENABLE) == 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DBGDrivWrite: buffer %x is disabled", (IMG_UINTPTR_T) psStream));
+ return(0);
+ }
+
+ if (ui32Space < 8)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DBGDrivWrite: buffer %x is full", (IMG_UINTPTR_T) psStream));
+ return(0);
+ }
+
+ /*
+ Only copy what we can..
+ */
+ if (ui32Space <= (ui32InBuffSize + 4))
+ {
+ ui32InBuffSize = ui32Space - 8;
+ }
+
+ /*
+ Write the stuff...
+ */
+ 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);
+}
+
+/*!****************************************************************************
+ @name DBGDrivWriteCM
+ @brief Write capture mode data, wraps DBGDrivWrite
+ @param psStream - stream
+ @param pui8InBuf - input buffer
+ @param ui32InBuffSize - buffer size
+ @param ui32Level - verbosity level
+ @return bytes written, 0 if recoverable error, -1 if unrecoverable error
+*****************************************************************************/
+IMG_UINT32 IMG_CALLCONV DBGDrivWriteCM(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+ /*
+ Validate buffer.
+ */
+ if (!StreamValidForWrite(psStream))
+ {
+ return(0xFFFFFFFFUL);
+ }
+
+ /*
+ Only write data if debug mode adds up...
+ */
+ if (psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED)
+ {
+ if ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE) == 0)
+ {
+ /* throw away non-capturing data */
+ return(ui32InBuffSize);
+ }
+ }
+ else
+ {
+ if (psStream->psCtrl->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
+ {
+ if ((psStream->psCtrl->ui32Current != g_ui32HotKeyFrame) || (g_bHotKeyPressed == IMG_FALSE))
+ {
+ /* throw away non-capturing data */
+ return(ui32InBuffSize);
+ }
+ }
+ }
+
+ return(DBGDrivWrite2(psStream,pui8InBuf,ui32InBuffSize,ui32Level));
+}
+
+
+/*!****************************************************************************
+ @name DBGDrivWritePersist
+ @brief Copies data from a buffer into selected stream's init phase. Stream size should be expandable.
+ @param psStream - stream for output
+ @param pui8InBuf - input buffer
+ @param ui32InBuffSize - size of input
+ @param ui32Level - not used
+ @return bytes copied, 0 if recoverable error, -1 if unrecoverable error
+*****************************************************************************/
+static IMG_UINT32 DBGDrivWritePersist(PDBG_STREAM psMainStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+ DBG_STREAM *psStream;
+ PVR_UNREFERENCED_PARAMETER(ui32Level);
+
+ /*
+ Validate buffer.
+ */
+ if (!StreamValidForWrite(psMainStream))
+ {
+ return(0xFFFFFFFFUL);
+ }
+
+ /* Always append persistent data to init phase so it's available on
+ * subsequent app runs.
+ */
+ psStream = psMainStream->psInitStream;
+ if(psStream->bCircularAllowed == IMG_TRUE)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "DBGDrivWritePersist: Init phase is a circular buffer, some data may be lost"));
+ }
+
+ PVR_DPF((PVR_DBGDRIV_MESSAGE, "Append %x b to %s: Roff = %x, WOff = %x [bw = %x]",
+ ui32InBuffSize,
+ psStream->szName,
+ psStream->ui32RPtr,
+ psStream->ui32WPtr,
+ psStream->ui32DataWritten));
+
+ return( WriteExpandingBuffer(psStream, pui8InBuf, ui32InBuffSize) );
+}
+
+/*!****************************************************************************
+ @name DBGDrivWrite2
+ @brief Copies data from a buffer into selected (expandable) stream.
+ @param psMainStream - stream for output
+ @param pui8InBuf - input buffer
+ @param ui32InBuffSize - size of input
+ @param ui32Level - debug level of input
+ @return bytes copied, 0 if recoverable error, -1 if unrecoverable error
+*****************************************************************************/
+IMG_UINT32 IMG_CALLCONV DBGDrivWrite2(PDBG_STREAM psMainStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level)
+{
+ DBG_STREAM *psStream;
+
+ /*
+ Validate buffer.
+ */
+ if (!StreamValidForWrite(psMainStream))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DBGDrivWrite2: stream not valid"));
+ return(0xFFFFFFFFUL);
+ }
+
+ /*
+ Check debug level.
+ */
+ if ((psMainStream->psCtrl->ui32DebugLevel & ui32Level) == 0)
+ {
+ return(0);
+ }
+
+ if(psMainStream->psCtrl->bInitPhaseComplete)
+ {
+ psStream = psMainStream;
+ }
+ else
+ {
+ psStream = psMainStream->psInitStream;
+ }
+
+ PVR_DPF((PVR_DBGDRIV_MESSAGE, "Recv(exp) %d b for %s: Roff = %x, WOff = %x",
+ ui32InBuffSize,
+ psStream->szName,
+ psStream->ui32RPtr,
+ psStream->ui32WPtr));
+
+ return( WriteExpandingBuffer(psStream, pui8InBuf, ui32InBuffSize) );
+}
+
+/*!****************************************************************************
+ @name DBGDrivRead
+ @brief Read from debug driver buffers
+ @param psMainStream - stream
+ @param bReadInitBuffer - whether to read from the init stream or the main stream
+ @param ui32OutBuffSize - available space in client buffer
+ @param pui8OutBuf - output buffer
+ @return bytes read, 0 if failure occurred
+*****************************************************************************/
+IMG_UINT32 IMG_CALLCONV DBGDrivRead(PDBG_STREAM psMainStream, IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBuffSize,IMG_UINT8 * pui8OutBuf)
+{
+ IMG_UINT32 ui32Data;
+ DBG_STREAM *psStream;
+
+ /*
+ Validate buffer.
+ */
+ if (!StreamValidForRead(psMainStream))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DBGDrivRead: buffer %x is invalid", (IMG_UINTPTR_T) psMainStream));
+ return(0);
+ }
+
+ if(bReadInitBuffer)
+ {
+ psStream = psMainStream->psInitStream;
+ }
+ else
+ {
+ psStream = psMainStream;
+ }
+
+ /* Don't read beyond the init phase marker point */
+ if (psStream->ui32RPtr == psStream->ui32WPtr ||
+ ((psStream->ui32InitPhaseWOff > 0) &&
+ (psStream->ui32RPtr >= psStream->ui32InitPhaseWOff)) )
+ {
+ return(0);
+ }
+
+ /*
+ Get amount of data in buffer.
+ */
+ if (psStream->ui32RPtr <= psStream->ui32WPtr)
+ {
+ ui32Data = psStream->ui32WPtr - psStream->ui32RPtr;
+ }
+ else
+ {
+ ui32Data = psStream->ui32WPtr + (psStream->ui32Size - psStream->ui32RPtr);
+ }
+
+ /*
+ Don't read beyond the init phase marker point
+ */
+ if ((psStream->ui32InitPhaseWOff > 0) &&
+ (psStream->ui32InitPhaseWOff < psStream->ui32WPtr))
+ {
+ ui32Data = psStream->ui32InitPhaseWOff - psStream->ui32RPtr;
+ }
+
+ /*
+ Only transfer what target buffer can handle.
+ */
+ if (ui32Data > ui32OutBuffSize)
+ {
+ ui32Data = ui32OutBuffSize;
+ }
+
+ PVR_DPF((PVR_DBGDRIV_MESSAGE, "Send %x b from %s: Roff = %x, WOff = %x",
+ ui32Data,
+ psStream->szName,
+ psStream->ui32RPtr,
+ psStream->ui32WPtr));
+
+ /*
+ Split copy into two bits as necessay.
+ */
+ if ((psStream->ui32RPtr + ui32Data) > psStream->ui32Size)
+ { /* Calc block 1 and block 2 sizes */
+ IMG_UINT32 ui32B1 = psStream->ui32Size - psStream->ui32RPtr;
+ IMG_UINT32 ui32B2 = ui32Data - ui32B1;
+
+ /* Copy up to end of circular buffer */
+ HostMemCopy((IMG_VOID *) pui8OutBuf,
+ (IMG_VOID *)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32RPtr),
+ ui32B1);
+
+ /* Copy from start of circular buffer */
+ HostMemCopy((IMG_VOID *)(pui8OutBuf + ui32B1),
+ psStream->pvBase,
+ ui32B2);
+
+ /* Update read pointer now that we've copied the data out */
+ psStream->ui32RPtr = ui32B2;
+ }
+ else
+ { /* Copy data from wherever */
+ HostMemCopy((IMG_VOID *) pui8OutBuf,
+ (IMG_VOID *)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32RPtr),
+ ui32Data);
+
+ /* Update read pointer now that we've copied the data out */
+ psStream->ui32RPtr += ui32Data;
+
+ /* Check for wrapping */
+ if (psStream->ui32RPtr == psStream->ui32Size)
+ {
+ psStream->ui32RPtr = 0;
+ }
+ }
+
+ return(ui32Data);
+}
+
+/*!****************************************************************************
+ @name DBGDrivSetCaptureMode
+ @brief Set capture mode
+ @param psStream - stream
+ @param ui32Mode - capturing mode
+ @param ui32Start - start frame (frame mode only)
+ @param ui32End - end frame (frame mode)
+ @param ui32SampleRate - sampling frequency (frame mode)
+*****************************************************************************/
+void IMG_CALLCONV DBGDrivSetCaptureMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode,IMG_UINT32 ui32Start,IMG_UINT32 ui32End,IMG_UINT32 ui32SampleRate)
+{
+ /*
+ Validate buffer.
+ */
+ if (!StreamValid(psStream))
+ {
+ return;
+ }
+
+ psStream->psCtrl->ui32CapMode = ui32Mode;
+ psStream->psCtrl->ui32DefaultMode = ui32Mode;
+ psStream->psCtrl->ui32Start = ui32Start;
+ psStream->psCtrl->ui32End = ui32End;
+ psStream->psCtrl->ui32SampleRate = ui32SampleRate;
+
+ /*
+ Activate hotkey it the stream is of this type.
+ */
+ if (psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_HOTKEY)
+ {
+ ActivateHotKeys(psStream);
+ }
+}
+
+/*!****************************************************************************
+ @name DBGDrivSetOutputMode
+ @brief Change output mode
+ @param psStream - stream
+ @param ui32OutMode - output mode
+ @return none
+*****************************************************************************/
+void IMG_CALLCONV DBGDrivSetOutputMode(PDBG_STREAM psStream,IMG_UINT32 ui32OutMode)
+{
+ /*
+ Validate buffer.
+ */
+ if (!StreamValid(psStream))
+ {
+ return;
+ }
+
+ psStream->psCtrl->ui32OutMode = ui32OutMode;
+}
+
+/*!****************************************************************************
+ @name DBGDrivSetDebugLevel
+ @brief Change debug level
+ @param psStream - stream
+ @param ui32DebugLevel - verbosity level
+ @return none
+*****************************************************************************/
+void IMG_CALLCONV DBGDrivSetDebugLevel(PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel)
+{
+ /*
+ Validate buffer.
+ */
+ if (!StreamValid(psStream))
+ {
+ return;
+ }
+
+ psStream->psCtrl->ui32DebugLevel = ui32DebugLevel;
+}
+
+/*!****************************************************************************
+ @name DBGDrivSetFrame
+ @brief Advance frame counter
+ @param psStream - stream
+ @param ui32Frame - frame number
+ @return none
+*****************************************************************************/
+void IMG_CALLCONV DBGDrivSetFrame(PDBG_STREAM psStream,IMG_UINT32 ui32Frame)
+{
+ /*
+ Validate buffer.
+ */
+ if (!StreamValid(psStream))
+ {
+ return;
+ }
+
+ psStream->psCtrl->ui32Current = ui32Frame;
+
+ if ((ui32Frame >= psStream->psCtrl->ui32Start) &&
+ (ui32Frame <= psStream->psCtrl->ui32End) &&
+ (((ui32Frame - psStream->psCtrl->ui32Start) % psStream->psCtrl->ui32SampleRate) == 0))
+ {
+ psStream->psCtrl->ui32Flags |= DEBUG_FLAGS_ENABLESAMPLE;
+ }
+ else
+ {
+ psStream->psCtrl->ui32Flags &= ~DEBUG_FLAGS_ENABLESAMPLE;
+ }
+
+ if (g_bHotkeyMiddump)
+ {
+ if ((ui32Frame >= g_ui32HotkeyMiddumpStart) &&
+ (ui32Frame <= g_ui32HotkeyMiddumpEnd) &&
+ (((ui32Frame - g_ui32HotkeyMiddumpStart) % psStream->psCtrl->ui32SampleRate) == 0))
+ {
+ psStream->psCtrl->ui32Flags |= DEBUG_FLAGS_ENABLESAMPLE;
+ }
+ else
+ {
+ psStream->psCtrl->ui32Flags &= ~DEBUG_FLAGS_ENABLESAMPLE;
+ if (psStream->psCtrl->ui32Current > g_ui32HotkeyMiddumpEnd)
+ {
+ g_bHotkeyMiddump = IMG_FALSE;
+ }
+ }
+ }
+
+ /* Check to see if hotkey press has been registered (from keyboard filter) */
+ if (g_bHotKeyRegistered)
+ {
+ g_bHotKeyRegistered = IMG_FALSE;
+
+ PVR_DPF((PVR_DBG_MESSAGE,"Hotkey pressed (%p)!\n",psStream));
+
+ if (!g_bHotKeyPressed)
+ {
+ /*
+ Capture the next frame.
+ */
+ g_ui32HotKeyFrame = psStream->psCtrl->ui32Current + 2;
+
+ /*
+ Do the flag.
+ */
+ g_bHotKeyPressed = IMG_TRUE;
+ }
+
+ /*
+ If in framed hotkey mode, then set start frame.
+ */
+ if (((psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED) != 0) &&
+ ((psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_HOTKEY) != 0))
+ {
+ if (!g_bHotkeyMiddump)
+ {
+ /* Turn on */
+ g_ui32HotkeyMiddumpStart = g_ui32HotKeyFrame + 1;
+ g_ui32HotkeyMiddumpEnd = 0xffffffff;
+ g_bHotkeyMiddump = IMG_TRUE;
+ PVR_DPF((PVR_DBG_MESSAGE,"Sampling every %d frame(s)\n", psStream->psCtrl->ui32SampleRate));
+ }
+ else
+ {
+ /* Turn off */
+ g_ui32HotkeyMiddumpEnd = g_ui32HotKeyFrame;
+ PVR_DPF((PVR_DBG_MESSAGE,"Turning off sampling\n"));
+ }
+ }
+
+ }
+
+ /*
+ Clear the hotkey frame indicator when over that frame.
+ */
+ if (psStream->psCtrl->ui32Current > g_ui32HotKeyFrame)
+ {
+ g_bHotKeyPressed = IMG_FALSE;
+ }
+}
+
+/*!****************************************************************************
+ @name DBGDrivGetFrame
+ @brief Retrieve current frame number
+ @param psStream - stream
+ @return frame number
+*****************************************************************************/
+IMG_UINT32 IMG_CALLCONV DBGDrivGetFrame(PDBG_STREAM psStream)
+{
+ /*
+ Validate buffer.
+ */
+ if (!StreamValid(psStream))
+ {
+ return(0);
+ }
+
+ return(psStream->psCtrl->ui32Current);
+}
+
+/*!****************************************************************************
+ @name DBGDrivIsLastCaptureFrame
+ @brief Is this the last frame to be captured?
+ @param psStream - stream
+ @return true if last capture frame, false otherwise
+*****************************************************************************/
+IMG_BOOL IMG_CALLCONV DBGDrivIsLastCaptureFrame(PDBG_STREAM psStream)
+{
+ IMG_UINT32 ui32NextFrame;
+
+ /*
+ Validate buffer.
+ */
+ if (!StreamValid(psStream))
+ {
+ return IMG_FALSE;
+ }
+
+ if (psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED)
+ {
+ ui32NextFrame = psStream->psCtrl->ui32Current + psStream->psCtrl->ui32SampleRate;
+ if (ui32NextFrame > psStream->psCtrl->ui32End)
+ {
+ return IMG_TRUE;
+ }
+ }
+ return IMG_FALSE;
+}
+
+/*!****************************************************************************
+ @name DBGDrivIsCaptureFrame
+ @brief Is this a capture frame?
+ @param psStream - stream
+ @param bCheckPreviousFrame - set if it needs to be 1 frame ahead
+ @return true if capturing this frame, false otherwise
+*****************************************************************************/
+IMG_BOOL IMG_CALLCONV DBGDrivIsCaptureFrame(PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame)
+{
+ IMG_UINT32 ui32FrameShift = bCheckPreviousFrame ? 1UL : 0UL;
+
+ /*
+ Validate buffer.
+ */
+ if (!StreamValid(psStream))
+ {
+ return IMG_FALSE;
+ }
+
+ if (psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED)
+ {
+ /* Needs to be one frame ahead, so disppatch can turn everything on */
+ if (g_bHotkeyMiddump)
+ {
+ if ((psStream->psCtrl->ui32Current >= (g_ui32HotkeyMiddumpStart - ui32FrameShift)) &&
+ (psStream->psCtrl->ui32Current <= (g_ui32HotkeyMiddumpEnd - ui32FrameShift)) &&
+ ((((psStream->psCtrl->ui32Current + ui32FrameShift) - g_ui32HotkeyMiddumpStart) % psStream->psCtrl->ui32SampleRate) == 0))
+ {
+ return IMG_TRUE;
+ }
+ }
+ else
+ {
+ if ((psStream->psCtrl->ui32Current >= (psStream->psCtrl->ui32Start - ui32FrameShift)) &&
+ (psStream->psCtrl->ui32Current <= (psStream->psCtrl->ui32End - ui32FrameShift)) &&
+ ((((psStream->psCtrl->ui32Current + ui32FrameShift) - psStream->psCtrl->ui32Start) % psStream->psCtrl->ui32SampleRate) == 0))
+ {
+ return IMG_TRUE;
+ }
+ }
+ }
+ else if (psStream->psCtrl->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
+ {
+ if ((psStream->psCtrl->ui32Current == (g_ui32HotKeyFrame-ui32FrameShift)) && (g_bHotKeyPressed))
+ {
+ return IMG_TRUE;
+ }
+ }
+ return IMG_FALSE;
+}
+
+/*!****************************************************************************
+ @name DBGDrivOverrideMode
+ @brief Override capture mode
+ @param psStream - stream
+ @param ui32Mode - capture mode
+ @return none
+*****************************************************************************/
+void IMG_CALLCONV DBGDrivOverrideMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode)
+{
+ /*
+ Validate buffer.
+ */
+ if (!StreamValid(psStream))
+ {
+ return;
+ }
+
+ psStream->psCtrl->ui32CapMode = ui32Mode;
+}
+
+/*!****************************************************************************
+ @name DBGDrivDefaultMode
+ @param psStream - stream
+ @return none
+*****************************************************************************/
+void IMG_CALLCONV DBGDrivDefaultMode(PDBG_STREAM psStream)
+{
+ /*
+ Validate buffer.
+ */
+ if (!StreamValid(psStream))
+ {
+ return;
+ }
+
+ psStream->psCtrl->ui32CapMode = psStream->psCtrl->ui32DefaultMode;
+}
+
+/*!****************************************************************************
+ @name DBGDrivSetClientMarker
+ @brief Sets the marker to prevent reading initphase beyond data on behalf of previous app
+ @param psStream - stream
+ @param ui32Marker - byte offset in init buffer
+ @return nothing
+*****************************************************************************/
+IMG_VOID IMG_CALLCONV DBGDrivSetClientMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker)
+{
+ /*
+ Validate buffer
+ */
+ if (!StreamValid(psStream))
+ {
+ return;
+ }
+
+ psStream->ui32InitPhaseWOff = ui32Marker;
+}
+
+/*!****************************************************************************
+ @name DBGDrivSetMarker
+ @brief Sets the marker in the stream to split output files
+ @param psStream, ui32Marker
+ @return nothing
+*****************************************************************************/
+void IMG_CALLCONV DBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker)
+{
+ /*
+ Validate buffer
+ */
+ if (!StreamValid(psStream))
+ {
+ return;
+ }
+
+ psStream->ui32Marker = ui32Marker;
+}
+
+/*!****************************************************************************
+ @name DBGDrivGetMarker
+ @brief Gets the marker in the stream to split output files
+ @param psStream - stream
+ @return marker offset
+*****************************************************************************/
+IMG_UINT32 IMG_CALLCONV DBGDrivGetMarker(PDBG_STREAM psStream)
+{
+ /*
+ Validate buffer
+ */
+ if (!StreamValid(psStream))
+ {
+ return 0;
+ }
+
+ return psStream->ui32Marker;
+}
+
+
+/*!****************************************************************************
+ @name DBGDrivGetStreamOffset
+ @brief Gets the amount of data written to the stream
+ @param psMainStream - stream
+ @return bytes written
+*****************************************************************************/
+IMG_UINT32 IMG_CALLCONV DBGDrivGetStreamOffset(PDBG_STREAM psMainStream)
+{
+ PDBG_STREAM psStream;
+
+ /*
+ Validate buffer
+ */
+ if (!StreamValid(psMainStream))
+ {
+ return 0;
+ }
+
+ if(psMainStream->psCtrl->bInitPhaseComplete)
+ {
+ psStream = psMainStream;
+ }
+ else
+ {
+ psStream = psMainStream->psInitStream;
+ }
+
+ return psStream->ui32DataWritten;
+}
+
+/*!****************************************************************************
+ @name DBGDrivSetStreamOffset
+ @brief Sets the amount of data written to the stream
+ @param psMainStream - stream
+ @param ui32StreamOffset - stream offset
+ @return Nothing
+*****************************************************************************/
+IMG_VOID IMG_CALLCONV DBGDrivSetStreamOffset(PDBG_STREAM psMainStream, IMG_UINT32 ui32StreamOffset)
+{
+ PDBG_STREAM psStream;
+
+ /*
+ Validate buffer
+ */
+ if (!StreamValid(psMainStream))
+ {
+ return;
+ }
+
+ if(psMainStream->psCtrl->bInitPhaseComplete)
+ {
+ psStream = psMainStream;
+ }
+ else
+ {
+ psStream = psMainStream->psInitStream;
+ }
+
+ PVR_DPF((PVR_DBGDRIV_MESSAGE, "DBGDrivSetStreamOffset: %s set to %x b",
+ psStream->szName,
+ ui32StreamOffset));
+ psStream->ui32DataWritten = ui32StreamOffset;
+}
+
+/*!****************************************************************************
+ @name DBGDrivGetServiceTable
+ @brief get jump table for Services driver
+ @return pointer to jump table
+*****************************************************************************/
+IMG_PVOID IMG_CALLCONV DBGDrivGetServiceTable(IMG_VOID)
+{
+ return((IMG_PVOID)&g_sDBGKMServices);
+}
+
+/*!****************************************************************************
+ @name DBGDrivWriteLF
+ @brief Store data that should only be kept from the last frame dumped
+ @param psStream - stream
+ @param pui8InBuf - input buffer
+ @param ui32InBuffSize - size
+ @param ui32Level - verbosity level
+ @param ui32Flags - flags
+ @return bytes written
+*****************************************************************************/
+IMG_UINT32 IMG_CALLCONV DBGDrivWriteLF(PDBG_STREAM psStream, IMG_UINT8 * pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags)
+{
+ PDBG_LASTFRAME_BUFFER psLFBuffer;
+
+ /*
+ Validate buffer.
+ */
+ if (!StreamValidForWrite(psStream))
+ {
+ return(0xFFFFFFFFUL);
+ }
+
+ /*
+ Check debug level.
+ */
+ if ((psStream->psCtrl->ui32DebugLevel & ui32Level) == 0)
+ {
+ return(0xFFFFFFFFUL);
+ }
+
+ /*
+ Only write data if debug mode adds up...
+ */
+ if ((psStream->psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED) != 0)
+ {
+ if ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE) == 0)
+ {
+ /* throw away non-capturing data */
+ return(ui32InBuffSize);
+ }
+ }
+ else if (psStream->psCtrl->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
+ {
+ if ((psStream->psCtrl->ui32Current != g_ui32HotKeyFrame) || (g_bHotKeyPressed == IMG_FALSE))
+ {
+ /* throw away non-capturing data */
+ return(ui32InBuffSize);
+ }
+ }
+
+ psLFBuffer = FindLFBuf(psStream);
+
+ if (ui32Flags & WRITELF_FLAGS_RESETBUF)
+ {
+ /*
+ Copy the data into the buffer
+ */
+ ui32InBuffSize = (ui32InBuffSize > LAST_FRAME_BUF_SIZE) ? LAST_FRAME_BUF_SIZE : ui32InBuffSize;
+ HostMemCopy((IMG_VOID *)psLFBuffer->ui8Buffer, (IMG_VOID *)pui8InBuf, ui32InBuffSize);
+ psLFBuffer->ui32BufLen = ui32InBuffSize;
+ }
+ else
+ {
+ /*
+ Append the data to the end of the buffer
+ */
+ 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);
+}
+
+/*!****************************************************************************
+ @name DBGDrivReadLF
+ @brief Read data that should only be kept from the last frame dumped
+ @param psStream - stream
+ @param ui32OutBuffSize - buffer size
+ @param pui8OutBuf - output buffer
+ @return bytes read
+*****************************************************************************/
+IMG_UINT32 IMG_CALLCONV DBGDrivReadLF(PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 * pui8OutBuf)
+{
+ PDBG_LASTFRAME_BUFFER psLFBuffer;
+ IMG_UINT32 ui32Data;
+
+ /*
+ Validate buffer.
+ */
+ if (!StreamValidForRead(psStream))
+ {
+ return(0);
+ }
+
+ psLFBuffer = FindLFBuf(psStream);
+
+ /*
+ Get amount of data to copy
+ */
+ ui32Data = (ui32OutBuffSize < psLFBuffer->ui32BufLen) ? ui32OutBuffSize : psLFBuffer->ui32BufLen;
+
+ /*
+ Copy the data into the buffer
+ */
+ HostMemCopy((IMG_VOID *)pui8OutBuf, (IMG_VOID *)psLFBuffer->ui8Buffer, ui32Data);
+
+ return ui32Data;
+}
+
+/*!****************************************************************************
+ @name DBGDrivStartInitPhase
+ @brief Marks start of init phase
+ @param psStream - stream
+ @return void
+*****************************************************************************/
+IMG_VOID IMG_CALLCONV DBGDrivStartInitPhase(PDBG_STREAM psStream)
+{
+ psStream->psCtrl->bInitPhaseComplete = IMG_FALSE;
+}
+
+/*!****************************************************************************
+ @name DBGDrivStopInitPhase
+ @brief Marks end of init phase
+ @param psStream - stream
+ @return void
+*****************************************************************************/
+IMG_VOID IMG_CALLCONV DBGDrivStopInitPhase(PDBG_STREAM psStream)
+{
+ psStream->psCtrl->bInitPhaseComplete = IMG_TRUE;
+}
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+/*!****************************************************************************
+ @name DBGDrivWaitForEvent
+ @brief waits for an event
+ @param eEvent - debug driver event
+ @return void
+*****************************************************************************/
+IMG_VOID IMG_CALLCONV DBGDrivWaitForEvent(DBG_EVENT eEvent)
+{
+ HostWaitForEvent(eEvent);
+}
+#endif
+
+/*!****************************************************************************
+ @name ExpandStreamBuffer
+ @brief allocates a new buffer when the current one is full
+ @param psStream - stream
+ @param ui32NewSize - new size
+ @return IMG_TRUE - if allocation succeeded, IMG_FALSE - if not
+*****************************************************************************/
+IMG_BOOL ExpandStreamBuffer(PDBG_STREAM psStream, IMG_UINT32 ui32NewSize)
+{
+ IMG_VOID * pvNewBuf;
+ IMG_UINT32 ui32NewSizeInPages;
+ IMG_UINT32 ui32NewWOffset;
+ IMG_UINT32 ui32NewROffset;
+ IMG_UINT32 ui32SpaceInOldBuf;
+
+ /*
+ First check new size is bigger than existing size
+ */
+ if (psStream->ui32Size >= ui32NewSize)
+ {
+ return IMG_FALSE;
+ }
+
+ /*
+ Calc space in old buffer
+ */
+ ui32SpaceInOldBuf = SpaceInStream(psStream);
+
+ /*
+ Allocate new buffer
+ */
+ ui32NewSizeInPages = ((ui32NewSize + 0xfffUL) & ~0xfffUL) / 4096UL;
+
+ if ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
+ {
+ pvNewBuf = HostNonPageablePageAlloc(ui32NewSizeInPages);
+ }
+ else
+ {
+ pvNewBuf = HostPageablePageAlloc(ui32NewSizeInPages);
+ }
+
+ if (pvNewBuf == IMG_NULL)
+ {
+ return IMG_FALSE;
+ }
+
+ if(psStream->bCircularAllowed)
+ {
+ /*
+ Copy over old buffer to new one, we place data at start of buffer
+ even if Read offset is not at start of buffer
+ */
+ if (psStream->ui32RPtr <= psStream->ui32WPtr)
+ {
+ /*
+ No wrapping of data so copy data to start of new buffer
+ */
+ HostMemCopy(pvNewBuf,
+ (IMG_VOID *)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32RPtr),
+ psStream->ui32WPtr - psStream->ui32RPtr);
+ }
+ else
+ {
+ IMG_UINT32 ui32FirstCopySize;
+
+ /*
+ The data has wrapped around the buffer, copy beginning of buffer first
+ */
+ ui32FirstCopySize = psStream->ui32Size - psStream->ui32RPtr;
+
+ HostMemCopy(pvNewBuf,
+ (IMG_VOID *)((IMG_UINTPTR_T)psStream->pvBase + psStream->ui32RPtr),
+ ui32FirstCopySize);
+
+ /*
+ Now second half
+ */
+ HostMemCopy((IMG_VOID *)((IMG_UINTPTR_T)pvNewBuf + ui32FirstCopySize),
+ (IMG_VOID *)(IMG_PBYTE)psStream->pvBase,
+ psStream->ui32WPtr);
+ }
+ ui32NewROffset = 0;
+ }
+ else
+ {
+ /* Copy everything in the old buffer to the new one */
+ HostMemCopy(pvNewBuf, psStream->pvBase, psStream->ui32WPtr);
+ ui32NewROffset = psStream->ui32RPtr;
+ }
+
+ /*
+ New Write offset is at end of data
+ */
+ ui32NewWOffset = psStream->ui32Size - ui32SpaceInOldBuf;
+
+ /*
+ Free old buffer
+ */
+ if ((psStream->psCtrl->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
+ {
+ HostNonPageablePageFree(psStream->pvBase);
+ }
+ else
+ {
+ HostPageablePageFree(psStream->pvBase);
+ }
+
+ /*
+ Now set new params up
+ */
+ psStream->pvBase = pvNewBuf;
+ psStream->ui32RPtr = ui32NewROffset;
+ psStream->ui32WPtr = ui32NewWOffset;
+ psStream->ui32Size = ui32NewSizeInPages * 4096;
+
+ return IMG_TRUE;
+}
+
+/*!****************************************************************************
+ @name SpaceInStream
+ @brief remaining space in stream
+ @param psStream - stream
+ @return bytes remaining
+*****************************************************************************/
+IMG_UINT32 SpaceInStream(PDBG_STREAM psStream)
+{
+ IMG_UINT32 ui32Space;
+
+ if (psStream->bCircularAllowed)
+ {
+ /* Allow overwriting the buffer which was already read */
+ if (psStream->ui32RPtr > psStream->ui32WPtr)
+ {
+ ui32Space = psStream->ui32RPtr - psStream->ui32WPtr;
+ }
+ else
+ {
+ ui32Space = psStream->ui32RPtr + (psStream->ui32Size - psStream->ui32WPtr);
+ }
+ }
+ else
+ {
+ /* Don't overwrite anything */
+ ui32Space = psStream->ui32Size - psStream->ui32WPtr;
+ }
+
+ return ui32Space;
+}
+
+
+/*!****************************************************************************
+ @name DestroyAllStreams
+ @brief delete all streams in list
+ @return none
+*****************************************************************************/
+void DestroyAllStreams(void)
+{
+ while (g_psStreamList != IMG_NULL)
+ {
+ DBGDrivDestroyStream(g_psStreamList);
+ }
+ return;
+}
+
+/*!****************************************************************************
+ @name FindLFBuf
+ @brief finds last frame stream
+ @param psStream - stream to find
+ @return stream if found, NULL otherwise
+*****************************************************************************/
+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;
+}
+
+/******************************************************************************
+ End of file (DBGDRIV.C)
+******************************************************************************/
diff --git a/pvr-source/tools/intern/debug/dbgdriv/common/dbgdriv.h b/pvr-source/tools/intern/debug/dbgdriv/common/dbgdriv.h
new file mode 100644
index 0000000..d58c62d
--- /dev/null
+++ b/pvr-source/tools/intern/debug/dbgdriv/common/dbgdriv.h
@@ -0,0 +1,155 @@
+/*************************************************************************/ /*!
+@Title Debug Driver interface definition.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _DBGDRIV_
+#define _DBGDRIV_
+
+/*****************************************************************************
+ The odd constant or two
+*****************************************************************************/
+#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;
+
+/*****************************************************************************
+ KM mode functions
+*****************************************************************************/
+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_PVOID 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 DBGDrivSetClientMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker);
+IMG_VOID IMG_CALLCONV DBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker);
+IMG_UINT32 IMG_CALLCONV DBGDrivGetMarker(PDBG_STREAM psStream);
+IMG_BOOL IMG_CALLCONV DBGDrivIsLastCaptureFrame(PDBG_STREAM psStream);
+IMG_BOOL 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);
+
+/*****************************************************************************
+ Function prototypes
+*****************************************************************************/
+IMG_UINT32 AtoI(IMG_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_VOID MonoOut(IMG_CHAR * pszString,IMG_BOOL bNewLine);
+
+/*****************************************************************************
+ Secure handle Function prototypes
+*****************************************************************************/
+IMG_SID PStream2SID(PDBG_STREAM psStream);
+PDBG_STREAM SID2PStream(IMG_SID hStream);
+IMG_BOOL AddSIDEntry(PDBG_STREAM psStream);
+IMG_BOOL RemoveSIDEntry(PDBG_STREAM psStream);
+
+/*****************************************************************************
+ Declarations for Service table entry points
+*****************************************************************************/
+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_BOOL IMG_CALLCONV ExtDBGDrivIsLastCaptureFrame(PDBG_STREAM psStream);
+IMG_BOOL 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);
+IMG_VOID IMG_CALLCONV ExtDBGDrivSetConnectNotifier(DBGKM_CONNECT_NOTIFIER fn_notifier);
+
+IMG_UINT32 IMG_CALLCONV ExtDBGDrivWritePersist(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level);
+
+#endif
+
+/*****************************************************************************
+ End of file (DBGDRIV.H)
+*****************************************************************************/
diff --git a/pvr-source/tools/intern/debug/dbgdriv/common/dbgdriv_ioctl.h b/pvr-source/tools/intern/debug/dbgdriv/common/dbgdriv_ioctl.h
new file mode 100644
index 0000000..0909e6d
--- /dev/null
+++ b/pvr-source/tools/intern/debug/dbgdriv/common/dbgdriv_ioctl.h
@@ -0,0 +1,57 @@
+/*************************************************************************/ /*!
+@Title IOCTL implementations for debug device.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _IOCTL_
+#define _IOCTL_
+
+/*****************************************************************************
+ Global vars
+*****************************************************************************/
+
+#define MAX_DBGVXD_W32_API 25
+
+extern IMG_UINT32 (*g_DBGDrivProc[MAX_DBGVXD_W32_API])(IMG_VOID *, IMG_VOID *);
+
+#endif
+
+/*****************************************************************************
+ End of file (IOCTL.H)
+*****************************************************************************/
diff --git a/pvr-source/tools/intern/debug/dbgdriv/common/handle.c b/pvr-source/tools/intern/debug/dbgdriv/common/handle.c
new file mode 100644
index 0000000..a9d37a6
--- /dev/null
+++ b/pvr-source/tools/intern/debug/dbgdriv/common/handle.c
@@ -0,0 +1,141 @@
+/*************************************************************************/ /*!
+@Title Resource Handle Manager
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Provide resource handle management
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "img_defs.h"
+#include "dbgdrvif.h"
+#include "dbgdriv.h"
+
+/* max number of streams held in SID info table */
+#define MAX_SID_ENTRIES 8
+
+typedef struct _SID_INFO
+{
+ PDBG_STREAM psStream;
+} SID_INFO, *PSID_INFO;
+
+static SID_INFO gaSID_Xlat_Table[MAX_SID_ENTRIES];
+
+IMG_SID PStream2SID(PDBG_STREAM psStream)
+{
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ IMG_INT32 iIdx;
+
+ for (iIdx = 0; iIdx < MAX_SID_ENTRIES; iIdx++)
+ {
+ if (psStream == gaSID_Xlat_Table[iIdx].psStream)
+ {
+ /* idx is one based */
+ return (IMG_SID)iIdx+1;
+ }
+ }
+ }
+
+ return (IMG_SID)0;
+}
+
+
+PDBG_STREAM SID2PStream(IMG_SID hStream)
+{
+ /* changed to zero based */
+ IMG_INT32 iIdx = (IMG_INT32)hStream-1;
+
+ if (iIdx >= 0 && iIdx < MAX_SID_ENTRIES)
+ {
+ return gaSID_Xlat_Table[iIdx].psStream;
+ }
+ else
+ {
+ return (PDBG_STREAM)IMG_NULL;
+ }
+}
+
+
+IMG_BOOL AddSIDEntry(PDBG_STREAM psStream)
+{
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ IMG_INT32 iIdx;
+
+ for (iIdx = 0; iIdx < MAX_SID_ENTRIES; iIdx++)
+ {
+ if (psStream == gaSID_Xlat_Table[iIdx].psStream)
+ {
+ /* already created */
+ return IMG_TRUE;
+ }
+
+ if (gaSID_Xlat_Table[iIdx].psStream == (PDBG_STREAM)IMG_NULL)
+ {
+ /* free entry */
+ gaSID_Xlat_Table[iIdx].psStream = psStream;
+ return IMG_TRUE;
+ }
+ }
+ }
+
+ return IMG_FALSE;
+}
+
+IMG_BOOL RemoveSIDEntry(PDBG_STREAM psStream)
+{
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ IMG_INT32 iIdx;
+
+ for (iIdx = 0; iIdx < MAX_SID_ENTRIES; iIdx++)
+ {
+ if (psStream == gaSID_Xlat_Table[iIdx].psStream)
+ {
+ gaSID_Xlat_Table[iIdx].psStream = (PDBG_STREAM)IMG_NULL;
+ return IMG_TRUE;
+ }
+ }
+ }
+
+ return IMG_FALSE;
+}
+
+
+/******************************************************************************
+ End of file (handle.c)
+******************************************************************************/
diff --git a/pvr-source/tools/intern/debug/dbgdriv/common/hostfunc.h b/pvr-source/tools/intern/debug/dbgdriv/common/hostfunc.h
new file mode 100644
index 0000000..e92ad9a
--- /dev/null
+++ b/pvr-source/tools/intern/debug/dbgdriv/common/hostfunc.h
@@ -0,0 +1,82 @@
+/*************************************************************************/ /*!
+@Title Host function definitions for debug device.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _HOSTFUNC_
+#define _HOSTFUNC_
+
+/*****************************************************************************
+ Defines
+*****************************************************************************/
+#define HOST_PAGESIZE (4096)
+#define DBG_MEMORY_INITIALIZER (0xe2)
+
+/*****************************************************************************
+ Function prototypes
+*****************************************************************************/
+IMG_UINT32 HostReadRegistryDWORDFromString(IMG_CHAR *pcKey, IMG_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 /*defined(SUPPORT_DBGDRV_EVENT_OBJECTS) */
+
+#endif
+
+/*****************************************************************************
+ End of file (HOSTFUNC.H)
+*****************************************************************************/
diff --git a/pvr-source/tools/intern/debug/dbgdriv/common/hotkey.c b/pvr-source/tools/intern/debug/dbgdriv/common/hotkey.c
new file mode 100644
index 0000000..6bf20a6
--- /dev/null
+++ b/pvr-source/tools/intern/debug/dbgdriv/common/hotkey.c
@@ -0,0 +1,199 @@
+/*************************************************************************/ /*!
+@Title Debug driver utilities implementations.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Hotkey stuff
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+
+#if !defined(LINUX) && !defined(__QNXNTO__)
+#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"
+
+
+
+
+/*****************************************************************************
+ Global vars
+*****************************************************************************/
+
+IMG_UINT32 g_ui32HotKeyFrame = 0xFFFFFFFF;
+IMG_BOOL g_bHotKeyPressed = IMG_FALSE;
+IMG_BOOL g_bHotKeyRegistered = IMG_FALSE;
+
+/* Hotkey stuff */
+PRIVATEHOTKEYDATA g_PrivateHotKeyData;
+
+
+/*****************************************************************************
+ Code
+*****************************************************************************/
+
+
+/******************************************************************************
+ * Function Name: ReadInHotKeys
+ *
+ * Inputs : none
+ * Outputs : -
+ * Returns : nothing
+ * Globals Used : -
+ *
+ * Description : Gets Hot key entries from system.ini
+ *****************************************************************************/
+IMG_VOID ReadInHotKeys(IMG_VOID)
+{
+ g_PrivateHotKeyData.ui32ScanCode = 0x58; /* F12 */
+ g_PrivateHotKeyData.ui32ShiftState = 0x0;
+
+ /*
+ Find buffer names etc..
+ */
+ HostReadRegistryDWORDFromString("DEBUG\\Streams", "ui32ScanCode" , &g_PrivateHotKeyData.ui32ScanCode);
+ HostReadRegistryDWORDFromString("DEBUG\\Streams", "ui32ShiftState", &g_PrivateHotKeyData.ui32ShiftState);
+}
+
+/******************************************************************************
+ * Function Name: RegisterKeyPressed
+ *
+ * Inputs : IMG_UINT32 dwui32ScanCode, PHOTKEYINFO pInfo
+ * Outputs : -
+ * Returns : nothing
+ * Globals Used : -
+ *
+ * Description : Called when hotkey pressed.
+ *****************************************************************************/
+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)
+ {
+ /*
+ Capture the next frame.
+ */
+ g_ui32HotKeyFrame = psStream->psCtrl->ui32Current + 2;
+
+ /*
+ Do the flag.
+ */
+ g_bHotKeyPressed = IMG_TRUE;
+ }
+ }
+}
+
+/******************************************************************************
+ * Function Name: ActivateHotKeys
+ *
+ * Inputs : -
+ * Outputs : -
+ * Returns : -
+ * Globals Used : -
+ *
+ * Description : Installs HotKey callbacks
+ *****************************************************************************/
+IMG_VOID ActivateHotKeys(PDBG_STREAM psStream)
+{
+ /*
+ Setup hotkeys.
+ */
+ ReadInHotKeys();
+
+ /*
+ Has it already been allocated.
+ */
+ if (!g_PrivateHotKeyData.sHotKeyInfo.hHotKey)
+ {
+ if (g_PrivateHotKeyData.ui32ScanCode != 0)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,"Activate HotKey for PDUMP.\n"));
+
+ /*
+ Add in stream data.
+ */
+ g_PrivateHotKeyData.sHotKeyInfo.pvStream = psStream;
+
+ DefineHotKey(g_PrivateHotKeyData.ui32ScanCode, g_PrivateHotKeyData.ui32ShiftState, &g_PrivateHotKeyData.sHotKeyInfo);
+ }
+ else
+ {
+ g_PrivateHotKeyData.sHotKeyInfo.hHotKey = 0;
+ }
+ }
+}
+
+/******************************************************************************
+ * Function Name: DeactivateHotKeys
+ *
+ * Inputs : -
+ * Outputs : -
+ * Returns : -
+ * Globals Used : -
+ *
+ * Description : Removes HotKey callbacks
+ *****************************************************************************/
+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;
+ }
+}
+
+
+/*****************************************************************************
+ End of file (HOTKEY.C)
+*****************************************************************************/
diff --git a/pvr-source/tools/intern/debug/dbgdriv/common/hotkey.h b/pvr-source/tools/intern/debug/dbgdriv/common/hotkey.h
new file mode 100644
index 0000000..7aa2952
--- /dev/null
+++ b/pvr-source/tools/intern/debug/dbgdriv/common/hotkey.h
@@ -0,0 +1,82 @@
+/*************************************************************************/ /*!
+@Title Debug driver utilities header file.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Hotkey stuff
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#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; /* handle. */
+} HOTKEYINFO, *PHOTKEYINFO;
+
+typedef struct _privatehotkeydata
+{
+ IMG_UINT32 ui32ScanCode;
+ IMG_UINT32 ui32ShiftState;
+ HOTKEYINFO sHotKeyInfo;
+} PRIVATEHOTKEYDATA, *PPRIVATEHOTKEYDATA;
+
+
+/*****************************************************************************
+ Hotkey stuff
+*****************************************************************************/
+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
+
+/*****************************************************************************
+ End of file (HOTKEY.H)
+*****************************************************************************/
diff --git a/pvr-source/tools/intern/debug/dbgdriv/common/ioctl.c b/pvr-source/tools/intern/debug/dbgdriv/common/ioctl.c
new file mode 100644
index 0000000..1767a9b
--- /dev/null
+++ b/pvr-source/tools/intern/debug/dbgdriv/common/ioctl.c
@@ -0,0 +1,827 @@
+/*************************************************************************/ /*!
+@Title IOCTL implementations for debug device.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+
+#ifdef LINUX
+#include <asm/uaccess.h>
+#include "pvr_uaccess.h"
+#endif /* LINUX */
+
+#include "img_types.h"
+#include "dbgdrvif.h"
+#include "dbgdriv.h"
+#include "hotkey.h"
+#include "dbgdriv_ioctl.h"
+
+
+/*****************************************************************************
+ Code
+*****************************************************************************/
+
+/*****************************************************************************
+ FUNCTION : DBGDrivCreateStream
+
+ PURPOSE :
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivCreateStream(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_CREATESTREAM psIn;
+ IMG_VOID * *ppvOut;
+ #ifdef LINUX
+ static IMG_CHAR name[32];
+ #endif
+
+ psIn = (PDBG_IN_CREATESTREAM) pvInBuffer;
+ ppvOut = (IMG_VOID * *) pvOutBuffer;
+
+ #ifdef LINUX
+
+ if(pvr_copy_from_user(name, psIn->u.pszName, 32) != 0)
+ {
+ return IMG_FALSE;
+ }
+
+ *ppvOut = ExtDBGDrivCreateStream(name, psIn->ui32CapMode, psIn->ui32OutMode, 0, psIn->ui32Pages);
+
+ #else
+ *ppvOut = ExtDBGDrivCreateStream(psIn->u.pszName, psIn->ui32CapMode, psIn->ui32OutMode, DEBUG_FLAGS_NO_BUF_EXPANDSION, psIn->ui32Pages);
+ #endif
+
+
+ return(IMG_TRUE);
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDrivDestroyStream
+
+ PURPOSE :
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivDestroyStream(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_STREAM *ppsStream;
+ PDBG_STREAM psStream;
+
+ ppsStream = (PDBG_STREAM *) pvInBuffer;
+ psStream = (PDBG_STREAM) *ppsStream;
+
+ PVR_UNREFERENCED_PARAMETER( pvOutBuffer);
+
+ ExtDBGDrivDestroyStream(psStream);
+
+ return(IMG_TRUE);
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDrivGetStream
+
+ PURPOSE :
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivGetStream(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_FINDSTREAM psParams;
+ IMG_SID * phStream;
+
+ psParams = (PDBG_IN_FINDSTREAM)pvInBuffer;
+ phStream = (IMG_SID *)pvOutBuffer;
+
+ *phStream = PStream2SID(ExtDBGDrivFindStream(psParams->u.pszName, psParams->bResetStream));
+
+ return(IMG_TRUE);
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDrivWriteString
+
+ PURPOSE :
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivWriteString(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_WRITESTRING psParams;
+ IMG_UINT32 *pui32OutLen;
+ PDBG_STREAM psStream;
+
+ psParams = (PDBG_IN_WRITESTRING) pvInBuffer;
+ pui32OutLen = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(psParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32OutLen = ExtDBGDrivWriteString(psStream,psParams->u.pszString,psParams->ui32Level);
+ return(IMG_TRUE);
+ }
+ else
+ {
+ /* invalid SID */
+ *pui32OutLen = 0;
+ return(IMG_FALSE);
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDrivWriteStringCM
+
+ PURPOSE : Same as DBGDrivWriteString, but takes notice of capture mode.
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivWriteStringCM(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_WRITESTRING psParams;
+ IMG_UINT32 *pui32OutLen;
+ PDBG_STREAM psStream;
+
+ psParams = (PDBG_IN_WRITESTRING) pvInBuffer;
+ pui32OutLen = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(psParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32OutLen = ExtDBGDrivWriteStringCM(psStream,psParams->u.pszString,psParams->ui32Level);
+ return(IMG_TRUE);
+ }
+ else
+ {
+ /* invalid SID */
+ *pui32OutLen = 0;
+ return(IMG_FALSE);
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDrivReadString
+
+ PURPOSE :
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivReadString(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ IMG_UINT32 * pui32OutLen;
+ PDBG_IN_READSTRING psParams;
+ PDBG_STREAM psStream;
+
+ psParams = (PDBG_IN_READSTRING) pvInBuffer;
+ pui32OutLen = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(psParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32OutLen = ExtDBGDrivReadString(psStream,
+ psParams->u.pszString,psParams->ui32StringLen);
+ return(IMG_TRUE);
+ }
+ else
+ {
+ /* invalid SID */
+ *pui32OutLen = 0;
+ return(IMG_FALSE);
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDrivWrite
+
+ PURPOSE :
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivWrite(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ IMG_UINT32 * pui32BytesCopied;
+ PDBG_IN_WRITE psInParams;
+ PDBG_STREAM psStream;
+
+ psInParams = (PDBG_IN_WRITE) pvInBuffer;
+ pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(psInParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32BytesCopied = ExtDBGDrivWrite(psStream,
+ psInParams->u.pui8InBuffer,
+ psInParams->ui32TransferSize,
+ psInParams->ui32Level);
+ return(IMG_TRUE);
+ }
+ else
+ {
+ /* invalid SID */
+ *pui32BytesCopied = 0;
+ return(IMG_FALSE);
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDrivWrite2
+
+ PURPOSE :
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivWrite2(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ IMG_UINT32 * pui32BytesCopied;
+ PDBG_IN_WRITE psInParams;
+ PDBG_STREAM psStream;
+
+ psInParams = (PDBG_IN_WRITE) pvInBuffer;
+ pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(psInParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32BytesCopied = ExtDBGDrivWrite2(psStream,
+ psInParams->u.pui8InBuffer,
+ psInParams->ui32TransferSize,
+ psInParams->ui32Level);
+ return(IMG_TRUE);
+ }
+ else
+ {
+ /* invalid SID */
+ *pui32BytesCopied = 0;
+ return(IMG_FALSE);
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDrivWriteCM
+
+ PURPOSE : Same as DBGDIOCDrivWrite2, but takes notice of capture mode.
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivWriteCM(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ IMG_UINT32 * pui32BytesCopied;
+ PDBG_IN_WRITE psInParams;
+ PDBG_STREAM psStream;
+
+ psInParams = (PDBG_IN_WRITE) pvInBuffer;
+ pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(psInParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32BytesCopied = ExtDBGDrivWriteCM(psStream,
+ psInParams->u.pui8InBuffer,
+ psInParams->ui32TransferSize,
+ psInParams->ui32Level);
+ return(IMG_TRUE);
+ }
+ else
+ {
+ /* invalid SID */
+ *pui32BytesCopied = 0;
+ return(IMG_FALSE);
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDrivRead
+
+ PURPOSE :
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivRead(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ IMG_UINT32 * pui32BytesCopied;
+ PDBG_IN_READ psInParams;
+ PDBG_STREAM psStream;
+
+ psInParams = (PDBG_IN_READ) pvInBuffer;
+ pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(psInParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32BytesCopied = ExtDBGDrivRead(psStream,
+ psInParams->bReadInitBuffer,
+ psInParams->ui32OutBufferSize,
+ psInParams->u.pui8OutBuffer);
+ return(IMG_TRUE);
+ }
+ else
+ {
+ /* invalid SID */
+ *pui32BytesCopied = 0;
+ return(IMG_FALSE);
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDIOCDrivSetCaptureMode
+
+ PURPOSE :
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivSetCaptureMode(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_SETDEBUGMODE psParams;
+ PDBG_STREAM psStream;
+
+ psParams = (PDBG_IN_SETDEBUGMODE) pvInBuffer;
+ PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+
+ psStream = SID2PStream(psParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ ExtDBGDrivSetCaptureMode(psStream,
+ psParams->ui32Mode,
+ psParams->ui32Start,
+ psParams->ui32End,
+ psParams->ui32SampleRate);
+ return(IMG_TRUE);
+ }
+ else
+ {
+ /* invalid SID */
+ return(IMG_FALSE);
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDIOCDrivSetOutMode
+
+ PURPOSE :
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivSetOutMode(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_SETDEBUGOUTMODE psParams;
+ PDBG_STREAM psStream;
+
+ psParams = (PDBG_IN_SETDEBUGOUTMODE) pvInBuffer;
+ PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+
+ psStream = SID2PStream(psParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ ExtDBGDrivSetOutputMode(psStream,psParams->ui32Mode);
+ return(IMG_TRUE);
+ }
+ else
+ {
+ /* invalid SID */
+ return(IMG_FALSE);
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDIOCDrivSetDebugLevel
+
+ PURPOSE :
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivSetDebugLevel(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_SETDEBUGLEVEL psParams;
+ PDBG_STREAM psStream;
+
+ psParams = (PDBG_IN_SETDEBUGLEVEL) pvInBuffer;
+ PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+
+ psStream = SID2PStream(psParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ ExtDBGDrivSetDebugLevel(psStream,psParams->ui32Level);
+ return(IMG_TRUE);
+ }
+ else
+ {
+ /* invalid SID */
+ return(IMG_FALSE);
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDrivSetFrame
+
+ PURPOSE :
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivSetFrame(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_SETFRAME psParams;
+ PDBG_STREAM psStream;
+
+ psParams = (PDBG_IN_SETFRAME) pvInBuffer;
+ PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+
+ psStream = SID2PStream(psParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ ExtDBGDrivSetFrame(psStream,psParams->ui32Frame);
+ return(IMG_TRUE);
+ }
+ else
+ {
+ /* invalid SID */
+ return(IMG_FALSE);
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDrivGetFrame
+
+ PURPOSE :
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivGetFrame(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_STREAM psStream;
+ IMG_UINT32 *pui32Current;
+
+ pui32Current = (IMG_UINT32 *) pvOutBuffer;
+ psStream = SID2PStream(*(IMG_SID *)pvInBuffer);
+
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32Current = ExtDBGDrivGetFrame(psStream);
+ return(IMG_TRUE);
+ }
+ else
+ {
+ /* invalid SID */
+ *pui32Current = 0;
+ return(IMG_FALSE);
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDIOCDrivIsCaptureFrame
+
+ PURPOSE : Determines if this frame is a capture frame
+
+ PARAMETERS :
+
+ RETURNS : IMG_TRUE if current frame is to be captured
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivIsCaptureFrame(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_ISCAPTUREFRAME psParams;
+ IMG_UINT32 * pui32Current;
+ PDBG_STREAM psStream;
+
+ psParams = (PDBG_IN_ISCAPTUREFRAME) pvInBuffer;
+ pui32Current = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(psParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32Current = ExtDBGDrivIsCaptureFrame(psStream,
+ psParams->bCheckPreviousFrame);
+ return(IMG_TRUE);
+ }
+ else
+ {
+ /* invalid SID */
+ *pui32Current = 0;
+ return(IMG_FALSE);
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDrivOverrideMode
+
+ PURPOSE :
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivOverrideMode(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_OVERRIDEMODE psParams;
+ PDBG_STREAM psStream;
+
+ psParams = (PDBG_IN_OVERRIDEMODE) pvInBuffer;
+ PVR_UNREFERENCED_PARAMETER( pvOutBuffer);
+
+ psStream = SID2PStream(psParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ ExtDBGDrivOverrideMode(psStream,psParams->ui32Mode);
+ return(IMG_TRUE);
+ }
+ else
+ {
+ /* invalid SID */
+ return(IMG_FALSE);
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDrivDefaultMode
+
+ PURPOSE :
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivDefaultMode(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_STREAM psStream;
+
+ PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+
+ psStream = SID2PStream(*(IMG_SID *)pvInBuffer);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ ExtDBGDrivDefaultMode(psStream);
+ return(IMG_TRUE);
+ }
+ else
+ {
+ /* invalid SID */
+ return(IMG_FALSE);
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDIOCDrivSetMarker
+
+ PURPOSE : Sets the marker in the stream to split output files
+
+ PARAMETERS : pvInBuffer, pvOutBuffer
+
+ RETURNS : success
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivSetMarker(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_SETMARKER psParams;
+ PDBG_STREAM psStream;
+
+ psParams = (PDBG_IN_SETMARKER) pvInBuffer;
+ PVR_UNREFERENCED_PARAMETER(pvOutBuffer);
+
+ psStream = SID2PStream(psParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ ExtDBGDrivSetMarker(psStream, psParams->ui32Marker);
+ return(IMG_TRUE);
+ }
+ else
+ {
+ /* invalid SID */
+ return(IMG_FALSE);
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDIOCDrivGetMarker
+
+ PURPOSE : Gets the marker in the stream to split output files
+
+ PARAMETERS : pvInBuffer, pvOutBuffer
+
+ RETURNS : success
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivGetMarker(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_STREAM psStream;
+ IMG_UINT32 *pui32Current;
+
+ pui32Current = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(*(IMG_SID *)pvInBuffer);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32Current = ExtDBGDrivGetMarker(psStream);
+ return(IMG_TRUE);
+ }
+ else
+ {
+ /* invalid SID */
+ *pui32Current = 0;
+ return(IMG_FALSE);
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDrivGetServiceTable
+
+ PURPOSE :
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivGetServiceTable(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ IMG_PVOID * ppvOut;
+
+ PVR_UNREFERENCED_PARAMETER(pvInBuffer);
+ ppvOut = (IMG_PVOID *) pvOutBuffer;
+
+ *ppvOut = DBGDrivGetServiceTable();
+
+ return(IMG_TRUE);
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDIOCDrivWriteLF
+
+ PURPOSE :
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivWriteLF(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ PDBG_IN_WRITE_LF psInParams;
+ IMG_UINT32 *pui32BytesCopied;
+ PDBG_STREAM psStream;
+
+ psInParams = (PDBG_IN_WRITE_LF) pvInBuffer;
+ pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(psInParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32BytesCopied = ExtDBGDrivWriteLF(psStream,
+ psInParams->u.pui8InBuffer,
+ psInParams->ui32BufferSize,
+ psInParams->ui32Level,
+ psInParams->ui32Flags);
+ return(IMG_TRUE);
+ }
+ else
+ {
+ /* invalid SID */
+ return(IMG_FALSE);
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDIOCDrivReadLF
+
+ PURPOSE :
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static IMG_UINT32 DBGDIOCDrivReadLF(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer)
+{
+ IMG_UINT32 * pui32BytesCopied;
+ PDBG_IN_READ psInParams;
+ PDBG_STREAM psStream;
+
+ psInParams = (PDBG_IN_READ) pvInBuffer;
+ pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer;
+
+ psStream = SID2PStream(psInParams->hStream);
+ if (psStream != (PDBG_STREAM)IMG_NULL)
+ {
+ *pui32BytesCopied = ExtDBGDrivReadLF(psStream,
+ psInParams->ui32OutBufferSize,
+ psInParams->u.pui8OutBuffer);
+ return(IMG_TRUE);
+ }
+ else
+ {
+ /* invalid SID */
+ *pui32BytesCopied = 0;
+ return(IMG_FALSE);
+ }
+}
+
+/*****************************************************************************
+ FUNCTION : DBGDIOCDrivWaitForEvent
+
+ PURPOSE :
+
+ PARAMETERS :
+
+ RETURNS :
+*****************************************************************************/
+static 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);
+}
+
+/*
+ VxD DIOC interface jump table.
+*/
+IMG_UINT32 (*g_DBGDrivProc[25])(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
+};
+
+/*****************************************************************************
+ End of file (IOCTL.C)
+*****************************************************************************/
diff --git a/pvr-source/tools/intern/debug/dbgdriv/linux/hostfunc.c b/pvr-source/tools/intern/debug/dbgdriv/linux/hostfunc.c
new file mode 100644
index 0000000..5d5e9ef
--- /dev/null
+++ b/pvr-source/tools/intern/debug/dbgdriv/linux/hostfunc.c
@@ -0,0 +1,395 @@
+/*************************************************************************/ /*!
+@Title Debug driver file
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#include <linux/version.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/slab.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 /* defined(SUPPORT_DBGDRV_EVENT_OBJECTS) */
+
+#include "img_types.h"
+#include "pvr_debug.h"
+
+#include "dbgdrvif.h"
+#include "hostfunc.h"
+#include "dbgdriv.h"
+
+#if defined(MODULE) && defined(DEBUG) && !defined(SUPPORT_DRI_DRM)
+IMG_UINT32 gPVRDebugLevel = (DBGPRIV_FATAL | DBGPRIV_ERROR | DBGPRIV_WARNING);
+
+#define PVR_STRING_TERMINATOR '\0'
+#define PVR_IS_FILE_SEPARATOR(character) ( ((character) == '\\') || ((character) == '/') )
+
+/******************************************************************************/
+
+
+/*!
+******************************************************************************
+
+ @Function PVRSRVDebugPrintf
+
+ @Description To output a debug message to the user
+
+ @Input uDebugLevel: The current debug level
+ @Input pszFile: The source file generating the message
+ @Input uLine: The line of the source file
+ @Input pszFormat: The message format string
+ @Input ...: Zero or more arguments for use by the format string
+
+ @Return none
+******************************************************************************/
+void PVRSRVDebugPrintf (
+ IMG_UINT32 ui32DebugLevel,
+ const IMG_CHAR* pszFileName,
+ IMG_UINT32 ui32Line,
+ const IMG_CHAR* pszFormat,
+ ...
+ )
+{
+ IMG_BOOL bTrace;
+#if !defined(__sh__)
+ IMG_CHAR *pszLeafName;
+
+ pszLeafName = (char *)strrchr (pszFileName, '\\');
+
+ if (pszLeafName)
+ {
+ pszFileName = pszLeafName;
+ }
+#endif /* __sh__ */
+
+ bTrace = (IMG_BOOL)(ui32DebugLevel & DBGPRIV_CALLTRACE) ? IMG_TRUE : IMG_FALSE;
+
+ if (gPVRDebugLevel & ui32DebugLevel)
+ {
+ va_list vaArgs;
+ char szBuffer[256];
+ char *szBufferEnd = szBuffer;
+ char *szBufferLimit = szBuffer + sizeof(szBuffer) - 1;
+
+ /* The Limit - End pointer arithmetic we're doing in snprintf
+ ensures that our buffer remains null terminated from this */
+ *szBufferLimit = '\0';
+
+ snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "PVR_K:");
+ szBufferEnd += strlen(szBufferEnd);
+
+ /* Add in the level of warning */
+ if (bTrace == IMG_FALSE)
+ {
+ switch(ui32DebugLevel)
+ {
+ case DBGPRIV_FATAL:
+ {
+ snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Fatal):");
+ break;
+ }
+ case DBGPRIV_ERROR:
+ {
+ snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Error):");
+ break;
+ }
+ case DBGPRIV_WARNING:
+ {
+ snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Warning):");
+ break;
+ }
+ case DBGPRIV_MESSAGE:
+ {
+ snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Message):");
+ break;
+ }
+ case DBGPRIV_VERBOSE:
+ {
+ snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Verbose):");
+ break;
+ }
+ default:
+ {
+ snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Unknown message level)");
+ break;
+ }
+ }
+ szBufferEnd += strlen(szBufferEnd);
+ }
+ snprintf(szBufferEnd, szBufferLimit - szBufferEnd, " ");
+ szBufferEnd += strlen(szBufferEnd);
+
+ va_start (vaArgs, pszFormat);
+ vsnprintf(szBufferEnd, szBufferLimit - szBufferEnd, pszFormat, vaArgs);
+ va_end (vaArgs);
+ szBufferEnd += strlen(szBufferEnd);
+
+ /*
+ * Metrics and Traces don't need a location
+ */
+ if (bTrace == IMG_FALSE)
+ {
+ snprintf(szBufferEnd, szBufferLimit - szBufferEnd,
+ " [%d, %s]", (int)ui32Line, pszFileName);
+ szBufferEnd += strlen(szBufferEnd);
+ }
+
+ printk(KERN_INFO "%s\r\n", szBuffer);
+ }
+}
+#endif /* defined(DEBUG) && !defined(SUPPORT_DRI_DRM) */
+
+/*!
+******************************************************************************
+
+ @Function HostMemSet
+
+ @Description Function that does the same as the C memset() function
+
+ @Modified *pvDest : pointer to start of buffer to be set
+
+ @Input ui8Value: value to set each byte to
+
+ @Input ui32Size : number of bytes to set
+
+ @Return IMG_VOID
+
+******************************************************************************/
+IMG_VOID HostMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_UINT32 ui32Size)
+{
+ memset(pvDest, (int) ui8Value, (size_t) ui32Size);
+}
+
+/*!
+******************************************************************************
+
+ @Function HostMemCopy
+
+ @Description Function that does the same as the C memscpy() function
+
+ @Input pvDst - pointer to dst
+ @Output pvSrc - pointer to src
+ @Input ui32Size - bytes to copy
+
+ @Return none
+
+******************************************************************************/
+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)
+{
+ /* FIXME: Not yet implemented */
+ return 0;
+}
+
+IMG_VOID * HostPageablePageAlloc(IMG_UINT32 ui32Pages)
+{
+ return (void*)vmalloc(ui32Pages * PAGE_SIZE);/*, GFP_KERNEL);*/
+}
+
+IMG_VOID HostPageablePageFree(IMG_VOID * pvBase)
+{
+ vfree(pvBase);
+}
+
+IMG_VOID * HostNonPageablePageAlloc(IMG_UINT32 ui32Pages)
+{
+ return (void*)vmalloc(ui32Pages * PAGE_SIZE);/*, GFP_KERNEL);*/
+}
+
+IMG_VOID HostNonPageablePageFree(IMG_VOID * pvBase)
+{
+ vfree(pvBase);
+}
+
+IMG_VOID * HostMapKrnBufIntoUser(IMG_VOID * pvKrnAddr, IMG_UINT32 ui32Size, IMG_VOID **ppvMdl)
+{
+ /* FIXME: Not yet implemented */
+ return IMG_NULL;
+}
+
+IMG_VOID HostUnMapKrnBufFromUser(IMG_VOID * pvUserAddr, IMG_VOID * pvMdl, IMG_VOID * pvProcess)
+{
+ /* FIXME: Not yet implemented */
+}
+
+IMG_VOID HostCreateRegDeclStreams(IMG_VOID)
+{
+ /* FIXME: Not yet implemented */
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+typedef struct mutex MUTEX;
+#define INIT_MUTEX(m) mutex_init(m)
+#define DOWN_TRYLOCK(m) (!mutex_trylock(m))
+#define DOWN(m) mutex_lock(m)
+#define UP(m) mutex_unlock(m)
+#else
+typedef struct semaphore MUTEX;
+#define INIT_MUTEX(m) init_MUTEX(m)
+#define DOWN_TRYLOCK(m) down_trylock(m)
+#define DOWN(m) down(m)
+#define UP(m) up(m)
+#endif
+
+IMG_VOID *HostCreateMutex(IMG_VOID)
+{
+ MUTEX *psMutex;
+
+ psMutex = kmalloc(sizeof(*psMutex), GFP_KERNEL);
+ if (psMutex)
+ {
+ INIT_MUTEX(psMutex);
+ }
+
+ return psMutex;
+}
+
+IMG_VOID HostAquireMutex(IMG_VOID * pvMutex)
+{
+ BUG_ON(in_interrupt());
+
+#if defined(PVR_DEBUG_DBGDRV_DETECT_HOST_MUTEX_COLLISIONS)
+ if (DOWN_TRYLOCK((MUTEX *)pvMutex))
+ {
+ printk(KERN_INFO "HostAquireMutex: Waiting for mutex\n");
+ DOWN((MUTEX *)pvMutex);
+ }
+#else
+ DOWN((MUTEX *)pvMutex);
+#endif
+}
+
+IMG_VOID HostReleaseMutex(IMG_VOID * pvMutex)
+{
+ UP((MUTEX *)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:
+ /*
+ * More than one process may be woken up.
+ * Any process that wakes up should consume
+ * all the data from the streams.
+ */
+ wait_event_interruptible_timeout(sStreamDataEvent, iStreamData != 0, EVENT_WAIT_TIMEOUT_JIFFIES);
+ iStreamData = 0;
+ break;
+ default:
+ /*
+ * For unknown events, enter an interruptible sleep.
+ */
+ 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 /* defined(SUPPORT_DBGDRV_EVENT_OBJECTS) */
diff --git a/pvr-source/tools/intern/debug/dbgdriv/linux/main.c b/pvr-source/tools/intern/debug/dbgdriv/linux/main.c
new file mode 100644
index 0000000..c1ca85b
--- /dev/null
+++ b/pvr-source/tools/intern/debug/dbgdriv/linux/main.c
@@ -0,0 +1,355 @@
+/*************************************************************************/ /*!
+@Title Debug driver main file
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#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 <linux/version.h>
+
+#if defined(LDM_PLATFORM) && !defined(SUPPORT_DRI_DRM)
+#include <linux/platform_device.h>
+#endif
+
+#if defined(LDM_PCI) && !defined(SUPPORT_DRI_DRM)
+#include <linux/pci.h>
+#endif
+
+#include <asm/uaccess.h>
+
+#if defined(SUPPORT_DRI_DRM)
+#include "drmP.h"
+#include "drm.h"
+#endif
+
+#include "img_types.h"
+#include "linuxsrv.h"
+#include "dbgdriv_ioctl.h"
+#include "dbgdrvif.h"
+#include "dbgdriv.h"
+#include "hostfunc.h"
+#include "hotkey.h"
+#include "pvr_debug.h"
+#include "pvrmodule.h"
+#include "pvr_uaccess.h"
+
+#if defined(SUPPORT_DRI_DRM)
+
+#include "pvr_drm_shared.h"
+#include "pvr_drm.h"
+
+#else /* defined(SUPPORT_DRI_DRM) */
+
+#define DRVNAME "dbgdrv"
+MODULE_SUPPORTED_DEVICE(DRVNAME);
+
+#if (defined(LDM_PLATFORM) || defined(LDM_PCI)) && !defined(SUPPORT_DRI_DRM)
+static struct class *psDbgDrvClass;
+#endif
+
+static int AssignedMajorNumber = 0;
+
+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,
+};
+
+#endif /* defined(SUPPORT_DRI_DRM) */
+
+IMG_VOID DBGDrvGetServiceTable(DBGKM_SERVICE_TABLE **fn_table)
+{
+ extern DBGKM_SERVICE_TABLE g_sDBGKMServices;
+
+ *fn_table = &g_sDBGKMServices;
+}
+
+#if defined(SUPPORT_DRI_DRM)
+void dbgdrv_cleanup(void)
+#else
+static void __exit dbgdrv_cleanup(void)
+#endif
+{
+#if !defined(SUPPORT_DRI_DRM)
+#if defined(LDM_PLATFORM) || defined(LDM_PCI)
+ device_destroy(psDbgDrvClass, MKDEV(AssignedMajorNumber, 0));
+ class_destroy(psDbgDrvClass);
+#endif
+ unregister_chrdev(AssignedMajorNumber, DRVNAME);
+#endif /* !defined(SUPPORT_DRI_DRM) */
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+ HostDestroyEventObjects();
+#endif
+ HostDestroyMutex(g_pvAPIMutex);
+ return;
+}
+
+#if defined(SUPPORT_DRI_DRM)
+IMG_INT dbgdrv_init(void)
+#else
+static int __init dbgdrv_init(void)
+#endif
+{
+#if (defined(LDM_PLATFORM) || defined(LDM_PCI)) && !defined(SUPPORT_DRI_DRM)
+ struct device *psDev;
+#endif
+
+#if !defined(SUPPORT_DRI_DRM)
+ int err = -EBUSY;
+#endif
+
+ /* Init API mutex */
+ if ((g_pvAPIMutex=HostCreateMutex()) == IMG_NULL)
+ {
+ return -ENOMEM;
+ }
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+ /*
+ * The current implementation of HostCreateEventObjects on Linux
+ * can never fail, so there is no need to check for error.
+ */
+ (void) HostCreateEventObjects();
+#endif
+
+#if !defined(SUPPORT_DRI_DRM)
+ AssignedMajorNumber =
+ register_chrdev(AssignedMajorNumber, DRVNAME, &dbgdrv_fops);
+
+ if (AssignedMajorNumber <= 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR," unable to get major\n"));
+ goto ErrDestroyEventObjects;
+ }
+
+#if defined(LDM_PLATFORM) || defined(LDM_PCI)
+ /*
+ * This code (using GPL symbols) facilitates automatic device
+ * node creation on platforms with udev (or similar).
+ */
+ psDbgDrvClass = class_create(THIS_MODULE, DRVNAME);
+ if (IS_ERR(psDbgDrvClass))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: unable to create class (%ld)",
+ __func__, PTR_ERR(psDbgDrvClass)));
+ goto ErrUnregisterCharDev;
+ }
+
+ psDev = device_create(psDbgDrvClass, NULL, MKDEV(AssignedMajorNumber, 0),
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
+ NULL,
+#endif
+ DRVNAME);
+ if (IS_ERR(psDev))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: unable to create device (%ld)",
+ __func__, PTR_ERR(psDev)));
+ goto ErrDestroyClass;
+ }
+#endif /* defined(LDM_PLATFORM) || defined(LDM_PCI) */
+#endif /* !defined(SUPPORT_DRI_DRM) */
+
+ return 0;
+
+#if !defined(SUPPORT_DRI_DRM)
+ErrDestroyEventObjects:
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+ HostDestroyEventObjects();
+#endif
+#if defined(LDM_PLATFORM) || defined(LDM_PCI)
+ErrUnregisterCharDev:
+ unregister_chrdev(AssignedMajorNumber, DRVNAME);
+ErrDestroyClass:
+ class_destroy(psDbgDrvClass);
+#endif
+ return err;
+#endif /* !defined(SUPPORT_DRI_DRM) */
+}
+
+#if defined(SUPPORT_DRI_DRM)
+int dbgdrv_ioctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile)
+#else
+long dbgdrv_ioctl(struct file *file, unsigned int ioctlCmd, unsigned long arg)
+#endif
+{
+ IOCTL_PACKAGE *pIP = (IOCTL_PACKAGE *) arg;
+ char *buffer, *in, *out;
+ unsigned int cmd;
+
+ 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(pvr_copy_from_user(in, pIP->pInBuffer, pIP->ui32InBufferSize) != 0)
+ {
+ goto init_failed;
+ }
+
+ /* Extra -1 because ioctls start at DEBUG_SERVICE_IOCTL_BASE + 1 */
+ cmd = MAKEIOCTLINDEX(pIP->ui32Cmd) - DEBUG_SERVICE_IOCTL_BASE - 1;
+
+ if(pIP->ui32Cmd == DEBUG_SERVICE_READ)
+ {
+ IMG_UINT32 *pui32BytesCopied = (IMG_UINT32 *)out;
+ DBG_IN_READ *psReadInParams = (DBG_IN_READ *)in;
+ DBG_STREAM *psStream;
+ IMG_CHAR *ui8Tmp;
+
+ ui8Tmp = vmalloc(psReadInParams->ui32OutBufferSize);
+
+ if(!ui8Tmp)
+ {
+ goto init_failed;
+ }
+
+ psStream = SID2PStream(psReadInParams->hStream);
+ if(!psStream)
+ {
+ goto init_failed;
+ }
+
+ *pui32BytesCopied = ExtDBGDrivRead(psStream,
+ psReadInParams->bReadInitBuffer,
+ psReadInParams->ui32OutBufferSize,
+ ui8Tmp);
+
+ if(pvr_copy_to_user(psReadInParams->u.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;
+}
+
+
+/******************************************************************************
+ * Function Name: RemoveHotKey
+ *
+ * Inputs : -
+ * Outputs : -
+ * Returns : -
+ * Globals Used : -
+ *
+ * Description : Removes HotKey callbacks
+ *****************************************************************************/
+IMG_VOID RemoveHotKey (IMG_UINT32 hHotKey)
+{
+ PVR_UNREFERENCED_PARAMETER(hHotKey);
+}
+
+/******************************************************************************
+ * Function Name: DefineHotKey
+ *
+ * Inputs : -
+ * Outputs : -
+ * Returns : -
+ * Globals Used : -
+ *
+ * Description : Removes HotKey callbacks
+ *****************************************************************************/
+IMG_VOID DefineHotKey (IMG_UINT32 ui32ScanCode, IMG_UINT32 ui32ShiftState, PHOTKEYINFO psInfo)
+{
+ PVR_UNREFERENCED_PARAMETER(ui32ScanCode);
+ PVR_UNREFERENCED_PARAMETER(ui32ShiftState);
+ PVR_UNREFERENCED_PARAMETER(psInfo);
+}
+
+EXPORT_SYMBOL(DBGDrvGetServiceTable);
+
+#if !defined(SUPPORT_DRI_DRM)
+subsys_initcall(dbgdrv_init);
+module_exit(dbgdrv_cleanup);
+#endif