##############################################################################
#
-# Copyright (C) 2005 - 2013 by Vivante Corp.
+# Copyright (C) 2005 - 2014 by Vivante Corp.
#
# 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
#
AQROOT := $(srctree)/drivers/mxc/gpu-viv
-AQARCH := $(AQROOT)/arch/XAQ2
-AQVGARCH := $(AQROOT)/arch/GC350
include $(AQROOT)/config
KERNEL_DIR ?= $(TOOL_DIR)/kernel
OS_KERNEL_DIR := hal/os/linux/kernel
-ARCH_KERNEL_DIR := arch/$(notdir $(AQARCH))/hal/kernel
-ARCH_VG_KERNEL_DIR := arch/$(notdir $(AQVGARCH))/hal/kernel
+ARCH_KERNEL_DIR := hal/kernel/arch
+ARCH_VG_KERNEL_DIR := hal/kernel/archvg
HAL_KERNEL_DIR := hal/kernel
+# Check and include platform config.
+ifneq ($(PLATFORM),)
+
+# Get platform config path.
+PLATFORM_CONFIG ?= $(AQROOT)/$(OS_KERNEL_DIR)/platform/$(PLATFORM).config
+
+# Check whether it exists.
+PLATFORM_CONFIG := $(wildcard $(PLATFORM_CONFIG))
+
+# Include it if exists.
+ifneq ($(PLATFORM_CONFIG),)
+include $(PLATFORM_CONFIG)
+endif
+
+endif
+
+MODULE_NAME ?= galcore
+CUSTOMER_ALLOCATOR_OBJS ?=
+ALLOCATOR_ARRAY_H_LOCATION ?= $(OS_KERNEL_DIR)/allocator/default/
+
EXTRA_CFLAGS += -Werror
OBJS := $(OS_KERNEL_DIR)/gc_hal_kernel_device.o \
- $(OS_KERNEL_DIR)/gc_hal_kernel_driver.o \
$(OS_KERNEL_DIR)/gc_hal_kernel_linux.o \
$(OS_KERNEL_DIR)/gc_hal_kernel_math.o \
$(OS_KERNEL_DIR)/gc_hal_kernel_os.o \
- $(OS_KERNEL_DIR)/gc_hal_kernel_debugfs.o
+ $(OS_KERNEL_DIR)/gc_hal_kernel_debugfs.o \
+ $(OS_KERNEL_DIR)/gc_hal_kernel_allocator.o \
+
+ifneq ($(CONFIG_IOMMU_SUPPORT),)
+OBJS += $(OS_KERNEL_DIR)/gc_hal_kernel_iommu.o
+endif
+
+ifneq ($(PLATFORM),)
+OBJS += $(OS_KERNEL_DIR)/gc_hal_kernel_probe.o
+OBJS += $(OS_KERNEL_DIR)/platform/$(PLATFORM).o
+else
+OBJS += $(OS_KERNEL_DIR)/gc_hal_kernel_driver.o
+endif
OBJS += $(HAL_KERNEL_DIR)/gc_hal_kernel.o \
$(HAL_KERNEL_DIR)/gc_hal_kernel_command.o \
OBJS += $(ARCH_KERNEL_DIR)/gc_hal_kernel_context.o \
$(ARCH_KERNEL_DIR)/gc_hal_kernel_hardware.o
+ifeq ($(VIVANTE_ENABLE_3D), 1)
+OBJS += $(ARCH_KERNEL_DIR)/gc_hal_kernel_recorder.o
+endif
+
ifeq ($(VIVANTE_ENABLE_VG), 1)
OBJS +=\
$(HAL_KERNEL_DIR)/gc_hal_kernel_vg.o\
endif
ifneq ($(CONFIG_SYNC),)
+EXTRA_CFLAGS += -Idrivers/staging/android
+
OBJS += $(OS_KERNEL_DIR)/gc_hal_kernel_sync.o
endif
+ifeq ($(SECURITY), 1)
+OBJS += $(OS_KERNEL_DIR)/gc_hal_kernel_security_channel.o \
+ $(HAL_KERNEL_DIR)/gc_hal_kernel_security.o
+endif
+
+ifneq ($(CUSTOMER_ALLOCATOR_OBJS),)
+OBJS += $(CUSTOMER_ALLOCATOR_OBJS)
+endif
+
ifeq ($(KERNELRELEASE), )
.PHONY: all clean install
EXTRA_CFLAGS += -DLINUX -DDRIVER
-ifeq ($(ENUM_WORKAROUND), 1)
-EXTRA_CFLAGS += -DENUM_WORKAROUND=1
-else
-EXTRA_CFLAGS += -DENUM_WORKAROUND=0
-endif
-
ifeq ($(FLAREON),1)
EXTRA_CFLAGS += -DFLAREON
endif
EXTRA_CFLAGS += -DUSE_PLATFORM_DRIVER=0
endif
-
EXTRA_CFLAGS += -DVIVANTE_PROFILER=1
EXTRA_CFLAGS += -DVIVANTE_PROFILER_CONTEXT=1
-
-ifeq ($(ANDROID), 1)
-EXTRA_CFLAGS += -DANDROID=1
-endif
-
ifeq ($(ENABLE_GPU_CLOCK_BY_DRIVER), 1)
EXTRA_CFLAGS += -DENABLE_GPU_CLOCK_BY_DRIVER=1
else
EXTRA_CFLAGS += -DUSE_NEW_LINUX_SIGNAL=0
endif
-ifeq ($(NO_USER_DIRECT_ACCESS_FROM_KERNEL), 1)
-EXTRA_CFLAGS += -DNO_USER_DIRECT_ACCESS_FROM_KERNEL=1
-else
-EXTRA_CFLAGS += -DNO_USER_DIRECT_ACCESS_FROM_KERNEL=0
-endif
-
ifeq ($(FORCE_ALL_VIDEO_MEMORY_CACHED), 1)
EXTRA_CFLAGS += -DgcdPAGED_MEMORY_CACHEABLE=1
else
EXTRA_CFLAGS += -DgcdCACHE_FUNCTION_UNIMPLEMENTED=0
endif
-ifeq ($(SUPPORT_SWAP_RECTANGLE), 1)
-EXTRA_CFLAGS += -DgcdSUPPORT_SWAP_RECTANGLE=1
+ifeq ($(CONFIG_SMP), y)
+EXTRA_CFLAGS += -DgcdSMP=1
else
-EXTRA_CFLAGS += -DgcdSUPPORT_SWAP_RECTANGLE=0
+EXTRA_CFLAGS += -DgcdSMP=0
endif
-ifeq ($(VIVANTE_ENABLE_VG), 1)
-EXTRA_CFLAGS += -DgcdENABLE_VG=1
+ifeq ($(VIVANTE_ENABLE_3D),0)
+EXTRA_CFLAGS += -DgcdENABLE_3D=0
else
-EXTRA_CFLAGS += -DgcdENABLE_VG=0
+EXTRA_CFLAGS += -DgcdENABLE_3D=1
endif
-ifeq ($(CONFIG_SMP), y)
-EXTRA_CFLAGS += -DgcdSMP=1
+ifeq ($(VIVANTE_ENABLE_2D),0)
+EXTRA_CFLAGS += -DgcdENABLE_2D=0
else
-EXTRA_CFLAGS += -DgcdSMP=0
+EXTRA_CFLAGS += -DgcdENABLE_2D=1
endif
-ifeq ($(VIVANTE_NO_3D),1)
-EXTRA_CFLAGS += -DVIVANTE_NO_3D
+ifeq ($(VIVANTE_ENABLE_VG),0)
+EXTRA_CFLAGS += -DgcdENABLE_VG=0
+else
+EXTRA_CFLAGS += -DgcdENABLE_VG=1
endif
ifeq ($(ENABLE_OUTER_CACHE_PATCH), 1)
endif
endif
-ifneq ($(CONFIG_SYNC),)
-EXTRA_CFLAGS += -DgcdANDROID_NATIVE_FENCE_SYNC=1
+ifeq ($(gcdFPGA_BUILD), 1)
+EXTRA_CFLAGS += -DgcdFPGA_BUILD=1
+else
+EXTRA_CFLAGS += -DgcdFPGA_BUILD=0
+endif
+
+ifeq ($(SECURITY), 1)
+EXTRA_CFLAGS += -DgcdSECURITY=1
endif
EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel/inc
EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel
-EXTRA_CFLAGS += -I$(AQARCH)/hal/kernel
+EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel/arch
+EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel/inc
EXTRA_CFLAGS += -I$(AQROOT)/hal/os/linux/kernel
+EXTRA_CFLAGS += -I$(AQROOT)/$(ALLOCATOR_ARRAY_H_LOCATION)
ifeq ($(VIVANTE_ENABLE_VG), 1)
-EXTRA_CFLAGS += -I$(AQVGARCH)/hal/kernel
+EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel/archvg
endif
obj-$(CONFIG_MXC_GPU_VIV) += galcore.o
##############################################################################
#
-# Copyright (C) 2005 - 2013 by Vivante Corp.
+# Copyright (C) 2005 - 2014 by Vivante Corp.
#
# 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
ARCH_TYPE ?= arm
SDK_DIR ?= $(AQROOT)/build/sdk
-USE_3D_VG ?= 1
+VIVANTE_ENABLE_3D ?= 1
+VIVANTE_ENABLE_2D ?= 1
+VIVANTE_ENABLE_VG ?= 1
FORCE_ALL_VIDEO_MEMORY_CACHED ?= 0
NONPAGED_MEMORY_CACHEABLE ?= 0
NONPAGED_MEMORY_BUFFERABLE ?= 1
CACHE_FUNCTION_UNIMPLEMENTED ?= 0
-VIVANTE_ENABLE_VG ?= 1
-NO_USER_DIRECT_ACCESS_FROM_KERNEL ?= 1
-VIVANTE_NO_3D ?= 0
ENABLE_OUTER_CACHE_PATCH ?= 1
USE_BANK_ALIGNMENT ?= 1
BANK_BIT_START ?= 13
BANK_BIT_END ?= 15
BANK_CHANNEL_BIT ?= 12
-ENABLE_GPU_CLOCK_BY_DRIVER = 1
-
+PLATFORM ?= freescale/gc_hal_kernel_platform_imx6q14
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
gcvFALSE, gcvTRUE \
)
+#define _STATE_COUNT_OFFSET_HINT(reg, offset, count) \
+ _State(\
+ Context, index, \
+ (reg ## _Address >> 2) + offset, \
+ reg ## _ResetValue, \
+ count, \
+ gcvFALSE, gcvTRUE \
+ )
+
#define _STATE_X(reg) \
_State(\
Context, index, \
gcvTRUE, gcvFALSE \
)
+#define _STATE_INIT_VALUE(reg, value) \
+ _State(\
+ Context, index, \
+ reg ## _Address >> 2, \
+ value, \
+ reg ## _Count, \
+ gcvFALSE, gcvFALSE \
+ )
+
#define _CLOSE_RANGE() \
_TerminateStateBlock(Context, index)
#define gcdSTATE_MASK \
(((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x03 | 0xC0FFEE & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))))
-#if !defined(VIVANTE_NO_3D)
-static gctSIZE_T
+#if gcdENABLE_3D
+static gctUINT32
_TerminateStateBlock(
IN gckCONTEXT Context,
- IN gctSIZE_T Index
+ IN gctUINT32 Index
)
{
gctUINT32_PTR buffer;
- gctSIZE_T align;
+ gctUINT32 align;
/* Determine if we need alignment. */
align = (Index & 1) ? 1 : 0;
#endif
-static gctSIZE_T
+#if (gcdENABLE_3D || gcdENABLE_2D)
+static gctUINT32
_FlushPipe(
IN gckCONTEXT Context,
- IN gctSIZE_T Index,
+ IN gctUINT32 Index,
IN gcePIPE_SELECT Pipe
)
{
+ gctBOOL fcFlushStall;
+ gctUINT32 flushSlots;
+ gctBOOL iCacheInvalidate;
+
+ fcFlushStall
+ = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_FC_FLUSH_STALL);
+
+ iCacheInvalidate
+ = ((((gctUINT32) (Context->hardware->identity.chipMinorFeatures3)) >> (0 ? 3:3) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))));
+
+ flushSlots = 6;
+
+ if (fcFlushStall)
+ {
+ /* Flush tile status cache. */
+ flushSlots += 6;
+ }
+
+ if (iCacheInvalidate)
+ {
+ flushSlots += 12;
+ }
+
if (Context->buffer != gcvNULL)
{
gctUINT32_PTR buffer;
: ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
/* Semaphore from FE to PE. */
*buffer++
*buffer++
= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
- *buffer
+ *buffer++
= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ if (fcFlushStall)
+ {
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0594) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ /* Semaphore from FE to PE. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* Stall from FE to PE. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+ }
+
+ if (iCacheInvalidate)
+ {
+ /* Invalidate I$ after pipe is stalled */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0218) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x021A) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0218) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x021A) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
+
+ /* Semaphore from FE to PE. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* Stall from FE to PE. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+ }
}
- /* Flushing 3D pipe takes 6 slots. */
- return 6;
+ /* Number of slots taken by flushing pipe. */
+ return flushSlots;
}
+#endif
-#if !defined(VIVANTE_NO_3D)
-static gctSIZE_T
+#if gcdENABLE_3D
+static gctUINT32
_SemaphoreStall(
IN gckCONTEXT Context,
- IN gctSIZE_T Index
+ IN gctUINT32 Index
)
{
if (Context->buffer != gcvNULL)
}
#endif
-static gctSIZE_T
+#if (gcdENABLE_3D || gcdENABLE_2D)
+static gctUINT32
_SwitchPipe(
IN gckCONTEXT Context,
- IN gctSIZE_T Index,
+ IN gctUINT32 Index,
IN gcePIPE_SELECT Pipe
)
{
+ gctUINT32 slots = 6;
+
if (Context->buffer != gcvNULL)
{
gctUINT32_PTR buffer;
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
- *buffer
+ *buffer++
= (Pipe == gcvPIPE_2D)
? 0x1
: 0x0;
+
+ /* Semaphore from FE to PE. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* Stall from FE to PE. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
}
- return 2;
+ Context->pipeSelectBytes = slots * gcmSIZEOF(gctUINT32);
+
+ return slots;
}
+#endif
-#if !defined(VIVANTE_NO_3D)
-static gctSIZE_T
+#if gcdENABLE_3D
+static gctUINT32
_State(
IN gckCONTEXT Context,
- IN gctSIZE_T Index,
+ IN gctUINT32 Index,
IN gctUINT32 Address,
IN gctUINT32 Value,
- IN gctSIZE_T Size,
+ IN gctUINT32 Size,
IN gctBOOL FixedPoint,
IN gctBOOL Hinted
)
{
gctUINT32_PTR buffer;
- gctSIZE_T align, i;
+ gctUINT32 align;
+ gctUINT32 i;
/* Determine if we need alignment. */
align = (Index & 1) ? 1 : 0;
}
/* Walk all the states. */
- for (i = 0; i < Size; i += 1)
+ for (i = 0; i < (gctUINT32)Size; i += 1)
{
/* Set state to uninitialized value. */
buffer[Index + 1 + i] = Value;
/* Set index in state mapping table. */
- Context->map[Address + i].index = Index + 1 + i;
+ Context->map[Address + i].index = (gctUINT)Index + 1 + i;
#if gcdSECURE_USER
/* Save hint. */
}
/* Save information for this LoadState. */
- Context->lastIndex = Index;
- Context->lastAddress = Address + Size;
+ Context->lastIndex = (gctUINT)Index;
+ Context->lastAddress = Address + (gctUINT32)Size;
Context->lastSize = Size;
Context->lastFixed = FixedPoint;
((((gctUINT32) (buffer[Context->lastIndex])) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (Context->lastSize + Size) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
/* Walk all the states. */
- for (i = 0; i < Size; i += 1)
+ for (i = 0; i < (gctUINT32)Size; i += 1)
{
/* Set state to uninitialized value. */
buffer[Index + i] = Value;
/* Set index in state mapping table. */
- Context->map[Address + i].index = Index + i;
+ Context->map[Address + i].index = (gctUINT)Index + i;
#if gcdSECURE_USER
/* Save hint. */
}
/* Update last address and size. */
- Context->lastAddress += Size;
+ Context->lastAddress += (gctUINT32)Size;
Context->lastSize += Size;
/* Return number of slots required. */
return Size;
}
-static gctSIZE_T
+static gctUINT32
_StateMirror(
IN gckCONTEXT Context,
IN gctUINT32 Address,
- IN gctSIZE_T Size,
+ IN gctUINT32 Size,
IN gctUINT32 AddressMirror
)
{
- gctSIZE_T i;
+ gctUINT32 i;
/* Process when buffer is set. */
if (Context->buffer != gcvNULL)
}
#endif
+#if (gcdENABLE_3D || gcdENABLE_2D)
static gceSTATUS
_InitializeContextBuffer(
IN gckCONTEXT Context
)
{
gctUINT32_PTR buffer;
- gctSIZE_T index;
+ gctUINT32 index;
-#if !defined(VIVANTE_NO_3D)
+#if gcdENABLE_3D
+ gctBOOL halti0, halti1, halti2, halti3;
gctUINT i;
- gctUINT vertexUniforms, fragmentUniforms;
+ gctUINT vertexUniforms, fragmentUniforms, vsConstBase, psConstBase, constMax;
+ gctBOOL unifiedUniform;
gctUINT fe2vsCount;
- gctBOOL halti0;
#endif
/* Reset the buffer index. */
/* Build 2D states. *******************************************************/
-#if !defined(VIVANTE_NO_3D)
+#if gcdENABLE_3D
/**************************************************************************/
/* Build 3D states. *******************************************************/
+
halti0 = (((((gctUINT32) (Context->hardware->identity.chipMinorFeatures1)) >> (0 ? 23:23)) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1)))))) );
+ halti1 = (((((gctUINT32) (Context->hardware->identity.chipMinorFeatures2)) >> (0 ? 11:11)) & ((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1)))))) );
+ halti2 = (((((gctUINT32) (Context->hardware->identity.chipMinorFeatures4)) >> (0 ? 16:16)) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) );
+ halti3 = (((((gctUINT32) (Context->hardware->identity.chipMinorFeatures5)) >> (0 ? 9:9)) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) );
- /* Query shader support. */
- gcmkVERIFY_OK(gckHARDWARE_QueryShaderCaps(
- Context->hardware, &vertexUniforms, &fragmentUniforms, gcvNULL));
+ /* Query how many uniforms can support for non-unified uniform mode. */
+ {if (Context->hardware->identity.numConstants > 256){ unifiedUniform = gcvTRUE; vsConstBase = 0xC000; psConstBase = 0xC000; constMax = Context->hardware->identity.numConstants; vertexUniforms = 256; fragmentUniforms = constMax - vertexUniforms;}else if (Context->hardware->identity.numConstants == 256){ if (Context->hardware->identity.chipModel == gcv2000 && Context->hardware->identity.chipRevision == 0x5118) { unifiedUniform = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vertexUniforms = 256; fragmentUniforms = 64; constMax = 320; } else { unifiedUniform = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vertexUniforms = 256; fragmentUniforms = 256; constMax = 512; }}else{ unifiedUniform = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vertexUniforms = 168; fragmentUniforms = 64; constMax = 232;}};
- /* Store the 3D entry index. */
- Context->entryOffset3D = index * gcmSIZEOF(gctUINT32);
+#if !gcdENABLE_UNIFIED_CONSTANT
+ if (Context->hardware->identity.numConstants > 256)
+ {
+ unifiedUniform = gcvTRUE;
+ }
+ else
+ {
+ unifiedUniform = gcvFALSE;
+ }
+#endif
- /* Flush 2D pipe. */
- index += _FlushPipe(Context, index, gcvPIPE_2D);
+ /* Store the 3D entry index. */
+ Context->entryOffset3D = (gctUINT)index * gcmSIZEOF(gctUINT32);
/* Switch to 3D pipe. */
index += _SwitchPipe(Context, index, gcvPIPE_3D);
index += _State(Context, index, 0x0382C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x03834 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x03838 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x03854 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x0384C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
/* Front End states. */
- fe2vsCount = 12;
- if ((((((gctUINT32) (Context->hardware->identity.chipMinorFeatures1)) >> (0 ? 23:23)) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1)))))) ))
- {
- fe2vsCount = 16;
- }
+ fe2vsCount = 12;
+ if (halti0)
+ {
+ fe2vsCount = 16;
+ }
index += _State(Context, index, 0x00600 >> 2, 0x00000000, fe2vsCount, gcvFALSE, gcvFALSE);
index += _CLOSE_RANGE();
index += _State(Context, index, 0x00650 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00680 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE);
index += _State(Context, index, 0x006A0 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00674 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00670 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00678 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x0067C >> 2, 0xFFFFFFFF, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00740 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00780 >> 2, 0x3F800000, 16, gcvFALSE, gcvFALSE);
+ if (halti2)
+ {
+ index += _State(Context, index, 0x14600 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14640 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14680 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
+ }
+
+ /* This register is programed by all chips, which program all DECODE_SELECT as VS
+ ** except SAMPLER_DECODE_SELECT.
+ */
+ index += _State(Context, index, 0x00860 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ if (((((gctUINT32) (Context->hardware->identity.chipMinorFeatures3)) >> (0 ? 3:3) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))))
+ {
+ /* I-Cache states. */
+ index += _State(Context, index, 0x00868 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0086C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0304C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01028 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+
+ if (halti3)
+ {
+ index += _State(Context, index, 0x00890 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x0104C >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _CLOSE_RANGE();
+ }
+ }
+
/* Vertex Shader states. */
- index += _State(Context, index, 0x00800 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00804 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00808 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x0080C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00810 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00820 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00830 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
- index += _State(Context, index, 0x00838 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
- if (Context->hardware->identity.instructionCount <= 256)
- {
- index += _State(Context, index, 0x04000 >> 2, 0x00000000, 1024, gcvFALSE, gcvFALSE);
- }
index += _CLOSE_RANGE();
- index += _State(Context, index, 0x05000 >> 2, 0x00000000, vertexUniforms * 4, gcvFALSE, gcvFALSE);
/* Primitive Assembly states. */
index += _State(Context, index, 0x00A00 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
index += _State(Context, index, 0x00A28 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00A2C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00A30 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
- index += _State(Context, index, 0x00A40 >> 2, 0x00000000, 10, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A40 >> 2, 0x00000000, Context->hardware->identity.varyingsCount, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00A34 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00A38 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00A3C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00A80 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00A84 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
index += _State(Context, index, 0x00A8C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A88 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+#if gcdMULTI_GPU
+ index += _State(Context, index, 0x03A00 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x03A04 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x03A08 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+#endif
/* Setup states. */
index += _State(Context, index, 0x00C00 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
index += _State(Context, index, 0x00C04 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
index += _State(Context, index, 0x00E04 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00E40 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00E08 >> 2, 0x00000031, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00E24 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00E20 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ if (halti2)
+ {
+ index += _State(Context, index, 0x00E0C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ }
/* Pixel Shader states. */
- index += _State(Context, index, 0x01000 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x01004 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x01008 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x0100C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x01010 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
- index += _State(Context, index, 0x01018 >> 2, 0x01000000, 1, gcvFALSE, gcvFALSE);
- if (Context->hardware->identity.instructionCount <= 256)
- {
- index += _State(Context, index, 0x06000 >> 2, 0x00000000, 1024, gcvFALSE, gcvFALSE);
- }
+ index += _State(Context, index, 0x01030 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _CLOSE_RANGE();
- index += _State(Context, index, 0x07000 >> 2, 0x00000000, fragmentUniforms * 4, gcvFALSE, gcvFALSE);
/* Texture states. */
index += _State(Context, index, 0x02000 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
index += _State(Context, index, (0x02740 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
index += _CLOSE_RANGE();
- if ((((((gctUINT32) (Context->hardware->identity.chipMinorFeatures2)) >> (0 ? 11:11)) & ((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1)))))) ))
+ if ((((((gctUINT32) (Context->hardware->identity.chipMinorFeatures1)) >> (0 ? 22:22)) & ((gctUINT32) ((((1 ? 22:22) - (0 ? 22:22) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 22:22) - (0 ? 22:22) + 1)))))) ))
+ {
+ /*
+ * Linear stride LODn will overwrite LOD0 on GC880,GC2000.
+ * And only LOD0 is valid for this register.
+ */
+ gctUINT count = halti1 ? 14 : 1;
+
+ for (i = 0; i < 12; i += 1)
+ {
+ index += _State(Context, index, (0x02C00 >> 2) + i * 16, 0x00000000, count, gcvFALSE, gcvFALSE);
+ }
+ }
+
+ if (halti1)
{
gctUINT texBlockCount;
+ gctUINT gcregTXLogSizeResetValue;
+
+ /* Enable the integer filter pipe for all texture samplers
+ so that the floating point filter clock will shut off until
+ we start using the floating point filter.
+ */
+ gcregTXLogSizeResetValue = ((((gctUINT32) (0x00000000)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 29:29) - (0 ? 29:29) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 29:29) - (0 ? 29:29) + 1))))))) << (0 ? 29:29))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 29:29) - (0 ? 29:29) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 29:29) - (0 ? 29:29) + 1))))))) << (0 ? 29:29)));
/* New texture block. */
index += _State(Context, index, 0x10000 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x10080 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
- index += _State(Context, index, 0x10100 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10100 >> 2, gcregTXLogSizeResetValue, 32, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x10180 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x10200 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x10280 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
- for (i = 0; i < 256 / 16; i += 1)
- {
- index += _State(Context, index, (0x02C00 >> 2) + i * 16, 0x00000000, 14, gcvFALSE, gcvFALSE);
- }
index += _State(Context, index, 0x10300 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x10380 >> 2, 0x00321000, 32, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x10400 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x12400 >> 2, 0x00000000, 256, gcvFALSE, gcvFALSE);
}
- if ((Context->hardware->identity.chipModel == gcv2000)
- && (Context->hardware->identity.chipRevision == 0x5108))
- {
- texBlockCount = 12;
- }
- else
- {
- texBlockCount = ((512) >> (4));
- }
+ texBlockCount = ((512) >> (4));
+
for (i = 0; i < texBlockCount; i += 1)
{
index += _State(Context, index, (0x10800 >> 2) + (i << 4), 0x00000000, 14, gcvFALSE, gcvTRUE);
}
}
+ if (halti2)
+ {
+ index += _State(Context, index, 0x10700 >> 2, 0x00000F00, 32, gcvFALSE, gcvFALSE);
+ }
+
+ if (halti3)
+ {
+ index += _State(Context, index, 0x10780 >> 2, 0x00030000, 32, gcvFALSE, gcvFALSE);
+ }
+
+ /* ASTC */
+ if ((((((gctUINT32) (Context->hardware->identity.chipMinorFeatures4)) >> (0 ? 13:13)) & ((gctUINT32) ((((1 ? 13:13) - (0 ? 13:13) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:13) - (0 ? 13:13) + 1)))))) ))
+ {
+ index += _State(Context, index, 0x10500 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10580 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10600 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10680 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ }
+
/* YUV. */
index += _State(Context, index, 0x01678 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x0167C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00918 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x0091C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x00924 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ if (((((gctUINT32) (Context->hardware->identity.chipMinorFeatures3)) >> (0 ? 21:21) & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))))
+ {
+ index += _State(Context, index, 0x00940 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00944 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00948 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0094C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00950 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00954 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ }
+
index += _CLOSE_RANGE();
- if (Context->hardware->identity.instructionCount > 1024)
- {
- /* New Shader instruction memory. */
- index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
- index += _State(Context, index, 0x0101C >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE);
- index += _State(Context, index, 0x00860 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
- index += _CLOSE_RANGE();
-
- for (i = 0;
- i < Context->hardware->identity.instructionCount << 2;
- i += 256 << 2
- )
- {
- index += _State(Context, index, (0x20000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE);
- index += _CLOSE_RANGE();
- }
- }
- else if (Context->hardware->identity.instructionCount > 256)
- {
- /* New Shader instruction memory. */
- index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
- index += _State(Context, index, 0x0101C >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE);
- index += _CLOSE_RANGE();
-
- /* VX instruction memory. */
- for (i = 0;
- i < Context->hardware->identity.instructionCount << 2;
- i += 256 << 2
- )
- {
- index += _State(Context, index, (0x0C000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE);
- index += _CLOSE_RANGE();
- }
-
- _StateMirror(Context, 0x08000 >> 2, Context->hardware->identity.instructionCount << 2 , 0x0C000 >> 2);
- }
+ if (!halti3)
+ {
+ if (Context->hardware->identity.instructionCount > 1024)
+ {
+ /* New Shader instruction PC registers. */
+ index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0101C >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+
+ for (i = 0;
+ i < Context->hardware->identity.instructionCount << 2;
+ i += 256 << 2
+ )
+ {
+ index += _State(Context, index, (0x20000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ }
+ }
+ else if (Context->hardware->identity.instructionCount > 256)
+ {
+ /* New Shader instruction PC registers. */
+ index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0101C >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+
+ /* VX instruction memory. */
+ for (i = 0;
+ i < Context->hardware->identity.instructionCount << 2;
+ i += 256 << 2
+ )
+ {
+ index += _State(Context, index, (0x0C000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ }
+
+ _StateMirror(Context, 0x08000 >> 2, Context->hardware->identity.instructionCount << 2 , 0x0C000 >> 2);
+ }
+ else /* if (Context->hardware->identity.instructionCount <= 256) */
+ {
+ /* old shader instruction PC registers */
+ index += _State(Context, index, 0x00800 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00838 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+
+ index += _State(Context, index, 0x01000 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01018 >> 2, 0x01000000, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+
+ index += _State(Context, index, 0x04000 >> 2, 0x00000000, 1024, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ index += _State(Context, index, 0x06000 >> 2, 0x00000000, 1024, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ }
+ }
+ /* I cache use the new instruction PC registers */
+ else
+ {
+ /* New Shader instruction PC registers. */
+ index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0101C >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ }
+
+ if (unifiedUniform)
+ {
+ gctINT numConstants = Context->hardware->identity.numConstants;
+
+ index += _State(Context, index, 0x01024 >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00864 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+
+ for (i = 0;
+ numConstants > 0;
+ i += 256 << 2,
+ numConstants -= 256
+ )
+ {
+ if (numConstants >= 256)
+ {
+ index += _State(Context, index, (0x30000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE);
+ }
+ else
+ {
+ index += _State(Context, index, (0x30000 >> 2) + i, 0x00000000, numConstants << 2, gcvFALSE, gcvFALSE);
+ }
+ index += _CLOSE_RANGE();
+ }
+ }
+#if gcdENABLE_UNIFIED_CONSTANT
+ else
+#endif
+ {
+ index += _State(Context, index, 0x05000 >> 2, 0x00000000, vertexUniforms * 4, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x07000 >> 2, 0x00000000, fragmentUniforms * 4, gcvFALSE, gcvFALSE);
+ }
/* Store the index of the "XD" entry. */
- Context->entryOffsetXDFrom3D = index * gcmSIZEOF(gctUINT32);
+ Context->entryOffsetXDFrom3D = (gctUINT)index * gcmSIZEOF(gctUINT32);
/* Pixel Engine states. */
else
{
index += _State(Context, index, (0x01460 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
+ }
+
+ if (Context->hardware->identity.pixelPipes > 1 || halti0)
+ {
+ index += _State(Context, index, (0x01480 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
+ }
+
+ for (i = 0; i < 3; i++)
+ {
+ index += _State(Context, index, (0x01500 >> 2) + (i << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
+ }
- for (i = 0; i < 2; i++)
+ if (halti2)
+ {
+ for (i = 0; i < 7; i++)
{
- index += _State(Context, index, (0x01500 >> 2) + (i << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x14800 >> 2) + (i << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
}
+ index += _State(Context, index, 0x14900 >> 2, 0x00000000, 7, gcvFALSE, gcvFALSE);
}
- if (Context->hardware->identity.pixelPipes > 1 || halti0)
+
+ if (halti3)
{
- index += _State(Context, index, (0x01480 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x014BC >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
}
/* Resolve states. */
index += _State(Context, index, 0x016B4 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _CLOSE_RANGE();
- if (Context->hardware->identity.pixelPipes > 1)
+ if ((Context->hardware->identity.pixelPipes > 1) || halti1)
{
index += _State(Context, index, (0x016C0 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
index += _State(Context, index, 0x01700 >> 2, 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvFALSE);
}
+#if gcd3DBLIT
+ index += _State(Context, index, (0x14000 >> 2) + (0 << 1), 0x00000000, 2, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x14008 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x1400C >> 2, 0x0001C800, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14010 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x14014 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, (0x14018 >> 2) + (0 << 1), 0x00000000, 2, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x14020 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x14024 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14028 >> 2, 0x0001C800, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x1402C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14030 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14034 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14038 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x1403C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14040 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14044 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14048 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x1404C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14050 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14058 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x1405C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14054 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14100 >> 2, 0x00000000, 64, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14200 >> 2, 0x00000000, 64, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14064 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14068 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ index += _State(Context, index, 0x1406C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14070 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14074 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14078 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x1407C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14080 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14084 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14088 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x1408C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14090 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ index += _State(Context, index, 0x14094 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x14098 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+#endif
+
/* Tile status. */
index += _State(Context, index, 0x01654 >> 2, 0x00200000, 1, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x01720 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x01740 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE);
index += _State(Context, index, 0x01760 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
+
+
+ if (halti2)
+ {
+ index += _State(Context, index, 0x01780 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x016BC >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, (0x017A0 >> 2) + 1, 0x00000000, 7, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, (0x017C0 >> 2) + 1, 0x00000000, 7, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x017E0 >> 2) + 1, 0x00000000, 7, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x01A00 >> 2) + 1, 0x00000000, 7, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, (0x01A20 >> 2) + 1, 0x00000000, 7, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, (0x01A40 >> 2) + 1, 0x00000000, 7, gcvFALSE, gcvFALSE);
+ }
+
index += _CLOSE_RANGE();
+ if(((((gctUINT32) (Context->hardware->identity.chipMinorFeatures4)) >> (0 ? 25:25) & ((gctUINT32) ((((1 ? 25:25) - (0 ? 25:25) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:25) - (0 ? 25:25) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 25:25) - (0 ? 25:25) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:25) - (0 ? 25:25) + 1))))))))
+ {
+ index += _State(Context, index, 0x03860 >> 2, 0x6, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ }
+
+ if (halti3)
+ {
+ index += _State(Context, index, 0x01A80 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE);
+ index += _CLOSE_RANGE();
+ }
+
/* Semaphore/stall. */
index += _SemaphoreStall(Context, index);
#endif
/**************************************************************************/
/* Link to another address. ***********************************************/
- Context->linkIndex3D = index;
+ Context->linkIndex3D = (gctUINT)index;
if (buffer != gcvNULL)
{
/* Pipe switch for the case where neither 2D nor 3D are used. *************/
/* Store the 3D entry index. */
- Context->entryOffsetXDFrom2D = index * gcmSIZEOF(gctUINT32);
+ Context->entryOffsetXDFrom2D = (gctUINT)index * gcmSIZEOF(gctUINT32);
/* Flush 2D pipe. */
index += _FlushPipe(Context, index, gcvPIPE_2D);
index += _SwitchPipe(Context, index, gcvPIPE_3D);
/* Store the location of the link. */
- Context->linkIndexXD = index;
+ Context->linkIndexXD = (gctUINT)index;
if (buffer != gcvNULL)
{
/* Success. */
return gcvSTATUS_OK;
}
+#endif
static gceSTATUS
_DestroyContext(
/* Free state delta map. */
if (buffer->logical != gcvNULL)
{
-#if gcdVIRTUAL_COMMAND_BUFFER
- gcmkONERROR(gckEVENT_DestroyVirtualCommandBuffer(
- Context->hardware->kernel->eventObj,
- Context->totalSize,
- buffer->physical,
- buffer->logical,
- gcvKERNEL_PIXEL
- ));
-
-#else
- gcmkONERROR(gckEVENT_FreeContiguousMemory(
- Context->hardware->kernel->eventObj,
- Context->totalSize,
- buffer->physical,
- buffer->logical,
- gcvKERNEL_PIXEL
- ));
-#endif
+ if (Context->hardware->kernel->virtualCommandBuffer)
+ {
+ gcmkONERROR(gckEVENT_DestroyVirtualCommandBuffer(
+ Context->hardware->kernel->eventObj,
+ Context->totalSize,
+ buffer->physical,
+ buffer->logical,
+ gcvKERNEL_PIXEL
+ ));
+ }
+ else
+ {
+ gcmkONERROR(gckEVENT_FreeContiguousMemory(
+ Context->hardware->kernel->eventObj,
+ Context->totalSize,
+ buffer->physical,
+ buffer->logical,
+ gcvKERNEL_PIXEL
+ ));
+ }
buffer->logical = gcvNULL;
}
}
#endif
/* Free record array copy. */
+#if REMOVE_DUPLICATED_COPY_FROM_USER
+ if (Context->recordArrayMap != gcvNULL)
+ {
+ gcsRECORD_ARRAY_MAP_PTR map = Context->recordArrayMap;
+
+ do
+ {
+ /* Free record array. */
+ gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, map->kData));
+ map = map->next;
+ }
+ while (map != Context->recordArrayMap);
+
+ gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->recordArrayMap));
+ }
+#else
if (Context->recordArray != gcvNULL)
{
gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->recordArray));
}
+#endif
/* Free the state mapping. */
if (Context->map != gcvNULL)
** Pointer to a variable thet will receive the gckCONTEXT object
** pointer.
*/
+#if (gcdENABLE_3D || gcdENABLE_2D)
gceSTATUS
gckCONTEXT_Construct(
IN gckOS Os,
{
gceSTATUS status;
gckCONTEXT context = gcvNULL;
- gctSIZE_T allocationSize;
+ gctUINT32 allocationSize;
gctUINT i;
gctPOINTER pointer = gcvNULL;
+ gctUINT32 address;
gcmkHEADER_ARG("Os=0x%08X Hardware=0x%08X", Os, Hardware);
context->hardware = Hardware;
-#if defined(VIVANTE_NO_3D)
+#if !gcdENABLE_3D
context->entryPipe = gcvPIPE_2D;
context->exitPipe = gcvPIPE_2D;
#elif gcdCMD_NO_2D_CONTEXT
/* Compute the size of the record array. **********************************/
context->recordArraySize
- = gcmSIZEOF(gcsSTATE_DELTA_RECORD) * context->stateCount;
+ = gcmSIZEOF(gcsSTATE_DELTA_RECORD) * (gctUINT)context->stateCount;
if (context->stateCount > 0)
/* Allocate a context buffer. */
gcsCONTEXT_PTR buffer;
+ gctSIZE_T totalSize = context->totalSize;
+
/* Allocate the context buffer structure. */
gcmkONERROR(gckOS_Allocate(
Os,
));
/* Create a new physical context buffer. */
-#if gcdVIRTUAL_COMMAND_BUFFER
- gcmkONERROR(gckKERNEL_AllocateVirtualCommandBuffer(
- context->hardware->kernel,
- gcvFALSE,
- &context->totalSize,
- &buffer->physical,
- &pointer
- ));
+ if (context->hardware->kernel->virtualCommandBuffer)
+ {
+ gcmkONERROR(gckKERNEL_AllocateVirtualCommandBuffer(
+ context->hardware->kernel,
+ gcvFALSE,
+ &totalSize,
+ &buffer->physical,
+ &pointer
+ ));
-#else
- gcmkONERROR(gckOS_AllocateContiguous(
- Os,
- gcvFALSE,
- &context->totalSize,
- &buffer->physical,
- &pointer
- ));
-#endif
+ gcmkONERROR(gckKERNEL_GetGPUAddress(
+ context->hardware->kernel,
+ pointer,
+ gcvFALSE,
+ &address
+ ));
+ }
+ else
+ {
+ gcmkONERROR(gckOS_AllocateContiguous(
+ Os,
+ gcvFALSE,
+ &totalSize,
+ &buffer->physical,
+ &pointer
+ ));
+
+ gcmkONERROR(gckHARDWARE_ConvertLogical(
+ context->hardware,
+ pointer,
+ gcvFALSE,
+ &address
+ ));
+ }
buffer->logical = pointer;
+ buffer->address = address;
/* Set gckEVENT object pointer. */
buffer->eventObj = Hardware->kernel->eventObj;
if (context->linkIndexXD != 0)
{
gctPOINTER xdLink;
- gctUINT8_PTR xdEntryLogical;
- gctSIZE_T xdEntrySize;
- gctSIZE_T linkBytes;
+ gctUINT32 xdEntryAddress;
+ gctUINT32 xdEntrySize;
+ gctUINT32 linkBytes;
/* Determine LINK parameters. */
xdLink
= &buffer->logical[context->linkIndexXD];
- xdEntryLogical
- = (gctUINT8_PTR) buffer->logical
+ xdEntryAddress
+ = buffer->address
+ context->entryOffsetXDFrom3D;
xdEntrySize
/* Query LINK size. */
gcmkONERROR(gckHARDWARE_Link(
- Hardware, gcvNULL, gcvNULL, 0, &linkBytes
+ Hardware, gcvNULL, 0, 0, &linkBytes
));
/* Generate a LINK. */
gcmkONERROR(gckHARDWARE_Link(
Hardware,
xdLink,
- xdEntryLogical,
+ xdEntryAddress,
xdEntrySize,
&linkBytes
));
gcmkFOOTER();
return status;
}
+#endif
/******************************************************************************\
**
IN gcsSTATE_DELTA_PTR StateDelta
)
{
-#ifndef VIVANTE_NO_3D
+#if gcdENABLE_3D
gceSTATUS status = gcvSTATUS_OK;
gcsSTATE_DELTA _stateDelta;
gckKERNEL kernel;
gcsSTATE_DELTA_PTR kDelta = gcvNULL;
gcsSTATE_DELTA_RECORD_PTR record;
gcsSTATE_DELTA_RECORD_PTR recordArray = gcvNULL;
+#if REMOVE_DUPLICATED_COPY_FROM_USER
+ gcsRECORD_ARRAY_MAP_PTR recordArrayMap = gcvNULL;
+#endif
gctUINT elementCount;
gctUINT address;
gctUINT32 mask;
gcmkONERROR(gckOS_QueryNeedCopy(Context->os, ProcessID, &needCopy));
/* Allocate the copy buffer for the user record array. */
+#if REMOVE_DUPLICATED_COPY_FROM_USER
+ if (needCopy && (Context->recordArrayMap == gcvNULL))
+ {
+ /* Allocate enough maps. */
+ gcmkONERROR(gckOS_Allocate(
+ Context->os,
+ gcmSIZEOF(gcsRECORD_ARRAY_MAP_PTR) * gcdCONTEXT_BUFFER_COUNT,
+ (gctPOINTER *) &Context->recordArrayMap
+ ));
+
+ for (i = 0; i < gcdCONTEXT_BUFFER_COUNT; i++)
+ {
+ /* Next mapping id. */
+ gctUINT n = (i + 1) % gcdCONTEXT_BUFFER_COUNT;
+
+ recordArrayMap = &Context->recordArrayMap[i];
+
+ /* Allocate the buffer. */
+ gcmkONERROR(gckOS_Allocate(
+ Context->os,
+ Context->recordArraySize,
+ (gctPOINTER *) &recordArrayMap->kData
+ ));
+
+ /* Initialize fields. */
+ recordArrayMap->key = 0;
+ recordArrayMap->next = &Context->recordArrayMap[n];
+ }
+ }
+#else
if (needCopy && (Context->recordArray == gcvNULL))
{
/* Allocate the buffer. */
(gctPOINTER *) &Context->recordArray
));
}
+#endif
/* Get the current context buffer. */
buffer = Context->buffer;
gcmkONERROR(gckKERNEL_GetProcessDBCache(kernel, ProcessID, &cache));
#endif
-#if gcmIS_DEBUG(gcdDEBUG_CODE) && 1 && !defined(VIVANTE_NO_3D)
+#if gcmIS_DEBUG(gcdDEBUG_CODE) && 1 && gcdENABLE_3D
/* Update current context token. */
buffer->logical[Context->map[0x0E14].index]
- = gcmPTR2INT(Context);
+ = (gctUINT32)gcmPTR2INT32(Context);
#endif
/* Are there any pending deltas? */
(gctPOINTER *) &kDelta
));
+#if REMOVE_DUPLICATED_COPY_FROM_USER
+ if (needCopy)
+ {
+ recordArray = gcvNULL;
+ recordArrayMap = Context->recordArrayMap;
+
+ do
+ {
+ /* Check if recordArray is alreay opened. */
+ if (recordArrayMap->key == kDelta->recordArray)
+ {
+ /* Found. */
+ recordArray = recordArrayMap->kData;
+ break;
+ }
+
+ recordArrayMap = recordArrayMap->next;
+ }
+ while (recordArrayMap != Context->recordArrayMap);
+
+ if (recordArray == gcvNULL)
+ {
+ while (recordArrayMap->key != 0)
+ {
+ /* Found an empty slot. */
+ recordArrayMap = recordArrayMap->next;
+ }
+
+ /* Get access to the state records. */
+ gcmkONERROR(gckOS_CopyFromUserData(
+ kernel->os,
+ recordArrayMap->kData,
+ gcmUINT64_TO_PTR(kDelta->recordArray),
+ Context->recordArraySize
+ ));
+
+ /* Save user pointer as key. */
+ recordArrayMap->key = kDelta->recordArray;
+ recordArray = recordArrayMap->kData;
+ }
+ }
+ else
+ {
+ /* Get access to the state records. */
+ gcmkONERROR(gckOS_MapUserPointer(
+ kernel->os,
+ gcmUINT64_TO_PTR(kDelta->recordArray),
+ Context->recordArraySize,
+ (gctPOINTER *) &recordArray
+ ));
+ }
+#else
/* Get access to the state records. */
gcmkONERROR(gckKERNEL_OpenUserData(
kernel, needCopy,
gcmUINT64_TO_PTR(kDelta->recordArray), Context->recordArraySize,
(gctPOINTER *) &recordArray
));
+#endif
/* Merge all pending states. */
for (j = 0; j < kDelta->recordCount; j += 1)
/* Skip the state if not mapped. */
if (index == 0)
{
-#if gcdDEBUG
- if ((address != 0x0594)
- && (address != 0x0E00)
- && (address != 0x0E03)
- )
- {
-#endif
- gcmkTRACE(
- gcvLEVEL_ERROR,
- "%s(%d): State 0x%04X is not mapped.\n",
- __FUNCTION__, __LINE__,
- address
- );
-#if gcdDEBUG
- }
-#endif
continue;
}
/* Get the next state delta. */
nDelta = gcmUINT64_TO_PTR(kDelta->next);
+#if REMOVE_DUPLICATED_COPY_FROM_USER
+ if (needCopy)
+ {
+ if (kDelta->refCount == 0)
+ {
+ /* No other reference, reset the mapping. */
+ recordArrayMap->key = 0;
+ }
+ }
+ else
+ {
+ /* Close access to the state records. */
+ gcmkONERROR(gckOS_UnmapUserPointer(
+ kernel->os,
+ gcmUINT64_TO_PTR(kDelta->recordArray),
+ Context->recordArraySize,
+ (gctPOINTER *) recordArray
+ ));
+
+ recordArray = gcvNULL;
+ }
+#else
/* Get access to the state records. */
gcmkONERROR(gckKERNEL_CloseUserData(
kernel, needCopy,
gcmUINT64_TO_PTR(kDelta->recordArray), Context->recordArraySize,
(gctPOINTER *) &recordArray
));
+#endif
/* Close access to the current state delta. */
gcmkONERROR(gckKERNEL_CloseUserData(
/* Get the next context buffer. */
buffer = buffer->next;
- if (buffer == gcvNULL)
- {
- gcmkONERROR(gcvSTATUS_NOT_FOUND);
- }
+ if (buffer == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
}
while (Context->buffer != buffer);
OnError:
/* Get access to the state records. */
- if (kDelta != gcvNULL)
- {
+ if (kDelta != gcvNULL)
+ {
gcmkVERIFY_OK(gckKERNEL_CloseUserData(
kernel, needCopy,
gcvFALSE,
gcmUINT64_TO_PTR(kDelta->recordArray), Context->recordArraySize,
(gctPOINTER *) &recordArray
));
- }
+ }
/* Close access to the current state delta. */
gcmkVERIFY_OK(gckKERNEL_CloseUserData(
#endif
}
+gceSTATUS
+gckCONTEXT_MapBuffer(
+ IN gckCONTEXT Context,
+ OUT gctUINT32 *Physicals,
+ OUT gctUINT64 *Logicals,
+ OUT gctUINT32 *Bytes
+ )
+{
+ gceSTATUS status;
+ int i = 0;
+ gctSIZE_T pageCount;
+ gckVIRTUAL_COMMAND_BUFFER_PTR commandBuffer;
+ gckKERNEL kernel = Context->hardware->kernel;
+ gctPOINTER logical;
+ gctPHYS_ADDR physical;
+
+ gcsCONTEXT_PTR buffer;
+
+ gcmkHEADER();
+
+ gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
+
+ buffer = Context->buffer;
+
+ for (i = 0; i < gcdCONTEXT_BUFFER_COUNT; i++)
+ {
+ if (kernel->virtualCommandBuffer)
+ {
+ commandBuffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)buffer->physical;
+ physical = commandBuffer->physical;
+
+ gcmkONERROR(gckOS_CreateUserVirtualMapping(
+ kernel->os,
+ physical,
+ Context->totalSize,
+ &logical,
+ &pageCount));
+ }
+ else
+ {
+ physical = buffer->physical;
+
+ gcmkONERROR(gckOS_MapMemory(
+ kernel->os,
+ physical,
+ Context->totalSize,
+ &logical));
+ }
+
+ Physicals[i] = gcmPTR_TO_NAME(physical);
+
+ Logicals[i] = gcmPTR_TO_UINT64(logical);
+
+ buffer = buffer->next;
+ }
+
+ *Bytes = (gctUINT)Context->totalSize;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#include "gc_hal_kernel_buffer.h"
+/* Exprimental optimization. */
+#define REMOVE_DUPLICATED_COPY_FROM_USER 1
+
#ifdef __cplusplus
extern "C" {
#endif
/* Logical address of the context buffer. */
gctUINT32_PTR logical;
+ /* Hardware address of the context buffer. */
+ gctUINT32 address;
+
/* Pointer to the LINK commands. */
gctPOINTER link2D;
gctPOINTER link3D;
}
gcsCONTEXT;
+typedef struct _gcsRECORD_ARRAY_MAP * gcsRECORD_ARRAY_MAP_PTR;
+struct _gcsRECORD_ARRAY_MAP
+{
+ /* User pointer key. */
+ gctUINT64 key;
+
+ /* Kernel memory buffer. */
+ gcsSTATE_DELTA_RECORD_PTR kData;
+
+ /* Next map. */
+ gcsRECORD_ARRAY_MAP_PTR next;
+
+};
+
/* gckCONTEXT structure that hold the current context. */
struct _gckCONTEXT
{
gckHARDWARE hardware;
/* Command buffer alignment. */
- gctSIZE_T alignment;
- gctSIZE_T reservedHead;
- gctSIZE_T reservedTail;
+ gctUINT32 alignment;
+ gctUINT32 reservedHead;
+ gctUINT32 reservedTail;
/* Context buffer metrics. */
gctSIZE_T stateCount;
- gctSIZE_T totalSize;
- gctSIZE_T bufferSize;
+ gctUINT32 totalSize;
+ gctUINT32 bufferSize;
gctUINT32 linkIndex2D;
gctUINT32 linkIndex3D;
gctUINT32 linkIndexXD;
/* A copy of the user record array. */
gctUINT recordArraySize;
+#if REMOVE_DUPLICATED_COPY_FROM_USER
+ gcsRECORD_ARRAY_MAP_PTR recordArrayMap;
+#else
gcsSTATE_DELTA_RECORD_PTR recordArray;
+#endif
/* Requested pipe select for context. */
gcePIPE_SELECT entryPipe;
gctUINT32 lastIndex;
gctBOOL lastFixed;
+ gctUINT32 pipeSelectBytes;
+
/* Hint array. */
#if gcdSECURE_USER
gctBOOL_PTR hint;
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#include "gc_hal_kernel_context.h"
#endif
+#define gcdDISABLE_FE_L2 1
+
#define _GC_OBJ_ZONE gcvZONE_HARDWARE
+#define gcmSEMAPHORESTALL(buffer) \
+ do \
+ { \
+ /* Arm the PE-FE Semaphore. */ \
+ *buffer++ \
+ = gcmSETFIELDVALUE(0, AQ_COMMAND_LOAD_STATE_COMMAND, OPCODE, LOAD_STATE) \
+ | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, COUNT, 1) \
+ | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, ADDRESS, 0x0E02); \
+ \
+ *buffer++ \
+ = gcmSETFIELDVALUE(0, AQ_SEMAPHORE, SOURCE, FRONT_END) \
+ | gcmSETFIELDVALUE(0, AQ_SEMAPHORE, DESTINATION, PIXEL_ENGINE);\
+ \
+ /* STALL FE until PE is done flushing. */ \
+ *buffer++ \
+ = gcmSETFIELDVALUE(0, STALL_COMMAND, OPCODE, STALL); \
+ \
+ *buffer++ \
+ = gcmSETFIELDVALUE(0, STALL_STALL, SOURCE, FRONT_END) \
+ | gcmSETFIELDVALUE(0, STALL_STALL, DESTINATION, PIXEL_ENGINE); \
+ } while(0)
+
typedef struct _gcsiDEBUG_REGISTERS * gcsiDEBUG_REGISTERS_PTR;
typedef struct _gcsiDEBUG_REGISTERS
{
}
gcsiDEBUG_REGISTERS;
-extern int gpu3DMinClock;
/******************************************************************************\
********************************* Support Code *********************************
\******************************************************************************/
+static gctBOOL
+_IsHardwareMatch(
+ IN gckHARDWARE Hardware,
+ IN gctINT32 ChipModel,
+ IN gctUINT32 ChipRevision
+ )
+{
+ return ((Hardware->identity.chipModel == ChipModel) &&
+ (Hardware->identity.chipRevision == ChipRevision));
+}
+
static gceSTATUS
_ResetGPU(
IN gckHARDWARE Hardware,
gctUINT32 numConstants = 0;
gctUINT32 bufferSize = 0;
gctUINT32 varyingsCount = 0;
- gctBOOL useHZ;
+#if gcdMULTI_GPU
+ gctUINT32 gpuCoreCount = 0;
+#endif
gcmkHEADER_ARG("Os=0x%x", Os);
0x00020,
(gctUINT32_PTR) &Identity->chipModel));
- /* !!!! HACK ALERT !!!! */
- /* Because people change device IDs without letting software know
- ** about it - here is the hack to make it all look the same. Only
- ** for GC400 family. Next time - TELL ME!!! */
if (((Identity->chipModel & 0xFF00) == 0x0400)
- && (Identity->chipModel != 0x0420))
+ && (Identity->chipModel != 0x0420)
+ && (Identity->chipModel != 0x0428))
{
Identity->chipModel = (gceCHIPMODEL) (Identity->chipModel & 0x0400);
}
Identity->chipRevision = 0x1051;
}
}
+
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x000A8,
+ &Identity->productID));
}
gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
0x0001C,
&Identity->chipFeatures));
-#ifndef VIVANTE_NO_3D
+#if gcdENABLE_3D
/* Disable fast clear on GC700. */
if (Identity->chipModel == gcv700)
{
Identity->chipMinorFeatures2 = 0;
Identity->chipMinorFeatures3 = 0;
Identity->chipMinorFeatures4 = 0;
+ Identity->chipMinorFeatures5 = 0;
}
else
{
0x00088,
&Identity->chipMinorFeatures3));
- /*The BG2 chip has no compression supertiled, and the bit of GCMinorFeature3BugFixes15 is n/a*/
- if(Identity->chipModel == gcv1000 && Identity->chipRevision == 0x5036)
- {
- Identity->chipMinorFeatures3
- = ((((gctUINT32) (Identity->chipMinorFeatures3)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
- Identity->chipMinorFeatures3
- = ((((gctUINT32) (Identity->chipMinorFeatures3)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27)));
- }
/* Read chip minor featuress register #4. */
gcmkONERROR(
gckOS_ReadRegisterEx(Os, Core,
0x00094,
&Identity->chipMinorFeatures4));
+
+ /* Read chip minor featuress register #5. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x000A0,
+ &Identity->chipMinorFeatures5));
}
else
{
Identity->chipMinorFeatures2 = 0;
Identity->chipMinorFeatures3 = 0;
Identity->chipMinorFeatures4 = 0;
+ Identity->chipMinorFeatures5 = 0;
}
}
/* Exception for GC1000, revision 5035 & GC800, revision 4612 */
if (((Identity->chipModel == gcv1000) && ((Identity->chipRevision == 0x5035)
|| (Identity->chipRevision == 0x5036)
- || (Identity->chipRevision == 0x5037)))
- || ((Identity->chipModel == gcv800) && (Identity->chipRevision == 0x4612))
- || ((Identity->chipModel == gcv860) && (Identity->chipRevision == 0x4647)))
+ || (Identity->chipRevision == 0x5037)
+ || (Identity->chipRevision == 0x5039)
+ || (Identity->chipRevision >= 0x5040)))
+ || ((Identity->chipModel == gcv800) && (Identity->chipRevision == 0x4612))
+ || ((Identity->chipModel == gcv600) && (Identity->chipRevision >= 0x4650))
+ || ((Identity->chipModel == gcv860) && (Identity->chipRevision == 0x4647))
+ || ((Identity->chipModel == gcv400) && (Identity->chipRevision >= 0x4633)))
{
Identity->superTileMode = 1;
}
- if (Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5245)
- {
- useHZ = ((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 26:26) & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))))
- || ((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 8:8) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))));
- }
- else
- {
- useHZ = gcvFALSE;
- }
-
- if (useHZ)
- {
- /* Disable EZ. */
- Identity->chipFeatures
- = ((((gctUINT32) (Identity->chipFeatures)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)));
- }
-
- /* Disable HZ when EZ is present for older chips. */
- else if (!((((gctUINT32) (Identity->chipFeatures)) >> (0 ? 16:16) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))))
- {
- /* Disable HIERARCHICAL_Z. */
- Identity->chipMinorFeatures
- = ((((gctUINT32) (Identity->chipMinorFeatures)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27)));
- }
-
- /* Disable rectangle primitive when chip is gc880_5_1_0_rc6*/
- if ((Identity->chipModel == gcv880) && (Identity->chipRevision == 0x5106))
- {
- /* Disable rectangle primitive. */
- Identity->chipMinorFeatures2
- = ((((gctUINT32) (Identity->chipMinorFeatures2)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
- }
-
- if ((Identity->chipModel == gcv800) && (Identity->chipRevision == 0x4605))
- {
- /* Correct feature bit: RTL does not have such feature. */
- Identity->chipFeatures
- = ((((gctUINT32) (Identity->chipFeatures)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)));
- }
-
gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
"Identity: chipFeatures=0x%08X",
Identity->chipFeatures);
"Identity: chipMinorFeatures4=0x%08X",
Identity->chipMinorFeatures4);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Identity: chipMinorFeatures5=0x%08X",
+ Identity->chipMinorFeatures5);
+
/***************************************************************************
** Get chip specs.
*/
if (((((gctUINT32) (Identity->chipMinorFeatures)) >> (0 ? 21:21) & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))))
{
- gctUINT32 specs, specs2, specs3;
+ gctUINT32 specs, specs2, specs3, specs4;
/* Read gcChipSpecs register. */
gcmkONERROR(
&specs));
/* Extract the fields. */
- streamCount = (((((gctUINT32) (specs)) >> (0 ? 3:0)) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1)))))) );
registerMax = (((((gctUINT32) (specs)) >> (0 ? 7:4)) & ((gctUINT32) ((((1 ? 7:4) - (0 ? 7:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:4) - (0 ? 7:4) + 1)))))) );
threadCount = (((((gctUINT32) (specs)) >> (0 ? 11:8)) & ((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1)))))) );
shaderCoreCount = (((((gctUINT32) (specs)) >> (0 ? 24:20)) & ((gctUINT32) ((((1 ? 24:20) - (0 ? 24:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:20) - (0 ? 24:20) + 1)))))) );
&specs3));
varyingsCount = (((((gctUINT32) (specs3)) >> (0 ? 8:4)) & ((gctUINT32) ((((1 ? 8:4) - (0 ? 8:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:4) - (0 ? 8:4) + 1)))))) );
+#if gcdMULTI_GPU
+ gpuCoreCount = (((((gctUINT32) (specs3)) >> (0 ? 2:0)) & ((gctUINT32) ((((1 ? 2:0) - (0 ? 2:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:0) - (0 ? 2:0) + 1)))))) );
+#endif
+
+ /* Read gcChipSpecs4 register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x0009C,
+ &specs4));
+
+
+ streamCount = (((((gctUINT32) (specs4)) >> (0 ? 16:12)) & ((gctUINT32) ((((1 ? 16:12) - (0 ? 16:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:12) - (0 ? 16:12) + 1)))))) );
+ if (streamCount == 0)
+ {
+ /* Extract stream count from older register. */
+ streamCount = (((((gctUINT32) (specs)) >> (0 ? 3:0)) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1)))))) );
+ }
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Identity: chipSpecs1=0x%08X",
+ specs);
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Identity: chipSpecs2=0x%08X",
+ specs2);
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Identity: chipSpecs3=0x%08X",
+ specs3);
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Identity: chipSpecs4=0x%08X",
+ specs4);
}
/* Get the number of pixel pipes. */
{
Identity->instructionCount = 512;
}
- }
-
- if (((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 3:3) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))))
- {
- Identity->instructionCount = 512;
+ else if (((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 3:3) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))))
+ {
+ Identity->instructionCount = 512;
+ }
}
gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
if (varyingsCount != 0)
{
- /* Bug 4480. */
- /*Identity->varyingsCount = varyingsCount;*/
- Identity->varyingsCount = 12;
+ Identity->varyingsCount = varyingsCount;
}
else if (((((gctUINT32) (Identity->chipMinorFeatures1)) >> (0 ? 23:23) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1))))))))
{
}
/* For some cores, it consumes two varying for position, so the max varying vectors should minus one. */
- if ((Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5222) ||
+ if ((Identity->chipModel == gcv5000 && Identity->chipRevision == 0x5434) ||
+ (Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5222) ||
(Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5208) ||
+ (Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5245) ||
+ (Identity->chipModel == gcv3000 && Identity->chipRevision == 0x5435) ||
+ (Identity->chipModel == gcv2200 && Identity->chipRevision == 0x5244) ||
+ (Identity->chipModel == gcv1500 && Identity->chipRevision == 0x5246) ||
((Identity->chipModel == gcv2100 || Identity->chipModel == gcv2000) && Identity->chipRevision == 0x5108) ||
(Identity->chipModel == gcv880 && (Identity->chipRevision == 0x5107 || Identity->chipRevision == 0x5106)))
{
Identity->varyingsCount -= 1;
}
+ Identity->chip2DControl = 0;
+ if (Identity->chipModel == gcv320)
+ {
+ gctUINT32 data;
+
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os,
+ Core,
+ 0x0002C,
+ &data));
+
+ if ((data != 33956864) &&
+ ((Identity->chipRevision == 0x5007) ||
+ (Identity->chipRevision == 0x5220)))
+ {
+ Identity->chip2DControl |= 0xFF &
+ (Identity->chipRevision == 0x5220 ? 8 :
+ (Identity->chipRevision == 0x5007 ? 12 : 0));
+ }
+
+ if (Identity->chipRevision == 0x5007)
+ {
+ /* Disable splitting rectangle. */
+ Identity->chip2DControl |= 0x100;
+
+ /* Enable 2D Flush. */
+ Identity->chip2DControl |= 0x200;
+ }
+ }
+
+#if gcdMULTI_GPU
+#if gcdMULTI_GPU > 1
+ Identity->gpuCoreCount = gpuCoreCount + 1;
+#else
+ Identity->gpuCoreCount = 1;
+#endif
+#endif
+
/* Success. */
gcmkFOOTER();
return gcvSTATUS_OK;
return status;
}
+#define gcdDEBUG_MODULE_CLOCK_GATING 0
+#define gcdDISABLE_MODULE_CLOCK_GATING 0
+#define gcdDISABLE_FE_CLOCK_GATING 0
+#define gcdDISABLE_PE_CLOCK_GATING 0
+#define gcdDISABLE_SH_CLOCK_GATING 0
+#define gcdDISABLE_PA_CLOCK_GATING 0
+#define gcdDISABLE_SE_CLOCK_GATING 0
+#define gcdDISABLE_RA_CLOCK_GATING 0
+#define gcdDISABLE_RA_EZ_CLOCK_GATING 0
+#define gcdDISABLE_RA_HZ_CLOCK_GATING 0
+#define gcdDISABLE_TX_CLOCK_GATING 0
+
+#if gcdDEBUG_MODULE_CLOCK_GATING
+gceSTATUS
+_ConfigureModuleLevelClockGating(
+ gckHARDWARE Hardware
+ )
+{
+ gctUINT32 data;
+
+ gcmkVERIFY_OK(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ &data));
+
+#if gcdDISABLE_FE_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+#endif
+
+#if gcdDISABLE_PE_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)));
+#endif
+
+#if gcdDISABLE_SH_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)));
+#endif
+
+#if gcdDISABLE_PA_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+#endif
+
+#if gcdDISABLE_SE_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
+#endif
+
+#if gcdDISABLE_RA_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
+#endif
+
+#if gcdDISABLE_TX_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7)));
+#endif
+
+#if gcdDISABLE_RA_EZ_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)));
+#endif
+
+#if gcdDISABLE_RA_HZ_CLOCK_GATING
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1))))))) << (0 ? 17:17))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1))))))) << (0 ? 17:17)));
+#endif
+
+ gcmkVERIFY_OK(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ data));
+
+#if gcdDISABLE_MODULE_CLOCK_GATING
+ gcmkVERIFY_OK(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress +
+ 0x00100,
+ &data));
+
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+
+ gcmkVERIFY_OK(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00100,
+ data));
+#endif
+
+ return gcvSTATUS_OK;
+}
+#endif
+
#if gcdPOWEROFF_TIMEOUT
void
_PowerTimerFunction(
)
{
gceSTATUS status;
- gctSIZE_T bytes, requested;
+ gctUINT32 bytes, requested;
gctPOINTER buffer;
/* Get the size of the flush command. */
return status;
}
+gctBOOL
+_IsGPUIdle(
+ IN gctUINT32 Idle
+ )
+{
+ return (((((gctUINT32) (Idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) )
+ && (((((gctUINT32) (Idle)) >> (0 ? 1:1)) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1)))))) )
+ && (((((gctUINT32) (Idle)) >> (0 ? 3:3)) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) )
+ && (((((gctUINT32) (Idle)) >> (0 ? 4:4)) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1)))))) )
+ && (((((gctUINT32) (Idle)) >> (0 ? 5:5)) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1)))))) )
+ && (((((gctUINT32) (Idle)) >> (0 ? 6:6)) & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1)))))) )
+ && (((((gctUINT32) (Idle)) >> (0 ? 7:7)) & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1)))))) )
+ && (((((gctUINT32) (Idle)) >> (0 ? 2:2)) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))) )
+ ;
+}
+
/******************************************************************************\
****************************** gckHARDWARE API code *****************************
\******************************************************************************/
gceSTATUS status;
gckHARDWARE hardware = gcvNULL;
gctUINT16 data = 0xff00;
- gctUINT32 axi_ot;
gctPOINTER pointer = gcvNULL;
+#if gcdMULTI_GPU_AFFINITY
+ gctUINT32 control;
+#endif
gcmkHEADER_ARG("Os=0x%x", Os);
hardware->type = gcvHARDWARE_VG;
break;
+ case gcv200:
case gcv300:
case gcv320:
+ case gcv328:
case gcv420:
+ case gcv428:
hardware->type = gcvHARDWARE_2D;
- /*set outstanding limit*/
- gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00414, &axi_ot));
- axi_ot = (axi_ot & (~0xFF)) | 0x10;
- gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00414, axi_ot));
break;
default:
+#if gcdMULTI_GPU_AFFINITY
+ hardware->type = (Core == gcvCORE_MAJOR) ? gcvHARDWARE_3D : gcvHARDWARE_OCL;
+#else
hardware->type = gcvHARDWARE_3D;
- if(hardware->identity.chipModel == gcv880)
+#endif
+
+ if(hardware->identity.chipModel == gcv880 && hardware->identity.chipRevision == 0x5107)
{
/*set outstanding limit*/
+ gctUINT32 axi_ot;
gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00414, &axi_ot));
- axi_ot = (axi_ot & (~0xFF)) | 0x10;
+ axi_ot = (axi_ot & (~0xFF)) | 0x00010;
gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00414, axi_ot));
}
+
if ((((((gctUINT32) (hardware->identity.chipFeatures)) >> (0 ? 9:9)) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) ))
{
hardware->type = (gceHARDWARE_TYPE) (hardware->type | gcvHARDWARE_2D);
"_ResetGPU failed: status=%d\n", status);
}
+#if gcdMULTI_GPU
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x0055C,
+#if gcdDISABLE_FE_L2
+ 0x00FFFFFF));
+#else
+ 0x00FFFF05));
+#endif
+
+#elif gcdMULTI_GPU_AFFINITY
+ control = ((((gctUINT32) (0x00FF0A05)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27)));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x0055C,
+ control));
+#endif
+
hardware->powerMutex = gcvNULL;
hardware->mmuVersion
hardware->clockState = gcvTRUE;
hardware->powerState = gcvTRUE;
hardware->lastWaitLink = ~0U;
+ hardware->lastEnd = ~0U;
hardware->globalSemaphore = gcvNULL;
#if gcdENABLE_FSCALE_VAL_ADJUST
hardware->powerOnFscaleVal = 64;
#endif
gcmkONERROR(gckOS_AtomConstruct(Os, &hardware->pageTableDirty));
+ gcmkONERROR(gckOS_AtomConstruct(Os, &hardware->pendingEvent));
#if gcdLINK_QUEUE_SIZE
hardware->linkQueue.front = 0;
/* Disable profiler by default */
hardware->gpuProfiler = gcvFALSE;
+#if defined(LINUX) || defined(__QNXNTO__) || defined(UNDERCE)
+ if (hardware->mmuVersion)
+ {
+ hardware->endAfterFlushMmuCache = gcvTRUE;
+ }
+ else
+#endif
+ {
+ hardware->endAfterFlushMmuCache = gcvFALSE;
+ }
+
+ gcmkONERROR(gckOS_QueryOption(Os, "mmu", (gctUINT32_PTR)&hardware->enableMMU));
+
+ hardware->minFscaleValue = 1;
+
/* Return pointer to the gckHARDWARE object. */
*Hardware = hardware;
gcmkVERIFY_OK(gckOS_AtomDestroy(Os, hardware->pageTableDirty));
}
+ if (hardware->pendingEvent != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Os, hardware->pendingEvent));
+ }
+
gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, hardware));
}
gcmkVERIFY_OK(gckOS_AtomDestroy(Hardware->os, Hardware->pageTableDirty));
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Hardware->os, Hardware->pendingEvent));
+
+ gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
+ Hardware->os,
+ Hardware->functionBytes,
+ Hardware->functionPhysical,
+ Hardware->functionLogical
+ ));
+
/* Mark the object as unknown. */
Hardware->object.type = gcvOBJ_UNKNOWN;
gctUINT32 baseAddress;
gctUINT32 chipRev;
gctUINT32 control;
+ gctUINT32 data;
+ gctUINT32 regPMC = 0;
gcmkHEADER_ARG("Hardware=0x%x", Hardware);
0x00424,
baseAddress));
-#if !VIVANTE_PROFILER
{
- gctUINT32 data;
-
gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
Hardware->core,
Hardware->powerBaseAddress +
+ 0x00100,
data));
-#ifndef VIVANTE_NO_3D
+#if gcdENABLE_3D
/* Disable PE clock gating on revs < 5.0 when HZ is present without a
** bug fix. */
if ((Hardware->identity.chipRevision < 0x5000)
+ && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HZ)
&& ((((gctUINT32) (Hardware->identity.chipMinorFeatures1)) >> (0 ? 9:9) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) == (0x0 & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))))
- && ((((gctUINT32) (Hardware->identity.chipMinorFeatures)) >> (0 ? 27:27) & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1)))))))
)
{
- gcmkONERROR(
- gckOS_ReadRegisterEx(Hardware->os,
- Hardware->core,
- Hardware->powerBaseAddress
- + 0x00104,
- &data));
+ if (regPMC == 0)
+ {
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ ®PMC));
+ }
/* Disable PE clock gating. */
- data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)));
-
- gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os,
- Hardware->core,
- Hardware->powerBaseAddress
- + 0x00104,
- data));
+ regPMC = ((((gctUINT32) (regPMC)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)));
}
#endif
}
-#endif
- /* Special workaround for this core
- ** Make sure pulse eater kicks in only when SH is idle */
if (Hardware->identity.chipModel == gcv4000 &&
- Hardware->identity.chipRevision == 0x5208)
+ ((Hardware->identity.chipRevision == 0x5208) || (Hardware->identity.chipRevision == 0x5222)))
{
- gcmkONERROR(
+ gcmkONERROR(
gckOS_WriteRegisterEx(Hardware->os,
Hardware->core,
0x0010C,
((((gctUINT32) (0x01590880)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1))))))) << (0 ? 23:23))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1))))))) << (0 ? 23:23)))));
}
- if ((gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI2) == gcvFALSE)
- || (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI2) && (Hardware->identity.chipRevision < 0x5422))
- )
+ if (Hardware->identity.chipModel == gcv1000 &&
+ (Hardware->identity.chipRevision == 0x5039 ||
+ Hardware->identity.chipRevision == 0x5040))
{
- gctUINT32 data;
-
- gcmkONERROR(
- gckOS_ReadRegisterEx(Hardware->os,
- Hardware->core,
- Hardware->powerBaseAddress
- + 0x00104,
- &data));
-
-
- data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:15) - (0 ? 15:15) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) << (0 ? 15:15))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 15:15) - (0 ? 15:15) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) << (0 ? 15:15)));
+ gctUINT32 pulseEater;
+ pulseEater = ((((gctUINT32) (0x01590880)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)));
gcmkONERROR(
gckOS_WriteRegisterEx(Hardware->os,
Hardware->core,
- Hardware->powerBaseAddress
- + 0x00104,
- data));
+ 0x0010C,
+ ((((gctUINT32) (pulseEater)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1))))))) << (0 ? 17:17))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1))))))) << (0 ? 17:17)))));
}
- /* Special workaround for this core
- ** Make sure FE and TX are on different buses */
- if ((Hardware->identity.chipModel == gcv2000)
- && (Hardware->identity.chipRevision == 0x5108))
+ if ((gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI2) == gcvSTATUS_FALSE)
+ || (Hardware->identity.chipRevision < 0x5422)
+ )
{
- gctUINT32 data;
+ if (regPMC == 0)
+ {
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ ®PMC));
+ }
+
+ regPMC = ((((gctUINT32) (regPMC)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:15) - (0 ? 15:15) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) << (0 ? 15:15))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 15:15) - (0 ? 15:15) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) << (0 ? 15:15)));
+ }
+ if (_IsHardwareMatch(Hardware, gcv2000, 0x5108))
+ {
gcmkONERROR(
gckOS_ReadRegisterEx(Hardware->os,
Hardware->core,
data));
}
- /* Test if MMU is initialized. */
- if ((Hardware->kernel != gcvNULL)
- && (Hardware->kernel->mmu != gcvNULL)
- )
+ gcmkONERROR(
+ gckHARDWARE_SetMMU(Hardware,
+ Hardware->kernel->mmu->pageTableLogical));
+
+ if (Hardware->identity.chipModel >= gcv400
+ && Hardware->identity.chipModel != gcv420)
{
- /* Reset MMU. */
- if (Hardware->mmuVersion == 0)
+ if (regPMC == 0)
{
- gcmkONERROR(
- gckHARDWARE_SetMMU(Hardware,
- Hardware->kernel->mmu->pageTableLogical));
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ ®PMC));
}
+
+ /* Disable PA clock gating. */
+ regPMC = ((((gctUINT32) (regPMC)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
}
- if (Hardware->identity.chipModel >= gcv400
- && Hardware->identity.chipModel != gcv420
- && (((((gctUINT32) (Hardware->identity.chipMinorFeatures3)) >> (0 ? 15:15) & ((gctUINT32) ((((1 ? 15:15) - (0 ? 15:15) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:15) - (0 ? 15:15) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 15:15) - (0 ? 15:15) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) != gcvTRUE)
- )
+ /* Limit 2D outstanding request. */
+ if (_IsHardwareMatch(Hardware, gcv880, 0x5107))
{
- gctUINT32 data;
+ gctUINT32 axi_ot;
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00414, &axi_ot));
+ axi_ot = (axi_ot & (~0xFF)) | 0x00010;
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00414, axi_ot));
+ }
+
+ if (Hardware->identity.chip2DControl & 0xFF)
+ {
+ gctUINT32 data;
gcmkONERROR(
gckOS_ReadRegisterEx(Hardware->os,
Hardware->core,
- Hardware->powerBaseAddress
- + 0x00104,
+ 0x00414,
&data));
- /* Disable PA clock gating. */
- data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (Hardware->identity.chip2DControl & 0xFF) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)));
gcmkONERROR(
gckOS_WriteRegisterEx(Hardware->os,
Hardware->core,
- Hardware->powerBaseAddress
- + 0x00104,
+ 0x00414,
data));
}
-#if gcdHZ_L2_DISALBE
- /* Disable HZ-L2. */
- if (((((gctUINT32) (Hardware->identity.chipMinorFeatures3)) >> (0 ? 26:26) & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) == gcvTRUE ||
- ((((gctUINT32) (Hardware->identity.chipMinorFeatures3)) >> (0 ? 8:8) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1))))))) == gcvTRUE)
+ if (_IsHardwareMatch(Hardware, gcv1000, 0x5035))
{
- gctUINT32 data;
-
gcmkONERROR(
gckOS_ReadRegisterEx(Hardware->os,
Hardware->core,
0x00414,
&data));
+ /* Disable HZ-L2. */
data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12)));
gcmkONERROR(
0x00414,
data));
}
-#endif
- /* Limit 2D outstanding request. */
- if(Hardware->identity.chipModel == gcv880)
+ if (_IsHardwareMatch(Hardware, gcv4000, 0x5222))
{
- gctUINT32 axi_ot;
- gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00414, &axi_ot));
- axi_ot = (axi_ot & (~0xFF)) | 0x10;
- gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00414, axi_ot));
+ if (regPMC == 0)
+ {
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ ®PMC));
+ }
+
+ /* Disable TX clock gating. */
+ regPMC = ((((gctUINT32) (regPMC)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7)));
}
- if ((Hardware->identity.chipModel == gcv320)
- && ((Hardware->identity.chipRevision == 0x5007)
- || (Hardware->identity.chipRevision == 0x5220)))
+ if (_IsHardwareMatch(Hardware, gcv880, 0x5106))
{
- gctUINT32 data;
+ Hardware->kernel->timeOut = 140 * 1000;
+ }
+ if (regPMC == 0)
+ {
gcmkONERROR(
gckOS_ReadRegisterEx(Hardware->os,
Hardware->core,
- 0x0002C,
- &data));
- if (data != 33956864)
- {
- gcmkONERROR(
- gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ ®PMC));
+ }
+
+ /* Disable RA HZ clock gating. */
+ regPMC = ((((gctUINT32) (regPMC)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1))))))) << (0 ? 17:17))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1))))))) << (0 ? 17:17)));
+
+ /* Disable RA EZ clock gating. */
+ regPMC = ((((gctUINT32) (regPMC)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)));
+
+ if (regPMC != 0)
+ {
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ regPMC));
+ }
+
+ if (_IsHardwareMatch(Hardware, gcv2000, 0x5108)
+ || _IsHardwareMatch(Hardware, gcv320, 0x5007)
+ || _IsHardwareMatch(Hardware, gcv880, 0x5106)
+ || _IsHardwareMatch(Hardware, gcv400, 0x4645)
+ )
+ {
+ /* Update GPU AXI cache atttribute. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00008,
+ 0x00002200));
+ }
+
+
+ if ((Hardware->identity.chipRevision > 0x5420)
+ && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PIPE_3D))
+ {
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
Hardware->core,
- 0x00414,
+ 0x0010C,
&data));
- data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (Hardware->identity.chipRevision == 0x5220 ? 8 : (Hardware->identity.chipRevision == 0x5007 ? 16 : 0)) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)));
+ /* Disable internal DFS. */
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1))))))) << (0 ? 18:18))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1))))))) << (0 ? 18:18)));
- gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os,
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
Hardware->core,
- 0x00414,
+ 0x0010C,
data));
- }
}
- /* Update GPU AXI cache atttribute. */
- gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
- Hardware->core,
- 0x00008,
- 0x00002200));
+#if gcdDEBUG_MODULE_CLOCK_GATING
+ _ConfigureModuleLevelClockGating(Hardware);
+#endif
/* Success. */
gcmkFOOTER_NO();
Identity->chipMinorFeatures2 = Hardware->identity.chipMinorFeatures2;
Identity->chipMinorFeatures3 = Hardware->identity.chipMinorFeatures3;
Identity->chipMinorFeatures4 = Hardware->identity.chipMinorFeatures4;
+ Identity->chipMinorFeatures5 = Hardware->identity.chipMinorFeatures5;
/* Return chip specs. */
Identity->streamCount = Hardware->identity.streamCount;
Identity->bufferSize = Hardware->identity.bufferSize;
Identity->varyingsCount = Hardware->identity.varyingsCount;
Identity->superTileMode = Hardware->identity.superTileMode;
+#if gcdMULTI_GPU
+ Identity->gpuCoreCount = Hardware->identity.gpuCoreCount;
+#endif
+ Identity->chip2DControl = Hardware->identity.chip2DControl;
+
+ Identity->productID = Hardware->identity.productID;
/* Success. */
gcmkFOOTER_NO();
** gckHARDWARE Hardware
** Pointer to the gckHARDWARE object.
**
-** gctPOINTER Logical
-** Logical address of command buffer.
+** gctUINT32 Address
+** Hardware address of command buffer.
**
** gctSIZE_T Bytes
** Number of bytes for the prefetch unit (until after the first LINK).
gceSTATUS
gckHARDWARE_Execute(
IN gckHARDWARE Hardware,
- IN gctPOINTER Logical,
-#ifdef __QNXNTO__
- IN gctPOINTER Physical,
- IN gctBOOL PhysicalAddresses,
-#endif
+ IN gctUINT32 Address,
IN gctSIZE_T Bytes
)
{
gceSTATUS status;
- gctUINT32 address = 0, control;
+ gctUINT32 control;
- gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Bytes=%lu",
- Hardware, Logical, Bytes);
+ gcmkHEADER_ARG("Hardware=0x%x Address=0x%x Bytes=%lu",
+ Hardware, Address, Bytes);
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
- gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
-
-#ifdef __QNXNTO__
- if (PhysicalAddresses && (Hardware->mmuVersion == 0))
- {
- /* Convert physical into hardware specific address. */
- gcmkONERROR(
- gckHARDWARE_ConvertPhysical(Hardware, Physical, &address));
- }
- else
- {
-#endif
- /* Convert logical into hardware specific address. */
- gcmkONERROR(
- gckHARDWARE_ConvertLogical(Hardware, Logical, &address));
-#ifdef __QNXNTO__
- }
-#endif
/* Enable all events. */
gcmkONERROR(
/* Write address register. */
gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00654, address));
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00654, Address));
/* Build control register. */
control = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)))
gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
"Started command buffer @ 0x%08x",
- address);
+ Address);
/* Success. */
gcmkFOOTER_NO();
IN gckHARDWARE Hardware,
IN gctPOINTER Logical,
IN gctUINT32 Offset,
- IN OUT gctSIZE_T * Bytes,
+ IN OUT gctUINT32 * Bytes,
OUT gctUINT32 * WaitOffset,
- OUT gctSIZE_T * WaitSize
+ OUT gctUINT32 * WaitSize
)
{
static const gctUINT waitCount = 200;
gceSTATUS status;
gctUINT32 address;
gctUINT32_PTR logical;
- gctSIZE_T bytes;
+ gctUINT32 bytes;
gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Offset=0x%08x *Bytes=%lu",
Hardware, Logical, Offset, gcmOPT_VALUE(Bytes));
gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
gcmkVERIFY_ARGUMENT((Logical != gcvNULL) || (Bytes != gcvNULL));
- /* Compute number of bytes required. */
-#if gcd6000_SUPPORT
- bytes = gcmALIGN(Offset + 96, 8) - Offset;
+#if gcdMULTI_GPU && !gcdDISABLE_FE_L2
+ bytes = gcmALIGN(Offset + 40, 8) - Offset;
#else
+ /* Compute number of bytes required. */
bytes = gcmALIGN(Offset + 16, 8) - Offset;
#endif
-
/* Cast the input pointer. */
logical = (gctUINT32_PTR) Logical;
}
/* Convert logical into hardware specific address. */
- gcmkONERROR(gckHARDWARE_ConvertLogical(Hardware, logical, &address));
+ gcmkONERROR(gckHARDWARE_ConvertLogical(Hardware, logical, gcvFALSE, &address));
/* Store the WAIT/LINK address. */
Hardware->lastWaitLink = address;
= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (waitCount) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
-#if gcd6000_SUPPORT
- /* Send FE-PE sempahore token. */
- logical[2]
- = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
-
- logical[3]
- = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+#if gcdMULTI_GPU && !gcdDISABLE_FE_L2
+ logical[2] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | gcvCORE_3D_0_MASK;
- /* Send FE-PE stall token. */
- logical[4]
- = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+ logical[3] = 0;
- logical[5]
- = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
-
- /*************************************************************/
- /* Enable chip ID 0. */
- logical[6] =
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
- | (1 << 0);
-
- /* Send semaphore from FE to ChipID 1. */
- logical[8] =
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
-
- logical[9] =
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24)));
-
- /* Send semaphore from FE to ChipID 1. */
- logical[10] =
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
-
- logical[11] =
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24)));
-
- /*************************************************************/
- /* Enable chip ID 1. */
- logical[12] =
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
- | (1 << 1);
-
- /* Send semaphore from FE to ChipID 1. */
- logical[14] =
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+ /* LoadState(AQFlush, 1), flush. */
+ logical[4] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
- logical[15] =
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24)));
+ logical[5] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
- /* Wait for semaphore from ChipID 0. */
- logical[16] =
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+ logical[6] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | gcvCORE_3D_ALL_MASK;
- logical[17] =
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24)));
+ logical[7] = 0;
- /*************************************************************/
- /* Enable all chips. */
- logical[18] =
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
- | (0xFFFF);
+ /* Append LINK(2, address). */
+ logical[8] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
- /* LoadState(AQFlush, 1), flush. */
- logical[20]
- = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+ logical[9] = address;
- logical[21]
- = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%08x: WAIT %u", address, waitCount
+ );
- /* Append LINK(2, address). */
- logical[22]
- = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%x: FLUSH 0x%x", address + 8, logical[3]);
- logical[23] = address;
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%08x: LINK 0x%08x, #%lu",
+ address + 16, address, bytes
+ );
#else
+
/* Append LINK(2, address). */
logical[2]
= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
address + 8, address, bytes
);
#endif
-
if (WaitOffset != gcvNULL)
{
/* Return the offset pointer to WAIT command. */
if (WaitSize != gcvNULL)
{
/* Return number of bytes used by the WAIT command. */
+#if gcdMULTI_GPU && !gcdDISABLE_FE_L2
+ *WaitSize = 32;
+#else
*WaitSize = 8;
+#endif
}
}
gckHARDWARE_End(
IN gckHARDWARE Hardware,
IN gctPOINTER Logical,
- IN OUT gctSIZE_T * Bytes
+ IN OUT gctUINT32 * Bytes
)
{
gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+ gctUINT32 address;
gceSTATUS status;
gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
/* Make sure the CPU writes out the data to memory. */
gcmkONERROR(
gckOS_MemoryBarrier(Hardware->os, Logical));
+
+ gcmkONERROR(gckHARDWARE_ConvertLogical(Hardware, logical, gcvFALSE, &address));
+
+ Hardware->lastEnd = address;
}
if (Bytes != gcvNULL)
return status;
}
-/*******************************************************************************
-**
-** gckHARDWARE_Nop
-**
-** Append a NOP command at the specified location in the command queue.
-**
-** INPUT:
-**
-** gckHARDWARE Hardware
-** Pointer to an gckHARDWARE object.
-**
-** gctPOINTER Logical
-** Pointer to the current location inside the command queue to append
-** NOP command at or gcvNULL just to query the size of the NOP command.
-**
-** gctSIZE_T * Bytes
-** Pointer to the number of bytes available for the NOP command. If
-** 'Logical' is gcvNULL, this argument will be ignored.
-**
-** OUTPUT:
-**
-** gctSIZE_T * Bytes
-** Pointer to a variable that will receive the number of bytes required
-** for the NOP command. If 'Bytes' is gcvNULL, nothing will be returned.
-*/
+#if gcdMULTI_GPU
gceSTATUS
-gckHARDWARE_Nop(
+gckHARDWARE_ChipEnable(
IN gckHARDWARE Hardware,
IN gctPOINTER Logical,
+ IN gceCORE_3D_MASK ChipEnable,
IN OUT gctSIZE_T * Bytes
)
{
gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
gceSTATUS status;
- gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
- Hardware, Logical, gcmOPT_VALUE(Bytes));
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x ChipEnable=0x%x *Bytes=%lu",
+ Hardware, Logical, ChipEnable, gcmOPT_VALUE(Bytes));
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
}
- /* Append NOP. */
- logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+ /* Append CHIPENABLE. */
+ logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ChipEnable;
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: NOP", Logical);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: CHIPENABLE 0x%x", Logical, ChipEnable);
}
if (Bytes != gcvNULL)
{
- /* Return number of bytes required by the NOP command. */
+ /* Return number of bytes required by the CHIPENABLE command. */
*Bytes = 8;
}
gcmkFOOTER();
return status;
}
+#endif
/*******************************************************************************
**
-** gckHARDWARE_Wait
+** gckHARDWARE_Nop
**
-** Append a WAIT command at the specified location in the command queue.
+** Append a NOP command at the specified location in the command queue.
**
** INPUT:
**
**
** gctPOINTER Logical
** Pointer to the current location inside the command queue to append
-** WAIT command at or gcvNULL just to query the size of the WAIT command.
-**
-** gctUINT32 Count
-** Number of cycles to wait.
+** NOP command at or gcvNULL just to query the size of the NOP command.
**
** gctSIZE_T * Bytes
-** Pointer to the number of bytes available for the WAIT command. If
+** Pointer to the number of bytes available for the NOP command. If
** 'Logical' is gcvNULL, this argument will be ignored.
**
** OUTPUT:
** for the NOP command. If 'Bytes' is gcvNULL, nothing will be returned.
*/
gceSTATUS
-gckHARDWARE_Wait(
+gckHARDWARE_Nop(
IN gckHARDWARE Hardware,
IN gctPOINTER Logical,
- IN gctUINT32 Count,
IN OUT gctSIZE_T * Bytes
)
{
+ gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
gceSTATUS status;
- gctUINT32_PTR logical;
- gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Count=%u *Bytes=%lu",
- Hardware, Logical, Count, gcmOPT_VALUE(Bytes));
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
+ Hardware, Logical, gcmOPT_VALUE(Bytes));
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
- /* Cast the input pointer. */
- logical = (gctUINT32_PTR) Logical;
-
if (Logical != gcvNULL)
{
if (*Bytes < 8)
gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
}
- /* Append WAIT. */
- logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (Count) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
-
-#if gcmIS_DEBUG(gcdDEBUG_TRACE)
- {
- gctUINT32 address;
-
- /* Convert logical into hardware specific address. */
- gcmkONERROR(gckHARDWARE_ConvertLogical(
- Hardware, logical, &address
- ));
+ /* Append NOP. */
+ logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
- gcmkTRACE_ZONE(
- gcvLEVEL_INFO, gcvZONE_HARDWARE,
- "0x%08x: WAIT %u", address, Count
- );
- }
-#endif
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: NOP", Logical);
}
if (Bytes != gcvNULL)
{
- /* Return number of bytes required by the WAIT command. */
+ /* Return number of bytes required by the NOP command. */
*Bytes = 8;
}
IN gctPOINTER Logical,
IN gctUINT8 Event,
IN gceKERNEL_WHERE FromWhere,
- IN OUT gctSIZE_T * Bytes
+ IN OUT gctUINT32 * Bytes
)
{
gctUINT size;
gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
gcmkVERIFY_ARGUMENT(Event < 32);
+#if gcdMULTI_GPU
+ if (FromWhere == gcvKERNEL_COMMAND) FromWhere = gcvKERNEL_PIXEL;
+#endif
+
/* Determine the size of the command. */
size = (Hardware->extraEventStates && (FromWhere == gcvKERNEL_PIXEL))
logical[6] = 0;
logical[7] = 0;
}
+
+#if gcdINTERRUPT_STATISTIC
+ if (Event < gcmCOUNTOF(Hardware->kernel->eventObj->queues))
+ {
+ gckOS_AtomSetMask(Hardware->pendingEvent, 1 << Event);
+ }
+#endif
}
if (Bytes != gcvNULL)
IN gckHARDWARE Hardware,
IN gctPOINTER Logical,
IN gcePIPE_SELECT Pipe,
- IN OUT gctSIZE_T * Bytes
+ IN OUT gctUINT32 * Bytes
)
{
gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
** the LINK command at or gcvNULL just to query the size of the LINK
** command.
**
-** gctPOINTER FetchAddress
-** Logical address of destination of LINK.
+** gctUINT32 FetchAddress
+** Hardware address of destination of LINK.
**
** gctSIZE_T FetchSize
** Number of bytes in destination of LINK.
gckHARDWARE_Link(
IN gckHARDWARE Hardware,
IN gctPOINTER Logical,
- IN gctPOINTER FetchAddress,
- IN gctSIZE_T FetchSize,
- IN OUT gctSIZE_T * Bytes
+ IN gctUINT32 FetchAddress,
+ IN gctUINT32 FetchSize,
+ IN OUT gctUINT32 * Bytes
)
{
gceSTATUS status;
gctSIZE_T bytes;
- gctUINT32 address;
gctUINT32 link;
gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
}
- /* Convert logical address to hardware address. */
- gcmkONERROR(
- gckHARDWARE_ConvertLogical(Hardware, FetchAddress, &address));
-
gcmkONERROR(
- gckOS_WriteMemory(Hardware->os, logical + 1, address));
+ gckOS_WriteMemory(Hardware->os, logical + 1, FetchAddress));
/* Make sure the address got written before the LINK command. */
gcmkONERROR(
gckOS_MemoryBarrier(Hardware->os, logical + 1));
/* Compute number of 64-byte aligned bytes to fetch. */
- bytes = gcmALIGN(address + FetchSize, 64) - address;
+ bytes = gcmALIGN(FetchAddress + FetchSize, 64) - FetchAddress;
/* Append LINK(bytes / 8), FetchAddress. */
link = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
gcmkONERROR(
gckOS_MemoryBarrier(Hardware->os, logical));
-#if gcdLINK_QUEUE_SIZE && gcdVIRTUAL_COMMAND_BUFFER
- if (address >= 0x80000000)
+#if gcdLINK_QUEUE_SIZE && !gcdPROCESS_ADDRESS_SPACE
+ if ((Hardware->kernel->virtualCommandBuffer)
+ && (Hardware->kernel->stuckDump > 2)
+ )
{
- gckLINKQUEUE_Enqueue(&Hardware->linkQueue, address, address + bytes);
+ gctBOOL in;
+
+ gcmkVERIFY_OK(gckCOMMAND_AddressInKernelCommandBuffer(
+ Hardware->kernel->command, FetchAddress, &in));
+
+ if (in == gcvFALSE)
+ {
+ /* Record user command buffer and context buffer link
+ ** information for stuck dump.
+ **/
+ gckLINKQUEUE_Enqueue(
+ &Hardware->linkQueue, FetchAddress, FetchAddress + (gctUINT)bytes);
+ }
}
#endif
}
gckOS_MemoryBarrier(Hardware->os, Logical));
/* Notify gckKERNEL object of change. */
+#if gcdMULTI_GPU
gcmkONERROR(
gckKERNEL_Notify(Hardware->kernel,
+ 0,
gcvNOTIFY_COMMAND_QUEUE,
gcvFALSE));
+#else
+ gcmkONERROR(
+ gckKERNEL_Notify(Hardware->kernel,
+ gcvNOTIFY_COMMAND_QUEUE,
+ gcvFALSE));
+#endif
if (status == gcvSTATUS_CHIP_NOT_READY)
{
- gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING);
+ gcmkONERROR(gcvSTATUS_DEVICE);
}
/* Success. */
** gctPOINTER Logical
** Logical address to convert.
**
+** gctBOOL InUserSpace
+** gcvTRUE if the memory in user space.
+**
** gctUINT32* Address
** Return hardware specific address.
**
gckHARDWARE_ConvertLogical(
IN gckHARDWARE Hardware,
IN gctPOINTER Logical,
+ IN gctBOOL InUserSpace,
OUT gctUINT32 * Address
)
{
gceSTATUS status;
gctUINT32 baseAddress;
- gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x", Hardware, Logical);
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x InUserSpace=%d",
+ Hardware, Logical, InUserSpace);
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
gcmkVERIFY_ARGUMENT(Address != gcvNULL);
-#if gcdVIRTUAL_COMMAND_BUFFER
- status = gckKERNEL_GetGPUAddress(Hardware->kernel, Logical, Address);
-
- if (status == gcvSTATUS_INVALID_ADDRESS)
-#endif
+ /* Convert logical address into a physical address. */
+ if (InUserSpace)
{
- /* Convert logical address into a physical address. */
- gcmkONERROR(
- gckOS_GetPhysicalAddress(Hardware->os, Logical, &address));
-
- /* For old MMU, get GPU address according to baseAddress. */
- if (Hardware->mmuVersion == 0)
- {
- gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
-
- /* Subtract base address to get a GPU address. */
- gcmkASSERT(address >= baseAddress);
- address -= baseAddress;
- }
-
- /* Return hardware specific address. */
- *Address = (Hardware->mmuVersion == 0)
- ? ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))) | (((gctUINT32) ((gctUINT32) (address) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0)))
- : address;
+ gcmkONERROR(gckOS_UserLogicalToPhysical(Hardware->os, Logical, &address));
+ }
+ else
+ {
+ gcmkONERROR(gckOS_GetPhysicalAddress(Hardware->os, Logical, &address));
}
-
- /* Success. */
- gcmkFOOTER_ARG("*Address=0x%08x", *Address);
- return gcvSTATUS_OK;
-
-OnError:
- /* Return the status. */
- gcmkFOOTER();
- return status;
-}
-
-/*******************************************************************************
-**
-** gckHARDWARE_ConvertPhysical
-**
-** Convert a physical address into a hardware specific address.
-**
-** INPUT:
-**
-** gckHARDWARE Hardware
-** Pointer to an gckHARDWARE object.
-**
-** gctPHYS_ADDR Physical
-** Physical address to convert.
-**
-** gctUINT32* Address
-** Return hardware specific address.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gckHARDWARE_ConvertPhysical(
- IN gckHARDWARE Hardware,
- IN gctPHYS_ADDR Physical,
- OUT gctUINT32 * Address
- )
-{
- gctUINT32 address;
- gctUINT32 baseAddress;
-
- gcmkHEADER_ARG("Hardware=0x%x Physical=0x%x", Hardware, Physical);
-
- /* Verify the arguments. */
- gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
- gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
- gcmkVERIFY_ARGUMENT(Address != gcvNULL);
-
- address = gcmPTR2INT(Physical);
/* For old MMU, get GPU address according to baseAddress. */
if (Hardware->mmuVersion == 0)
{
- gcmkVERIFY_OK(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
+ gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
/* Subtract base address to get a GPU address. */
gcmkASSERT(address >= baseAddress);
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))) | (((gctUINT32) ((gctUINT32) (address) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0)))
: address;
- /* Return the status. */
+ /* Success. */
gcmkFOOTER_ARG("*Address=0x%08x", *Address);
return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
}
/*******************************************************************************
gceSTATUS
gckHARDWARE_Interrupt(
IN gckHARDWARE Hardware,
+#if gcdMULTI_GPU
+ IN gctUINT CoreId,
+#endif
IN gctBOOL InterruptValid
)
{
gckEVENT eventObj;
- gctUINT32 data;
+ gctUINT32 data = 0;
gceSTATUS status;
gcmkHEADER_ARG("Hardware=0x%x InterruptValid=%d", Hardware, InterruptValid);
if (InterruptValid)
{
/* Read AQIntrAcknowledge register. */
+#if gcdMULTI_GPU
+ if (Hardware->core == gcvCORE_MAJOR)
+ {
+ gcmkONERROR(
+ gckOS_ReadRegisterByCoreId(Hardware->os,
+ Hardware->core,
+ CoreId,
+ 0x00010,
+ &data));
+ }
+ else
+ {
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00010,
+ &data));
+ }
+#else
gcmkONERROR(
gckOS_ReadRegisterEx(Hardware->os,
Hardware->core,
0x00010,
&data));
+#endif
if (data == 0)
{
}
else
{
+
+#if gcdINTERRUPT_STATISTIC
+ gckOS_AtomClearMask(Hardware->pendingEvent, data);
+#endif
+
/* Inform gckEVENT of the interrupt. */
- status = gckEVENT_Interrupt(eventObj, data);
+ status = gckEVENT_Interrupt(eventObj,
+#if gcdMULTI_GPU
+ CoreId,
+#endif
+ data);
}
}
else
{
- /* Handle events. */
- status = gckEVENT_Notify(eventObj, 0);
+ /* Handle events. */
+ status = gckEVENT_Notify(eventObj, 0);
}
OnError:
gceSTATUS
gckHARDWARE_QueryCommandBuffer(
IN gckHARDWARE Hardware,
- OUT gctSIZE_T * Alignment,
- OUT gctSIZE_T * ReservedHead,
- OUT gctSIZE_T * ReservedTail
+ OUT gctUINT32 * Alignment,
+ OUT gctUINT32 * ReservedHead,
+ OUT gctUINT32 * ReservedTail
)
{
gcmkHEADER_ARG("Hardware=0x%x", Hardware);
return gcvSTATUS_OK;
}
-#ifndef VIVANTE_NO_3D
+#if gcdENABLE_3D
/*******************************************************************************
**
** gckHARDWARE_QueryShaderCaps
** Pointer to a variable receiving the number of uniforms in the
** fragment shader.
**
-** gctUINT * Varyings
-** Pointer to a variable receiving the maimum number of varyings.
+** gctBOOL * UnifiedUnforms
+** Pointer to a variable receiving whether the uniformas are unified.
*/
gceSTATUS
gckHARDWARE_QueryShaderCaps(
IN gckHARDWARE Hardware,
OUT gctUINT * VertexUniforms,
OUT gctUINT * FragmentUniforms,
- OUT gctUINT * Varyings
+ OUT gctBOOL * UnifiedUnforms
)
{
+ gctBOOL unifiedConst;
gctUINT32 vsConstMax;
gctUINT32 psConstMax;
+ gctUINT32 vsConstBase;
+ gctUINT32 psConstBase;
+ gctUINT32 ConstMax;
gcmkHEADER_ARG("Hardware=0x%x VertexUniforms=0x%x "
- "FragmentUniforms=0x%x Varyings=0x%x",
+ "FragmentUniforms=0x%x UnifiedUnforms=0x%x",
Hardware, VertexUniforms,
- FragmentUniforms, Varyings);
+ FragmentUniforms, UnifiedUnforms);
- if ((Hardware->identity.chipModel == gcv2000)
- && (Hardware->identity.chipRevision == 0x5118))
- {
- vsConstMax = 256;
- psConstMax = 64;
- }
- else if (Hardware->identity.numConstants > 256)
- {
- vsConstMax = 256;
- psConstMax = 256;
- }
- else if (Hardware->identity.numConstants == 256)
- {
- vsConstMax = 256;
- psConstMax = 256;
- }
- else
- {
- vsConstMax = 168;
- psConstMax = 64;
- }
+ {if (Hardware->identity.numConstants > 256){ unifiedConst = gcvTRUE; vsConstBase = 0xC000; psConstBase = 0xC000; ConstMax = Hardware->identity.numConstants; vsConstMax = 256; psConstMax = ConstMax - vsConstMax;}else if (Hardware->identity.numConstants == 256){ if (Hardware->identity.chipModel == gcv2000 && Hardware->identity.chipRevision == 0x5118) { unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vsConstMax = 256; psConstMax = 64; ConstMax = 320; } else { unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vsConstMax = 256; psConstMax = 256; ConstMax = 512; }}else{ unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vsConstMax = 168; psConstMax = 64; ConstMax = 232;}};
if (VertexUniforms != gcvNULL)
{
+ /* Return the vs shader const count. */
*VertexUniforms = vsConstMax;
}
if (FragmentUniforms != gcvNULL)
{
+ /* Return the ps shader const count. */
*FragmentUniforms = psConstMax;
}
- if (Varyings != gcvNULL)
+ if (UnifiedUnforms != gcvNULL)
{
- /* Return the shader varyings count. */
- *Varyings = Hardware->identity.varyingsCount;
+ /* Return whether the uniformas are unified. */
+ *UnifiedUnforms = unifiedConst;
}
/* Success. */
{
gceSTATUS status;
gctUINT32 address = 0;
- gctUINT32 baseAddress;
+ gctUINT32 idle;
+ gctUINT32 timer = 0, delay = 1;
gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x", Hardware, Logical);
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
- gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
- /* Convert the logical address into an hardware address. */
- gcmkONERROR(
- gckHARDWARE_ConvertLogical(Hardware, Logical, &address));
+ if (Hardware->mmuVersion == 0)
+ {
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
- /* Also get the base address - we need a real physical address. */
- gcmkONERROR(
- gckOS_GetBaseAddress(Hardware->os, &baseAddress));
+ /* Convert the logical address into physical address. */
+ gcmkONERROR(gckOS_GetPhysicalAddress(Hardware->os, Logical, &address));
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
- "Setting page table to 0x%08X",
- address + baseAddress);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Setting page table to 0x%08X",
+ address);
- /* Write the AQMemoryFePageTable register. */
- gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os,
- Hardware->core,
- 0x00400,
- address + baseAddress));
+ /* Write the AQMemoryFePageTable register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00400,
+ address));
- /* Write the AQMemoryRaPageTable register. */
- gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os,
- Hardware->core,
- 0x00410,
- address + baseAddress));
+ /* Write the AQMemoryRaPageTable register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00410,
+ address));
- /* Write the AQMemoryTxPageTable register. */
- gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os,
- Hardware->core,
- 0x00404,
- address + baseAddress));
+ /* Write the AQMemoryTxPageTable register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00404,
+ address));
- /* Write the AQMemoryPePageTable register. */
- gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os,
- Hardware->core,
- 0x00408,
- address + baseAddress));
+ /* Write the AQMemoryPePageTable register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00408,
+ address));
- /* Write the AQMemoryPezPageTable register. */
- gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os,
- Hardware->core,
- 0x0040C,
- address + baseAddress));
+ /* Write the AQMemoryPezPageTable register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0040C,
+ address));
+ }
+ else if (Hardware->enableMMU == gcvTRUE)
+ {
+ /* Execute prepared command sequence. */
+ gcmkONERROR(gckHARDWARE_Execute(
+ Hardware,
+ Hardware->functions[gcvHARDWARE_FUNCTION_MMU].address,
+ Hardware->functions[gcvHARDWARE_FUNCTION_MMU].bytes
+ ));
+
+ /* Wait until MMU configure finishes. */
+ do
+ {
+ gckOS_Delay(Hardware->os, delay);
+
+ gcmkONERROR(gckOS_ReadRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x00004,
+ &idle));
+
+ timer += delay;
+ delay *= 2;
+
+#if gcdGPU_TIMEOUT
+ if (timer >= Hardware->kernel->timeOut)
+ {
+ /* Even if hardware is not reset correctly, let software
+ ** continue to avoid software stuck. Software will timeout again
+ ** and try to recover GPU in next timeout.
+ */
+ gcmkONERROR(gcvSTATUS_DEVICE);
+ }
+#endif
+ }
+ while (!(((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ));
+
+ /* Enable MMU. */
+ gcmkONERROR(gckOS_WriteRegisterEx(
+ Hardware->os,
+ Hardware->core,
+ 0x0018C,
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (gcvTRUE) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ ));
+ }
/* Return the status. */
gcmkFOOTER_NO();
- return status;
+ return gcvSTATUS_OK;
OnError:
/* Return the status. */
gceSTATUS status;
gckCOMMAND command;
gctUINT32_PTR buffer;
- gctSIZE_T bufferSize;
- gctBOOL commitEntered = gcvFALSE;
+ gctUINT32 bufferSize;
gctPOINTER pointer = gcvNULL;
gctUINT32 flushSize;
gctUINT32 count;
/* Verify the gckCOMMAND object pointer. */
command = Hardware->kernel->command;
- /* Acquire the command queue. */
- gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvFALSE));
- commitEntered = gcvTRUE;
-
/* Flush the memory controller. */
if (Hardware->mmuVersion == 0)
{
buffer = (gctUINT32_PTR) pointer;
- count = (bufferSize - flushSize + 7) >> 3;
+ count = ((gctUINT)bufferSize - flushSize + 7) >> 3;
gcmkONERROR(gckOS_GetPhysicalAddress(command->os, buffer, &physical));
= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
gcmkONERROR(gckCOMMAND_Execute(command, flushSize));
}
- /* Release the command queue. */
- gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvFALSE));
- commitEntered = gcvFALSE;
-
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
- if (commitEntered)
- {
- /* Release the command queue mutex. */
- gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Hardware->kernel->command,
- gcvFALSE));
- }
/* Return the status. */
gcmkFOOTER();
return status;
}
-/*******************************************************************************
-**
-** gckHARDWARE_SetMMUv2
-**
-** Set the page table base address.
-**
-** INPUT:
-**
-** gckHARDWARE Harwdare
-** Pointer to an gckHARDWARE object.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
gceSTATUS
-gckHARDWARE_SetMMUv2(
+gckHARDWARE_SetMMUStates(
IN gckHARDWARE Hardware,
- IN gctBOOL Enable,
IN gctPOINTER MtlbAddress,
IN gceMMU_MODE Mode,
IN gctPOINTER SafeAddress,
- IN gctBOOL FromPower
+ IN gctPOINTER Logical,
+ IN OUT gctUINT32 * Bytes
)
{
gceSTATUS status;
gctUINT32 config, address;
- gckCOMMAND command;
gctUINT32_PTR buffer;
- gctSIZE_T bufferSize;
- gctBOOL commitEntered = gcvFALSE;
- gctPOINTER pointer = gcvNULL;
- gctBOOL acquired = gcvFALSE;
+ gctBOOL ace;
+ gctUINT32 reserveBytes = 16 + 4 * 4;
+
gctBOOL config2D;
- gctSIZE_T configSize;
- gcmkHEADER_ARG("Hardware=0x%x Enable=%d", Hardware, Enable);
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Hardware->mmuVersion != 0);
+
+ ace = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_ACE);
+
+ if (ace)
+ {
+ reserveBytes += 8;
+ }
config2D = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PIPE_3D)
&& gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PIPE_2D);
- configSize = 4 * 4;
-
if (config2D)
{
- configSize +=
+ reserveBytes +=
/* Pipe Select. */
4 * 4
/* Configure MMU States. */
- + 4 * 4;
+ + 4 * 4
+ /* Semaphore stall */
+ + 4 * 8;
}
/* Convert logical address into physical address. */
gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
}
- switch (Mode)
+ switch (Mode)
+ {
+ case gcvMMU_MODE_1K:
+ if (config & 0x3FF)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
+ }
+
+ config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ break;
+
+ case gcvMMU_MODE_4K:
+ if (config & 0xFFF)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
+ }
+
+ config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+ break;
+
+ default:
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ if (Logical != gcvNULL)
+ {
+ buffer = Logical;
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++ = config;
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0060) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++ = address;
+
+ if (ace)
+ {
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0068) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++ = 0;
+ }
+
+ do{*buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));} while(0);;
+
+ if (config2D)
+ {
+ /* LoadState(AQPipeSelect, 1), pipe. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++ = 0x1;
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++ = config;
+
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0060) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++ = address;
+
+ do{*buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));} while(0);;
+
+ /* LoadState(AQPipeSelect, 1), pipe. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ *buffer++ = 0x0;
+
+ do{*buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));} while(0);;
+ }
+
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ *Bytes = reserveBytes;
+ }
+
+ /* Return the status. */
+ gcmkFOOTER_NO();
+ return status;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+#if gcdPROCESS_ADDRESS_SPACE
+/*******************************************************************************
+**
+** gckHARDWARE_ConfigMMU
+**
+** Append a MMU Configuration command sequence at the specified location in the command
+** queue. That command sequence consists of mmu configuration, LINK and WAIT/LINK.
+** LINK is fetched and paresed with new mmu configuration.
+**
+** If MMU Configuration is not changed between commit, change last WAIT/LINK to
+** link to ENTRY.
+**
+** -+-----------+-----------+-----------------------------------------
+** | WAIT/LINK | WAIT/LINK |
+** -+-----------+-----------+-----------------------------------------
+** | /|\
+** \|/ |
+** +--------------------+
+** | ENTRY | ... | LINK |
+** +--------------------+
+**
+** If MMU Configuration is changed between commit, change last WAIT/LINK to
+** link to MMU CONFIGURATION command sequence, and there are an EVNET and
+** an END at the end of this command sequence, when interrupt handler
+** receives this event, it will start FE at ENTRY to continue the command
+** buffer execution.
+**
+** -+-----------+-------------------+---------+---------+-----------+--
+** | WAIT/LINK | MMU CONFIGURATION | EVENT | END | WAIT/LINK |
+** -+-----------+-------------------+---------+---------+-----------+--
+** | /|\ /|\
+** +-------------+ |
+** +--------------------+
+** | ENTRY | ... | LINK |
+** +--------------------+
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command queue to append
+** command sequence at or gcvNULL just to query the size of the
+** command sequence.
+**
+** gctPOINTER MtlbLogical
+** Pointer to the current Master TLB.
+**
+** gctUINT32 Offset
+** Offset into command buffer required for alignment.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the command
+** sequence. If 'Logical' is gcvNULL, this argument will be ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** by the command sequence. If 'Bytes' is gcvNULL, nothing will
+** be returned.
+**
+** gctUINT32 * WaitLinkOffset
+** Pointer to a variable that will receive the offset of the WAIT/LINK command
+** from the specified logcial pointer.
+** If 'WaitLinkOffset' is gcvNULL nothing will be returned.
+**
+** gctSIZE_T * WaitLinkBytes
+** Pointer to a variable that will receive the number of bytes used by
+** the WAIT command.
+** If 'WaitLinkBytes' is gcvNULL nothing will be returned.
+*/
+gceSTATUS
+gckHARDWARE_ConfigMMU(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctPOINTER MtlbLogical,
+ IN gctUINT32 Offset,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctSIZE_T * WaitLinkOffset,
+ OUT gctSIZE_T * WaitLinkBytes
+ )
+{
+ gceSTATUS status;
+ gctSIZE_T bytes, bytesAligned;
+ gctUINT32 config;
+ gctUINT32_PTR buffer = (gctUINT32_PTR) Logical;
+ gctUINT32 physical;
+ gctUINT32 event;
+
+ gcmkHEADER_ARG("Hardware=0x%08X Logical=0x%08x MtlbLogical=0x%08X",
+ Hardware, Logical, MtlbLogical);
+
+ bytes
+ /* Flush cache states. */
+ = 18 * 4
+ /* MMU configuration states. */
+ + 6 * 4
+ /* EVENT. */
+ + 2 * 4
+ /* END. */
+ + 2 * 4
+ /* WAIT/LINK. */
+ + 4 * 4;
+
+ /* Compute number of bytes required. */
+ bytesAligned = gcmALIGN(Offset + bytes, 8) - Offset;
+
+ if (buffer != gcvNULL)
{
- case gcvMMU_MODE_1K:
- if (config & 0x3FF)
+ if (MtlbLogical == gcvNULL)
{
- gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
}
- config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
-
- break;
+ /* Get physical address of this command buffer segment. */
+ gcmkONERROR(gckOS_GetPhysicalAddress(Hardware->os, buffer, &physical));
- case gcvMMU_MODE_4K:
- if (config & 0xFFF)
- {
- gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
- }
+ /* Get physical address of Master TLB. */
+ gcmkONERROR(gckOS_GetPhysicalAddress(Hardware->os, MtlbLogical, &config));
- config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
- break;
+ /* Flush cache. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
- default:
- gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
- }
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
- /* Verify the gckCOMMAND object pointer. */
- command = Hardware->kernel->command;
+ /* Flush tile status cache. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0594) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
- /* Acquire the command queue. */
- gcmkONERROR(gckCOMMAND_EnterCommit(command, FromPower));
- commitEntered = gcvTRUE;
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
- gcmkONERROR(gckCOMMAND_Reserve(
- command, configSize, &pointer, &bufferSize
- ));
+ /* Arm the PE-FE Semaphore. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
- buffer = pointer;
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
- buffer[0]
- = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+ /* STALL FE until PE is done flushing. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
- buffer[1] = config;
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
- buffer[2]
- = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0060) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+ /* LINK to next slot to flush FE FIFO. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (4) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
- buffer[3] = address;
+ *buffer++
+ = physical + 10 * gcmSIZEOF(gctUINT32);
- if (config2D)
- {
- /* LoadState(AQPipeSelect, 1), pipe. */
- buffer[4]
+ /* Configure MMU. */
+ *buffer++
= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
- buffer[5] = 0x1;
+ *buffer++
+ = (((((gctUINT32) (~0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) & ((((gctUINT32) (~0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))));
- buffer[6]
+ /* Arm the PE-FE Semaphore. */
+ *buffer++
= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
- buffer[7] = config;
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
- buffer[8]
- = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0060) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+ /* STALL FE until PE is done flushing. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
- buffer[9] = address;
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
- /* LoadState(AQPipeSelect, 1), pipe. */
- buffer[10]
+ /* LINK to next slot to flush FE FIFO. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *buffer++
+ = physical + 18 * 4;
+
+ *buffer++
= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
- buffer[11] = 0x0;
- }
-
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
- "Setup MMU: config=%08x, Safe Address=%08x\n.", config, address);
+ *buffer++
+ = config;
- gcmkONERROR(gckCOMMAND_Execute(command, configSize));
+ /* Arm the PE-FE Semaphore. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
- if (FromPower == gcvFALSE)
- {
- /* Acquire global semaphore to suspend power management until MMU
- ** is enabled. And acquired it before gckCOMMAND_ExitCommit to
- ** make sure GPU keeps ON. */
- gcmkONERROR(
- gckOS_AcquireSemaphore(Hardware->os, Hardware->globalSemaphore));
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
- acquired = gcvTRUE;
- }
+ /* STALL FE until PE is done flushing. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
- /* Release the command queue. */
- gcmkONERROR(gckCOMMAND_ExitCommit(command, FromPower));
- commitEntered = gcvFALSE;
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
- "call gckCOMMAND_Stall to make sure the config is done.\n ");
+ /* Event 29. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
- gcmkONERROR(gckCOMMAND_Stall(command, FromPower));
+ event = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
+ event = ((((gctUINT32) (event)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) ((gctUINT32) (29) & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)));
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
- "Enable MMU through GCREG_MMU_CONTROL.");
+ *buffer++
+ = event;
- /* Enable MMU. */
- gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os,
- Hardware->core,
- 0x0018C,
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (Enable) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))));
+ /* Append END. */
+ *buffer++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x02 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+ }
- if (FromPower == gcvFALSE)
+ if (Bytes != gcvNULL)
{
- /* Relase global semaphore. */
- gcmkVERIFY_OK(
- gckOS_ReleaseSemaphore(Hardware->os, Hardware->globalSemaphore));
-
- acquired = gcvFALSE;
+ *Bytes = bytesAligned;
}
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
- "call gckCOMMAND_Stall to check MMU available.\n");
-
- gcmkONERROR(gckCOMMAND_Stall(command, FromPower));
-
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
- "The MMU is available.\n");
-
- /* Return the status. */
- gcmkFOOTER_NO();
- return status;
-
-OnError:
- if (commitEntered)
+ if (WaitLinkOffset != gcvNULL)
{
- /* Release the command queue mutex. */
- gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Hardware->kernel->command,
- FromPower));
+ *WaitLinkOffset = bytes - 4 * 4;
}
- if (acquired)
+ if (WaitLinkBytes != gcvNULL)
{
- gcmkVERIFY_OK(
- gckOS_ReleaseSemaphore(Hardware->os, Hardware->globalSemaphore));
+#if gcdMULTI_GPU
+ *WaitLinkBytes = 40;
+#else
+ *WaitLinkBytes = 4 * 4;
+#endif
}
- /* Return the status. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
gcmkFOOTER();
return status;
}
+#endif
/*******************************************************************************
**
gceSTATUS status;
gctUINT32 idle = 0;
gctINT retry, poll, pollCount;
+ gctUINT32 address;
gcmkHEADER_ARG("Hardware=0x%x Wait=%d", Hardware, Wait);
gcmkONERROR(
gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00004, &idle));
+ /* Read the current FE address. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00664,
+ &address));
+
+
/* See if we have to wait for FE idle. */
- if ((((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
+ if (_IsGPUIdle(idle)
+ && (address == Hardware->lastEnd + 8)
+ )
{
/* FE is idle. */
break;
}
/* Check if we need to wait for FE and FE is busy. */
- if (Wait && !(((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
+ if (Wait && !_IsGPUIdle(idle))
{
/* Wait a little. */
gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
/* Return idle to caller. */
*Data = idle;
+#if defined(EMULATOR)
+ /* Wait a little while until CModel FE gets END.
+ * END is supposed to be appended by caller.
+ */
+ gckOS_Delay(gcvNULL, 100);
+#endif
+
/* Success. */
gcmkFOOTER_ARG("*Data=0x%08x", *Data);
return gcvSTATUS_OK;
IN gckHARDWARE Hardware,
IN gceKERNEL_FLUSH Flush,
IN gctPOINTER Logical,
- IN OUT gctSIZE_T * Bytes
+ IN OUT gctUINT32 * Bytes
)
{
gctUINT32 pipe;
gctUINT32 flush = 0;
+ gctBOOL flushTileStatus;
gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
gceSTATUS status;
- gctBOOL fcFlushStall;
- gctUINT32 reserveBytes = 8;
+ gctUINT32 reserveBytes
+ /* Semaphore/Stall */
+ = 4 * gcmSIZEOF(gctUINT32);
gcmkHEADER_ARG("Hardware=0x%x Flush=0x%x Logical=0x%x *Bytes=%lu",
Hardware, Flush, Logical, gcmOPT_VALUE(Bytes));
/* Get current pipe. */
pipe = Hardware->kernel->command->pipeSelect;
- fcFlushStall
- = ((((gctUINT32) (Hardware->identity.chipMinorFeatures1)) >> (0 ? 31:31) & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1)))))))
- && (Flush == gcvFLUSH_ALL)
- ;
-
- if (fcFlushStall)
- {
- reserveBytes += 8;
- }
+ /* Flush tile status cache. */
+ flushTileStatus = Flush & gcvFLUSH_TILE_STATUS;
/* Flush 3D color cache. */
if ((Flush & gcvFLUSH_COLOR) && (pipe == 0x0))
if ((Flush & gcvFLUSH_TEXTURE) && (pipe == 0x0))
{
flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)));
- flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
}
/* Flush 2D cache. */
flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)));
}
+#if gcdMULTI_GPU
+ /* Flush L2 cache. */
+ if ((Flush & gcvFLUSH_L2) && (pipe == 0x0))
+ {
+ flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
+ }
+#endif
+
+ /* Determine reserve bytes. */
+ if (flush)
+ {
+ reserveBytes += 2 * gcmSIZEOF(gctUINT32);
+ }
+
+ if (flushTileStatus)
+ {
+ reserveBytes += 2 * gcmSIZEOF(gctUINT32);
+ }
+
/* See if there is a valid flush. */
- if (flush == 0)
+ if ((flush == 0) && (flushTileStatus == gcvFALSE))
{
if (Bytes != gcvNULL)
{
gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
}
- /* Append LOAD_STATE to AQFlush. */
- logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+ if (flush)
+ {
+ /* Append LOAD_STATE to AQFlush. */
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
- logical[1] = flush;
+ *logical++
+ = flush;
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
- "0x%x: FLUSH 0x%x", logical, flush);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%x: FLUSH 0x%x", logical - 1, flush);
+ }
- if (fcFlushStall)
+ if (flushTileStatus)
{
- logical[2] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0594) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
-
- logical[3] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0594) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
- "0x%x: FLUSH 0x%x", logical + 3, logical[3]);
+ "0x%x: FLUSH TILE STATUS 0x%x", logical - 1, logical[-1]);
}
+ /* Semaphore. */
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+ /* Stall. */
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ *logical++
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x05 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
}
if (Bytes != gcvNULL)
IN gctINT Compression
)
{
-#ifndef VIVANTE_NO_3D
+#if gcdENABLE_3D
gctUINT32 debug;
gceSTATUS status;
gcmSTRING(gcvPOWER_SUSPEND_BROADCAST),
gcmSTRING(gcvPOWER_OFF_BROADCAST),
gcmSTRING(gcvPOWER_OFF_RECOVERY),
+ gcmSTRING(gcvPOWER_OFF_TIMEOUT),
gcmSTRING(gcvPOWER_ON_AUTO)
};
gckOS os;
gctUINT flag, clock;
gctPOINTER buffer;
- gctSIZE_T bytes, requested;
+ gctUINT32 bytes, requested;
gctBOOL acquired = gcvFALSE;
gctBOOL mutexAcquired = gcvFALSE;
gctBOOL stall = gcvTRUE;
command = Hardware->kernel->command;
gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
- if (Hardware->powerManagement == gcvFALSE)
- {
- gcmkFOOTER_NO();
- return gcvSTATUS_OK;
- }
-
/* Start profiler. */
gcmkPROFILE_INIT(freq, time);
break;
}
+ if (Hardware->powerManagement == gcvFALSE
+ && State != gcvPOWER_ON
+ )
+ {
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
/* Get current process and thread IDs. */
gcmkONERROR(gckOS_GetProcessID(&process));
gcmkONERROR(gckOS_GetThreadID(&thread));
gcmkFOOTER_NO();
return gcvSTATUS_OK;
}
- else if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
+ else if (State != gcvPOWER_ON)
{
/* Called from IST,
** so waiting here will cause deadlock,
** if lock holder call gckCOMMAND_Stall() */
- gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
- }
-#if gcdPOWEROFF_TIMEOUT
- else if(State == gcvPOWER_OFF && timeout == gcvTRUE)
- {
- /*
- ** try to aqcuire the mutex with more milliseconds,
- ** flush_delayed_work should be running with timeout,
- ** so waiting here will cause deadlock */
- status = gckOS_AcquireMutex(os, Hardware->powerMutex, gcdPOWEROFF_TIMEOUT);
-
- if (status == gcvSTATUS_TIMEOUT)
- {
- gckOS_Print("GPU Timer deadlock, exit by timeout!!!!\n");
-
- gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
- }
+ status = gcvSTATUS_INVALID_REQUEST;
+ goto OnError;
}
-#endif
else
{
/* Acquire the power mutex. */
if (State == gcvPOWER_SUSPEND && Hardware->chipPowerState == gcvPOWER_OFF && broadcast)
{
-#if gcdPOWER_SUSNPEND_WHEN_IDLE
- /* Do nothing */
+#if gcdPOWER_SUSPEND_WHEN_IDLE
+ /* Do nothing */
- /* Release the power mutex. */
+ /* Release the power mutex. */
gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
- gcmkFOOTER_NO();
+ gcmkFOOTER_NO();
return gcvSTATUS_OK;
#else
- /* Clock should be on when switch power from off to suspend */
+ /* Clock should be on when switch power from off to suspend */
clock = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
commitEntered = gcvFALSE;
/* Wait to finish all commands. */
+#if gcdMULTI_GPU
+ gcmkONERROR(gckCOMMAND_Stall(command, gcvTRUE, gcvCORE_3D_ALL_MASK));
+#else
gcmkONERROR(gckCOMMAND_Stall(command, gcvTRUE));
+#endif
}
}
if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
{
if (Hardware->identity.chipModel == gcv4000
- && Hardware->identity.chipRevision == 0x5208)
+ && ((Hardware->identity.chipRevision == 0x5208) || (Hardware->identity.chipRevision == 0x5222)))
{
clock &= ~2U;
}
gcmkONERROR(Hardware->startIsr(Hardware->isrContext));
isrStarted = gcvTRUE;
}
-
- /* Set NEW MMU. */
- if (Hardware->mmuVersion != 0 && configMmu)
- {
- gcmkONERROR(
- gckHARDWARE_SetMMUv2(
- Hardware,
- gcvTRUE,
- Hardware->kernel->mmu->mtlbLogical,
- gcvMMU_MODE_4K,
- (gctUINT8_PTR)Hardware->kernel->mmu->mtlbLogical + gcdMMU_MTLB_SIZE,
- gcvTRUE
- ));
- }
}
/* Get time until started. */
** gckHARDWARE_SetPowerManagement
**
** Configure GPU power management function.
-** Only used in driver initialization stage.
**
** INPUT:
**
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ if(!Hardware->powerManagementLock)
+ {
+ gcmkVERIFY_OK(
+ gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE));
- Hardware->powerManagement = PowerManagement;
+ Hardware->powerManagement = PowerManagement;
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
+ }
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
}
+/*******************************************************************************
+**
+** gckHARDWARE_SetPowerManagementLock
+**
+** Disable dynamic GPU power management switch.
+** Only used in driver initialization stage.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** gctBOOL Lock
+** Power Mangement Lock State.
+**
+*/
+gceSTATUS
+gckHARDWARE_SetPowerManagementLock(
+ IN gckHARDWARE Hardware,
+ IN gctBOOL Lock
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ Hardware->powerManagementLock = Lock;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
/*******************************************************************************
**
** gckHARDWARE_SetGpuProfiler
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ if (GpuProfiler == gcvTRUE)
+ {
+ gctUINT32 data = 0;
+
+ /* Need to disable clock gating when doing profiling. */
+ gcmkVERIFY_OK(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress +
+ 0x00100,
+ &data));
+
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+
+ gcmkVERIFY_OK(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00100,
+ data));
+ }
+
Hardware->gpuProfiler = GpuProfiler;
/* Success. */
if (Hardware->chipPowerState == gcvPOWER_ON)
{
- gctUINT32 data;
+ gctUINT32 data;
gcmkONERROR(
gckOS_ReadRegisterEx(Hardware->os,
)
{
*FscaleValue = Hardware->powerOnFscaleVal;
- if ((gpu3DMinClock > 0) && (gpu3DMinClock <= 64) && (Hardware->core == gcvCORE_MAJOR))
- *MinFscaleValue = gpu3DMinClock;
- else
- *MinFscaleValue = 1;
+ *MinFscaleValue = Hardware->minFscaleValue;
*MaxFscaleValue = 64;
return gcvSTATUS_OK;
}
+gceSTATUS
+gckHARDWARE_SetMinFscaleValue(
+ IN gckHARDWARE Hardware,
+ IN gctUINT MinFscaleValue
+ )
+{
+ if (MinFscaleValue >= 1 && MinFscaleValue <= 64)
+ {
+ Hardware->minFscaleValue = MinFscaleValue;
+ }
+
+ return gcvSTATUS_OK;
+}
#endif
#if gcdPOWEROFF_TIMEOUT
{
gceSTATUS status;
gctUINT32 idle, address;
+ gctBOOL isIdle;
+#if gcdMULTI_GPU > 1
+ gctUINT32 idle3D1 = 0;
+ gctUINT32 address3D1;
+ gctBOOL isIdle3D1 = gcvFALSE;
+#endif
+
+#if gcdINTERRUPT_STATISTIC
+ gctINT32 pendingInterrupt;
+#endif
gcmkHEADER_ARG("Hardware=0x%x", Hardware);
/* We are idle when the power is not ON. */
if (Hardware->chipPowerState != gcvPOWER_ON)
{
- *IsIdle = gcvTRUE;
+ isIdle = gcvTRUE;
+#if gcdMULTI_GPU > 1
+ isIdle3D1 = gcvTRUE;
+#endif
}
else
gcmkONERROR(
gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00004, &idle));
+#if gcdMULTI_GPU > 1
+ if (Hardware->core == gcvCORE_MAJOR)
+ {
+ gcmkONERROR(
+ gckOS_ReadRegisterByCoreId(Hardware->os,
+ Hardware->core,
+ gcvCORE_3D_1_ID,
+ 0x00004,
+ &idle3D1));
+ }
+#endif
+
/* Pipe must be idle. */
if (((((((gctUINT32) (idle)) >> (0 ? 1:1)) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1)))))) ) != 1)
|| ((((((gctUINT32) (idle)) >> (0 ? 3:3)) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) ) != 1)
)
{
/* Something is busy. */
- *IsIdle = gcvFALSE;
+ isIdle = gcvFALSE;
}
else
{
+#if gcdSECURITY
+ isIdle = gcvTRUE;
+ address = 0;
+#else
/* Read the current FE address. */
gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
Hardware->core,
/* Test if address is inside the last WAIT/LINK sequence. */
if ((address >= Hardware->lastWaitLink)
+#if gcdMULTI_GPU
+ && (address <= Hardware->lastWaitLink + 40)
+#else
&& (address <= Hardware->lastWaitLink + 16)
+#endif
)
{
/* FE is in last WAIT/LINK and the pipe is idle. */
- *IsIdle = gcvTRUE;
+ isIdle = gcvTRUE;
}
else
{
/* FE is not in WAIT/LINK yet. */
- *IsIdle = gcvFALSE;
+ isIdle = gcvFALSE;
+ }
+#endif
+ }
+
+#if gcdMULTI_GPU > 1
+ if (Hardware->core == gcvCORE_MAJOR)
+ {
+ /* Pipe must be idle. */
+ if (((((((gctUINT32) (idle3D1)) >> (0 ? 1:1)) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1)))))) ) != 1)
+ || ((((((gctUINT32) (idle3D1)) >> (0 ? 3:3)) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) ) != 1)
+ || ((((((gctUINT32) (idle3D1)) >> (0 ? 4:4)) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1)))))) ) != 1)
+ || ((((((gctUINT32) (idle3D1)) >> (0 ? 5:5)) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1)))))) ) != 1)
+ || ((((((gctUINT32) (idle3D1)) >> (0 ? 6:6)) & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1)))))) ) != 1)
+ || ((((((gctUINT32) (idle3D1)) >> (0 ? 7:7)) & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1)))))) ) != 1)
+ || ((((((gctUINT32) (idle3D1)) >> (0 ? 2:2)) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))) ) != 1)
+ )
+ {
+ /* Something is busy. */
+ isIdle3D1 = gcvFALSE;
+ }
+
+ else
+ {
+ /* Read the current FE address. */
+ gcmkONERROR(gckOS_ReadRegisterByCoreId(Hardware->os,
+ Hardware->core,
+ gcvCORE_3D_1_ID,
+ 0x00664,
+ &address3D1));
+
+ /* Test if address is inside the last WAIT/LINK sequence. */
+ if ((address3D1 >= Hardware->lastWaitLink)
+ && (address3D1 <= Hardware->lastWaitLink + 40)
+ )
+ {
+ /* FE is in last WAIT/LINK and the pipe is idle. */
+ isIdle3D1 = gcvTRUE;
+ }
+ else
+ {
+ /* FE is not in WAIT/LINK yet. */
+ isIdle3D1 = gcvFALSE;
+ }
}
}
+#endif
+
+ }
+
+#if gcdINTERRUPT_STATISTIC
+ gcmkONERROR(gckOS_AtomGet(
+ Hardware->os,
+ Hardware->kernel->eventObj->interruptCount,
+ &pendingInterrupt
+ ));
+
+ if (pendingInterrupt)
+ {
+ isIdle = gcvFALSE;
+ }
+#endif
+
+#if gcdMULTI_GPU > 1
+ if (Hardware->core == gcvCORE_MAJOR)
+ {
+ *IsIdle = (isIdle & isIdle3D1);
+ }
+ else
+#endif
+ {
+ *IsIdle = isIdle;
}
/* Success. */
gceSTATUS
gckHARDWARE_QueryProfileRegisters(
IN gckHARDWARE Hardware,
- IN gctBOOL Reset,
+ IN gctBOOL Reset,
OUT gcsPROFILER_COUNTERS * Counters
)
{
gcmkONERROR(
gckOS_ReadRegisterEx(Hardware->os,
- Hardware->core,
+ Hardware->core,
0x0007C,
&profiler->gpuIdleCyclesCounter));
profiler->pe_pixel_count_drawn_by_color_pipe = 0;
profiler->pe_pixel_count_drawn_by_depth_pipe = 0;
- /* Walk through all avaiable pixel pipes. */
+ /* Walk through all avaiable pixel pipes. */
for (i = 0; i < Hardware->identity.pixelPipes; ++i)
{
/* Select proper pipe. */
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
- Hardware->core,
- 0x00000,
- ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20))) | (((gctUINT32) ((gctUINT32) (i) & ((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20)))));
+ Hardware->core,
+ 0x00000,
+ ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20))) | (((gctUINT32) ((gctUINT32) (i) & ((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20)))));
/* BW */
gcmkONERROR(
0x00000,
clock));
- if(Reset){
- /* Reset counters. */
- gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 1));
- gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 0));
- gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00438, 0));
- gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00078, 0));
- gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+ /* Reset counters. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 1));
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 0));
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00438, 0));
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00078, 0));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))
));
- }
/* SH */
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_branch_inst_counter));
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (14) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_texld_inst_counter));
- if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24)))
-));}
+));
/* PA */
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_trivial_rejected_counter));
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_culled_counter));
- if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)))
-));}
+));
/* SE */
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_triangle_count));
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_lines_count));
- if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8)))
-));}
+));
/* RA */
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_pipe_cache_miss_counter));
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (10) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_prefetch_cache_miss_counter));
- if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))
-));}
+));
/* TX */
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_hit_texel_count));
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_texel_count));
- if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24)))
-));}
+));
/* MC */
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_IP));
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_write_req_8B_from_pipeline));
- if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)))
-));}
+));
/* HI */
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_request_stalled));
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_data_stalled));
- if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8)))
-));}
+));
/* Success. */
gcmkFOOTER_NO();
}
#endif
+
#if VIVANTE_PROFILER_CONTEXT
#define gcmkUPDATE_PROFILE_DATA(data) \
profilerHistroy->data += profiler->data
gceSTATUS
gckHARDWARE_QueryContextProfile(
IN gckHARDWARE Hardware,
- IN gctBOOL Reset,
+ IN gctBOOL Reset,
IN gckCONTEXT Context,
OUT gcsPROFILER_COUNTERS * Counters
)
profiler, &Context->histroyProfiler, gcmSIZEOF(gcsPROFILER_COUNTERS)
));
- if (Reset)
- {
- /* Reset counters. */
- gcmkVERIFY_OK(gckOS_ZeroMemory(
- &Context->histroyProfiler, gcmSIZEOF(gcsPROFILER_COUNTERS)
- ));
- }
+ /* Reset counters. */
+ gcmkVERIFY_OK(gckOS_ZeroMemory(
+ &Context->histroyProfiler, gcmSIZEOF(gcsPROFILER_COUNTERS)
+ ));
gcmkVERIFY_OK(gckOS_ReleaseMutex(
command->os, command->mutexContextSeq
return status;
}
+static gctUINT32
+CalcDelta(
+ IN gctUINT32 new,
+ IN gctUINT32 old
+ )
+{
+ if (new >= old)
+ {
+ return new - old;
+ }
+ else
+ {
+ return (gctUINT32)((gctUINT64)new + 0x100000000ll - old);
+ }
+}
gceSTATUS
gckHARDWARE_UpdateContextProfile(
gcsPROFILER_COUNTERS * profiler = &Context->latestProfiler;
gcsPROFILER_COUNTERS * profilerHistroy = &Context->histroyProfiler;
gctUINT i, clock;
- gctUINT32 colorKilled, colorDrawn, depthKilled, depthDrawn;
+ gctUINT32 colorKilled = 0, colorDrawn = 0, depthKilled = 0, depthDrawn = 0;
gctUINT32 totalRead, totalWrite;
gceCHIPMODEL chipModel;
gctUINT32 chipRevision;
clock));
-
-
/* Reset counters. */
gcmkONERROR(
gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 1));
if (needResetShader)
{
temp = profiler->ps_inst_counter;
- profiler->ps_inst_counter -= Context->prevPSInstCount;
+ profiler->ps_inst_counter = CalcDelta(temp, Context->prevPSInstCount);
Context->prevPSInstCount = temp;
}
gcmkUPDATE_PROFILE_DATA(ps_inst_counter);
if (needResetShader)
{
temp = profiler->rendered_pixel_counter;
- profiler->rendered_pixel_counter -= Context->prevPSPixelCount;
+ profiler->rendered_pixel_counter = CalcDelta(temp, Context->prevPSPixelCount);
Context->prevPSPixelCount = temp;
}
gcmkUPDATE_PROFILE_DATA(rendered_pixel_counter);
if (needResetShader)
{
temp = profiler->vs_inst_counter;
- profiler->vs_inst_counter -= Context->prevVSInstCount;
+ profiler->vs_inst_counter = CalcDelta(temp, Context->prevVSInstCount);
Context->prevVSInstCount = temp;
}
gcmkUPDATE_PROFILE_DATA(vs_inst_counter);
if (needResetShader)
{
temp = profiler->rendered_vertice_counter;
- profiler->rendered_vertice_counter -= Context->prevVSVertexCount;
+ profiler->rendered_vertice_counter = CalcDelta(temp, Context->prevVSVertexCount);
Context->prevVSVertexCount = temp;
}
gcmkUPDATE_PROFILE_DATA(rendered_vertice_counter);
if (needResetShader)
{
temp = profiler->vtx_branch_inst_counter;
- profiler->vtx_branch_inst_counter -= Context->prevVSBranchInstCount;
+ profiler->vtx_branch_inst_counter = CalcDelta(temp, Context->prevVSBranchInstCount);
Context->prevVSBranchInstCount = temp;
}
gcmkUPDATE_PROFILE_DATA(vtx_branch_inst_counter);
if (needResetShader)
{
temp = profiler->vtx_texld_inst_counter;
- profiler->vtx_texld_inst_counter -= Context->prevVSTexInstCount;
+ profiler->vtx_texld_inst_counter = CalcDelta(temp, Context->prevVSTexInstCount);
Context->prevVSTexInstCount = temp;
}
gcmkUPDATE_PROFILE_DATA(vtx_texld_inst_counter);
if (needResetShader)
{
temp = profiler->pxl_branch_inst_counter;
- profiler->pxl_branch_inst_counter -= Context->prevPSBranchInstCount;
+ profiler->pxl_branch_inst_counter = CalcDelta(temp, Context->prevPSBranchInstCount);
Context->prevPSBranchInstCount = temp;
}
gcmkUPDATE_PROFILE_DATA(pxl_branch_inst_counter);
if (needResetShader)
{
temp = profiler->pxl_texld_inst_counter;
- profiler->pxl_texld_inst_counter -= Context->prevPSTexInstCount;
+ profiler->pxl_texld_inst_counter = CalcDelta(temp, Context->prevPSTexInstCount);
Context->prevPSTexInstCount = temp;
}
gcmkUPDATE_PROFILE_DATA(pxl_texld_inst_counter);
}
#endif
+
+#if VIVANTE_PROFILER_NEW
+gceSTATUS
+gckHARDWARE_InitProfiler(
+ IN gckHARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+ gctUINT32 control;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ &control));
+ /* Enable debug register. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11)))));
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
static gceSTATUS
_ResetGPU(
IN gckHARDWARE Hardware,
continue;
}
+#if gcdMULTI_GPU > 1
+ if (Core == gcvCORE_MAJOR)
+ {
+ /* Read idle register. */
+ gcmkONERROR(gckOS_ReadRegisterByCoreId(Os,
+ Core,
+ gcvCORE_3D_1_ID,
+ 0x00004,
+ &idle));
+
+ if ((((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ) == 0)
+ {
+ continue;
+ }
+ }
+#endif
/* Read reset register. */
gcmkONERROR(gckOS_ReadRegisterEx(Os,
Core,
continue;
}
+#if gcdMULTI_GPU > 1
+ if (Core == gcvCORE_MAJOR)
+ {
+ /* Read reset register. */
+ gcmkONERROR(gckOS_ReadRegisterByCoreId(Os,
+ Core,
+ gcvCORE_3D_1_ID,
+ 0x00000,
+ &control));
+
+ if (((((((gctUINT32) (control)) >> (0 ? 16:16)) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) ) == 0)
+ || ((((((gctUINT32) (control)) >> (0 ? 17:17)) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1)))))) ) == 0)
+ )
+ {
+ continue;
+ }
+ }
+#endif
/* GPU is idle. */
break;
}
)
{
gceSTATUS status;
- gckCOMMAND command;
- gctBOOL acquired = gcvFALSE;
- gctBOOL mutexAcquired = gcvFALSE;
- gctUINT32 process, thread;
gcmkHEADER_ARG("Hardware=0x%x", Hardware);
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
- command = Hardware->kernel->command;
- gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
-
- if (Hardware->identity.chipRevision < 0x4600)
- {
- /* Not supported - we need the isolation bit. */
- gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
- }
-
- status = gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, 0);
- if (status == gcvSTATUS_TIMEOUT)
- {
- gcmkONERROR(gckOS_GetProcessID(&process));
- gcmkONERROR(gckOS_GetThreadID(&thread));
-
- if ((Hardware->powerProcess == process)
- && (Hardware->powerThread == thread))
- {
- /* No way to recovery from a error in power management. */
- gcmkFOOTER_NO();
- return gcvSTATUS_OK;
- }
- }
- else
- {
- mutexAcquired = gcvTRUE;
- }
-
- if (Hardware->chipPowerState == gcvPOWER_ON)
- {
- /* Acquire the power management semaphore. */
- gcmkONERROR(
- gckOS_AcquireSemaphore(Hardware->os, command->powerSemaphore));
- acquired = gcvTRUE;
- }
-
- if ((Hardware->chipPowerState == gcvPOWER_ON)
- || (Hardware->chipPowerState == gcvPOWER_IDLE)
- )
- {
- /* Stop the command processor. */
- gcmkONERROR(gckCOMMAND_Stop(command, gcvTRUE));
- }
-
- /* Stop isr, we will start it again when power on GPU. */
- if (Hardware->stopIsr)
- {
- gcmkONERROR(Hardware->stopIsr(Hardware->isrContext));
- }
/* Hardware reset. */
status = gckOS_ResetGPU(Hardware->os, Hardware->core);
if (gcmIS_ERROR(status))
{
+ if (Hardware->identity.chipRevision < 0x4600)
+ {
+ /* Not supported - we need the isolation bit. */
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
/* Soft reset. */
gcmkONERROR(_ResetGPU(Hardware, Hardware->os, Hardware->core));
}
- /* Force an OFF to ON power switch. */
- Hardware->chipPowerState = gcvPOWER_OFF;
+ /* Initialize hardware. */
+ gcmkONERROR(gckHARDWARE_InitializeHardware(Hardware));
- gcmkONERROR(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
- mutexAcquired = gcvFALSE;
+ /* Jump to address into which GPU should run if it doesn't stuck. */
+ gcmkONERROR(gckHARDWARE_Execute(Hardware, Hardware->kernel->restoreAddress, 16));
+
+ gcmkPRINT("[galcore]: recovery done");
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
- if (acquired)
- {
- /* Release the power management semaphore. */
- gcmkVERIFY_OK(
- gckOS_ReleaseSemaphore(Hardware->os, command->powerSemaphore));
- }
-
- if (mutexAcquired)
- {
- gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex);
- }
+ gcmkPRINT("[galcore]: Hardware not reset successfully, give up");
/* Return the error. */
gcmkFOOTER();
/* Make sure this is a load state. */
if (((((gctUINT32) (State)) >> (0 ? 31:27) & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1)))))) == (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))))
{
-#ifndef VIVANTE_NO_3D
+#if gcdENABLE_3D
/* Get the state address. */
switch ((((((gctUINT32) (State)) >> (0 ? 15:0)) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1)))))) ))
{
IN gctUINT8 EventID
)
{
-#ifndef VIVANTE_NO_3D
+#if gcdENABLE_3D
gceSTATUS status;
gctUINT32_PTR triggerState;
/* Flush the cache for the wait/link. */
gcmkONERROR(gckOS_CacheClean(
Hardware->os, ProcessID, gcvNULL,
- Physical, Logical, Offset + Size
+ (gctUINT32)Physical, Logical, Offset + Size
));
#endif
);*/
available = gcvFALSE;
break;
+
case gcvFEATURE_MC20:
available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures)) >> (0 ? 22:22) & ((gctUINT32) ((((1 ? 22:22) - (0 ? 22:22) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 22:22) - (0 ? 22:22) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 22:22) - (0 ? 22:22) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 22:22) - (0 ? 22:22) + 1)))))));
break;
+
+ case gcvFEATURE_EARLY_Z:
+ available = ((((gctUINT32) (Hardware->identity.chipFeatures)) >> (0 ? 16:16) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) == (0x0 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))));
+ break;
+
+ case gcvFEATURE_HZ:
+ available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures)) >> (0 ? 27:27) & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1)))))));
+ break;
+
+ case gcvFEATURE_NEW_HZ:
+ available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures3)) >> (0 ? 26:26) & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))));
+ break;
+
+ case gcvFEATURE_FAST_MSAA:
+ available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures3)) >> (0 ? 8:8) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))));
+ break;
+
+ case gcvFEATURE_SMALL_MSAA:
+ available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures4)) >> (0 ? 18:18) & ((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1)))))));
+ break;
+
case gcvFEATURE_DYNAMIC_FREQUENCY_SCALING:
/* This feature doesn't apply for 2D cores. */
available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures2)) >> (0 ? 14:14) & ((gctUINT32) ((((1 ? 14:14) - (0 ? 14:14) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 14:14) - (0 ? 14:14) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 14:14) - (0 ? 14:14) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 14:14) - (0 ? 14:14) + 1)))))))
&& ((((gctUINT32) (Hardware->identity.chipFeatures)) >> (0 ? 2:2) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))));
+
+ if (Hardware->identity.chipModel == gcv1000 &&
+ (Hardware->identity.chipRevision == 0x5039 ||
+ Hardware->identity.chipRevision == 0x5040))
+ {
+ available = gcvFALSE;
+ }
+ break;
+
+ case gcvFEATURE_ACE:
+ available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures3)) >> (0 ? 18:18) & ((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1)))))));
+ break;
+
+ case gcvFEATURE_HALTI2:
+ available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures4)) >> (0 ? 16:16) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))));
break;
case gcvFEATURE_PIPE_2D:
break;
case gcvFEATURE_PIPE_3D:
-#ifndef VIVANTE_NO_3D
+#if gcdENABLE_3D
available = ((((gctUINT32) (Hardware->identity.chipFeatures)) >> (0 ? 2:2) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))));
#else
available = gcvFALSE;
#endif
break;
- case gcvFEATURE_HALTI2:
- available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures4)) >> (0 ? 16:16) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))));
+ case gcvFEATURE_FC_FLUSH_STALL:
+ available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures1)) >> (0 ? 31:31) & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1)))))));
break;
default:
}
/* Return result. */
- gcmkFOOTER_ARG("%d", available ? gcvSTATUS_TRUE : gcvSTATUS_OK);
- return available ? gcvSTATUS_TRUE : gcvSTATUS_OK;
+ gcmkFOOTER_ARG("%d", available ? gcvSTATUS_TRUE : gcvSTATUS_FALSE);
+ return available ? gcvSTATUS_TRUE : gcvSTATUS_FALSE;
}
/*******************************************************************************
IN gckHARDWARE Hardware
)
{
-#if !gcdPOWER_SUSNPEND_WHEN_IDLE && !gcdPOWEROFF_TIMEOUT
- gctUINT32 mmu, mmuStatus, address, i;
-#if gcdDEBUG
- gctUINT32 mtlb, stlb, offset;
+ gctUINT32 mmu = 0;
+ gctUINT32 mmuStatus = 0;
+ gctUINT32 address = 0;
+ gctUINT32 i = 0;
+ gctUINT32 mtlb = 0;
+ gctUINT32 stlb = 0;
+ gctUINT32 offset = 0;
+#if gcdPROCESS_ADDRESS_SPACE
+ gcsDATABASE_PTR database;
#endif
gcmkHEADER_ARG("Hardware=0x%x", Hardware);
gckMMU_DumpPageTableEntry(Hardware->kernel->mmu, address);
+#if gcdPROCESS_ADDRESS_SPACE
+ for (i = 0; i < gcmCOUNTOF(Hardware->kernel->db->db); ++i)
+ {
+ for (database = Hardware->kernel->db->db[i];
+ database != gcvNULL;
+ database = database->next)
+ {
+ gcmkPRINT(" database [%d] :", database->processID);
+ gckMMU_DumpPageTableEntry(database->mmu, address);
+ }
+ }
+#endif
}
- gcmkFOOTER_NO();
-#else
- /* If clock could be off automatically, we can't read mmu debug
- ** register here; build driver with gcdPOWER_SUSPEND_WHEN_IDLE = 0
- ** and gcdPOWEROFF_TIMEOUT = 0 to make it safe to read mmu register. */
- gcmkPRINT("[galcore] %s(%d): MMU Exception!", __FUNCTION__, __LINE__);
-#endif
+ gckHARDWARE_DumpGPUState(Hardware);
+ gcmkFOOTER_NO();
return gcvSTATUS_OK;
}
};
gceSTATUS status;
- gckKERNEL kernel;
- gctUINT32 idle, axi;
- gctUINT32 dmaAddress1, dmaAddress2;
- gctUINT32 dmaState1, dmaState2;
- gctUINT32 dmaLow, dmaHigh;
- gctUINT32 cmdState, cmdDmaState, cmdFetState;
- gctUINT32 dmaReqState, calState, veReqState;
+ gckKERNEL kernel = gcvNULL;
+ gctUINT32 idle = 0, axi = 0;
+ gctUINT32 dmaAddress1 = 0, dmaAddress2 = 0;
+ gctUINT32 dmaState1 = 0, dmaState2 = 0;
+ gctUINT32 dmaLow = 0, dmaHigh = 0;
+ gctUINT32 cmdState = 0, cmdDmaState = 0, cmdFetState = 0;
+ gctUINT32 dmaReqState = 0, calState = 0, veReqState = 0;
gctUINT i;
- gctUINT pipe, pixelPipes;
- gctUINT32 control, oldControl;
+ gctUINT pipe = 0, pixelPipes = 0;
+ gctUINT32 control = 0, oldControl = 0;
gckOS os = Hardware->os;
gceCORE core = Hardware->core;
gcmkPRINT_N(4, " 0x%08X\n", dmaAddress2);
}
}
+
gcmkPRINT_N(4, " dmaLow = 0x%08X\n", dmaLow);
gcmkPRINT_N(4, " dmaHigh = 0x%08X\n", dmaHigh);
gcmkPRINT_N(4, " dmaState = 0x%08X\n", dmaState2);
gcmkPRINT_N(4, " Debug registers of pipe[%d]:\n", pipe);
/* Switch pipe. */
- gckOS_ReadRegisterEx(os, core, 0x0, &control);
+ gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x0, &control));
control &= ~(0xF << 20);
control |= (pipe << 20);
- gckOS_WriteRegisterEx(os, core, 0x0, control);
+ gcmkONERROR(gckOS_WriteRegisterEx(os, core, 0x0, control));
for (i = 0; i < gcmCOUNTOF(_dbgRegs); i += 1)
{
}
/* Restore control. */
- gckOS_WriteRegisterEx(os, core, 0x0, oldControl);
+ gcmkONERROR(gckOS_WriteRegisterEx(os, core, 0x0, oldControl));
/* dump stack. */
gckOS_DumpCallStack(os);
return status;
}
-
-#if gcdFRAME_DB
static gceSTATUS
gckHARDWARE_ReadPerformanceRegister(
IN gckHARDWARE Hardware,
gctUINT i, clock;
gcsHAL_FRAME_INFO info;
#if gcdFRAME_DB_RESET
- gctUINT reset;
+ gctUINT reset;
#endif
gcmkHEADER_ARG("Hardware=0x%x", Hardware);
gcmkFOOTER();
return status;
}
-#endif
#if gcdDVFS
#define READ_FROM_EATER1 0
}
#endif
+/*******************************************************************************
+**
+** gckHARDWARE_PrepareFunctions
+**
+** Generate command buffer snippets which will be used by gckHARDWARE, by which
+** gckHARDWARE can manipulate GPU by FE command without using gckCOMMAND to avoid
+** race condition and deadlock.
+**
+** Notice:
+** 1. Each snippet can only be executed when GPU is idle.
+** 2. Execution is triggered by AHB (0x658)
+** 3. Each snippet followed by END so software can sync with GPU by checking GPU
+** idle
+** 4. It is transparent to gckCOMMAND command buffer.
+**
+** Existing Snippets:
+** 1. MMU Configure
+** For new MMU, after GPU is reset, FE execute this command sequence to enble MMU.
+*/
+gceSTATUS
+gckHARDWARE_PrepareFunctions(
+ gckHARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+ gckOS os;
+ gctUINT32 offset = 0;
+ gctUINT32 mmuBytes;
+ gctUINT32 endBytes;
+ gctUINT8_PTR logical;
+
+ gcmkHEADER_ARG("%x", Hardware);
+
+ os = Hardware->os;
+
+ gcmkVERIFY_OK(gckOS_GetPageSize(os, &Hardware->functionBytes));
+
+ /* Allocate a command buffer. */
+ gcmkONERROR(gckOS_AllocateNonPagedMemory(
+ os,
+ gcvFALSE,
+ &Hardware->functionBytes,
+ &Hardware->functionPhysical,
+ &Hardware->functionLogical
+ ));
+
+ gcmkONERROR(gckOS_GetPhysicalAddress(
+ os,
+ Hardware->functionLogical,
+ &Hardware->functionAddress
+ ));
+
+ if (Hardware->mmuVersion > 0)
+ {
+ /* MMU configure command sequence. */
+ logical = (gctUINT8_PTR)Hardware->functionLogical + offset;
+
+ Hardware->functions[gcvHARDWARE_FUNCTION_MMU].address
+ = Hardware->functionAddress + offset;
+
+ gcmkONERROR(gckHARDWARE_SetMMUStates(
+ Hardware,
+ Hardware->kernel->mmu->mtlbLogical,
+ gcvMMU_MODE_4K,
+ (gctUINT8_PTR)Hardware->kernel->mmu->mtlbLogical + gcdMMU_MTLB_SIZE,
+ logical,
+ &mmuBytes
+ ));
+
+ offset += mmuBytes;
+
+ logical = (gctUINT8_PTR)Hardware->functionLogical + offset;
+
+ gcmkONERROR(gckHARDWARE_End(
+ Hardware,
+ gcvNULL,
+ &endBytes
+ ));
+
+ gcmkONERROR(gckHARDWARE_End(
+ Hardware,
+ logical,
+ &endBytes
+ ));
+
+ offset += endBytes;
+
+ Hardware->functions[gcvHARDWARE_FUNCTION_MMU].bytes = mmuBytes + endBytes;
+ }
+
+ gcmkASSERT(offset < Hardware->functionBytes);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
extern "C" {
#endif
+typedef enum {
+ gcvHARDWARE_FUNCTION_MMU,
+ gcvHARDWARE_FUNCTION_FLUSH,
+
+ gcvHARDWARE_FUNCTION_NUM,
+}
+gceHARDWARE_FUNCTION;
+
+
+typedef struct _gcsHARWARE_FUNCTION
+{
+ /* Entry of the function. */
+ gctUINT32 address;
+
+ /* Bytes of the function. */
+ gctUINT32 bytes;
+}
+gcsHARDWARE_FUNCTION;
+
/* gckHARDWARE object. */
struct _gckHARDWARE
{
gctUINT32 powerThread;
gceCHIPPOWERSTATE chipPowerState;
gctUINT32 lastWaitLink;
+ gctUINT32 lastEnd;
gctBOOL clockState;
gctBOOL powerState;
gctPOINTER globalSemaphore;
gctUINT32 mmuVersion;
+ /* Whether use new MMU. It is meaningless
+ ** for old MMU since old MMU is always enabled.
+ */
+ gctBOOL enableMMU;
+
/* Type */
gceHARDWARE_TYPE type;
gctPOINTER powerOffTimer;
#endif
- gctPOINTER pageTableDirty;
-
#if gcdENABLE_FSCALE_VAL_ADJUST
- /* FSCALE_VAL when gcvPOWER_ON. */
gctUINT32 powerOnFscaleVal;
#endif
+ gctPOINTER pageTableDirty;
#if gcdLINK_QUEUE_SIZE
struct _gckLINKQUEUE linkQueue;
#endif
gctBOOL powerManagement;
+ gctBOOL powerManagementLock;
gctBOOL gpuProfiler;
+
+ gctBOOL endAfterFlushMmuCache;
+
+ gctUINT32 minFscaleValue;
+
+ gctPOINTER pendingEvent;
+
+ /* Function used by gckHARDWARE. */
+ gctPHYS_ADDR functionPhysical;
+ gctPOINTER functionLogical;
+ gctUINT32 functionAddress;
+ gctSIZE_T functionBytes;
+
+ gcsHARDWARE_FUNCTION functions[gcvHARDWARE_FUNCTION_NUM];
};
gceSTATUS
OUT gcsHAL_FRAME_INFO * FrameInfo
);
-gceSTATUS
-gckHARDWARE_SetFscaleValue(
- IN gckHARDWARE Hardware,
- IN gctUINT32 FscaleValue
- );
-
-gceSTATUS
-gckHARDWARE_GetFscaleValue(
- IN gckHARDWARE Hardware,
- IN gctUINT * FscaleValue,
- IN gctUINT * MinFscaleValue,
- IN gctUINT * MaxFscaleValue
- );
-
#ifdef __cplusplus
}
#endif
--- /dev/null
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2014 by Vivante Corp.
+*
+* 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.
+*
+*****************************************************************************/
+
+
+#include "gc_hal.h"
+#include "gc_hal_kernel.h"
+#include "gc_hal_kernel_context.h"
+
+/*
+ * -----------------------
+ * HARDWARE STATE RECORDER
+ * -----------------------
+ *
+ * State mirror buffer is used to 'mirror' hardware states since hardware
+ * states can't be dumpped. It is a context buffer which stores 'global'
+ * context.
+ *
+ * For each commit, state recorder
+ * 1) Records context buffer (if there is) and command buffers in this commit.
+ * 2) Parse those buffers to estimate the state changed.
+ * 3) Stores result to a mirror buffer.
+ *
+ * == Commit 0 ====================================================================
+ *
+ * Context Buffer 0
+ *
+ * Command Buffer 0
+ *
+ * Mirror Buffer 0 <- Context Buffer 0 + Command Buffer 0
+ *
+ * == Commit 1 ====================================================================
+ *
+ * Command Buffer 1
+ *
+ * Mirror Buffer 1 <- Command buffer 1 + Mirror Buffer 0
+ *
+ * == Commit 2 ====================================================================
+ *
+ * Context Buffer 2 (optional)
+ *
+ * Command Buffer 2
+ *
+ * Mirror Buffer 2 <- Command buffer 2 + Context Buffer 2 + Mirror Buffer 1
+ *
+ * == Commit N ====================================================================
+ *
+ * For Commit N, these buffers are needed to reproduce hardware's behavior in
+ * this commit.
+ *
+ * Mirror Buffer [N - 1] : State Mirror accumlated by past commits,
+ * which is used to restore hardware state.
+ * Context Buffer [N] :
+ * Command Buffer [N] : Command buffer executed by hardware in this commit.
+ *
+ * If sequence of states programming matters, hardware's behavior can't be reproduced,
+ * but the state values stored in mirror buffer are assuring.
+ */
+
+/* Queue size. */
+#define gcdNUM_RECORDS 6
+
+typedef struct _gcsPARSER_HANDLER * gckPARSER_HANDLER;
+
+typedef void
+(*HandlerFunction)(
+ IN gckPARSER_HANDLER Handler,
+ IN gctUINT32 Addr,
+ IN gctUINT32 Data
+ );
+
+typedef struct _gcsPARSER_HANDLER
+{
+ gctUINT32 type;
+ gctUINT32 cmd;
+ gctPOINTER private;
+ HandlerFunction function;
+}
+gcsPARSER_HANDLER;
+
+typedef struct _gcsPARSER * gckPARSER;
+typedef struct _gcsPARSER
+{
+ gctUINT8_PTR currentCmdBufferAddr;
+
+ /* Current command. */
+ gctUINT32 lo;
+ gctUINT32 hi;
+
+ gctUINT8 cmdOpcode;
+ gctUINT16 cmdAddr;
+ gctUINT32 cmdSize;
+ gctUINT32 cmdRectCount;
+ gctUINT8 skip;
+ gctUINT32 skipCount;
+
+ gctBOOL allow;
+
+ /* Callback used by parser to handle a command. */
+ gckPARSER_HANDLER commandHandler;
+}
+gcsPARSER;
+
+typedef struct _gcsMIRROR
+{
+ gctUINT32_PTR logical[gcdNUM_RECORDS];
+ gctUINT32 bytes;
+ gcsSTATE_MAP_PTR map;
+ gctUINT32 stateCount;
+}
+gcsMIRROR;
+
+typedef struct _gcsDELTA
+{
+ gctUINT64 commitStamp;
+ gctUINT32_PTR command;
+ gctUINT32 commandBytes;
+ gctUINT32_PTR context;
+ gctUINT32 contextBytes;
+}
+gcsDELTA;
+
+typedef struct _gcsRECORDER
+{
+ gckOS os;
+ gcsMIRROR mirror;
+ gcsDELTA deltas[gcdNUM_RECORDS];
+
+ /* Index of current record. */
+ gctUINT index;
+
+ /* Number of records. */
+ gctUINT num;
+
+ /* Plugin used by gckPARSER. */
+ gcsPARSER_HANDLER recorderHandler;
+ gckPARSER parser;
+}
+gcsRECORDER;
+
+
+/******************************************************************************\
+***************************** Command Buffer Parser ****************************
+\******************************************************************************/
+
+/*
+** Command buffer parser checks command buffer in FE's view to make sure there
+** is no format error.
+**
+** Parser provide a callback mechnisam, so plug-in can be added to implement
+** other functions.
+*/
+
+static void
+_HandleLoadState(
+ IN OUT gckPARSER Parser
+ )
+{
+ gctUINT i;
+ gctUINT32_PTR data = (gctUINT32_PTR)Parser->currentCmdBufferAddr;
+ gctUINT32 cmdAddr = Parser->cmdAddr;
+
+ if (Parser->commandHandler == gcvNULL
+ || Parser->commandHandler->cmd != 0x01
+ )
+ {
+ /* No handler for this command. */
+ return;
+ }
+
+ for (i = 0; i < Parser->cmdSize; i++)
+ {
+ Parser->commandHandler->function(Parser->commandHandler, cmdAddr, *data);
+
+ /* Advance to next state. */
+ cmdAddr++;
+ data++;
+ }
+}
+
+static void
+_GetCommand(
+ IN OUT gckPARSER Parser
+ )
+{
+ gctUINT32 * buffer = (gctUINT32 *)Parser->currentCmdBufferAddr;
+
+ gctUINT16 cmdRectCount;
+ gctUINT16 cmdDataCount;
+
+ Parser->hi = buffer[0];
+ Parser->lo = buffer[1];
+
+ Parser->cmdOpcode = (((((gctUINT32) (Parser->hi)) >> (0 ? 31:27)) & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1)))))) );
+ Parser->cmdRectCount = 1;
+
+ switch (Parser->cmdOpcode)
+ {
+ case 0x01:
+ /* Extract count. */
+ Parser->cmdSize = (((((gctUINT32) (Parser->hi)) >> (0 ? 25:16)) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1)))))) );
+ if (Parser->cmdSize == 0)
+ {
+ /* 0 means 1024. */
+ Parser->cmdSize = 1024;
+ }
+ Parser->skip = (Parser->cmdSize & 0x1) ? 0 : 1;
+
+ /* Extract address. */
+ Parser->cmdAddr = (((((gctUINT32) (Parser->hi)) >> (0 ? 15:0)) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1)))))) );
+
+ Parser->currentCmdBufferAddr = Parser->currentCmdBufferAddr + 4;
+ Parser->skipCount = Parser->cmdSize + Parser->skip;
+ break;
+
+ case 0x05:
+ Parser->cmdSize = 4;
+ Parser->skipCount = gcmALIGN(Parser->cmdSize, 2);
+ break;
+
+ case 0x06:
+ Parser->cmdSize = 5;
+ Parser->skipCount = gcmALIGN(Parser->cmdSize, 2);
+ break;
+
+ case 0x0C:
+ Parser->cmdSize = 3;
+ Parser->skipCount = gcmALIGN(Parser->cmdSize, 2);
+ break;
+
+ case 0x09:
+ Parser->cmdSize = 2;
+ Parser->cmdAddr = 0x0F16;
+ Parser->skipCount = gcmALIGN(Parser->cmdSize, 2);
+ break;
+
+ case 0x04:
+ Parser->cmdSize = 1;
+ Parser->cmdAddr = 0x0F06;
+
+ cmdRectCount = (((((gctUINT32) (Parser->hi)) >> (0 ? 15:8)) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1)))))) );
+ cmdDataCount = (((((gctUINT32) (Parser->hi)) >> (0 ? 26:16)) & ((gctUINT32) ((((1 ? 26:16) - (0 ? 26:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:16) - (0 ? 26:16) + 1)))))) );
+
+ Parser->skipCount = gcmALIGN(Parser->cmdSize, 2)
+ + cmdRectCount * 2
+ + gcmALIGN(cmdDataCount, 2);
+
+ Parser->cmdRectCount = cmdRectCount;
+ break;
+
+ case 0x03:
+ Parser->currentCmdBufferAddr = Parser->currentCmdBufferAddr + 8;
+ Parser->skipCount = 0;
+ break;
+
+ case 0x02:
+ Parser->currentCmdBufferAddr = Parser->currentCmdBufferAddr + 8;
+ Parser->skipCount = 0;
+ break;
+
+ default:
+ /* Unknown command is a risk. */
+ Parser->allow = gcvFALSE;
+ break;
+ }
+}
+
+static void
+_ParseCommand(
+ IN OUT gckPARSER Parser
+ )
+{
+ switch(Parser->cmdOpcode)
+ {
+ case 0x01:
+ _HandleLoadState(Parser);
+ break;
+ case 0x05:
+ case 0x06:
+ case 0x0C:
+ break;
+ case 0x04:
+ break;
+ default:
+ break;
+ }
+
+ /* Advance to next command. */
+ Parser->currentCmdBufferAddr = Parser->currentCmdBufferAddr
+ + (Parser->skipCount << 2);
+}
+
+gceSTATUS
+gckPARSER_Parse(
+ IN gckPARSER Parser,
+ IN gctUINT8_PTR Buffer,
+ IN gctUINT32 Bytes
+ )
+{
+ gckPARSER parser = Parser;
+ gctUINT8_PTR end = (gctUINT8_PTR)Buffer + Bytes;
+
+ /* Initialize parser. */
+ parser->currentCmdBufferAddr = (gctUINT8_PTR)Buffer;
+ parser->skip = 0;
+ parser->allow = gcvTRUE;
+
+ /* Go through command buffer until reaching the end
+ ** or meeting an error. */
+ do
+ {
+ _GetCommand(parser);
+
+ _ParseCommand(parser);
+ }
+ while ((parser->currentCmdBufferAddr < end) && (parser->allow == gcvTRUE));
+
+ if (parser->allow == gcvFALSE)
+ {
+ /* Error detected. */
+ return gcvSTATUS_NOT_SUPPORTED;
+ }
+
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckPARSER_RegisterCommandHandler
+**
+** Register a command handler which will be called when parser get a command.
+**
+*/
+gceSTATUS
+gckPARSER_RegisterCommandHandler(
+ IN gckPARSER Parser,
+ IN gckPARSER_HANDLER Handler
+ )
+{
+ Parser->commandHandler = Handler;
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckPARSER_Construct(
+ IN gckOS Os,
+ IN gckPARSER_HANDLER Handler,
+ OUT gckPARSER * Parser
+ )
+{
+ gceSTATUS status;
+ gckPARSER pointer;
+
+ gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsPARSER), (gctPOINTER *)&pointer));
+
+ /* Put it here temp, should have a more general plug-in mechnisam. */
+ pointer->commandHandler = Handler;
+
+ *Parser = pointer;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+void
+gckPARSER_Destroy(
+ IN gckOS Os,
+ IN gckPARSER Parser
+ )
+{
+ gcmkOS_SAFE_FREE(Os, Parser);
+}
+
+/******************************************************************************\
+**************************** Hardware States Recorder **************************
+\******************************************************************************/
+
+static void
+_RecodeState(
+ IN gckPARSER_HANDLER Handler,
+ IN gctUINT32 Addr,
+ IN gctUINT32 Data
+ )
+{
+ gcmkVERIFY_OK(gckRECORDER_UpdateMirror(Handler->private, Addr, Data));
+}
+
+static gctUINT
+_Previous(
+ IN gctUINT Index
+ )
+{
+ if (Index == 0)
+ {
+ return gcdNUM_RECORDS - 1;
+ }
+
+ return Index - 1;
+}
+
+static gctUINT
+_Next(
+ IN gctUINT Index
+ )
+{
+ return (Index + 1) % gcdNUM_RECORDS;
+}
+
+gceSTATUS
+gckRECORDER_Construct(
+ IN gckOS Os,
+ IN gckHARDWARE Hardware,
+ OUT gckRECORDER * Recorder
+ )
+{
+ gceSTATUS status;
+ gckCONTEXT context = gcvNULL;
+ gckRECORDER recorder = gcvNULL;
+ gctUINT32 mapSize;
+ gctUINT i;
+ gctBOOL virtualCommandBuffer = Hardware->kernel->virtualCommandBuffer;
+
+ /* TODO: We only need context buffer and state map, it should be able to get without construct a
+ ** new context.
+ ** Now it is leaked, since we can't free it when command buffer is gone.
+ */
+
+ /* MMU is not ready now. */
+ Hardware->kernel->virtualCommandBuffer = gcvFALSE;
+
+ gcmkONERROR(gckCONTEXT_Construct(Os, Hardware, 0, &context));
+
+ /* Restore. */
+ Hardware->kernel->virtualCommandBuffer = virtualCommandBuffer;
+
+ gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsRECORDER), (gctPOINTER *)&recorder));
+
+ gckOS_ZeroMemory(recorder, gcmSIZEOF(gcsRECORDER));
+
+ /* Copy state map. */
+ recorder->mirror.stateCount = context->stateCount;
+
+ mapSize = context->stateCount * gcmSIZEOF(gcsSTATE_MAP);
+
+ gcmkONERROR(gckOS_Allocate(Os, mapSize, (gctPOINTER *)&recorder->mirror.map));
+
+ gckOS_MemCopy(recorder->mirror.map, context->map, mapSize);
+
+ /* Copy context buffer. */
+ recorder->mirror.bytes = context->totalSize;
+
+ for (i = 0; i < gcdNUM_RECORDS; i++)
+ {
+ gcmkONERROR(gckOS_Allocate(Os, context->totalSize, (gctPOINTER *)&recorder->mirror.logical[i]));
+ gckOS_MemCopy(recorder->mirror.logical[i], context->buffer->logical, context->totalSize);
+ }
+
+ for (i = 0; i < gcdNUM_RECORDS; i++)
+ {
+ /* TODO : Optimize size. */
+ gcmkONERROR(gckOS_Allocate(Os, gcdCMD_BUFFER_SIZE, (gctPOINTER *)&recorder->deltas[i].command));
+ gcmkONERROR(gckOS_Allocate(Os, context->totalSize, (gctPOINTER *)&recorder->deltas[i].context));
+ }
+
+ recorder->index = 0;
+ recorder->num = 0;
+
+ /* Initialize Parser plugin. */
+ recorder->recorderHandler.cmd = 0x01;
+ recorder->recorderHandler.private = recorder;
+ recorder->recorderHandler.function = _RecodeState;
+
+ gcmkONERROR(gckPARSER_Construct(Os, &recorder->recorderHandler, &recorder->parser));
+
+ recorder->os = Os;
+
+ *Recorder = recorder;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ if (recorder)
+ {
+ gckRECORDER_Destory(Os, recorder);
+ }
+
+ return status;
+}
+
+gceSTATUS
+gckRECORDER_Destory(
+ IN gckOS Os,
+ IN gckRECORDER Recorder
+ )
+{
+ gctUINT i;
+
+ if (Recorder->mirror.map)
+ {
+ gcmkOS_SAFE_FREE(Os, Recorder->mirror.map);
+ }
+
+ for (i = 0; i < gcdNUM_RECORDS; i++)
+ {
+ if (Recorder->mirror.logical[i])
+ {
+ gcmkOS_SAFE_FREE(Os, Recorder->mirror.logical[i]);
+ }
+ }
+
+ for (i = 0; i < gcdNUM_RECORDS; i++)
+ {
+ if (Recorder->deltas[i].command)
+ {
+ gcmkOS_SAFE_FREE(Os, Recorder->deltas[i].command);
+ }
+
+ if (Recorder->deltas[i].context)
+ {
+ gcmkOS_SAFE_FREE(Os, Recorder->deltas[i].context);
+ }
+ }
+
+ if (Recorder->parser)
+ {
+ gckPARSER_Destroy(Os, Recorder->parser);
+ }
+
+ gcmkOS_SAFE_FREE(Os, Recorder);
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckRECORDER_UpdateMirror(
+ IN gckRECORDER Recorder,
+ IN gctUINT32 State,
+ IN gctUINT32 Data
+ )
+{
+ gctUINT32 index;
+ gcsSTATE_MAP_PTR map = Recorder->mirror.map;
+ gctUINT32_PTR buffer = Recorder->mirror.logical[Recorder->index];
+
+ if (State >= Recorder->mirror.stateCount)
+ {
+ /* Ignore them just like HW does. */
+ return gcvSTATUS_OK;
+ }
+
+ index = map[State].index;
+
+ if (index)
+ {
+ buffer[index] = Data;
+ }
+
+ return gcvSTATUS_OK;
+}
+
+void
+gckRECORDER_AdvanceIndex(
+ IN gckRECORDER Recorder,
+ IN gctUINT64 CommitStamp
+ )
+{
+ /* Get next record. */
+ gctUINT next = (Recorder->index + 1) % gcdNUM_RECORDS;
+
+ /* Record stamp of this commit. */
+ Recorder->deltas[Recorder->index].commitStamp = CommitStamp;
+
+ /* Mirror of next record is mirror of this record and delta in next record. */
+ gckOS_MemCopy(Recorder->mirror.logical[next],
+ Recorder->mirror.logical[Recorder->index], Recorder->mirror.bytes);
+
+ /* Advance to next record. */
+ Recorder->index = next;
+
+ Recorder->num = gcmMIN(Recorder->num + 1, gcdNUM_RECORDS - 1);
+
+
+ /* Reset delta. */
+ Recorder->deltas[Recorder->index].commandBytes = 0;
+ Recorder->deltas[Recorder->index].contextBytes = 0;
+}
+
+void
+gckRECORDER_Record(
+ IN gckRECORDER Recorder,
+ IN gctUINT8_PTR CommandBuffer,
+ IN gctUINT32 CommandBytes,
+ IN gctUINT8_PTR ContextBuffer,
+ IN gctUINT32 ContextBytes
+ )
+{
+ gcsDELTA * delta = &Recorder->deltas[Recorder->index];
+
+ if (CommandBytes != 0xFFFFFFFF)
+ {
+ gckPARSER_Parse(Recorder->parser, CommandBuffer, CommandBytes);
+ gckOS_MemCopy(delta->command, CommandBuffer, CommandBytes);
+ delta->commandBytes = CommandBytes;
+ }
+
+ if (ContextBytes != 0xFFFFFFFF)
+ {
+ gckPARSER_Parse(Recorder->parser, ContextBuffer, ContextBytes);
+ gckOS_MemCopy(delta->context, ContextBuffer, ContextBytes);
+ delta->contextBytes = ContextBytes;
+ }
+}
+
+void
+gckRECORDER_Dump(
+ IN gckRECORDER Recorder
+ )
+{
+ gctUINT last = Recorder->index;
+ gctUINT previous;
+ gctUINT i;
+ gcsMIRROR *mirror = &Recorder->mirror;
+ gcsDELTA *delta;
+ gckOS os = Recorder->os;
+
+ for (i = 0; i < Recorder->num; i++)
+ {
+ last = _Previous(last);
+ }
+
+ for (i = 0; i < Recorder->num; i++)
+ {
+ delta = &Recorder->deltas[last];
+
+ /* Dump record */
+ gcmkPRINT("#[commit %llu]", delta->commitStamp);
+
+ if (delta->commitStamp)
+ {
+ previous = _Previous(last);
+
+ gcmkPRINT("#[mirror]");
+ gckOS_DumpBuffer(os, mirror->logical[previous], mirror->bytes, gceDUMP_BUFFER_CONTEXT, gcvTRUE);
+ gcmkPRINT("@[kernel.execute]");
+ }
+
+ if (delta->contextBytes)
+ {
+ gckOS_DumpBuffer(os, delta->context, delta->contextBytes, gceDUMP_BUFFER_CONTEXT, gcvTRUE);
+ gcmkPRINT("@[kernel.execute]");
+ }
+
+ gckOS_DumpBuffer(os, delta->command, delta->commandBytes, gceDUMP_BUFFER_USER, gcvTRUE);
+ gcmkPRINT("@[kernel.execute]");
+
+ last = _Next(last);
+ }
+}
+
+
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
IN gctUINT32 Pipe,
IN gctPOINTER Logical,
IN gctUINT32 Address,
- IN gctSIZE_T Count,
- IN OUT gctSIZE_T * Bytes
+ IN gctUINT32 Count,
+ IN OUT gctUINT32 * Bytes
)
{
gcmkHEADER_ARG("Command=0x%x Pipe=0x%x Logical=0x%x Address=0x%x Count=0x%x Bytes = 0x%x",
IN gctPOINTER Logical,
IN gctUINT32 FetchAddress,
IN gctUINT FetchCount,
- IN OUT gctSIZE_T * Bytes
+ IN OUT gctUINT32 * Bytes
)
{
gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x",
IN gctPOINTER Logical,
IN gctUINT32 FetchAddress,
IN gctUINT FetchCount,
- IN OUT gctSIZE_T * Bytes
+ IN OUT gctUINT32 * Bytes
)
{
gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x",
IN gctPOINTER Logical,
IN gctUINT32 FetchAddress,
IN gctUINT FetchCount,
- IN OUT gctSIZE_T * Bytes
+ IN OUT gctUINT32 * Bytes
)
{
gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x",
gckVGCOMMAND_ReturnCommand(
IN gckVGCOMMAND Command,
IN gctPOINTER Logical,
- IN OUT gctSIZE_T * Bytes
+ IN OUT gctUINT32 * Bytes
)
{
gcmkHEADER_ARG("Command=0x%x Logical=0x%x Bytes = 0x%x",
IN gctPOINTER Logical,
IN gceBLOCK Block,
IN gctINT32 InterruptId,
- IN OUT gctSIZE_T * Bytes
+ IN OUT gctUINT32 * Bytes
)
{
gcmkHEADER_ARG("Command=0x%x Logical=0x%x Block=0x%x InterruptId=0x%x Bytes = 0x%x",
IN gckVGCOMMAND Command,
IN gctPOINTER Logical,
IN gctINT32 InterruptId,
- IN OUT gctSIZE_T * Bytes
+ IN OUT gctUINT32 * Bytes
)
{
gcmkHEADER_ARG("Command=0x%x Logical=0x%x InterruptId=0x%x Bytes = 0x%x",
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
IN gctUINT32 Pipe,
IN gctPOINTER Logical,
IN gctUINT32 Address,
- IN gctSIZE_T Count,
- IN OUT gctSIZE_T * Bytes
+ IN gctUINT32 Count,
+ IN OUT gctUINT32 * Bytes
);
/* Form a RESTART command at the specified location in the command buffer. */
IN gctPOINTER Logical,
IN gctUINT32 FetchAddress,
IN gctUINT FetchCount,
- IN OUT gctSIZE_T * Bytes
+ IN OUT gctUINT32 * Bytes
);
/* Form a FETCH command at the specified location in the command buffer. */
IN gctPOINTER Logical,
IN gctUINT32 FetchAddress,
IN gctUINT FetchCount,
- IN OUT gctSIZE_T * Bytes
+ IN OUT gctUINT32 * Bytes
);
/* Form a CALL command at the specified location in the command buffer. */
IN gctPOINTER Logical,
IN gctUINT32 FetchAddress,
IN gctUINT FetchCount,
- IN OUT gctSIZE_T * Bytes
+ IN OUT gctUINT32 * Bytes
);
/* Form a RETURN command at the specified location in the command buffer. */
gckVGCOMMAND_ReturnCommand(
IN gckVGCOMMAND Command,
IN gctPOINTER Logical,
- IN OUT gctSIZE_T * Bytes
+ IN OUT gctUINT32 * Bytes
);
/* Form an EVENT command at the specified location in the command buffer. */
IN gctPOINTER Logical,
IN gceBLOCK Block,
IN gctINT32 InterruptId,
- IN OUT gctSIZE_T * Bytes
+ IN OUT gctUINT32 * Bytes
);
/* Form an END command at the specified location in the command buffer. */
IN gckVGCOMMAND Command,
IN gctPOINTER Logical,
IN gctINT32 InterruptId,
- IN OUT gctSIZE_T * Bytes
+ IN OUT gctUINT32 * Bytes
);
#endif /* __gc_hal_kernel_hardware_command_h_ */
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
hardware->clockState = gcvTRUE;
hardware->powerState = gcvTRUE;
- hardware->powerOffTime = 0;
#if gcdPOWEROFF_TIMEOUT
- hardware->powerOffTimeout = gcdPOWEROFF_TIMEOUT;
+ hardware->powerOffTime = 0;
+ hardware->powerOffTimeout = gcdPOWEROFF_TIMEOUT;
gcmkVERIFY_OK(gckOS_CreateTimer(Os,
_VGPowerTimerFunction,
while (gcvFALSE);
#if gcdPOWEROFF_TIMEOUT
- if (hardware->powerOffTimer != gcvNULL)
- {
- gcmkVERIFY_OK(gckOS_StopTimer(Os, hardware->powerOffTimer));
- gcmkVERIFY_OK(gckOS_DestroyTimer(Os, hardware->powerOffTimer));
- }
+ if (hardware->powerOffTimer != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_StopTimer(Os, hardware->powerOffTimer));
+ gcmkVERIFY_OK(gckOS_DestroyTimer(Os, hardware->powerOffTimer));
+ }
#endif
- if (hardware->pageTableDirty != gcvNULL)
+ gcmkVERIFY_OK(gckOS_SetGPUPower(Os, gcvCORE_VG, gcvFALSE, gcvFALSE));
+
+ if (hardware != gcvNULL && hardware->pageTableDirty != gcvNULL)
{
gcmkVERIFY_OK(gckOS_AtomDestroy(Os, hardware->pageTableDirty));
}
gcmkVERIFY_OK(gckOS_Free(Os, hardware));
}
- gcmkVERIFY_OK(gckOS_SetGPUPower(Os, gcvCORE_VG, gcvFALSE, gcvFALSE));
-
gcmkFOOTER();
/* Return the status. */
return status;
gckVGHARDWARE_Execute(
IN gckVGHARDWARE Hardware,
IN gctUINT32 Address,
- IN gctSIZE_T Count
+ IN gctUINT32 Count
)
{
gceSTATUS status;
** gctPOINTER Logical
** Logical address to convert.
**
+** gctBOOL InUserSpace
+** gcvTRUE if the memory in user space.
+**
** gctUINT32* Address
** Return hardware specific address.
**
gckVGHARDWARE_ConvertLogical(
IN gckVGHARDWARE Hardware,
IN gctPOINTER Logical,
+ IN gctBOOL InUserSpace,
OUT gctUINT32 * Address
)
{
gctUINT32 address;
gceSTATUS status;
- gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Address=0x%x",
- Hardware, Logical, Address);
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x InUserSpace=%d Address=0x%x",
+ Hardware, Logical, InUserSpace, Address);
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
do
{
/* Convert logical address into a physical address. */
- gcmkERR_BREAK(gckOS_GetPhysicalAddress(
- Hardware->os, Logical, &address
- ));
+ if (InUserSpace)
+ {
+ gcmkERR_BREAK(gckOS_UserLogicalToPhysical(
+ Hardware->os, Logical, &address
+ ));
+ }
+ else
+ {
+ gcmkERR_BREAK(gckOS_GetPhysicalAddress(
+ Hardware->os, Logical, &address
+ ));
+ }
/* Return hardware specific address. */
*Address = ((((gctUINT32) (address)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)));
do
{
/* Convert the logical address into an hardware address. */
- gcmkERR_BREAK(gckVGHARDWARE_ConvertLogical(Hardware, Logical, &address) );
+ gcmkERR_BREAK(gckVGHARDWARE_ConvertLogical(Hardware, Logical,
+ gcvFALSE, &address));
/* Write the AQMemoryFePageTable register. */
gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
0x00400,
- gcmkFIXADDRESS(address)) );
+ gcmkFIXADDRESS(address)));
/* Write the AQMemoryTxPageTable register. */
gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
0x00404,
- gcmkFIXADDRESS(address)) );
+ gcmkFIXADDRESS(address)));
/* Write the AQMemoryPePageTable register. */
gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
0x00408,
- gcmkFIXADDRESS(address)) );
+ gcmkFIXADDRESS(address)));
/* Write the AQMemoryPezPageTable register. */
gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
0x0040C,
- gcmkFIXADDRESS(address)) );
+ gcmkFIXADDRESS(address)));
/* Write the AQMemoryRaPageTable register. */
gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
0x00410,
- gcmkFIXADDRESS(address)) );
+ gcmkFIXADDRESS(address)));
}
while (gcvFALSE);
gcmkERR_BREAK(gckOS_WaitSignal(
command->os,
command->powerStallSignal,
- gcdGPU_TIMEOUT));
+ command->kernel->kernel->timeOut));
}
acquired = gcvTRUE;
}
- if (flag & gcvPOWER_FLAG_STOP)
- {
- }
/* Get time until stopped. */
gcmkPROFILE_QUERY(time, stopTime);
- /* Only process this when hardware is enabled. */
- if (Hardware->clockState && Hardware->powerState)
- {
- }
if (flag & gcvPOWER_FLAG_DELAY)
{
if (flag & gcvPOWER_FLAG_INITIALIZE)
{
+
+ /* Initialize GPU here, replaced by InitializeHardware later */
gcmkONERROR(gckVGHARDWARE_SetMMU(Hardware, Hardware->kernel->mmu->pageTableLogical));
+ gcmkVERIFY_OK(gckVGHARDWARE_SetFastClear(Hardware, -1));
/* Force the command queue to reload the next context. */
command->currentContext = 0;
/* Get time until off. */
gcmkPROFILE_QUERY(time, offTime);
- if (flag & gcvPOWER_FLAG_START)
- {
- }
/* Get time until started. */
gcmkPROFILE_QUERY(time, startTime);
return gcvSTATUS_OK;
}
+#if gcdPOWEROFF_TIMEOUT
gceSTATUS
gckVGHARDWARE_SetPowerOffTimeout(
IN gckVGHARDWARE Hardware,
gcmkFOOTER_ARG("*Timeout=%d", *Timeout);
return gcvSTATUS_OK;
}
+#endif
gceSTATUS
gckVGHARDWARE_QueryIdle(
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
gctISRMANAGERFUNC stopIsr;
gctPOINTER isrContext;
gctPOINTER pageTableDirty;
-
#if gcdPOWEROFF_TIMEOUT
gctUINT32 powerOffTime;
gctUINT32 powerOffTimeout;
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
gcmDEFINE2TEXT(gcvHAL_FREE_CONTIGUOUS_MEMORY),
gcmDEFINE2TEXT(gcvHAL_ALLOCATE_VIDEO_MEMORY),
gcmDEFINE2TEXT(gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY),
- gcmDEFINE2TEXT(gcvHAL_FREE_VIDEO_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_RELEASE_VIDEO_MEMORY),
gcmDEFINE2TEXT(gcvHAL_MAP_MEMORY),
gcmDEFINE2TEXT(gcvHAL_UNMAP_MEMORY),
gcmDEFINE2TEXT(gcvHAL_MAP_USER_MEMORY),
gcmDEFINE2TEXT(gcvHAL_GET_PROFILE_SETTING),
gcmDEFINE2TEXT(gcvHAL_SET_PROFILE_SETTING),
gcmDEFINE2TEXT(gcvHAL_READ_ALL_PROFILE_REGISTERS),
+ gcmDEFINE2TEXT(gcvHAL_PROFILE_REGISTERS_2D),
#if VIVANTE_PROFILER_PERDRAW
- gcmDEFINE2TEXT(gcvHAL_READ_PROFILER_REGISTER_SETTING),
+ gcvHAL_READ_PROFILER_REGISTER_SETTING,
#endif
- gcmDEFINE2TEXT(gcvHAL_PROFILE_REGISTERS_2D),
gcmDEFINE2TEXT(gcvHAL_SET_POWER_MANAGEMENT_STATE),
gcmDEFINE2TEXT(gcvHAL_QUERY_POWER_MANAGEMENT_STATE),
gcmDEFINE2TEXT(gcvHAL_GET_BASE_ADDRESS),
gcmDEFINE2TEXT(gcvHAL_VERSION),
gcmDEFINE2TEXT(gcvHAL_CHIP_INFO),
gcmDEFINE2TEXT(gcvHAL_ATTACH),
- gcmDEFINE2TEXT(gcvHAL_DETACH)
+ gcmDEFINE2TEXT(gcvHAL_DETACH),
+ gcmDEFINE2TEXT(gcvHAL_COMPOSE),
+ gcmDEFINE2TEXT(gcvHAL_SET_TIMEOUT),
+ gcmDEFINE2TEXT(gcvHAL_GET_FRAME_INFO),
+ gcmDEFINE2TEXT(gcvHAL_QUERY_COMMAND_BUFFER),
+ gcmDEFINE2TEXT(gcvHAL_COMMIT_DONE),
+ gcmDEFINE2TEXT(gcvHAL_DUMP_GPU_STATE),
+ gcmDEFINE2TEXT(gcvHAL_DUMP_EVENT),
+ gcmDEFINE2TEXT(gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER),
+ gcmDEFINE2TEXT(gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER),
+ gcmDEFINE2TEXT(gcvHAL_SET_FSCALE_VALUE),
+ gcmDEFINE2TEXT(gcvHAL_GET_FSCALE_VALUE),
+ gcmDEFINE2TEXT(gcvHAL_NAME_VIDEO_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_IMPORT_VIDEO_MEMORY),
+ gcmDEFINE2TEXT(gcvHAL_QUERY_RESET_TIME_STAMP),
+ gcmDEFINE2TEXT(gcvHAL_READ_REGISTER_EX),
+ gcmDEFINE2TEXT(gcvHAL_WRITE_REGISTER_EX),
+ gcmDEFINE2TEXT(gcvHAL_SYNC_POINT),
+ gcmDEFINE2TEXT(gcvHAL_CREATE_NATIVE_FENCE),
+ gcmDEFINE2TEXT(gcvHAL_DESTROY_MMU),
+ gcmDEFINE2TEXT(gcvHAL_SHBUF),
};
#endif
-#if gcdENABLE_RECOVERY
+#if gcdGPU_TIMEOUT && gcdINTERRUPT_STATISTIC
void
-_ResetFinishFunction(
+_MonitorTimerFunction(
gctPOINTER Data
)
{
gckKERNEL kernel = (gckKERNEL)Data;
+ gctUINT32 pendingInterrupt;
+ gctBOOL reset = gcvFALSE;
+ gctUINT32 mask;
+ gctUINT32 advance = kernel->timeOut/2;
+
+#if gcdENABLE_VG
+ if (kernel->core == gcvCORE_VG)
+ {
+ return;
+ }
+#endif
+
+ if (kernel->monitorTimerStop)
+ {
+ /* Stop. */
+ return;
+ }
+
+ gckOS_AtomGet(kernel->os, kernel->eventObj->interruptCount, &pendingInterrupt);
+
+ if (kernel->monitoring == gcvFALSE)
+ {
+ if (pendingInterrupt)
+ {
+ /* Begin to mointor GPU state. */
+ kernel->monitoring = gcvTRUE;
+
+ /* Record current state. */
+ kernel->lastCommitStamp = kernel->eventObj->lastCommitStamp;
+ kernel->restoreAddress = kernel->hardware->lastWaitLink;
+ gcmkVERIFY_OK(gckOS_AtomGet(
+ kernel->os,
+ kernel->hardware->pendingEvent,
+ &kernel->restoreMask
+ ));
+
+ /* Clear timeout. */
+ kernel->timer = 0;
+ }
+ }
+ else
+ {
+ if (pendingInterrupt)
+ {
+ gcmkVERIFY_OK(gckOS_AtomGet(
+ kernel->os,
+ kernel->hardware->pendingEvent,
+ &mask
+ ));
+
+ if (kernel->eventObj->lastCommitStamp == kernel->lastCommitStamp
+ && kernel->hardware->lastWaitLink == kernel->restoreAddress
+ && mask == kernel->restoreMask
+ )
+ {
+ /* GPU state is not changed, accumlate timeout. */
+ kernel->timer += advance;
+
+ if (kernel->timer >= kernel->timeOut)
+ {
+ /* GPU stuck, trigger reset. */
+ reset = gcvTRUE;
+ }
+ }
+ else
+ {
+ /* GPU state changed, cancel current timeout.*/
+ kernel->monitoring = gcvFALSE;
+ }
+ }
+ else
+ {
+ /* GPU finish all jobs, cancel current timeout*/
+ kernel->monitoring = gcvFALSE;
+ }
+ }
+
+ if (reset)
+ {
+ gckKERNEL_Recovery(kernel);
+
+ /* Work in this timeout is done. */
+ kernel->monitoring = gcvFALSE;
+ }
+
+ gcmkVERIFY_OK(gckOS_StartTimer(kernel->os, kernel->monitorTimer, advance));
+}
+#endif
+
+#if gcdPROCESS_ADDRESS_SPACE
+gceSTATUS
+_MapCommandBuffer(
+ IN gckKERNEL Kernel
+ )
+{
+ gceSTATUS status;
+ gctUINT32 i;
+ gctUINT32 physical;
+ gckMMU mmu;
+
+ gcmkONERROR(gckKERNEL_GetProcessMMU(Kernel, &mmu));
+
+ for (i = 0; i < gcdCOMMAND_QUEUES; i++)
+ {
+ gcmkONERROR(gckOS_GetPhysicalAddress(
+ Kernel->os,
+ Kernel->command->queues[i].logical,
+ &physical
+ ));
+
+ gcmkONERROR(gckMMU_FlatMapping(mmu, physical));
+ }
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+#endif
+
+void
+_DumpDriverConfigure(
+ IN gckKERNEL Kernel
+ )
+{
+ gcmkPRINT_N(0, "**************************\n");
+ gcmkPRINT_N(0, "*** GPU DRV CONFIG ***\n");
+ gcmkPRINT_N(0, "**************************\n");
- gckOS_AtomSet(kernel->os, kernel->resetAtom, 0);
+ gcmkPRINT("Galcore version %d.%d.%d.%d\n",
+ gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH, gcvVERSION_BUILD);
+
+ gckOS_DumpParam();
}
+
+void
+_DumpState(
+ IN gckKERNEL Kernel
+ )
+{
+ /* Dump GPU Debug registers. */
+ gcmkVERIFY_OK(gckHARDWARE_DumpGPUState(Kernel->hardware));
+
+ if (Kernel->virtualCommandBuffer)
+ {
+ gcmkVERIFY_OK(gckCOMMAND_DumpExecutingBuffer(Kernel->command));
+ }
+
+ /* Dump Pending event. */
+ gcmkVERIFY_OK(gckEVENT_Dump(Kernel->eventObj));
+
+ /* Dump Process DB. */
+ gcmkVERIFY_OK(gckKERNEL_DumpProcessDB(Kernel));
+
+#if gcdRECORD_COMMAND
+ /* Dump record. */
+ gckRECORDER_Dump(Kernel->command->recorder);
#endif
+}
/*******************************************************************************
**
#if gcdDVFS
kernel->dvfs = gcvNULL;
#endif
+ kernel->monitorTimer = gcvNULL;
/* Initialize the gckKERNEL object. */
kernel->object.type = gcvOBJ_KERNEL;
kernel->os = Os;
kernel->core = Core;
-
if (SharedDB == gcvNULL)
{
gcmkONERROR(gckOS_Allocate(Os,
/* Construct a database mutex. */
gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->dbMutex));
- /* Construct a id-pointer database. */
+ /* Construct a video memory name database. */
+ gcmkONERROR(gckKERNEL_CreateIntegerDatabase(kernel, &kernel->db->nameDatabase));
+
+ /* Construct a video memory name database mutex. */
+ gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->nameDatabaseMutex));
+
+ /* Construct a pointer name database. */
gcmkONERROR(gckKERNEL_CreateIntegerDatabase(kernel, &kernel->db->pointerDatabase));
- /* Construct a id-pointer database mutex. */
+ /* Construct a pointer name database mutex. */
gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->pointerDatabaseMutex));
}
else
kernel->timers[i].stopTime = 0;
}
- kernel->timeOut = gcdGPU_TIMEOUT;
-
/* Save context. */
kernel->context = Context;
-#if gcdVIRTUAL_COMMAND_BUFFER
- kernel->virtualBufferHead =
- kernel->virtualBufferTail = gcvNULL;
-
- gcmkONERROR(
- gckOS_CreateMutex(Os, (gctPOINTER)&kernel->virtualBufferLock));
-#endif
-
/* Construct atom holding number of clients. */
kernel->atomClients = gcvNULL;
gcmkONERROR(gckOS_AtomConstruct(Os, &kernel->atomClients));
/* Construct the gckMMU object. */
gcmkONERROR(
gckVGKERNEL_Construct(Os, Context, kernel, &kernel->vg));
+
+ kernel->timeOut = gcdGPU_TIMEOUT;
}
else
#endif
/* Set pointer to gckKERNEL object in gckHARDWARE object. */
kernel->hardware->kernel = kernel;
- /* Initialize the hardware. */
- gcmkONERROR(
- gckHARDWARE_InitializeHardware(kernel->hardware));
+ kernel->timeOut = kernel->hardware->type == gcvHARDWARE_2D
+ ? gcdGPU_2D_TIMEOUT
+ : gcdGPU_TIMEOUT
+ ;
+
+ /* Initialize virtual command buffer. */
+ /* TODO: Remove platform limitation after porting. */
+#if (defined(LINUX) || defined(__QNXNTO__))
+ kernel->virtualCommandBuffer = gcvTRUE;
+#else
+ kernel->virtualCommandBuffer = gcvFALSE;
+#endif
+
+#if gcdSECURITY
+ kernel->virtualCommandBuffer = gcvFALSE;
+#endif
/* Construct the gckCOMMAND object. */
gcmkONERROR(
gcmkONERROR(
gckMMU_Construct(kernel, gcdMMU_SIZE, &kernel->mmu));
-#if gcdENABLE_RECOVERY
- gcmkONERROR(
- gckOS_AtomConstruct(Os, &kernel->resetAtom));
+ gcmkVERIFY_OK(gckOS_GetTime(&kernel->resetTimeStamp));
- gcmkVERIFY_OK(
- gckOS_CreateTimer(Os,
- (gctTIMERFUNCTION)_ResetFinishFunction,
- (gctPOINTER)kernel,
- &kernel->resetFlagClearTimer));
- kernel->resetTimeStamp = 0;
-#endif
+ gcmkONERROR(gckHARDWARE_PrepareFunctions(kernel->hardware));
+
+ /* Initialize the hardware. */
+ gcmkONERROR(
+ gckHARDWARE_InitializeHardware(kernel->hardware));
#if gcdDVFS
if (gckHARDWARE_IsFeatureAvailable(kernel->hardware,
gcmkONERROR(gckOS_CreateSyncTimeline(Os, &kernel->timeline));
#endif
+ kernel->recovery = gcvTRUE;
+ kernel->stuckDump = 1;
+
+ kernel->virtualBufferHead =
+ kernel->virtualBufferTail = gcvNULL;
+
+ gcmkONERROR(
+ gckOS_CreateMutex(Os, (gctPOINTER)&kernel->virtualBufferLock));
+
+#if gcdSECURITY
+ /* Connect to security service for this GPU. */
+ gcmkONERROR(gckKERNEL_SecurityOpen(kernel, kernel->core, &kernel->securityChannel));
+#endif
+
+#if gcdGPU_TIMEOUT && gcdINTERRUPT_STATISTIC
+ if (kernel->timeOut)
+ {
+ gcmkVERIFY_OK(gckOS_CreateTimer(
+ Os,
+ (gctTIMERFUNCTION)_MonitorTimerFunction,
+ (gctPOINTER)kernel,
+ &kernel->monitorTimer
+ ));
+
+ kernel->monitoring = gcvFALSE;
+
+ kernel->monitorTimerStop = gcvFALSE;
+
+ gcmkVERIFY_OK(gckOS_StartTimer(
+ Os,
+ kernel->monitorTimer,
+ 100
+ ));
+ }
+#endif
+
/* Return pointer to the gckKERNEL object. */
*Kernel = kernel;
gcmkVERIFY_OK(gckOS_AtomDestroy(Os, kernel->atomClients));
}
-#if gcdENABLE_RECOVERY
- if (kernel->resetAtom != gcvNULL)
- {
- gcmkVERIFY_OK(gckOS_AtomDestroy(Os, kernel->resetAtom));
- }
-
- if (kernel->resetFlagClearTimer)
- {
- gcmkVERIFY_OK(gckOS_StopTimer(Os, kernel->resetFlagClearTimer));
- gcmkVERIFY_OK(gckOS_DestroyTimer(Os, kernel->resetFlagClearTimer));
- }
-#endif
-
if (kernel->dbCreated && kernel->db != gcvNULL)
{
if (kernel->db->dbMutex != gcvNULL)
gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, kernel->db));
}
-#if gcdVIRTUAL_COMMAND_BUFFER
if (kernel->virtualBufferLock != gcvNULL)
{
/* Destroy the virtual command buffer mutex. */
gcmkVERIFY_OK(gckOS_DeleteMutex(Os, kernel->virtualBufferLock));
}
-#endif
#if gcdDVFS
if (kernel->dvfs)
}
#endif
+ if (kernel->monitorTimer)
+ {
+ gcmkVERIFY_OK(gckOS_StopTimer(Os, kernel->monitorTimer));
+ gcmkVERIFY_OK(gckOS_DestroyTimer(Os, kernel->monitorTimer));
+ }
+
gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, kernel));
}
database = databaseNext)
{
databaseNext = database->next;
+
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, database->counterMutex));
gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, database));
}
if (Kernel->db->lastDatabase != gcvNULL)
{
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->lastDatabase->counterMutex));
gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, Kernel->db->lastDatabase));
}
/* Destroy the database mutex. */
gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->dbMutex));
+ /* Destroy video memory name database. */
+ gcmkVERIFY_OK(gckKERNEL_DestroyIntegerDatabase(Kernel, Kernel->db->nameDatabase));
+
+ /* Destroy video memory name database mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->nameDatabaseMutex));
+
/* Destroy id-pointer database. */
gcmkVERIFY_OK(gckKERNEL_DestroyIntegerDatabase(Kernel, Kernel->db->pointerDatabase));
/* Destroy id-pointer database mutex. */
gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
+
+ /* Destroy the database. */
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, Kernel->db));
+
+ /* Notify stuck timer to quit. */
+ Kernel->monitorTimerStop = gcvTRUE;
}
#if gcdENABLE_VG
/* Destroy the gckHARDWARE object. */
gcmkVERIFY_OK(gckHARDWARE_Destroy(Kernel->hardware));
-
-#if gcdENABLE_RECOVERY
- gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Kernel->resetAtom));
-
- if (Kernel->resetFlagClearTimer)
- {
- gcmkVERIFY_OK(gckOS_StopTimer(Kernel->os, Kernel->resetFlagClearTimer));
- gcmkVERIFY_OK(gckOS_DestroyTimer(Kernel->os, Kernel->resetFlagClearTimer));
- }
-#endif
}
/* Detsroy the client atom. */
gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Kernel->atomClients));
-#if gcdVIRTUAL_COMMAND_BUFFER
gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->virtualBufferLock));
-#endif
#if gcdDVFS
if (Kernel->dvfs)
gcmkVERIFY_OK(gckOS_DestroySyncTimeline(Kernel->os, Kernel->timeline));
#endif
+#if gcdSECURITY
+ gcmkVERIFY_OK(gckKERNEL_SecurityClose(Kernel->securityChannel));
+#endif
+
+ if (Kernel->monitorTimer)
+ {
+ gcmkVERIFY_OK(gckOS_StopTimer(Kernel->os, Kernel->monitorTimer));
+ gcmkVERIFY_OK(gckOS_DestroyTimer(Kernel->os, Kernel->monitorTimer));
+ }
+
/* Mark the gckKERNEL object as unknown. */
Kernel->object.type = gcvOBJ_UNKNOWN;
return gcvSTATUS_OK;
}
-#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/oom.h>
-#include <linux/sched.h>
-#include <linux/notifier.h>
-
-extern struct task_struct *lowmem_deathpending;
-static unsigned long lowmem_deathpending_timeout;
-
-static int force_contiguous_lowmem_shrink(IN gckKERNEL Kernel)
-{
- struct task_struct *p;
- struct task_struct *selected = NULL;
- int tasksize;
- int ret = -1;
- int min_adj = 0;
- int selected_tasksize = 0;
- int selected_oom_adj;
- /*
- * If we already have a death outstanding, then
- * bail out right away; indicating to vmscan
- * that we have nothing further to offer on
- * this pass.
- *
- */
- if (lowmem_deathpending &&
- time_before_eq(jiffies, lowmem_deathpending_timeout))
- return 0;
- selected_oom_adj = min_adj;
-
- read_lock(&tasklist_lock);
- for_each_process(p) {
- struct mm_struct *mm;
- struct signal_struct *sig;
- gcuDATABASE_INFO info;
- int oom_adj;
-
- task_lock(p);
- mm = p->mm;
- sig = p->signal;
- if (!mm || !sig) {
- task_unlock(p);
- continue;
- }
- oom_adj = sig->oom_adj;
- if (oom_adj < min_adj) {
- task_unlock(p);
- continue;
- }
-
- tasksize = 0;
- if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_VIDEO_MEMORY, &info) == gcvSTATUS_OK){
- tasksize += info.counters.bytes / PAGE_SIZE;
- }
- if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_CONTIGUOUS, &info) == gcvSTATUS_OK){
- tasksize += info.counters.bytes / PAGE_SIZE;
- }
-
- task_unlock(p);
-
- if (tasksize <= 0)
- continue;
-
- gckOS_Print("<gpu> pid %d (%s), adj %d, size %d \n", p->pid, p->comm, oom_adj, tasksize);
-
- if (selected) {
- if (oom_adj < selected_oom_adj)
- continue;
- if (oom_adj == selected_oom_adj &&
- tasksize <= selected_tasksize)
- continue;
- }
- selected = p;
- selected_tasksize = tasksize;
- selected_oom_adj = oom_adj;
- }
- if (selected) {
- gckOS_Print("<gpu> send sigkill to %d (%s), adj %d, size %d\n",
- selected->pid, selected->comm,
- selected_oom_adj, selected_tasksize);
- lowmem_deathpending = selected;
- lowmem_deathpending_timeout = jiffies + HZ;
- force_sig(SIGKILL, selected);
- ret = 0;
- }
- read_unlock(&tasklist_lock);
- return ret;
-}
-
-#endif
-
/*******************************************************************************
**
** _AllocateMemory
** Pointer to a gcsHAL_INTERFACE structure that receives any data to be
** returned.
*/
-static gceSTATUS
-_AllocateMemory(
+gceSTATUS
+gckKERNEL_AllocateLinearMemory(
IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
IN OUT gcePOOL * Pool,
IN gctSIZE_T Bytes,
- IN gctSIZE_T Alignment,
+ IN gctUINT32 Alignment,
IN gceSURF_TYPE Type,
- OUT gcuVIDMEM_NODE_PTR * Node
+ IN gctUINT32 Flag,
+ OUT gctUINT32 * Node
)
{
gcePOOL pool;
gctINT loopCount;
gcuVIDMEM_NODE_PTR node = gcvNULL;
gctBOOL tileStatusInVirtual;
- gctBOOL forceContiguous = gcvFALSE;
+ gctBOOL contiguous = gcvFALSE;
+ gctBOOL cacheable = gcvFALSE;
+ gctSIZE_T bytes = Bytes;
+ gctUINT32 handle = 0;
+ gceDATABASE_TYPE type;
gcmkHEADER_ARG("Kernel=0x%x *Pool=%d Bytes=%lu Alignment=%lu Type=%d",
Kernel, *Pool, Bytes, Alignment, Type);
gcmkVERIFY_ARGUMENT(Pool != gcvNULL);
gcmkVERIFY_ARGUMENT(Bytes != 0);
-#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
-_AllocateMemory_Retry:
-#endif
+ /* Get basic type. */
+ Type &= 0xFF;
+
+ /* Check flags. */
+ contiguous = Flag & gcvALLOC_FLAG_CONTIGUOUS;
+ cacheable = Flag & gcvALLOC_FLAG_CACHEABLE;
+
+AllocateMemory:
+
/* Get initial pool. */
switch (pool = *Pool)
{
- case gcvPOOL_DEFAULT_FORCE_CONTIGUOUS:
- forceContiguous = gcvTRUE;
case gcvPOOL_DEFAULT:
case gcvPOOL_LOCAL:
pool = gcvPOOL_LOCAL_INTERNAL;
loopCount = (gctINT) gcvPOOL_NUMBER_OF_POOLS;
break;
- case gcvPOOL_DEFAULT_FORCE_CONTIGUOUS_CACHEABLE:
- pool = gcvPOOL_CONTIGUOUS;
- loopCount = 1;
- forceContiguous = gcvTRUE;
- break;
-
default:
loopCount = 1;
break;
{
/* Create a gcuVIDMEM_NODE for virtual memory. */
gcmkONERROR(
- gckVIDMEM_ConstructVirtual(Kernel, gcvFALSE, Bytes, &node));
+ gckVIDMEM_ConstructVirtual(Kernel, Flag | gcvALLOC_FLAG_NON_CONTIGUOUS, Bytes, &node));
+
+ bytes = node->Virtual.bytes;
+ node->Virtual.type = Type;
/* Success. */
break;
if (pool == gcvPOOL_CONTIGUOUS)
{
#if gcdCONTIGUOUS_SIZE_LIMIT
- if (Bytes > gcdCONTIGUOUS_SIZE_LIMIT && forceContiguous == gcvFALSE)
+ if (Bytes > gcdCONTIGUOUS_SIZE_LIMIT && contiguous == gcvFALSE)
{
status = gcvSTATUS_OUT_OF_MEMORY;
}
#endif
{
/* Create a gcuVIDMEM_NODE from contiguous memory. */
- status = gckVIDMEM_ConstructVirtual(Kernel, gcvTRUE, Bytes, &node);
+ status = gckVIDMEM_ConstructVirtual(
+ Kernel,
+ Flag | gcvALLOC_FLAG_CONTIGUOUS,
+ Bytes,
+ &node);
}
- if (gcmIS_SUCCESS(status) || forceContiguous == gcvTRUE)
+ if (gcmIS_SUCCESS(status))
{
- /* Memory allocated. */
- if(node && forceContiguous == gcvTRUE)
- {
- gctUINT32 physAddr=0;
- gctUINT32 baseAddress = 0;
-
- gcmkONERROR(
- gckOS_LockPages(Kernel->os,
- node->Virtual.physical,
- node->Virtual.bytes,
- gcvFALSE,
- &node->Virtual.logical,
- &node->Virtual.pageCount));
-
- /* Convert logical address into a physical address. */
- gcmkONERROR(
- gckOS_GetPhysicalAddress(Kernel->os,
- node->Virtual.logical,
- &physAddr));
-
- gcmkONERROR(
- gckOS_UnlockPages(Kernel->os,
- node->Virtual.physical,
- node->Virtual.bytes,
- node->Virtual.logical));
-
- gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress));
-
- gcmkASSERT(physAddr >= baseAddress);
-
- /* Subtract baseAddress to get a GPU address used for programming. */
- physAddr -= baseAddress;
-
- if((physAddr & 0x80000000) || ((physAddr + Bytes) & 0x80000000))
- {
- gckOS_Print("gpu virtual memory 0x%x cannot be allocated in force contiguous request!\n", physAddr);
-
- gcmkONERROR(gckVIDMEM_Free(node));
-
- node = gcvNULL;
- }
- }
+ bytes = node->Virtual.bytes;
+ node->Virtual.type = Type;
+ /* Memory allocated. */
break;
}
}
else
+ /* gcvPOOL_SYSTEM can't be cacheable. */
+ if (cacheable == gcvFALSE)
{
/* Get pointer to gckVIDMEM object for pool. */
-#if gcdUSE_VIDMEM_PER_PID
- gctUINT32 pid;
- gckOS_GetProcessID(&pid);
-
- status = gckKERNEL_GetVideoMemoryPoolPid(Kernel, pool, pid, &videoMemory);
- if (status == gcvSTATUS_NOT_FOUND)
- {
- /* Create VidMem pool for this process. */
- status = gckKERNEL_CreateVideoMemoryPoolPid(Kernel, pool, pid, &videoMemory);
- }
-#else
status = gckKERNEL_GetVideoMemoryPool(Kernel, pool, &videoMemory);
-#endif
if (gcmIS_SUCCESS(status))
{
/* Allocate memory. */
- status = gckVIDMEM_AllocateLinear(videoMemory,
- Bytes,
- Alignment,
- Type,
- &node);
+#if defined(gcdLINEAR_SIZE_LIMIT)
+ /* 512 KB */
+ if (Bytes > gcdLINEAR_SIZE_LIMIT)
+ {
+ status = gcvSTATUS_OUT_OF_MEMORY;
+ }
+ else
+#endif
+ {
+ status = gckVIDMEM_AllocateLinear(Kernel,
+ videoMemory,
+ Bytes,
+ Alignment,
+ Type,
+ (*Pool == gcvPOOL_SYSTEM),
+ &node);
+ }
if (gcmIS_SUCCESS(status))
{
/* Memory allocated. */
node->VidMem.pool = pool;
+ bytes = node->VidMem.bytes;
break;
}
}
else
if (pool == gcvPOOL_CONTIGUOUS)
{
- tileStatusInVirtual =
- gckHARDWARE_IsFeatureAvailable(Kernel->hardware,
- gcvFEATURE_MC20);
+#if gcdENABLE_VG
+ if (Kernel->vg)
+ {
+ tileStatusInVirtual = gcvFALSE;
+ }
+ else
+#endif
+ {
+ tileStatusInVirtual =
+ gckHARDWARE_IsFeatureAvailable(Kernel->hardware,
+ gcvFEATURE_MC20);
+ }
if (Type == gcvSURF_TILE_STATUS && tileStatusInVirtual != gcvTRUE)
{
gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
}
+ if (contiguous)
+ {
+ break;
+ }
+
/* Advance to virtual memory. */
pool = gcvPOOL_VIRTUAL;
}
if (node == gcvNULL)
{
-
-#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
- if(forceContiguous == gcvTRUE)
+ if (contiguous)
{
- if(force_contiguous_lowmem_shrink(Kernel) == 0)
+ /* Broadcast OOM message. */
+ status = gckOS_Broadcast(Kernel->os, Kernel->hardware, gcvBROADCAST_OUT_OF_MEMORY);
+
+ if (gcmIS_SUCCESS(status))
{
- /* Sleep 1 millisecond. */
- gckOS_Delay(gcvNULL, 1);
- goto _AllocateMemory_Retry;
+ /* Get some memory. */
+ gckOS_Delay(gcvNULL, 1);
+ goto AllocateMemory;
}
}
-#endif
+
/* Nothing allocated. */
gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
}
+ /* Allocate handle for this video memory. */
+ gcmkONERROR(
+ gckVIDMEM_NODE_Allocate(Kernel, node, Type, pool, &handle));
+
/* Return node and pool used for allocation. */
- *Node = node;
+ *Node = handle;
*Pool = pool;
+ /* Encode surface type and pool to database type. */
+ type = gcvDB_VIDEO_MEMORY
+ | (Type << gcdDB_VIDEO_MEMORY_TYPE_SHIFT)
+ | (pool << gcdDB_VIDEO_MEMORY_POOL_SHIFT);
+
+ /* Record in process db. */
+ gcmkONERROR(
+ gckKERNEL_AddProcessDB(Kernel,
+ ProcessID,
+ type,
+ gcmINT2PTR(handle),
+ gcvNULL,
+ bytes));
+
/* Return status. */
gcmkFOOTER_ARG("*Pool=%d *Node=0x%x", *Pool, *Node);
return gcvSTATUS_OK;
OnError:
+ if (handle)
+ {
+ /* Destroy handle allocated. */
+ gcmkVERIFY_OK(gckVIDMEM_HANDLE_Dereference(Kernel, ProcessID, handle));
+ }
+
+ if (node)
+ {
+ /* Free video memory allocated. */
+ gcmkVERIFY_OK(gckVIDMEM_Free(Kernel, node));
+ }
+
+ /* For some case like chrome with webgl test, it needs too much memory so that it invokes oom_killer
+ * And the case is killed by oom_killer, the user wants not to see the crash and hope the case iteself handles the condition
+ * So the patch reports the out_of_memory to the case */
+ if ( status == gcvSTATUS_OUT_OF_MEMORY && (Flag & gcvALLOC_FLAG_MEMLIMIT) )
+ gcmkPRINT("The running case is out_of_memory");
+
/* Return the status. */
gcmkFOOTER();
return status;
/*******************************************************************************
**
-** gckKERNEL_Dispatch
+** gckKERNEL_ReleaseVideoMemory
**
-** Dispatch a command received from the user HAL layer.
+** Release handle of a video memory.
**
** INPUT:
**
** gckKERNEL Kernel
** Pointer to an gckKERNEL object.
**
-** gctBOOL FromUser
-** whether the call is from the user space.
+** gctUINT32 ProcessID
+** ProcessID of current process.
**
-** gcsHAL_INTERFACE * Interface
-** Pointer to a gcsHAL_INTERFACE structure that defines the command to
-** be dispatched.
+** gctUINT32 Handle
+** Handle of video memory.
**
** OUTPUT:
**
-** gcsHAL_INTERFACE * Interface
-** Pointer to a gcsHAL_INTERFACE structure that receives any data to be
-** returned.
+** Nothing.
*/
-
gceSTATUS
-gckKERNEL_Dispatch(
+gckKERNEL_ReleaseVideoMemory(
IN gckKERNEL Kernel,
- IN gctBOOL FromUser,
- IN OUT gcsHAL_INTERFACE * Interface
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 Handle
)
{
- gceSTATUS status = gcvSTATUS_OK;
- gctSIZE_T bytes;
- gcuVIDMEM_NODE_PTR node;
- gctBOOL locked = gcvFALSE;
- gctPHYS_ADDR physical = gcvNULL;
- gctPOINTER logical = gcvNULL;
- gctPOINTER info = gcvNULL;
- gckCONTEXT context = gcvNULL;
- gctUINT32 address;
- gctUINT32 processID;
- gckKERNEL kernel = Kernel;
-#if gcdSECURE_USER
- gcskSECURE_CACHE_PTR cache;
-#endif
- gctBOOL asynchronous;
- gctPOINTER paddr = gcvNULL;
-#if !USE_NEW_LINUX_SIGNAL
- gctSIGNAL signal;
-#endif
- gceSURF_TYPE type;
+ gceSTATUS status;
+ gckVIDMEM_NODE nodeObject;
+ gceDATABASE_TYPE type;
- gcmkHEADER_ARG("Kernel=0x%x FromUser=%d Interface=0x%x",
- Kernel, FromUser, Interface);
+ gcmkHEADER_ARG("Kernel=0x%08X ProcessID=%d Handle=%d",
+ Kernel, ProcessID, Handle);
- /* Verify the arguments. */
- gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
- gcmkVERIFY_ARGUMENT(Interface != gcvNULL);
+ gcmkONERROR(
+ gckVIDMEM_HANDLE_Lookup(Kernel, ProcessID, Handle, &nodeObject));
-#if gcmIS_DEBUG(gcdDEBUG_TRACE)
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
- "Dispatching command %d (%s)",
- Interface->command, _DispatchText[Interface->command]);
-#endif
-#if QNX_SINGLE_THREADED_DEBUGGING
- gckOS_AcquireMutex(Kernel->os, Kernel->debugMutex, gcvINFINITE);
-#endif
+ type = gcvDB_VIDEO_MEMORY
+ | (nodeObject->type << gcdDB_VIDEO_MEMORY_TYPE_SHIFT)
+ | (nodeObject->pool << gcdDB_VIDEO_MEMORY_POOL_SHIFT);
- /* Get the current process ID. */
- gcmkONERROR(gckOS_GetProcessID(&processID));
+ gcmkONERROR(
+ gckKERNEL_RemoveProcessDB(Kernel,
+ ProcessID,
+ type,
+ gcmINT2PTR(Handle)));
-#if gcdSECURE_USER
- gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache));
-#endif
+ gckVIDMEM_HANDLE_Dereference(Kernel, ProcessID, Handle);
- /* Dispatch on command. */
- switch (Interface->command)
- {
- case gcvHAL_GET_BASE_ADDRESS:
- /* Get base address. */
- gcmkONERROR(
- gckOS_GetBaseAddress(Kernel->os,
- &Interface->u.GetBaseAddress.baseAddress));
- break;
+ gckVIDMEM_NODE_Dereference(Kernel, nodeObject);
- case gcvHAL_QUERY_VIDEO_MEMORY:
- /* Query video memory size. */
- gcmkONERROR(gckKERNEL_QueryVideoMemory(Kernel, Interface));
- break;
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
- case gcvHAL_QUERY_CHIP_IDENTITY:
- /* Query chip identity. */
- gcmkONERROR(
- gckHARDWARE_QueryChipIdentity(
- Kernel->hardware,
- &Interface->u.QueryChipIdentity));
- break;
+OnError:
+ gcmkFOOTER();
+ return status;
+}
- case gcvHAL_MAP_MEMORY:
- physical = gcmINT2PTR(Interface->u.MapMemory.physical);
+/*******************************************************************************
+**
+** gckKERNEL_LockVideoMemory
+**
+** Lock a video memory node. It will generate a cpu virtual address used
+** by software and a GPU address used by GPU.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gceCORE Core
+** GPU to which video memory is locked.
+**
+** gcsHAL_INTERFACE * Interface
+** Pointer to a gcsHAL_INTERFACE structure that defines the command to
+** be dispatched.
+**
+** OUTPUT:
+**
+** gcsHAL_INTERFACE * Interface
+** Pointer to a gcsHAL_INTERFACE structure that receives any data to be
+** returned.
+*/
+gceSTATUS
+gckKERNEL_LockVideoMemory(
+ IN gckKERNEL Kernel,
+ IN gceCORE Core,
+ IN gctUINT32 ProcessID,
+ IN gctBOOL FromUser,
+ IN OUT gcsHAL_INTERFACE * Interface
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE nodeObject = gcvNULL;
+ gcuVIDMEM_NODE_PTR node = gcvNULL;
+ gctBOOL locked = gcvFALSE;
+ gctBOOL asynchronous = gcvFALSE;
+#ifndef __QNXNTO__
+ gctPOINTER pointer = gcvNULL;
+#endif
- /* Map memory. */
- gcmkONERROR(
- gckKERNEL_MapMemory(Kernel,
- physical,
- (gctSIZE_T) Interface->u.MapMemory.bytes,
- &logical));
+ gcmkHEADER_ARG("Kernel=0x%08X ProcessID=%d",
+ Kernel, ProcessID);
- Interface->u.MapMemory.logical = gcmPTR_TO_UINT64(logical);
+ gcmkONERROR(
+ gckVIDMEM_HANDLE_LookupAndReference(Kernel,
+ Interface->u.LockVideoMemory.node,
+ &nodeObject));
- gcmkVERIFY_OK(
- gckKERNEL_AddProcessDB(Kernel,
- processID, gcvDB_MAP_MEMORY,
- logical,
- physical,
- (gctSIZE_T) Interface->u.MapMemory.bytes));
- break;
+ node = nodeObject->node;
- case gcvHAL_UNMAP_MEMORY:
- physical = gcmINT2PTR(Interface->u.UnmapMemory.physical);
+ Interface->u.LockVideoMemory.gid = 0;
- /* Unmap memory. */
- gcmkONERROR(
- gckKERNEL_UnmapMemory(Kernel,
- physical,
- (gctSIZE_T) Interface->u.UnmapMemory.bytes,
- gcmUINT64_TO_PTR(Interface->u.UnmapMemory.logical)));
- gcmkVERIFY_OK(
- gckKERNEL_RemoveProcessDB(Kernel,
- processID, gcvDB_MAP_MEMORY,
- gcmUINT64_TO_PTR(Interface->u.UnmapMemory.logical)));
- break;
+ /* Lock video memory. */
+ gcmkONERROR(
+ gckVIDMEM_Lock(Kernel,
+ nodeObject,
+ Interface->u.LockVideoMemory.cacheable,
+ &Interface->u.LockVideoMemory.address,
+ &Interface->u.LockVideoMemory.gid,
+ &Interface->u.LockVideoMemory.physicalAddress));
- case gcvHAL_ALLOCATE_NON_PAGED_MEMORY:
- bytes = (gctSIZE_T) Interface->u.AllocateNonPagedMemory.bytes;
+ locked = gcvTRUE;
- /* Allocate non-paged memory. */
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ /* Map video memory address into user space. */
+#ifdef __QNXNTO__
+ if (node->VidMem.logical == gcvNULL)
+ {
+ gcmkONERROR(
+ gckKERNEL_MapVideoMemory(Kernel,
+ FromUser,
+ Interface->u.LockVideoMemory.address,
+ ProcessID,
+ node->VidMem.bytes,
+ &node->VidMem.logical));
+ }
+ gcmkASSERT(node->VidMem.logical != gcvNULL);
+
+ Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->VidMem.logical);
+#else
gcmkONERROR(
- gckOS_AllocateNonPagedMemory(
- Kernel->os,
- FromUser,
- &bytes,
- &physical,
- &logical));
+ gckKERNEL_MapVideoMemoryEx(Kernel,
+ Core,
+ FromUser,
+ Interface->u.LockVideoMemory.address,
+ &pointer));
- Interface->u.AllocateNonPagedMemory.bytes = bytes;
- Interface->u.AllocateNonPagedMemory.logical = gcmPTR_TO_UINT64(logical);
- Interface->u.AllocateNonPagedMemory.physical = gcmPTR_TO_NAME(physical);
+ Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(pointer);
+#endif
+ }
+ else
+ {
+ Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->Virtual.logical);
- gcmkVERIFY_OK(
- gckKERNEL_AddProcessDB(Kernel,
- processID, gcvDB_NON_PAGED,
- logical,
- gcmINT2PTR(Interface->u.AllocateNonPagedMemory.physical),
- bytes));
+ /* Success. */
+ status = gcvSTATUS_OK;
+ }
- break;
+#if gcdPROCESS_ADDRESS_SPACE
+ gcmkONERROR(gckVIDMEM_Node_Lock(
+ Kernel,
+ nodeObject,
+ &Interface->u.LockVideoMemory.address
+ ));
+#endif
- case gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER:
-#if gcdVIRTUAL_COMMAND_BUFFER
- bytes = (gctSIZE_T) Interface->u.AllocateVirtualCommandBuffer.bytes;
- gcmkONERROR(
- gckKERNEL_AllocateVirtualCommandBuffer(
- Kernel,
- FromUser,
- &bytes,
- &physical,
- &logical));
+#if gcdSECURE_USER
+ /* Return logical address as physical address. */
+ Interface->u.LockVideoMemory.address =
+ (gctUINT32)(Interface->u.LockVideoMemory.memory);
+#endif
+ gcmkONERROR(
+ gckKERNEL_AddProcessDB(Kernel,
+ ProcessID, gcvDB_VIDEO_MEMORY_LOCKED,
+ gcmINT2PTR(Interface->u.LockVideoMemory.node),
+ gcvNULL,
+ 0));
- Interface->u.AllocateVirtualCommandBuffer.bytes = bytes;
- Interface->u.AllocateVirtualCommandBuffer.logical = gcmPTR_TO_UINT64(logical);
- Interface->u.AllocateVirtualCommandBuffer.physical = gcmPTR_TO_NAME(physical);
+ gckVIDMEM_HANDLE_Reference(
+ Kernel, ProcessID, (gctUINT32)Interface->u.LockVideoMemory.node);
- gcmkVERIFY_OK(
- gckKERNEL_AddProcessDB(Kernel,
- processID, gcvDB_COMMAND_BUFFER,
- logical,
- gcmINT2PTR(Interface->u.AllocateVirtualCommandBuffer.physical),
- bytes));
-#else
- status = gcvSTATUS_NOT_SUPPORTED;
-#endif
- break;
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
- case gcvHAL_FREE_NON_PAGED_MEMORY:
- physical = gcmNAME_TO_PTR(Interface->u.FreeNonPagedMemory.physical);
+OnError:
+ if (locked)
+ {
+ /* Roll back the lock. */
+ gcmkVERIFY_OK(gckVIDMEM_Unlock(Kernel,
+ nodeObject,
+ gcvSURF_TYPE_UNKNOWN,
+ &asynchronous));
- /* Unmap user logical out of physical memory first. */
- gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os,
- physical,
- (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes,
- gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
+ if (gcvTRUE == asynchronous)
+ {
+ /* Bottom Half */
+ gcmkVERIFY_OK(gckVIDMEM_Unlock(Kernel,
+ nodeObject,
+ gcvSURF_TYPE_UNKNOWN,
+ gcvNULL));
+ }
+ }
- /* Free non-paged memory. */
- gcmkONERROR(
- gckOS_FreeNonPagedMemory(Kernel->os,
- (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes,
- physical,
- gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
+ if (nodeObject != gcvNULL)
+ {
+ gckVIDMEM_NODE_Dereference(Kernel, nodeObject);
+ }
- gcmkVERIFY_OK(
- gckKERNEL_RemoveProcessDB(Kernel,
- processID, gcvDB_NON_PAGED,
- gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
+ gcmkFOOTER();
+ return status;
+}
-#if gcdSECURE_USER
- gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
- Kernel,
- cache,
- gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical),
- Interface->u.FreeNonPagedMemory.bytes));
-#endif
+/*******************************************************************************
+**
+** gckKERNEL_UnlockVideoMemory
+**
+** Unlock a video memory node.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctUINT32 ProcessID
+** ProcessID of current process.
+**
+** gcsHAL_INTERFACE * Interface
+** Pointer to a gcsHAL_INTERFACE structure that defines the command to
+** be dispatched.
+**
+** OUTPUT:
+**
+** gcsHAL_INTERFACE * Interface
+** Pointer to a gcsHAL_INTERFACE structure that receives any data to be
+** returned.
+*/
+gceSTATUS
+gckKERNEL_UnlockVideoMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN OUT gcsHAL_INTERFACE * Interface
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE nodeObject;
+ gcuVIDMEM_NODE_PTR node;
- gcmRELEASE_NAME(Interface->u.FreeNonPagedMemory.physical);
+ gcmkHEADER_ARG("Kernel=0x%08X ProcessID=%d",
+ Kernel, ProcessID);
- break;
+ gcmkONERROR(gckVIDMEM_HANDLE_Lookup(
+ Kernel,
+ ProcessID,
+ (gctUINT32)Interface->u.UnlockVideoMemory.node,
+ &nodeObject));
- case gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY:
- bytes = (gctSIZE_T) Interface->u.AllocateContiguousMemory.bytes;
+ node = nodeObject->node;
- /* Allocate contiguous memory. */
- gcmkONERROR(gckOS_AllocateContiguous(
- Kernel->os,
- FromUser,
- &bytes,
- &physical,
- &logical));
+ /* Unlock video memory. */
+#if gcdSECURE_USER
+ /* Save node information before it disappears. */
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ logical = gcvNULL;
+ bytes = 0;
+ }
+ else
+ {
+ logical = node->Virtual.logical;
+ bytes = node->Virtual.bytes;
+ }
+#endif
- Interface->u.AllocateContiguousMemory.bytes = bytes;
- Interface->u.AllocateContiguousMemory.logical = gcmPTR_TO_UINT64(logical);
- Interface->u.AllocateContiguousMemory.physical = gcmPTR_TO_NAME(physical);
-
- gcmkONERROR(gckHARDWARE_ConvertLogical(
- Kernel->hardware,
- gcmUINT64_TO_PTR(Interface->u.AllocateContiguousMemory.logical),
- &Interface->u.AllocateContiguousMemory.address));
-
- gcmkVERIFY_OK(gckKERNEL_AddProcessDB(
- Kernel,
- processID, gcvDB_CONTIGUOUS,
- logical,
- gcmINT2PTR(Interface->u.AllocateContiguousMemory.physical),
- bytes));
-
- break;
-
- case gcvHAL_FREE_CONTIGUOUS_MEMORY:
- physical = gcmNAME_TO_PTR(Interface->u.FreeContiguousMemory.physical);
-
- /* Unmap user logical out of physical memory first. */
- gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os,
- physical,
- (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes,
- gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical)));
-
- /* Free contiguous memory. */
- gcmkONERROR(
- gckOS_FreeContiguous(Kernel->os,
- physical,
- gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical),
- (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes));
-
- gcmkVERIFY_OK(
- gckKERNEL_RemoveProcessDB(Kernel,
- processID, gcvDB_CONTIGUOUS,
- gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
+ /* Unlock video memory. */
+ gcmkONERROR(gckVIDMEM_Unlock(
+ Kernel,
+ nodeObject,
+ Interface->u.UnlockVideoMemory.type,
+ &Interface->u.UnlockVideoMemory.asynchroneous));
#if gcdSECURE_USER
- gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
- Kernel,
- cache,
- gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical),
- Interface->u.FreeContiguousMemory.bytes));
+ /* Flush the translation cache for virtual surfaces. */
+ if (logical != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(Kernel,
+ cache,
+ logical,
+ bytes));
+ }
#endif
- gcmRELEASE_NAME(Interface->u.FreeContiguousMemory.physical);
-
- break;
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
- case gcvHAL_ALLOCATE_VIDEO_MEMORY:
+OnError:
+ gcmkFOOTER();
+ return status;
+}
- gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+gceSTATUS
+gckKERNEL_QueryDatabase(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN OUT gcsHAL_INTERFACE * Interface
+ )
+{
+ gceSTATUS status;
+ gctINT i;
+ gcuDATABASE_INFO tmp;
- break;
+ gceDATABASE_TYPE type[3] = {
+ gcvDB_VIDEO_MEMORY | (gcvPOOL_SYSTEM << gcdDB_VIDEO_MEMORY_POOL_SHIFT),
+ gcvDB_VIDEO_MEMORY | (gcvPOOL_CONTIGUOUS << gcdDB_VIDEO_MEMORY_POOL_SHIFT),
+ gcvDB_VIDEO_MEMORY | (gcvPOOL_VIRTUAL << gcdDB_VIDEO_MEMORY_POOL_SHIFT),
+ };
- case gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY:
- type = Interface->u.AllocateLinearVideoMemory.type;
+ gcmkHEADER();
- /* Allocate memory. */
- gcmkONERROR(
- _AllocateMemory(Kernel,
- &Interface->u.AllocateLinearVideoMemory.pool,
- Interface->u.AllocateLinearVideoMemory.bytes,
- Interface->u.AllocateLinearVideoMemory.alignment,
- Interface->u.AllocateLinearVideoMemory.type,
- &node));
+ /* Query video memory. */
+ gcmkONERROR(
+ gckKERNEL_QueryProcessDB(Kernel,
+ Interface->u.Database.processID,
+ !Interface->u.Database.validProcessID,
+ gcvDB_VIDEO_MEMORY,
+ &Interface->u.Database.vidMem));
- if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
- {
- bytes = node->VidMem.bytes;
- node->VidMem.type = type;
+ /* Query non-paged memory. */
+ gcmkONERROR(
+ gckKERNEL_QueryProcessDB(Kernel,
+ Interface->u.Database.processID,
+ !Interface->u.Database.validProcessID,
+ gcvDB_NON_PAGED,
+ &Interface->u.Database.nonPaged));
- gcmkONERROR(
- gckKERNEL_AddProcessDB(Kernel,
- processID, gcvDB_VIDEO_MEMORY_RESERVED,
- node,
- gcvNULL,
- bytes));
- }
- else
- {
- bytes = node->Virtual.bytes;
- node->Virtual.type = type;
+ /* Query contiguous memory. */
+ gcmkONERROR(
+ gckKERNEL_QueryProcessDB(Kernel,
+ Interface->u.Database.processID,
+ !Interface->u.Database.validProcessID,
+ gcvDB_CONTIGUOUS,
+ &Interface->u.Database.contiguous));
- if(node->Virtual.contiguous)
- {
- gcmkONERROR(
- gckKERNEL_AddProcessDB(Kernel,
- processID, gcvDB_VIDEO_MEMORY_CONTIGUOUS,
- node,
- gcvNULL,
- bytes));
- }
- else
- {
- gcmkONERROR(
- gckKERNEL_AddProcessDB(Kernel,
- processID, gcvDB_VIDEO_MEMORY_VIRTUAL,
- node,
- gcvNULL,
- bytes));
- }
+ /* Query GPU idle time. */
+ gcmkONERROR(
+ gckKERNEL_QueryProcessDB(Kernel,
+ Interface->u.Database.processID,
+ !Interface->u.Database.validProcessID,
+ gcvDB_IDLE,
+ &Interface->u.Database.gpuIdle));
+ for (i = 0; i < 3; i++)
+ {
+ /* Query each video memory pool. */
+ gcmkONERROR(
+ gckKERNEL_QueryProcessDB(Kernel,
+ Interface->u.Database.processID,
+ !Interface->u.Database.validProcessID,
+ type[i],
+ &Interface->u.Database.vidMemPool[i]));
+ }
- }
+ /* Query virtual command buffer pool. */
+ gcmkONERROR(
+ gckKERNEL_QueryProcessDB(Kernel,
+ Interface->u.Database.processID,
+ !Interface->u.Database.validProcessID,
+ gcvDB_COMMAND_BUFFER,
+ &tmp));
- gcmkONERROR(
- gckKERNEL_AddProcessDB(Kernel,
- processID, gcvDB_VIDEO_MEMORY,
- node,
- gcvNULL,
- bytes));
+ Interface->u.Database.vidMemPool[2].counters.bytes += tmp.counters.bytes;
+ Interface->u.Database.vidMemPool[2].counters.maxBytes += tmp.counters.maxBytes;
+ Interface->u.Database.vidMemPool[2].counters.totalBytes += tmp.counters.totalBytes;
- /* Get the node. */
- Interface->u.AllocateLinearVideoMemory.node = gcmPTR_TO_UINT64(node);
- break;
+ Interface->u.Database.vidMem.counters.bytes += tmp.counters.bytes;
+ Interface->u.Database.vidMem.counters.maxBytes += tmp.counters.maxBytes;
+ Interface->u.Database.vidMem.counters.totalBytes += tmp.counters.totalBytes;
- case gcvHAL_FREE_VIDEO_MEMORY:
- node = gcmUINT64_TO_PTR(Interface->u.FreeVideoMemory.node);
-#ifdef __QNXNTO__
- if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM
- && node->VidMem.logical != gcvNULL)
- {
- gcmkONERROR(
- gckKERNEL_UnmapVideoMemory(Kernel,
- node->VidMem.logical,
- processID,
- node->VidMem.bytes));
- node->VidMem.logical = gcvNULL;
- }
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+ gckKERNEL_DumpVidMemUsage(Kernel, Interface->u.Database.processID);
#endif
- /* Free video memory. */
- gcmkONERROR(
- gckVIDMEM_Free(node));
- gcmkONERROR(
- gckKERNEL_RemoveProcessDB(Kernel,
- processID, gcvDB_VIDEO_MEMORY,
- node));
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
- if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
- {
- gcmkONERROR(
- gckKERNEL_RemoveProcessDB(Kernel,
- processID, gcvDB_VIDEO_MEMORY_RESERVED,
- node));
- }
- else if(node->Virtual.contiguous)
- {
- gcmkONERROR(
- gckKERNEL_RemoveProcessDB(Kernel,
- processID, gcvDB_VIDEO_MEMORY_CONTIGUOUS,
- node));
- }
- else
- {
- gcmkONERROR(
- gckKERNEL_RemoveProcessDB(Kernel,
- processID, gcvDB_VIDEO_MEMORY_VIRTUAL,
- node));
- }
+OnError:
+ gcmkFOOTER();
+ return status;
+}
- break;
+gceSTATUS
+gckKERNEL_ConfigPowerManagement(
+ IN gckKERNEL Kernel,
+ IN OUT gcsHAL_INTERFACE * Interface
+)
+{
+ gceSTATUS status;
+ gctBOOL enable = Interface->u.ConfigPowerManagement.enable;
- case gcvHAL_LOCK_VIDEO_MEMORY:
- node = gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node);
+ gcmkHEADER();
- /* Lock video memory. */
- gcmkONERROR(
- gckVIDMEM_Lock(Kernel,
- node,
- Interface->u.LockVideoMemory.cacheable,
- &Interface->u.LockVideoMemory.address));
+ gcmkONERROR(gckHARDWARE_SetPowerManagement(Kernel->hardware, enable));
- locked = gcvTRUE;
+ if (enable == gcvTRUE)
+ {
+ gcmkONERROR(
+ gckHARDWARE_SetPowerManagementState(Kernel->hardware, gcvPOWER_ON));
+ }
- if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
- {
- /* Map video memory address into user space. */
-#ifdef __QNXNTO__
- if (node->VidMem.logical == gcvNULL)
- {
- gcmkONERROR(
- gckKERNEL_MapVideoMemory(Kernel,
- FromUser,
- Interface->u.LockVideoMemory.address,
- processID,
- node->VidMem.bytes,
- &node->VidMem.logical));
- }
- gcmkASSERT(node->VidMem.logical != gcvNULL);
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
- Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->VidMem.logical);
-#else
- gcmkONERROR(
- gckKERNEL_MapVideoMemory(Kernel,
- FromUser,
- Interface->u.LockVideoMemory.address,
- &logical));
+OnError:
+ gcmkFOOTER();
+ return status;
+}
- Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(logical);
+/*******************************************************************************
+**
+** gckKERNEL_Dispatch
+**
+** Dispatch a command received from the user HAL layer.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctBOOL FromUser
+** whether the call is from the user space.
+**
+** gcsHAL_INTERFACE * Interface
+** Pointer to a gcsHAL_INTERFACE structure that defines the command to
+** be dispatched.
+**
+** OUTPUT:
+**
+** gcsHAL_INTERFACE * Interface
+** Pointer to a gcsHAL_INTERFACE structure that receives any data to be
+** returned.
+*/
+gceSTATUS
+gckKERNEL_Dispatch(
+ IN gckKERNEL Kernel,
+ IN gctBOOL FromUser,
+ IN OUT gcsHAL_INTERFACE * Interface
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ gctPHYS_ADDR physical = gcvNULL;
+ gctSIZE_T bytes;
+ gctPOINTER logical = gcvNULL;
+ gctPOINTER info = gcvNULL;
+#if (gcdENABLE_3D || gcdENABLE_2D)
+ gckCONTEXT context = gcvNULL;
#endif
- }
- else
- {
- Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->Virtual.logical);
-
- /* Success. */
- status = gcvSTATUS_OK;
- }
-
+ gckKERNEL kernel = Kernel;
+ gctUINT32 address;
+ gctUINT32 processID;
#if gcdSECURE_USER
- /* Return logical address as physical address. */
- Interface->u.LockVideoMemory.address =
- Interface->u.LockVideoMemory.memory;
+ gcskSECURE_CACHE_PTR cache;
+ gctPOINTER logical;
#endif
- gcmkONERROR(
- gckKERNEL_AddProcessDB(Kernel,
- processID, gcvDB_VIDEO_MEMORY_LOCKED,
- node,
- gcvNULL,
- 0));
+ gctUINT32 paddr = gcvINVALID_ADDRESS;
+#if !USE_NEW_LINUX_SIGNAL
+ gctSIGNAL signal;
+#endif
+ gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
- break;
+ gckVIDMEM_NODE nodeObject;
+ gctBOOL powerMutexAcquired = gcvFALSE;
- case gcvHAL_UNLOCK_VIDEO_MEMORY:
- /* Unlock video memory. */
- node = gcmUINT64_TO_PTR(Interface->u.UnlockVideoMemory.node);
+ gcmkHEADER_ARG("Kernel=0x%x FromUser=%d Interface=0x%x",
+ Kernel, FromUser, Interface);
-#if gcdSECURE_USER
- /* Save node information before it disappears. */
- if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
- {
- logical = gcvNULL;
- bytes = 0;
- }
- else
- {
- logical = node->Virtual.logical;
- bytes = node->Virtual.bytes;
- }
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Interface != gcvNULL);
+
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
+ "Dispatching command %d (%s)",
+ Interface->command, _DispatchText[Interface->command]);
+#endif
+#if QNX_SINGLE_THREADED_DEBUGGING
+ gckOS_AcquireMutex(Kernel->os, Kernel->debugMutex, gcvINFINITE);
#endif
- /* Unlock video memory. */
- gcmkONERROR(
- gckVIDMEM_Unlock(Kernel,
- node,
- Interface->u.UnlockVideoMemory.type,
- &Interface->u.UnlockVideoMemory.asynchroneous));
+ /* Get the current process ID. */
+ gcmkONERROR(gckOS_GetProcessID(&processID));
#if gcdSECURE_USER
- /* Flush the translation cache for virtual surfaces. */
- if (logical != gcvNULL)
- {
- gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(Kernel,
- cache,
- logical,
- bytes));
- }
+ gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache));
#endif
- if (Interface->u.UnlockVideoMemory.asynchroneous == gcvFALSE)
- {
- /* There isn't a event to unlock this node, remove record now */
- gcmkONERROR(
- gckKERNEL_RemoveProcessDB(Kernel,
- processID, gcvDB_VIDEO_MEMORY_LOCKED,
- node));
- }
- break;
- case gcvHAL_EVENT_COMMIT:
- /* Commit an event queue. */
- gcmkONERROR(
- gckEVENT_Commit(Kernel->eventObj,
- gcmUINT64_TO_PTR(Interface->u.Event.queue)));
- break;
+ /* Dispatch on command. */
+ switch (Interface->command)
+ {
+ case gcvHAL_GET_BASE_ADDRESS:
+ /* Get base address. */
+ gcmkONERROR(
+ gckOS_GetBaseAddress(Kernel->os,
+ &Interface->u.GetBaseAddress.baseAddress));
+ break;
+
+ case gcvHAL_QUERY_VIDEO_MEMORY:
+ /* Query video memory size. */
+ gcmkONERROR(gckKERNEL_QueryVideoMemory(Kernel, Interface));
+ break;
+
+ case gcvHAL_QUERY_CHIP_IDENTITY:
+ /* Query chip identity. */
+ gcmkONERROR(
+ gckHARDWARE_QueryChipIdentity(
+ Kernel->hardware,
+ &Interface->u.QueryChipIdentity));
+ break;
+
+ case gcvHAL_MAP_MEMORY:
+ physical = gcmINT2PTR(Interface->u.MapMemory.physical);
+
+ /* Map memory. */
+ gcmkONERROR(
+ gckKERNEL_MapMemory(Kernel,
+ physical,
+ (gctSIZE_T) Interface->u.MapMemory.bytes,
+ &logical));
+
+ Interface->u.MapMemory.logical = gcmPTR_TO_UINT64(logical);
+
+ gcmkVERIFY_OK(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID, gcvDB_MAP_MEMORY,
+ logical,
+ physical,
+ (gctSIZE_T) Interface->u.MapMemory.bytes));
+ break;
+
+ case gcvHAL_UNMAP_MEMORY:
+ physical = gcmINT2PTR(Interface->u.UnmapMemory.physical);
+
+ gcmkVERIFY_OK(
+ gckKERNEL_RemoveProcessDB(Kernel,
+ processID, gcvDB_MAP_MEMORY,
+ gcmUINT64_TO_PTR(Interface->u.UnmapMemory.logical)));
+
+ /* Unmap memory. */
+ gcmkONERROR(
+ gckKERNEL_UnmapMemory(Kernel,
+ physical,
+ (gctSIZE_T) Interface->u.UnmapMemory.bytes,
+ gcmUINT64_TO_PTR(Interface->u.UnmapMemory.logical)));
+ break;
+
+ case gcvHAL_ALLOCATE_NON_PAGED_MEMORY:
+ bytes = (gctSIZE_T) Interface->u.AllocateNonPagedMemory.bytes;
+
+ /* Allocate non-paged memory. */
+ gcmkONERROR(
+ gckOS_AllocateNonPagedMemory(
+ Kernel->os,
+ FromUser,
+ &bytes,
+ &physical,
+ &logical));
+
+ Interface->u.AllocateNonPagedMemory.bytes = bytes;
+ Interface->u.AllocateNonPagedMemory.logical = gcmPTR_TO_UINT64(logical);
+ Interface->u.AllocateNonPagedMemory.physical = gcmPTR_TO_NAME(physical);
+
+ gcmkVERIFY_OK(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID, gcvDB_NON_PAGED,
+ logical,
+ gcmINT2PTR(Interface->u.AllocateNonPagedMemory.physical),
+ bytes));
+ break;
+
+ case gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER:
+ bytes = (gctSIZE_T) Interface->u.AllocateVirtualCommandBuffer.bytes;
+
+ gcmkONERROR(
+ gckKERNEL_AllocateVirtualCommandBuffer(
+ Kernel,
+ FromUser,
+ &bytes,
+ &physical,
+ &logical));
+
+ Interface->u.AllocateVirtualCommandBuffer.bytes = bytes;
+ Interface->u.AllocateVirtualCommandBuffer.logical = gcmPTR_TO_UINT64(logical);
+ Interface->u.AllocateVirtualCommandBuffer.physical = gcmPTR_TO_NAME(physical);
+
+ gcmkVERIFY_OK(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID, gcvDB_COMMAND_BUFFER,
+ logical,
+ gcmINT2PTR(Interface->u.AllocateVirtualCommandBuffer.physical),
+ bytes));
+ break;
+
+ case gcvHAL_FREE_NON_PAGED_MEMORY:
+ physical = gcmNAME_TO_PTR(Interface->u.FreeNonPagedMemory.physical);
+
+ gcmkVERIFY_OK(
+ gckKERNEL_RemoveProcessDB(Kernel,
+ processID, gcvDB_NON_PAGED,
+ gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
+
+ /* Unmap user logical out of physical memory first. */
+ gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os,
+ physical,
+ (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes,
+ gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
+
+ /* Free non-paged memory. */
+ gcmkONERROR(
+ gckOS_FreeNonPagedMemory(Kernel->os,
+ (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes,
+ physical,
+ gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
+
+#if gcdSECURE_USER
+ gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
+ Kernel,
+ cache,
+ gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical),
+ (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes));
+#endif
+
+ gcmRELEASE_NAME(Interface->u.FreeNonPagedMemory.physical);
+ break;
+
+ case gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY:
+ bytes = (gctSIZE_T) Interface->u.AllocateContiguousMemory.bytes;
+
+ /* Allocate contiguous memory. */
+ gcmkONERROR(gckOS_AllocateContiguous(
+ Kernel->os,
+ FromUser,
+ &bytes,
+ &physical,
+ &logical));
+
+ Interface->u.AllocateContiguousMemory.bytes = bytes;
+ Interface->u.AllocateContiguousMemory.logical = gcmPTR_TO_UINT64(logical);
+ Interface->u.AllocateContiguousMemory.physical = gcmPTR_TO_NAME(physical);
+
+ gcmkONERROR(gckHARDWARE_ConvertLogical(
+ Kernel->hardware,
+ logical,
+ gcvTRUE,
+ &Interface->u.AllocateContiguousMemory.address));
+
+ gcmkVERIFY_OK(gckKERNEL_AddProcessDB(
+ Kernel,
+ processID, gcvDB_CONTIGUOUS,
+ logical,
+ gcmINT2PTR(Interface->u.AllocateContiguousMemory.physical),
+ bytes));
+ break;
+
+ case gcvHAL_FREE_CONTIGUOUS_MEMORY:
+ physical = gcmNAME_TO_PTR(Interface->u.FreeContiguousMemory.physical);
+
+ gcmkVERIFY_OK(
+ gckKERNEL_RemoveProcessDB(Kernel,
+ processID, gcvDB_CONTIGUOUS,
+ gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
+
+ /* Unmap user logical out of physical memory first. */
+ gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os,
+ physical,
+ (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes,
+ gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical)));
+
+ /* Free contiguous memory. */
+ gcmkONERROR(
+ gckOS_FreeContiguous(Kernel->os,
+ physical,
+ gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical),
+ (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes));
+
+#if gcdSECURE_USER
+ gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
+ Kernel,
+ cache,
+ gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical),
+ (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes));
+#endif
+
+ gcmRELEASE_NAME(Interface->u.FreeContiguousMemory.physical);
+ break;
+
+ case gcvHAL_ALLOCATE_VIDEO_MEMORY:
+
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+
+ break;
+
+ case gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY:
+ /* Allocate memory. */
+ gcmkONERROR(
+ gckKERNEL_AllocateLinearMemory(Kernel, processID,
+ &Interface->u.AllocateLinearVideoMemory.pool,
+ Interface->u.AllocateLinearVideoMemory.bytes,
+ Interface->u.AllocateLinearVideoMemory.alignment,
+ Interface->u.AllocateLinearVideoMemory.type,
+ Interface->u.AllocateLinearVideoMemory.flag,
+ &Interface->u.AllocateLinearVideoMemory.node));
+ break;
+
+ case gcvHAL_RELEASE_VIDEO_MEMORY:
+ /* Release video memory. */
+ gcmkONERROR(gckKERNEL_ReleaseVideoMemory(
+ Kernel, processID,
+ (gctUINT32)Interface->u.ReleaseVideoMemory.node
+ ));
+ break;
+
+ case gcvHAL_LOCK_VIDEO_MEMORY:
+ /* Lock video memory. */
+ gcmkONERROR(gckKERNEL_LockVideoMemory(Kernel, Kernel->core, processID, FromUser, Interface));
+ break;
+
+ case gcvHAL_UNLOCK_VIDEO_MEMORY:
+ /* Unlock video memory. */
+ gcmkONERROR(gckKERNEL_UnlockVideoMemory(Kernel, processID, Interface));
+ break;
+
+ case gcvHAL_EVENT_COMMIT:
+ /* Commit an event queue. */
+#if gcdMULTI_GPU
+ if (Interface->u.Event.gpuMode == gcvMULTI_GPU_MODE_INDEPENDENT)
+ {
+ gcmkONERROR(
+ gckEVENT_Commit(Kernel->eventObj,
+ gcmUINT64_TO_PTR(Interface->u.Event.queue),
+ Interface->u.Event.chipEnable));
+ }
+ else
+ {
+ gcmkONERROR(
+ gckEVENT_Commit(Kernel->eventObj,
+ gcmUINT64_TO_PTR(Interface->u.Event.queue),
+ gcvCORE_3D_ALL_MASK));
+ }
+#else
+ gcmkONERROR(
+ gckEVENT_Commit(Kernel->eventObj,
+ gcmUINT64_TO_PTR(Interface->u.Event.queue)));
+#endif
+ break;
case gcvHAL_COMMIT:
/* Commit a command and context buffer. */
+#if gcdMULTI_GPU
+ if (Interface->u.Commit.gpuMode == gcvMULTI_GPU_MODE_INDEPENDENT)
+ {
+ gcmkONERROR(
+ gckCOMMAND_Commit(Kernel->command,
+ Interface->u.Commit.context ?
+ gcmNAME_TO_PTR(Interface->u.Commit.context) : gcvNULL,
+ gcmUINT64_TO_PTR(Interface->u.Commit.commandBuffer),
+ gcmUINT64_TO_PTR(Interface->u.Commit.delta),
+ gcmUINT64_TO_PTR(Interface->u.Commit.queue),
+ processID,
+ Interface->u.Commit.chipEnable));
+ }
+ else
+ {
+ gcmkONERROR(
+ gckCOMMAND_Commit(Kernel->command,
+ Interface->u.Commit.context ?
+ gcmNAME_TO_PTR(Interface->u.Commit.context) : gcvNULL,
+ gcmUINT64_TO_PTR(Interface->u.Commit.commandBuffer),
+ gcmUINT64_TO_PTR(Interface->u.Commit.delta),
+ gcmUINT64_TO_PTR(Interface->u.Commit.queue),
+ processID,
+ gcvCORE_3D_ALL_MASK));
+ }
+#else
gcmkONERROR(
gckCOMMAND_Commit(Kernel->command,
Interface->u.Commit.context ?
gcmUINT64_TO_PTR(Interface->u.Commit.delta),
gcmUINT64_TO_PTR(Interface->u.Commit.queue),
processID));
+#endif
+
break;
case gcvHAL_STALL:
/* Stall the command queue. */
+#if gcdMULTI_GPU
+ gcmkONERROR(gckCOMMAND_Stall(Kernel->command, gcvFALSE, gcvCORE_3D_ALL_MASK));
+#else
gcmkONERROR(gckCOMMAND_Stall(Kernel->command, gcvFALSE));
+#endif
break;
case gcvHAL_MAP_USER_MEMORY:
address = Interface->u.UnmapUserMemory.address;
info = gcmNAME_TO_PTR(Interface->u.UnmapUserMemory.info);
+ gcmkVERIFY_OK(
+ gckKERNEL_RemoveProcessDB(Kernel,
+ processID, gcvDB_MAP_USER_MEMORY,
+ gcmINT2PTR(Interface->u.UnmapUserMemory.info)));
/* Unmap user memory. */
gcmkONERROR(
gckOS_UnmapUserMemory(Kernel->os,
Kernel,
cache,
gcmUINT64_TO_PTR(Interface->u.UnmapUserMemory.memory),
- Interface->u.UnmapUserMemory.size));
+ (gctSIZE_T) Interface->u.UnmapUserMemory.size));
#endif
- gcmkVERIFY_OK(
- gckKERNEL_RemoveProcessDB(Kernel,
- processID, gcvDB_MAP_USER_MEMORY,
- gcmINT2PTR(Interface->u.UnmapUserMemory.info)));
gcmRELEASE_NAME(Interface->u.UnmapUserMemory.info);
-
break;
#if !USE_NEW_LINUX_SIGNAL
break;
case gcvUSER_SIGNAL_DESTROY:
- /* Destroy the signal. */
- gcmkONERROR(
- gckOS_DestroyUserSignal(Kernel->os,
- Interface->u.UserSignal.id));
-
gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
Kernel,
processID, gcvDB_SIGNAL,
gcmINT2PTR(Interface->u.UserSignal.id)));
+
+ /* Destroy the signal. */
+ gcmkONERROR(
+ gckOS_DestroyUserSignal(Kernel->os,
+ Interface->u.UserSignal.id));
break;
case gcvUSER_SIGNAL_SIGNAL:
break;
case gcvUSER_SIGNAL_WAIT:
-#if gcdGPU_TIMEOUT
- if (Interface->u.UserSignal.wait == gcvINFINITE)
- {
- gckHARDWARE hardware;
- gctUINT32 timer = 0;
-
- for(;;)
- {
- /* Wait on the signal. */
- status = gckOS_WaitUserSignal(Kernel->os,
- Interface->u.UserSignal.id,
- gcdGPU_ADVANCETIMER);
-
- if (status == gcvSTATUS_TIMEOUT)
- {
- gcmkONERROR(
- gckOS_SignalQueryHardware(Kernel->os,
- (gctSIGNAL)(gctUINTPTR_T)Interface->u.UserSignal.id,
- &hardware));
-
- if (hardware)
- {
- /* This signal is bound to a hardware,
- ** so the timeout is limited by Kernel->timeOut.
- */
- timer += gcdGPU_ADVANCETIMER;
- }
-
- if (timer >= Kernel->timeOut)
- {
- gcmkONERROR(
- gckOS_Broadcast(Kernel->os,
- hardware,
- gcvBROADCAST_GPU_STUCK));
-
- timer = 0;
-
- /* If a few process try to reset GPU, only one
- ** of them can do the real reset, other processes
- ** still need to wait for this signal is triggered,
- ** which menas reset is finished.
- */
- continue;
- }
- }
- else
- {
- /* Bail out on other error. */
- gcmkONERROR(status);
-
- /* Wait for signal successfully. */
- break;
- }
- }
- }
- else
-#endif
- {
- /* Wait on the signal. */
- status = gckOS_WaitUserSignal(Kernel->os,
- Interface->u.UserSignal.id,
- Interface->u.UserSignal.wait);
- }
+ /* Wait on the signal. */
+ status = gckOS_WaitUserSignal(Kernel->os,
+ Interface->u.UserSignal.id,
+ Interface->u.UserSignal.wait);
break;
break;
case gcvUSER_SIGNAL_UNMAP:
- /* Destroy the signal. */
- gcmkONERROR(
- gckOS_DestroyUserSignal(Kernel->os,
- Interface->u.UserSignal.id));
-
gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
Kernel,
processID, gcvDB_SIGNAL,
gcmINT2PTR(Interface->u.UserSignal.id)));
+
+ /* Destroy the signal. */
+ gcmkONERROR(
+ gckOS_DestroyUserSignal(Kernel->os,
+ Interface->u.UserSignal.id));
break;
default:
{
gceCHIPPOWERSTATE power;
- gckOS_AcquireMutex(Kernel->os, Kernel->hardware->powerMutex, gcvINFINITE);
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->hardware->powerMutex, gcvINFINITE));
+ powerMutexAcquired = gcvTRUE;
gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware,
&power));
if (power == gcvPOWER_ON)
status = gcvSTATUS_CHIP_NOT_READY;
}
gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->hardware->powerMutex));
+ powerMutexAcquired = gcvFALSE;
}
#else
/* No access from user land to read registers. */
#endif
break;
+#if gcdMULTI_GPU
+ case gcvHAL_READ_REGISTER_EX:
+#if gcdREGISTER_ACCESS_FROM_USER
+ {
+ gceCHIPPOWERSTATE power;
+ gctUINT32 coreId = 0;
+ gctUINT32 coreSelect = Interface->u.ReadRegisterDataEx.coreSelect;
+
+ gckOS_AcquireMutex(Kernel->os, Kernel->hardware->powerMutex, gcvINFINITE);
+ powerMutexAcquired = gcvTRUE;
+ gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware,
+ &power));
+ if (power == gcvPOWER_ON)
+ {
+ for (; coreSelect != 0; coreSelect >>= 1, coreId++)
+ {
+ if (coreSelect & 1UL)
+ {
+ /* Read a register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterByCoreId(
+ Kernel->os,
+ Kernel->core,
+ coreId,
+ Interface->u.ReadRegisterDataEx.address,
+ &Interface->u.ReadRegisterDataEx.data[coreId]));
+ }
+ }
+ }
+ else
+ {
+ for (coreId = 0; coreId < gcdMULTI_GPU; coreId++)
+ {
+ /* Chip is in power-state. */
+ Interface->u.ReadRegisterDataEx.data[coreId] = 0;
+ }
+ status = gcvSTATUS_CHIP_NOT_READY;
+ }
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->hardware->powerMutex));
+ powerMutexAcquired = gcvFALSE;
+ }
+#else
+ gctUINT32 coreId;
+
+ /* No access from user land to read registers. */
+ for (coreId = 0; coreId < gcdMULTI_GPU; coreId++)
+ {
+ Interface->u.ReadRegisterDataEx.data[coreId] = 0;
+ }
+
+ status = gcvSTATUS_NOT_SUPPORTED;
+#endif
+ break;
+
+ case gcvHAL_WRITE_REGISTER_EX:
+#if gcdREGISTER_ACCESS_FROM_USER
+ {
+ gceCHIPPOWERSTATE power;
+ gctUINT32 coreId = 0;
+ gctUINT32 coreSelect = Interface->u.WriteRegisterDataEx.coreSelect;
+
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->hardware->powerMutex, gcvINFINITE));
+ powerMutexAcquired = gcvTRUE;
+ gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware,
+ &power));
+ if (power == gcvPOWER_ON)
+ {
+ for (; coreSelect != 0; coreSelect >>= 1, coreId++)
+ {
+ if (coreSelect & 1UL)
+ {
+ /* Write a register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterByCoreId(
+ Kernel->os,
+ Kernel->core,
+ coreId,
+ Interface->u.WriteRegisterDataEx.address,
+ Interface->u.WriteRegisterDataEx.data[coreId]));
+ }
+ }
+ }
+ else
+ {
+ /* Chip is in power-state. */
+ for (coreId = 0; coreId < gcdMULTI_GPU; coreId++)
+ {
+ Interface->u.WriteRegisterDataEx.data[coreId] = 0;
+ }
+ status = gcvSTATUS_CHIP_NOT_READY;
+ }
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->hardware->powerMutex));
+ powerMutexAcquired = gcvFALSE;
+ }
+#else
+ status = gcvSTATUS_NOT_SUPPORTED;
+#endif
+ break;
+#endif
+
case gcvHAL_WRITE_REGISTER:
#if gcdREGISTER_ACCESS_FROM_USER
{
status = gcvSTATUS_OK;
break;
+
case gcvHAL_SET_PROFILE_SETTING:
#if VIVANTE_PROFILER
/* Set profile setting */
if(Kernel->hardware->gpuProfiler)
+ {
Kernel->profileEnable = Interface->u.SetProfileSetting.enable;
+#if VIVANTE_PROFILER_NEW
+ if (Kernel->profileEnable)
+ gckHARDWARE_InitProfiler(Kernel->hardware);
+#endif
+ }
else
{
status = gcvSTATUS_NOT_SUPPORTED;
case gcvHAL_RESET:
/* Reset the hardware. */
- gckKERNEL_Recovery(Kernel);
+ gcmkONERROR(
+ gckHARDWARE_Reset(Kernel->hardware));
break;
case gcvHAL_DEBUG:
break;
case gcvHAL_DUMP_GPU_STATE:
- /* Dump GPU state */
{
gceCHIPPOWERSTATE power;
- gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware,
- &power));
+
+ _DumpDriverConfigure(Kernel);
+
+ gcmkONERROR(gckHARDWARE_QueryPowerManagementState(
+ Kernel->hardware,
+ &power
+ ));
+
if (power == gcvPOWER_ON)
{
Interface->u.ReadRegisterData.data = 1;
- gcmkVERIFY_OK(
- gckHARDWARE_DumpGPUState(Kernel->hardware));
-#if gcdVIRTUAL_COMMAND_BUFFER
- gcmkVERIFY_OK(
- gckCOMMAND_DumpExecutingBuffer(Kernel->command));
-#endif
+
+ _DumpState(Kernel);
}
else
{
Interface->u.ReadRegisterData.data = 0;
status = gcvSTATUS_CHIP_NOT_READY;
+
+ gcmkPRINT("[galcore]: Can't dump state if GPU isn't POWER ON.");
}
}
break;
case gcvHAL_DUMP_EVENT:
- /* Dump GPU event */
- gcmkVERIFY_OK(gckEVENT_Dump(Kernel->eventObj));
-
- /* Dump Process DB. */
- gcmkVERIFY_OK(gckKERNEL_DumpProcessDB(Kernel));
break;
case gcvHAL_CACHE:
- node = gcmUINT64_TO_PTR(Interface->u.Cache.node);
- if (node == gcvNULL)
- {
- /* FIXME Surface wrap some memory which is not allocated by us,
- ** So we don't have physical address to handle outer cache, ignore it*/
- status = gcvSTATUS_OK;
- break;
- }
- else if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
- {
- /* Video memory has no physical handles. */
- physical = gcvNULL;
- }
- else
+
+ logical = gcmUINT64_TO_PTR(Interface->u.Cache.logical);
+
+ if (Interface->u.Cache.node)
{
- /* Grab physical handle. */
- physical = node->Virtual.physical;
+ gcmkONERROR(gckVIDMEM_HANDLE_Lookup(
+ Kernel,
+ processID,
+ Interface->u.Cache.node,
+ &nodeObject));
+
+ if (nodeObject->node->VidMem.memory->object.type == gcvOBJ_VIDMEM
+ || nodeObject->node->Virtual.contiguous
+ )
+ {
+ /* If memory is contiguous, get physical address. */
+ gcmkONERROR(gckOS_GetPhysicalAddress(
+ Kernel->os, logical, (gctUINT32*)&paddr));
+ }
}
- logical = gcmUINT64_TO_PTR(Interface->u.Cache.logical);
bytes = (gctSIZE_T) Interface->u.Cache.bytes;
switch(Interface->u.Cache.operation)
{
bytes);
break;
- case gcvCACHE_MEMORY_BARRIER:
- status = gckOS_MemoryBarrier(Kernel->os,
- logical);
- break;
+ case gcvCACHE_MEMORY_BARRIER:
+ status = gckOS_MemoryBarrier(Kernel->os,
+ logical);
+ break;
default:
status = gcvSTATUS_INVALID_ARGUMENT;
break;
/* Check truncation overflow. */
Interface->u.TimeStamp.timeDelta = (gctINT32) timeDelta;
- /*bit0~bit30 is available*/
+ /*bit0~bit30 is available*/
if (timeDelta>>31)
{
Interface->u.TimeStamp.timeDelta = 0;
break;
case gcvHAL_DATABASE:
- /* Query video memory. */
- gcmkONERROR(
- gckKERNEL_QueryProcessDB(Kernel,
- Interface->u.Database.processID,
- !Interface->u.Database.validProcessID,
- gcvDB_VIDEO_MEMORY,
- &Interface->u.Database.vidMem));
-
- /* Query non-paged memory. */
- gcmkONERROR(
- gckKERNEL_QueryProcessDB(Kernel,
- Interface->u.Database.processID,
- !Interface->u.Database.validProcessID,
- gcvDB_NON_PAGED,
- &Interface->u.Database.nonPaged));
-
- /* Query contiguous memory. */
- gcmkONERROR(
- gckKERNEL_QueryProcessDB(Kernel,
- Interface->u.Database.processID,
- !Interface->u.Database.validProcessID,
- gcvDB_CONTIGUOUS,
- &Interface->u.Database.contiguous));
-
- /* Query GPU idle time. */
- gcmkONERROR(
- gckKERNEL_QueryProcessDB(Kernel,
- Interface->u.Database.processID,
- !Interface->u.Database.validProcessID,
- gcvDB_IDLE,
- &Interface->u.Database.gpuIdle));
- break;
-
- case gcvHAL_VIDMEM_DATABASE:
- /* Query reserved video memory. */
- gcmkONERROR(
- gckKERNEL_QueryProcessDB(Kernel,
- Interface->u.VidMemDatabase.processID,
- !Interface->u.VidMemDatabase.validProcessID,
- gcvDB_VIDEO_MEMORY_RESERVED,
- &Interface->u.VidMemDatabase.vidMemResv));
-
- /* Query contiguous video memory. */
- gcmkONERROR(
- gckKERNEL_QueryProcessDB(Kernel,
- Interface->u.VidMemDatabase.processID,
- !Interface->u.VidMemDatabase.validProcessID,
- gcvDB_VIDEO_MEMORY_CONTIGUOUS,
- &Interface->u.VidMemDatabase.vidMemCont));
-
- /* Query virtual video memory. */
- gcmkONERROR(
- gckKERNEL_QueryProcessDB(Kernel,
- Interface->u.VidMemDatabase.processID,
- !Interface->u.VidMemDatabase.validProcessID,
- gcvDB_VIDEO_MEMORY_VIRTUAL,
- &Interface->u.VidMemDatabase.vidMemVirt));
-
+ gcmkONERROR(gckKERNEL_QueryDatabase(Kernel, processID, Interface));
break;
case gcvHAL_VERSION:
Interface->u.ChipInfo.types[0] = Kernel->hardware->type;
break;
+#if (gcdENABLE_3D || gcdENABLE_2D)
case gcvHAL_ATTACH:
/* Attach user process. */
gcmkONERROR(
Interface->u.Attach.stateCount = bytes;
Interface->u.Attach.context = gcmPTR_TO_NAME(context);
+ if (Interface->u.Attach.map == gcvTRUE)
+ {
+ gcmkVERIFY_OK(
+ gckCONTEXT_MapBuffer(context,
+ Interface->u.Attach.physicals,
+ Interface->u.Attach.logicals,
+ &Interface->u.Attach.bytes));
+ }
+
gcmkVERIFY_OK(
gckKERNEL_AddProcessDB(Kernel,
processID, gcvDB_CONTEXT,
gcvNULL,
0));
break;
+#endif
case gcvHAL_DETACH:
- /* Detach user process. */
- gcmkONERROR(
- gckCOMMAND_Detach(Kernel->command,
- gcmNAME_TO_PTR(Interface->u.Detach.context)));
-
gcmkVERIFY_OK(
gckKERNEL_RemoveProcessDB(Kernel,
processID, gcvDB_CONTEXT,
gcmINT2PTR(Interface->u.Detach.context)));
+ /* Detach user process. */
+ gcmkONERROR(
+ gckCOMMAND_Detach(Kernel->command,
+ gcmNAME_TO_PTR(Interface->u.Detach.context)));
+
gcmRELEASE_NAME(Interface->u.Detach.context);
break;
gckKERNEL_SetTimeOut(Kernel, Interface->u.SetTimeOut.timeOut);
break;
-#if gcdFRAME_DB
case gcvHAL_GET_FRAME_INFO:
gcmkONERROR(gckHARDWARE_GetFrameInfo(
- Kernel->hardware,
- gcmUINT64_TO_PTR(Interface->u.GetFrameInfo.frameInfo)));
- break;
-#endif
-
- case gcvHAL_GET_SHARED_INFO:
- if (Interface->u.GetSharedInfo.data == gcvNULL)
- {
- gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
- }
- else
- {
- gctUINT32 pid = Interface->u.GetSharedInfo.pid;
- gctUINT32 dataId = Interface->u.GetSharedInfo.dataId;
- gctSIZE_T bytes = Interface->u.GetSharedInfo.bytes;
- gctPOINTER data = Interface->u.GetSharedInfo.data;
- gcsDATABASE_RECORD record;
-
- /* Find record. */
- gcmkONERROR(
- gckKERNEL_FindProcessDB(Kernel,
- pid,
- 0,
- gcvDB_SHARED_INFO,
- gcmINT2PTR(dataId),
- &record));
-
- /* Check memory size. */
- if (bytes < record.bytes)
- {
- /* Insufficient memory to hold shared data. */
- gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
- }
-
- /* Copy to user. */
- status = gckOS_CopyToUserData(Kernel->os,
- record.physical,
- data,
- record.bytes);
-
- /*
- * Remove from process db.
- * Every time when shared info is taken, the record is erased in
- * kernel side.
- */
- gcmkVERIFY_OK(
- gckKERNEL_RemoveProcessDB(Kernel,
- pid,
- gcvDB_SHARED_INFO,
- gcmINT2PTR(dataId)));
- /* Free existed data. */
- gcmkVERIFY_OK(
- gckOS_FreeMemory(Kernel->os, record.physical));
- }
- break;
-
- case gcvHAL_SET_SHARED_INFO:
- {
- gctUINT32 dataId = Interface->u.SetSharedInfo.dataId;
- gctPOINTER data = Interface->u.SetSharedInfo.data;
- gctUINT32 bytes = Interface->u.SetSharedInfo.bytes;
- gctPOINTER memory = gcvNULL;
- gcsDATABASE_RECORD record;
-
- if (gcmIS_SUCCESS(gckKERNEL_FindProcessDB(Kernel,
- processID,
- 0,
- gcvDB_SHARED_INFO,
- gcmINT2PTR(dataId),
- &record)))
- {
- /* Find a record with the same id. */
- if (bytes != record.bytes)
- {
- /* Remove from process db. */
- gcmkVERIFY_OK(
- gckKERNEL_RemoveProcessDB(Kernel,
- processID,
- gcvDB_SHARED_INFO,
- gcmINT2PTR(dataId)));
-
- /* Free existed data. */
- gcmkVERIFY_OK(
- gckOS_FreeMemory(Kernel->os, record.physical));
- }
- else
- {
- /* Re-use allocated memory. */
- memory = record.physical;
- }
- }
-
- if ((data == gcvNULL) || (bytes == 0))
- {
- /* Nothing to record. */
- break;
- }
-
- if (bytes > 1024)
- {
- /* Limite data size. */
- gcmkONERROR(gcvSTATUS_TOO_COMPLEX);
- }
-
- if (memory == gcvNULL)
- {
- /* Allocate memory for holding shared data. */
- gcmkONERROR(
- gckOS_AllocateMemory(Kernel->os, bytes, &memory));
-
- /* Add to process db. */
- status = gckKERNEL_AddProcessDB(Kernel,
- processID,
- gcvDB_SHARED_INFO,
- gcmINT2PTR(dataId),
- memory,
- bytes);
-
- if (gcmIS_ERROR(status))
- {
- /* Failed to add process db. Free allocated memory. */
- gcmkVERIFY_OK(gckOS_FreeMemory(Kernel->os, memory));
- break;
- }
- }
-
- /* Copy shared data to kernel memory. */
- gcmkONERROR(
- gckOS_CopyFromUserData(Kernel->os,
- memory,
- data,
- bytes));
- }
+ Kernel->hardware,
+ gcmUINT64_TO_PTR(Interface->u.GetFrameInfo.frameInfo)));
break;
case gcvHAL_SET_FSCALE_VALUE:
#endif
break;
- case gcvHAL_QUERY_RESET_TIME_STAMP:
-#if gcdENABLE_RECOVERY
- Interface->u.QueryResetTimeStamp.timeStamp = Kernel->resetTimeStamp;
-#else
- Interface->u.QueryResetTimeStamp.timeStamp = 0;
-#endif
+ case gcvHAL_NAME_VIDEO_MEMORY:
+ gcmkONERROR(gckVIDMEM_NODE_Name(Kernel,
+ Interface->u.NameVideoMemory.handle,
+ &Interface->u.NameVideoMemory.name));
break;
-#if gcdANDROID_NATIVE_FENCE_SYNC
- case gcvHAL_SYNC_POINT:
- {
- gctSYNC_POINT syncPoint;
+ case gcvHAL_IMPORT_VIDEO_MEMORY:
+ gcmkONERROR(gckVIDMEM_NODE_Import(Kernel,
+ Interface->u.ImportVideoMemory.name,
+ &Interface->u.ImportVideoMemory.handle));
- switch (Interface->u.SyncPoint.command)
- {
- case gcvSYNC_POINT_CREATE:
- gcmkONERROR(gckOS_CreateSyncPoint(Kernel->os, &syncPoint));
+ gcmkONERROR(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID, gcvDB_VIDEO_MEMORY,
+ gcmINT2PTR(Interface->u.ImportVideoMemory.handle),
+ gcvNULL,
+ 0));
+ break;
- Interface->u.SyncPoint.syncPoint = gcmPTR_TO_UINT64(syncPoint);
+ case gcvHAL_GET_VIDEO_MEMORY_FD:
+ gcmkONERROR(gckVIDMEM_NODE_GetFd(
+ Kernel,
+ Interface->u.GetVideoMemoryFd.handle,
+ &Interface->u.GetVideoMemoryFd.fd
+ ));
- gcmkVERIFY_OK(
- gckKERNEL_AddProcessDB(Kernel,
- processID, gcvDB_SYNC_POINT,
- syncPoint,
+ /* No need to add it to processDB because OS will release all fds when
+ ** process quits.
+ */
+ break;
+
+ case gcvHAL_QUERY_RESET_TIME_STAMP:
+ Interface->u.QueryResetTimeStamp.timeStamp = Kernel->resetTimeStamp;
+ break;
+
+ case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
+ buffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)gcmNAME_TO_PTR(Interface->u.FreeVirtualCommandBuffer.physical);
+
+ gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
+ Kernel,
+ processID,
+ gcvDB_COMMAND_BUFFER,
+ gcmUINT64_TO_PTR(Interface->u.FreeVirtualCommandBuffer.logical)));
+
+ gcmkONERROR(gckOS_DestroyUserVirtualMapping(
+ Kernel->os,
+ buffer->physical,
+ (gctSIZE_T)Interface->u.FreeVirtualCommandBuffer.bytes,
+ gcmUINT64_TO_PTR(Interface->u.FreeVirtualCommandBuffer.logical)));
+
+ gcmkONERROR(gckKERNEL_DestroyVirtualCommandBuffer(
+ Kernel,
+ (gctSIZE_T)Interface->u.FreeVirtualCommandBuffer.bytes,
+ (gctPHYS_ADDR)buffer,
+ gcmUINT64_TO_PTR(Interface->u.FreeVirtualCommandBuffer.logical)));
+
+ gcmRELEASE_NAME(Interface->u.FreeVirtualCommandBuffer.physical);
+ break;
+
+#if gcdANDROID_NATIVE_FENCE_SYNC
+ case gcvHAL_SYNC_POINT:
+ {
+ gctSYNC_POINT syncPoint;
+
+ switch (Interface->u.SyncPoint.command)
+ {
+ case gcvSYNC_POINT_CREATE:
+ gcmkONERROR(gckOS_CreateSyncPoint(Kernel->os, &syncPoint));
+
+ Interface->u.SyncPoint.syncPoint = gcmPTR_TO_UINT64(syncPoint);
+
+ gcmkVERIFY_OK(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID, gcvDB_SYNC_POINT,
+ syncPoint,
gcvNULL,
0));
break;
break;
#endif
+ case gcvHAL_SHBUF:
+ {
+ gctSHBUF shBuf;
+ gctPOINTER uData;
+ gctUINT32 bytes;
+
+ switch (Interface->u.ShBuf.command)
+ {
+ case gcvSHBUF_CREATE:
+ bytes = Interface->u.ShBuf.bytes;
+
+ /* Create. */
+ gcmkONERROR(gckKERNEL_CreateShBuffer(Kernel, bytes, &shBuf));
+
+ Interface->u.ShBuf.id = gcmPTR_TO_UINT64(shBuf);
+
+ gcmkVERIFY_OK(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID,
+ gcvDB_SHBUF,
+ shBuf,
+ gcvNULL,
+ 0));
+ break;
+
+ case gcvSHBUF_DESTROY:
+ shBuf = gcmUINT64_TO_PTR(Interface->u.ShBuf.id);
+
+ /* Check db first to avoid illegal destroy in the process. */
+ gcmkONERROR(
+ gckKERNEL_RemoveProcessDB(Kernel,
+ processID,
+ gcvDB_SHBUF,
+ shBuf));
+
+ gcmkONERROR(gckKERNEL_DestroyShBuffer(Kernel, shBuf));
+ break;
+
+ case gcvSHBUF_MAP:
+ shBuf = gcmUINT64_TO_PTR(Interface->u.ShBuf.id);
+
+ /* Map for current process access. */
+ gcmkONERROR(gckKERNEL_MapShBuffer(Kernel, shBuf));
+
+ gcmkVERIFY_OK(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID,
+ gcvDB_SHBUF,
+ shBuf,
+ gcvNULL,
+ 0));
+ break;
+
+ case gcvSHBUF_WRITE:
+ shBuf = gcmUINT64_TO_PTR(Interface->u.ShBuf.id);
+ uData = gcmUINT64_TO_PTR(Interface->u.ShBuf.data);
+ bytes = Interface->u.ShBuf.bytes;
+
+ /* Write. */
+ gcmkONERROR(
+ gckKERNEL_WriteShBuffer(Kernel, shBuf, uData, bytes));
+ break;
+
+ case gcvSHBUF_READ:
+ shBuf = gcmUINT64_TO_PTR(Interface->u.ShBuf.id);
+ uData = gcmUINT64_TO_PTR(Interface->u.ShBuf.data);
+ bytes = Interface->u.ShBuf.bytes;
+
+ /* Read. */
+ gcmkONERROR(
+ gckKERNEL_ReadShBuffer(Kernel,
+ shBuf,
+ uData,
+ bytes,
+ &bytes));
+
+ /* Return copied size. */
+ Interface->u.ShBuf.bytes = bytes;
+ break;
+
+ default:
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ break;
+ }
+ }
+ break;
+
+ case gcvHAL_CONFIG_POWER_MANAGEMENT:
+ gcmkONERROR(gckKERNEL_ConfigPowerManagement(Kernel, Interface));
+ break;
+
default:
/* Invalid command. */
gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
/* Save status. */
Interface->status = status;
- if (gcmIS_ERROR(status))
- {
- if (locked)
- {
- /* Roll back the lock. */
- gcmkVERIFY_OK(
- gckVIDMEM_Unlock(Kernel,
- gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node),
- gcvSURF_TYPE_UNKNOWN,
- &asynchronous));
-
- if (gcvTRUE == asynchronous)
- {
- /* Bottom Half */
- gcmkVERIFY_OK(
- gckVIDMEM_Unlock(Kernel,
- gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node),
- gcvSURF_TYPE_UNKNOWN,
- gcvNULL));
- }
- }
- }
-
#if QNX_SINGLE_THREADED_DEBUGGING
gckOS_ReleaseMutex(Kernel->os, Kernel->debugMutex);
#endif
+ if (powerMutexAcquired == gcvTRUE)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->hardware->powerMutex));
+ }
+
/* Return the status. */
gcmkFOOTER();
return status;
/* Create the process database. */
gcmkONERROR(gckKERNEL_CreateProcessDB(Kernel, PID));
}
+
+#if gcdPROCESS_ADDRESS_SPACE
+ /* Map kernel command buffer in the process's own MMU. */
+ gcmkONERROR(_MapCommandBuffer(Kernel));
+#endif
}
else
{
if (Kernel->vg == gcvNULL)
#endif
{
+#if gcdMULTI_GPU
+ status = gckEVENT_Submit(Kernel->eventObj, gcvTRUE, gcvFALSE, gcvCORE_3D_ALL_MASK);
+#else
status = gckEVENT_Submit(Kernel->eventObj, gcvTRUE, gcvFALSE);
+#endif
if (status == gcvSTATUS_INTERRUPTED && Kernel->eventObj->submitTimer)
{
#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
{
gctINT i;
- gctUINT32 data = gcmPTR2INT(*Data);
+ gctUINT32 data = gcmPTR2INT32(*Data);
gctUINT32 key, index;
gcskLOGICAL_CACHE_PTR hash;
*Data, key);
}
- /* Insert the slot at the head of the hash list. */
- slot->nextHash = hash->nextHash;
- if (slot->nextHash != gcvNULL)
+ /* Insert the slot at the head of the hash list. */
+ slot->nextHash = hash->nextHash;
+ if (slot->nextHash != gcvNULL)
+ {
+ slot->nextHash->prevHash = slot;
+ }
+ slot->prevHash = hash;
+ hash->nextHash = slot;
+ }
+
+ /* Move slot to head of list. */
+ if (slot != Cache->cache[0].next)
+ {
+ /* Unlink. */
+ slot->prev->next = slot->next;
+ slot->next->prev = slot->prev;
+
+ /* Move to head of chain. */
+ slot->prev = &Cache->cache[0];
+ slot->next = Cache->cache[0].next;
+ slot->prev->next = slot;
+ slot->next->prev = slot;
+ }
+ }
+#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_TABLE
+ {
+ gctUINT32 index = (gcmPTR2INT32(*Data) % gcdSECURE_CACHE_SLOTS) + 1;
+
+ /* Get cache slot. */
+ slot = &Cache->cache[index];
+
+ /* Check for cache miss. */
+ if (slot->logical != *Data)
+ {
+ /* Initialize the cache line. */
+ slot->logical = *Data;
+
+ /* Map the logical address to a DMA address. */
+ gcmkONERROR(
+ gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
+ }
+ }
+#endif
+
+ /* Return DMA address. */
+ *Data = gcmINT2PTR(slot->dma + (needBase ? baseAddress : 0));
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Data=0x%08x", *Data);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_FlushTranslationCache(
+ IN gckKERNEL Kernel,
+ IN gcskSECURE_CACHE_PTR Cache,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes
+ )
+{
+ gctINT i;
+ gcskLOGICAL_CACHE_PTR slot;
+ gctUINT8_PTR ptr;
+
+ gcmkHEADER_ARG("Kernel=0x%x Cache=0x%x Logical=0x%x Bytes=%lu",
+ Kernel, Cache, Logical, Bytes);
+
+ /* Do we need to flush the entire cache? */
+ if (Logical == gcvNULL)
+ {
+ /* Clear all cache slots. */
+ for (i = 1; i <= gcdSECURE_CACHE_SLOTS; ++i)
+ {
+ Cache->cache[i].logical = gcvNULL;
+
+#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
+ Cache->cache[i].nextHash = gcvNULL;
+ Cache->cache[i].prevHash = gcvNULL;
+#endif
+}
+
+#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
+ /* Zero the hash table. */
+ for (i = 0; i < gcmCOUNTOF(Cache->hash); ++i)
+ {
+ Cache->hash[i].nextHash = gcvNULL;
+ }
+#endif
+
+ /* Reset the cache functionality. */
+ Cache->cacheIndex = gcvNULL;
+ Cache->cacheFree = 1;
+ Cache->cacheStamp = 0;
+ }
+
+ else
+ {
+ gctUINT8_PTR low = (gctUINT8_PTR) Logical;
+ gctUINT8_PTR high = low + Bytes;
+
+#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LRU
+ gcskLOGICAL_CACHE_PTR next;
+
+ /* Walk all used cache slots. */
+ for (i = 1, slot = Cache->cache[0].next;
+ (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
+ ++i, slot = next
+ )
+ {
+ /* Save pointer to next slot. */
+ next = slot->next;
+
+ /* Test if this slot falls within the range to flush. */
+ ptr = (gctUINT8_PTR) slot->logical;
+ if ((ptr >= low) && (ptr < high))
+ {
+ /* Unlink slot. */
+ slot->prev->next = slot->next;
+ slot->next->prev = slot->prev;
+
+ /* Append slot to tail of cache. */
+ slot->prev = Cache->cache[0].prev;
+ slot->next = &Cache->cache[0];
+ slot->prev->next = slot;
+ slot->next->prev = slot;
+
+ /* Mark slot as empty. */
+ slot->logical = gcvNULL;
+ }
+ }
+
+#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR
+ gcskLOGICAL_CACHE_PTR next;
+
+ for (i = 1, slot = Cache->cache[0].next;
+ (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
+ ++i, slot = next)
+ {
+ /* Save pointer to next slot. */
+ next = slot->next;
+
+ /* Test if this slot falls within the range to flush. */
+ ptr = (gctUINT8_PTR) slot->logical;
+ if ((ptr >= low) && (ptr < high))
+ {
+ /* Test if this slot is the current slot. */
+ if (slot == Cache->cacheIndex)
+ {
+ /* Move to next or previous slot. */
+ Cache->cacheIndex = (slot->next->logical != gcvNULL)
+ ? slot->next
+ : (slot->prev->logical != gcvNULL)
+ ? slot->prev
+ : gcvNULL;
+ }
+
+ /* Unlink slot from cache. */
+ slot->prev->next = slot->next;
+ slot->next->prev = slot->prev;
+
+ /* Insert slot to head of cache. */
+ slot->prev = &Cache->cache[0];
+ slot->next = Cache->cache[0].next;
+ slot->prev->next = slot;
+ slot->next->prev = slot;
+
+ /* Mark slot as empty. */
+ slot->logical = gcvNULL;
+ slot->stamp = 0;
+ }
+ }
+
+#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
+ gctINT j;
+ gcskLOGICAL_CACHE_PTR hash, next;
+
+ /* Walk all hash tables. */
+ for (i = 0, hash = Cache->hash;
+ i < gcmCOUNTOF(Cache->hash);
+ ++i, ++hash)
+ {
+ /* Walk all slots in the hash. */
+ for (j = 0, slot = hash->nextHash;
+ (j < gcdSECURE_CACHE_SLOTS) && (slot != gcvNULL);
+ ++j, slot = next)
+ {
+ /* Save pointer to next slot. */
+ next = slot->next;
+
+ /* Test if this slot falls within the range to flush. */
+ ptr = (gctUINT8_PTR) slot->logical;
+ if ((ptr >= low) && (ptr < high))
+ {
+ /* Unlink slot from hash table. */
+ if (slot->prevHash == hash)
+ {
+ hash->nextHash = slot->nextHash;
+ }
+ else
+ {
+ slot->prevHash->nextHash = slot->nextHash;
+ }
+
+ if (slot->nextHash != gcvNULL)
+ {
+ slot->nextHash->prevHash = slot->prevHash;
+ }
+
+ /* Unlink slot from cache. */
+ slot->prev->next = slot->next;
+ slot->next->prev = slot->prev;
+
+ /* Append slot to tail of cache. */
+ slot->prev = Cache->cache[0].prev;
+ slot->next = &Cache->cache[0];
+ slot->prev->next = slot;
+ slot->next->prev = slot;
+
+ /* Mark slot as empty. */
+ slot->logical = gcvNULL;
+ slot->prevHash = gcvNULL;
+ slot->nextHash = gcvNULL;
+ }
+ }
+ }
+
+#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_TABLE
+ gctUINT32 index;
+
+ /* Loop while inside the range. */
+ for (i = 1; (low < high) && (i <= gcdSECURE_CACHE_SLOTS); ++i)
+ {
+ /* Get index into cache for this range. */
+ index = (gcmPTR2INT32(low) % gcdSECURE_CACHE_SLOTS) + 1;
+ slot = &Cache->cache[index];
+
+ /* Test if this slot falls within the range to flush. */
+ ptr = (gctUINT8_PTR) slot->logical;
+ if ((ptr >= low) && (ptr < high))
+ {
+ /* Remove entry from cache. */
+ slot->logical = gcvNULL;
+ }
+
+ /* Next block. */
+ low += gcdSECURE_CACHE_SLOTS;
+ }
+#endif
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+#endif
+
+/*******************************************************************************
+**
+** gckKERNEL_Recovery
+**
+** Try to recover the GPU from a fatal error.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckKERNEL_Recovery(
+ IN gckKERNEL Kernel
+ )
+{
+ gceSTATUS status;
+ gckEVENT eventObj;
+ gckHARDWARE hardware;
+#if gcdSECURE_USER
+ gctUINT32 processID;
+ gcskSECURE_CACHE_PTR cache;
+#endif
+ gctUINT32 mask = 0;
+ gckCOMMAND command;
+ gckENTRYDATA data;
+ gctUINT32 i = 0, count = 0;
+#if gcdINTERRUPT_STATISTIC
+ gctINT32 oldValue;
+#endif
+
+ gcmkHEADER_ARG("Kernel=0x%x", Kernel);
+
+ /* Validate the arguemnts. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+
+ /* Grab gckEVENT object. */
+ eventObj = Kernel->eventObj;
+ gcmkVERIFY_OBJECT(eventObj, gcvOBJ_EVENT);
+
+ /* Grab gckHARDWARE object. */
+ hardware = Kernel->hardware;
+ gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
+
+ /* Grab gckCOMMAND object. */
+ command = Kernel->command;
+ gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
+
+#if gcdSECURE_USER
+ /* Flush the secure mapping cache. */
+ gcmkONERROR(gckOS_GetProcessID(&processID));
+ gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache));
+ gcmkONERROR(gckKERNEL_FlushTranslationCache(Kernel, cache, gcvNULL, 0));
+#endif
+
+ if (Kernel->stuckDump == gcdSTUCK_DUMP_MINIMAL)
+ {
+ gcmkPRINT("[galcore]: GPU[%d] hang, automatic recovery.", Kernel->core);
+ }
+ else
+ {
+ _DumpDriverConfigure(Kernel);
+ _DumpState(Kernel);
+ }
+
+ if (Kernel->recovery == gcvFALSE)
+ {
+ gcmkPRINT("[galcore]: Stop driver to keep scene.");
+
+ for (;;)
+ {
+ gckOS_Delay(Kernel->os, 10000);
+ }
+ }
+
+ /* Clear queue. */
+ do
+ {
+ status = gckENTRYQUEUE_Dequeue(&command->queue, &data);
+ }
+ while (status == gcvSTATUS_OK);
+
+ /* Issuing a soft reset for the GPU. */
+ gcmkONERROR(gckHARDWARE_Reset(hardware));
+
+ mask = Kernel->restoreMask;
+
+ for (i = 0; i < 32; i++)
+ {
+ if (mask & (1 << i))
+ {
+ count++;
+ }
+ }
+
+ /* Handle all outstanding events now. */
+#if gcdSMP
+#if gcdMULTI_GPU
+ if (Kernel->core == gcvCORE_MAJOR)
+ {
+ for (i = 0; i < gcdMULTI_GPU; i++)
+ {
+ gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending3D[i], mask));
+ }
+ }
+ else
+ {
+ gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, mask));
+ }
+#else
+ gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, mask));
+#endif
+#else
+#if gcdMULTI_GPU
+ if (Kernel->core == gcvCORE_MAJOR)
+ {
+ for (i = 0; i < gcdMULTI_GPU; i++)
+ {
+ eventObj->pending3D[i] = mask;
+ }
+ }
+ else
+ {
+ eventObj->pending = mask;
+ }
+#else
+ eventObj->pending = mask;
+#endif
+#endif
+
+#if gcdINTERRUPT_STATISTIC
+ while (count--)
+ {
+ gcmkONERROR(gckOS_AtomDecrement(
+ Kernel->os,
+ eventObj->interruptCount,
+ &oldValue
+ ));
+ }
+
+ gckOS_AtomClearMask(Kernel->hardware->pendingEvent, mask);
+#endif
+
+ gcmkONERROR(gckEVENT_Notify(eventObj, 1));
+
+ gcmkVERIFY_OK(gckOS_GetTime(&Kernel->resetTimeStamp));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_OpenUserData
+**
+** Get access to the user data.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctBOOL NeedCopy
+** The flag indicating whether or not the data should be copied.
+**
+** gctPOINTER StaticStorage
+** Pointer to the kernel storage where the data is to be copied if
+** NeedCopy is gcvTRUE.
+**
+** gctPOINTER UserPointer
+** User pointer to the data.
+**
+** gctSIZE_T Size
+** Size of the data.
+**
+** OUTPUT:
+**
+** gctPOINTER * KernelPointer
+** Pointer to the kernel pointer that will be pointing to the data.
+*/
+gceSTATUS
+gckKERNEL_OpenUserData(
+ IN gckKERNEL Kernel,
+ IN gctBOOL NeedCopy,
+ IN gctPOINTER StaticStorage,
+ IN gctPOINTER UserPointer,
+ IN gctSIZE_T Size,
+ OUT gctPOINTER * KernelPointer
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG(
+ "Kernel=0x%08X NeedCopy=%d StaticStorage=0x%08X "
+ "UserPointer=0x%08X Size=%lu KernelPointer=0x%08X",
+ Kernel, NeedCopy, StaticStorage, UserPointer, Size, KernelPointer
+ );
+
+ /* Validate the arguemnts. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(!NeedCopy || (StaticStorage != gcvNULL));
+ gcmkVERIFY_ARGUMENT(UserPointer != gcvNULL);
+ gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Size > 0);
+
+ if (NeedCopy)
+ {
+ /* Copy the user data to the static storage. */
+ gcmkONERROR(gckOS_CopyFromUserData(
+ Kernel->os, StaticStorage, UserPointer, Size
+ ));
+
+ /* Set the kernel pointer. */
+ * KernelPointer = StaticStorage;
+ }
+ else
+ {
+ gctPOINTER pointer = gcvNULL;
+
+ /* Map the user pointer. */
+ gcmkONERROR(gckOS_MapUserPointer(
+ Kernel->os, UserPointer, Size, &pointer
+ ));
+
+ /* Set the kernel pointer. */
+ * KernelPointer = pointer;
+ }
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckKERNEL_CloseUserData
+**
+** Release resources associated with the user data connection opened by
+** gckKERNEL_OpenUserData.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctBOOL NeedCopy
+** The flag indicating whether or not the data should be copied.
+**
+** gctBOOL FlushData
+** If gcvTRUE, the data is written back to the user.
+**
+** gctPOINTER UserPointer
+** User pointer to the data.
+**
+** gctSIZE_T Size
+** Size of the data.
+**
+** OUTPUT:
+**
+** gctPOINTER * KernelPointer
+** Kernel pointer to the data.
+*/
+gceSTATUS
+gckKERNEL_CloseUserData(
+ IN gckKERNEL Kernel,
+ IN gctBOOL NeedCopy,
+ IN gctBOOL FlushData,
+ IN gctPOINTER UserPointer,
+ IN gctSIZE_T Size,
+ OUT gctPOINTER * KernelPointer
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ gctPOINTER pointer;
+
+ gcmkHEADER_ARG(
+ "Kernel=0x%08X NeedCopy=%d FlushData=%d "
+ "UserPointer=0x%08X Size=%lu KernelPointer=0x%08X",
+ Kernel, NeedCopy, FlushData, UserPointer, Size, KernelPointer
+ );
+
+ /* Validate the arguemnts. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(UserPointer != gcvNULL);
+ gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Size > 0);
+
+ /* Get a shortcut to the kernel pointer. */
+ pointer = * KernelPointer;
+
+ if (pointer != gcvNULL)
+ {
+ if (NeedCopy)
+ {
+ if (FlushData)
{
- slot->nextHash->prevHash = slot;
+ gcmkONERROR(gckOS_CopyToUserData(
+ Kernel->os, * KernelPointer, UserPointer, Size
+ ));
}
- slot->prevHash = hash;
- hash->nextHash = slot;
}
-
- /* Move slot to head of list. */
- if (slot != Cache->cache[0].next)
+ else
{
- /* Unlink. */
- slot->prev->next = slot->next;
- slot->next->prev = slot->prev;
-
- /* Move to head of chain. */
- slot->prev = &Cache->cache[0];
- slot->next = Cache->cache[0].next;
- slot->prev->next = slot;
- slot->next->prev = slot;
+ /* Unmap record from kernel memory. */
+ gcmkONERROR(gckOS_UnmapUserPointer(
+ Kernel->os,
+ UserPointer,
+ Size,
+ * KernelPointer
+ ));
}
- }
-#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_TABLE
- {
- gctUINT32 index = (gcmPTR2INT(*Data) % gcdSECURE_CACHE_SLOTS) + 1;
-
- /* Get cache slot. */
- slot = &Cache->cache[index];
-
- /* Check for cache miss. */
- if (slot->logical != *Data)
- {
- /* Initialize the cache line. */
- slot->logical = *Data;
- /* Map the logical address to a DMA address. */
- gcmkONERROR(
- gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
- }
+ /* Reset the kernel pointer. */
+ * KernelPointer = gcvNULL;
}
-#endif
-
- /* Return DMA address. */
- *Data = gcmINT2PTR(slot->dma + (needBase ? baseAddress : 0));
-
- /* Success. */
- gcmkFOOTER_ARG("*Data=0x%08x", *Data);
- return gcvSTATUS_OK;
OnError:
/* Return the status. */
return status;
}
-gceSTATUS
-gckKERNEL_FlushTranslationCache(
+void
+gckKERNEL_SetTimeOut(
IN gckKERNEL Kernel,
- IN gcskSECURE_CACHE_PTR Cache,
- IN gctPOINTER Logical,
- IN gctSIZE_T Bytes
+ IN gctUINT32 timeOut
)
{
- gctINT i;
- gcskLOGICAL_CACHE_PTR slot;
- gctUINT8_PTR ptr;
-
- gcmkHEADER_ARG("Kernel=0x%x Cache=0x%x Logical=0x%x Bytes=%lu",
- Kernel, Cache, Logical, Bytes);
-
- /* Do we need to flush the entire cache? */
- if (Logical == gcvNULL)
- {
- /* Clear all cache slots. */
- for (i = 1; i <= gcdSECURE_CACHE_SLOTS; ++i)
- {
- Cache->cache[i].logical = gcvNULL;
-
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
- Cache->cache[i].nextHash = gcvNULL;
- Cache->cache[i].prevHash = gcvNULL;
+ gcmkHEADER_ARG("Kernel=0x%x timeOut=%d", Kernel, timeOut);
+#if gcdGPU_TIMEOUT
+ Kernel->timeOut = timeOut;
#endif
+ gcmkFOOTER_NO();
}
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
- /* Zero the hash table. */
- for (i = 0; i < gcmCOUNTOF(Cache->hash); ++i)
- {
- Cache->hash[i].nextHash = gcvNULL;
- }
-#endif
-
- /* Reset the cache functionality. */
- Cache->cacheIndex = gcvNULL;
- Cache->cacheFree = 1;
- Cache->cacheStamp = 0;
- }
-
- else
- {
- gctUINT8_PTR low = (gctUINT8_PTR) Logical;
- gctUINT8_PTR high = low + Bytes;
+gceSTATUS
+gckKERNEL_AllocateVirtualCommandBuffer(
+ IN gckKERNEL Kernel,
+ IN gctBOOL InUserSpace,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctPHYS_ADDR * Physical,
+ OUT gctPOINTER * Logical
+ )
+{
+ gckOS os = Kernel->os;
+ gceSTATUS status;
+ gctPOINTER logical = gcvNULL;
+ gctSIZE_T pageCount;
+ gctSIZE_T bytes = *Bytes;
+ gckVIRTUAL_COMMAND_BUFFER_PTR buffer = gcvNULL;
+ gckMMU mmu;
+ gctUINT32 flag = gcvALLOC_FLAG_NON_CONTIGUOUS;
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LRU
- gcskLOGICAL_CACHE_PTR next;
+ gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
+ os, InUserSpace, gcmOPT_VALUE(Bytes));
- /* Walk all used cache slots. */
- for (i = 1, slot = Cache->cache[0].next;
- (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
- ++i, slot = next
- )
- {
- /* Save pointer to next slot. */
- next = slot->next;
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Bytes != gcvNULL);
+ gcmkVERIFY_ARGUMENT(*Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
- /* Test if this slot falls within the range to flush. */
- ptr = (gctUINT8_PTR) slot->logical;
- if ((ptr >= low) && (ptr < high))
- {
- /* Unlink slot. */
- slot->prev->next = slot->next;
- slot->next->prev = slot->prev;
+ gcmkONERROR(gckOS_Allocate(os,
+ sizeof(gckVIRTUAL_COMMAND_BUFFER),
+ (gctPOINTER)&buffer));
- /* Append slot to tail of cache. */
- slot->prev = Cache->cache[0].prev;
- slot->next = &Cache->cache[0];
- slot->prev->next = slot;
- slot->next->prev = slot;
+ gcmkONERROR(gckOS_ZeroMemory(buffer, sizeof(gckVIRTUAL_COMMAND_BUFFER)));
- /* Mark slot as empty. */
- slot->logical = gcvNULL;
- }
- }
+ buffer->bytes = bytes;
-#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR
- gcskLOGICAL_CACHE_PTR next;
+ gcmkONERROR(gckOS_AllocatePagedMemoryEx(os,
+ flag,
+ bytes,
+ gcvNULL,
+ &buffer->physical));
- for (i = 1, slot = Cache->cache[0].next;
- (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
- ++i, slot = next)
- {
- /* Save pointer to next slot. */
- next = slot->next;
+ if (InUserSpace)
+ {
+ gcmkONERROR(gckOS_CreateUserVirtualMapping(os,
+ buffer->physical,
+ bytes,
+ &logical,
+ &pageCount));
- /* Test if this slot falls within the range to flush. */
- ptr = (gctUINT8_PTR) slot->logical;
- if ((ptr >= low) && (ptr < high))
- {
- /* Test if this slot is the current slot. */
- if (slot == Cache->cacheIndex)
- {
- /* Move to next or previous slot. */
- Cache->cacheIndex = (slot->next->logical != gcvNULL)
- ? slot->next
- : (slot->prev->logical != gcvNULL)
- ? slot->prev
- : gcvNULL;
- }
+ *Logical =
+ buffer->userLogical = logical;
+ }
+ else
+ {
+ gcmkONERROR(gckOS_CreateKernelVirtualMapping(os,
+ buffer->physical,
+ bytes,
+ &logical,
+ &pageCount));
- /* Unlink slot from cache. */
- slot->prev->next = slot->next;
- slot->next->prev = slot->prev;
+ *Logical =
+ buffer->kernelLogical = logical;
+ }
- /* Insert slot to head of cache. */
- slot->prev = &Cache->cache[0];
- slot->next = Cache->cache[0].next;
- slot->prev->next = slot;
- slot->next->prev = slot;
+ buffer->pageCount = pageCount;
+ buffer->kernel = Kernel;
- /* Mark slot as empty. */
- slot->logical = gcvNULL;
- slot->stamp = 0;
- }
- }
+ gcmkONERROR(gckOS_GetProcessID(&buffer->pid));
-#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
- gctINT j;
- gcskLOGICAL_CACHE_PTR hash, next;
+#if gcdPROCESS_ADDRESS_SPACE
+ gcmkONERROR(gckKERNEL_GetProcessMMU(Kernel, &mmu));
+ buffer->mmu = mmu;
+#else
+ mmu = Kernel->mmu;
+#endif
- /* Walk all hash tables. */
- for (i = 0, hash = Cache->hash;
- i < gcmCOUNTOF(Cache->hash);
- ++i, ++hash)
- {
- /* Walk all slots in the hash. */
- for (j = 0, slot = hash->nextHash;
- (j < gcdSECURE_CACHE_SLOTS) && (slot != gcvNULL);
- ++j, slot = next)
- {
- /* Save pointer to next slot. */
- next = slot->next;
+ gcmkONERROR(gckMMU_AllocatePages(mmu,
+ pageCount,
+ &buffer->pageTable,
+ &buffer->gpuAddress));
- /* Test if this slot falls within the range to flush. */
- ptr = (gctUINT8_PTR) slot->logical;
- if ((ptr >= low) && (ptr < high))
- {
- /* Unlink slot from hash table. */
- if (slot->prevHash == hash)
- {
- hash->nextHash = slot->nextHash;
- }
- else
- {
- slot->prevHash->nextHash = slot->nextHash;
- }
- if (slot->nextHash != gcvNULL)
- {
- slot->nextHash->prevHash = slot->prevHash;
- }
+ gcmkONERROR(gckOS_MapPagesEx(os,
+ Kernel->core,
+ buffer->physical,
+ pageCount,
+ buffer->gpuAddress,
+ buffer->pageTable));
- /* Unlink slot from cache. */
- slot->prev->next = slot->next;
- slot->next->prev = slot->prev;
+ gcmkONERROR(gckMMU_Flush(mmu, gcvSURF_INDEX));
- /* Append slot to tail of cache. */
- slot->prev = Cache->cache[0].prev;
- slot->next = &Cache->cache[0];
- slot->prev->next = slot;
- slot->next->prev = slot;
+ *Physical = buffer;
- /* Mark slot as empty. */
- slot->logical = gcvNULL;
- slot->prevHash = gcvNULL;
- slot->nextHash = gcvNULL;
- }
- }
- }
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
+ "gpuAddress = %x pageCount = %d kernelLogical = %x userLogical=%x",
+ buffer->gpuAddress, buffer->pageCount,
+ buffer->kernelLogical, buffer->userLogical);
-#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_TABLE
- gctUINT32 index;
+ gcmkVERIFY_OK(gckOS_AcquireMutex(os, Kernel->virtualBufferLock, gcvINFINITE));
- /* Loop while inside the range. */
- for (i = 1; (low < high) && (i <= gcdSECURE_CACHE_SLOTS); ++i)
- {
- /* Get index into cache for this range. */
- index = (gcmPTR2INT(low) % gcdSECURE_CACHE_SLOTS) + 1;
- slot = &Cache->cache[index];
+ if (Kernel->virtualBufferHead == gcvNULL)
+ {
+ Kernel->virtualBufferHead =
+ Kernel->virtualBufferTail = buffer;
+ }
+ else
+ {
+ buffer->prev = Kernel->virtualBufferTail;
+ Kernel->virtualBufferTail->next = buffer;
+ Kernel->virtualBufferTail = buffer;
+ }
- /* Test if this slot falls within the range to flush. */
- ptr = (gctUINT8_PTR) slot->logical;
- if ((ptr >= low) && (ptr < high))
- {
- /* Remove entry from cache. */
- slot->logical = gcvNULL;
- }
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Kernel->virtualBufferLock));
- /* Next block. */
- low += gcdSECURE_CACHE_SLOTS;
- }
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (buffer->gpuAddress)
+ {
+#if gcdPROCESS_ADDRESS_SPACE
+ gcmkVERIFY_OK(
+ gckMMU_FreePages(mmu, buffer->pageTable, buffer->pageCount));
+#else
+ gcmkVERIFY_OK(
+ gckMMU_FreePages(Kernel->mmu, buffer->pageTable, buffer->pageCount));
#endif
}
- /* Success. */
- gcmkFOOTER_NO();
- return gcvSTATUS_OK;
+ if (buffer->userLogical)
+ {
+ gcmkVERIFY_OK(
+ gckOS_DestroyUserVirtualMapping(os,
+ buffer->physical,
+ bytes,
+ buffer->userLogical));
+ }
+
+ if (buffer->kernelLogical)
+ {
+ gcmkVERIFY_OK(
+ gckOS_DestroyKernelVirtualMapping(os,
+ buffer->physical,
+ bytes,
+ buffer->kernelLogical));
+ }
+
+ if (buffer->physical)
+ {
+ gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, bytes));
+ }
+
+ gcmkVERIFY_OK(gckOS_Free(os, buffer));
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
}
-#endif
-/*******************************************************************************
-**
-** gckKERNEL_Recovery
-**
-** Try to recover the GPU from a fatal error.
-**
-** INPUT:
-**
-** gckKERNEL Kernel
-** Pointer to an gckKERNEL object.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
gceSTATUS
-gckKERNEL_Recovery(
- IN gckKERNEL Kernel
+gckKERNEL_DestroyVirtualCommandBuffer(
+ IN gckKERNEL Kernel,
+ IN gctSIZE_T Bytes,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical
)
{
-#if gcdENABLE_RECOVERY
-#define gcdEVENT_MASK 0x3FFFFFFF
- gceSTATUS status;
- gckEVENT eventObj;
- gckHARDWARE hardware;
-#if gcdSECURE_USER
- gctUINT32 processID;
- gcskSECURE_CACHE_PTR cache;
-#endif
- gctUINT32 oldValue;
- gcmkHEADER_ARG("Kernel=0x%x", Kernel);
-
- /* Validate the arguemnts. */
- gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
-
- /* Grab gckEVENT object. */
- eventObj = Kernel->eventObj;
- gcmkVERIFY_OBJECT(eventObj, gcvOBJ_EVENT);
-
- /* Grab gckHARDWARE object. */
- hardware = Kernel->hardware;
- gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
+ gckOS os;
+ gckKERNEL kernel;
+ gckVIRTUAL_COMMAND_BUFFER_PTR buffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)Physical;
-#if gcdSECURE_USER
- /* Flush the secure mapping cache. */
- gcmkONERROR(gckOS_GetProcessID(&processID));
- gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache));
- gcmkONERROR(gckKERNEL_FlushTranslationCache(Kernel, cache, gcvNULL, 0));
-#endif
+ gcmkHEADER();
+ gcmkVERIFY_ARGUMENT(buffer != gcvNULL);
- gcmkONERROR(
- gckOS_AtomicExchange(Kernel->os, Kernel->resetAtom, 1, &oldValue));
+ kernel = buffer->kernel;
+ os = kernel->os;
- if (oldValue)
+ if (!buffer->userLogical)
{
- /* Some one else will recovery GPU. */
- return gcvSTATUS_OK;
+ gcmkVERIFY_OK(gckOS_DestroyKernelVirtualMapping(os,
+ buffer->physical,
+ Bytes,
+ Logical));
}
- gcmkPRINT("[galcore]: GPU[%d] hang, automatic recovery.", Kernel->core);
-
- /* Start a timer to clear reset flag, before timer is expired,
- ** other recovery request is ignored. */
+#if !gcdPROCESS_ADDRESS_SPACE
gcmkVERIFY_OK(
- gckOS_StartTimer(Kernel->os,
- Kernel->resetFlagClearTimer,
- gcdGPU_TIMEOUT - 500));
+ gckMMU_FreePages(kernel->mmu, buffer->pageTable, buffer->pageCount));
+#endif
+ gcmkVERIFY_OK(gckOS_UnmapPages(os, buffer->pageCount, buffer->gpuAddress));
- /* Try issuing a soft reset for the GPU. */
- status = gckHARDWARE_Reset(hardware);
- if (status == gcvSTATUS_NOT_SUPPORTED)
+ gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, Bytes));
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(os, kernel->virtualBufferLock, gcvINFINITE));
+
+ if (buffer == kernel->virtualBufferHead)
{
- /* Switch to OFF power. The next submit should return the GPU to ON
- ** state. */
- gcmkONERROR(
- gckHARDWARE_SetPowerManagementState(hardware,
- gcvPOWER_OFF_RECOVERY));
+ if ((kernel->virtualBufferHead = buffer->next) == gcvNULL)
+ {
+ kernel->virtualBufferTail = gcvNULL;
+ }
}
else
{
- /* Bail out on reset error. */
- gcmkONERROR(status);
- }
+ buffer->prev->next = buffer->next;
- /* Handle all outstanding events now. */
-#if gcdSMP
- gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, gcdEVENT_MASK));
-#else
- eventObj->pending = gcdEVENT_MASK;
-#endif
- gcmkONERROR(gckEVENT_Notify(eventObj, 1));
+ if (buffer == kernel->virtualBufferTail)
+ {
+ kernel->virtualBufferTail = buffer->prev;
+ }
+ else
+ {
+ buffer->next->prev = buffer->prev;
+ }
+ }
- /* Again in case more events got submitted. */
-#if gcdSMP
- gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, gcdEVENT_MASK));
-#else
- eventObj->pending = gcdEVENT_MASK;
-#endif
- gcmkONERROR(gckEVENT_Notify(eventObj, 2));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, kernel->virtualBufferLock));
- Kernel->resetTimeStamp++;
+ gcmkVERIFY_OK(gckOS_Free(os, buffer));
- /* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
-
-OnError:
- /* Return the status. */
- gcmkFOOTER();
- return status;
-#else
- return gcvSTATUS_OK;
-#endif
}
-/*******************************************************************************
-**
-** gckKERNEL_OpenUserData
-**
-** Get access to the user data.
-**
-** INPUT:
-**
-** gckKERNEL Kernel
-** Pointer to an gckKERNEL object.
-**
-** gctBOOL NeedCopy
-** The flag indicating whether or not the data should be copied.
-**
-** gctPOINTER StaticStorage
-** Pointer to the kernel storage where the data is to be copied if
-** NeedCopy is gcvTRUE.
-**
-** gctPOINTER UserPointer
-** User pointer to the data.
-**
-** gctSIZE_T Size
-** Size of the data.
-**
-** OUTPUT:
-**
-** gctPOINTER * KernelPointer
-** Pointer to the kernel pointer that will be pointing to the data.
-*/
gceSTATUS
-gckKERNEL_OpenUserData(
+gckKERNEL_GetGPUAddress(
+ IN gckKERNEL Kernel,
+ IN gctPOINTER Logical,
+ IN gctBOOL InUserSpace,
+ OUT gctUINT32 * Address
+ )
+{
+ gceSTATUS status;
+ gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
+ gctPOINTER start;
+ gctUINT32 pid;
+
+ gcmkHEADER_ARG("Logical = %x InUserSpace=%d.", Logical, InUserSpace);
+
+ gcmkVERIFY_OK(gckOS_GetProcessID(&pid));
+
+ status = gcvSTATUS_INVALID_ADDRESS;
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->virtualBufferLock, gcvINFINITE));
+
+ /* Walk all command buffer. */
+ for (buffer = Kernel->virtualBufferHead; buffer != gcvNULL; buffer = buffer->next)
+ {
+ if (InUserSpace)
+ {
+ start = buffer->userLogical;
+ }
+ else
+ {
+ start = buffer->kernelLogical;
+ }
+
+ if (start == gcvNULL)
+ {
+ continue;
+ }
+
+ if (Logical >= start
+ && (Logical < (gctPOINTER)((gctUINT8_PTR)start + buffer->pageCount * 4096))
+ && pid == buffer->pid
+ )
+ {
+ * Address = buffer->gpuAddress + (gctUINT32)((gctUINT8_PTR)Logical - (gctUINT8_PTR)start);
+ status = gcvSTATUS_OK;
+ break;
+ }
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->virtualBufferLock));
+
+ gcmkFOOTER_NO();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_QueryGPUAddress(
IN gckKERNEL Kernel,
- IN gctBOOL NeedCopy,
- IN gctPOINTER StaticStorage,
- IN gctPOINTER UserPointer,
- IN gctSIZE_T Size,
- OUT gctPOINTER * KernelPointer
+ IN gctUINT32 GpuAddress,
+ OUT gckVIRTUAL_COMMAND_BUFFER_PTR * Buffer
)
{
- gceSTATUS status;
-
- gcmkHEADER_ARG(
- "Kernel=0x%08X NeedCopy=%d StaticStorage=0x%08X "
- "UserPointer=0x%08X Size=%lu KernelPointer=0x%08X",
- Kernel, NeedCopy, StaticStorage, UserPointer, Size, KernelPointer
- );
+ gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
+ gctUINT32 start;
+ gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
- /* Validate the arguemnts. */
- gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
- gcmkVERIFY_ARGUMENT(!NeedCopy || (StaticStorage != gcvNULL));
- gcmkVERIFY_ARGUMENT(UserPointer != gcvNULL);
- gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
- gcmkVERIFY_ARGUMENT(Size > 0);
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->virtualBufferLock, gcvINFINITE));
- if (NeedCopy)
+ /* Walk all command buffers. */
+ for (buffer = Kernel->virtualBufferHead; buffer != gcvNULL; buffer = buffer->next)
{
- /* Copy the user data to the static storage. */
- gcmkONERROR(gckOS_CopyFromUserData(
- Kernel->os, StaticStorage, UserPointer, Size
- ));
+ start = (gctUINT32)buffer->gpuAddress;
- /* Set the kernel pointer. */
- * KernelPointer = StaticStorage;
+ if (GpuAddress >= start && GpuAddress < (start + buffer->pageCount * 4096))
+ {
+ /* Find a range matched. */
+ *Buffer = buffer;
+ status = gcvSTATUS_OK;
+ break;
+ }
}
- else
- {
- gctPOINTER pointer = gcvNULL;
-
- /* Map the user pointer. */
- gcmkONERROR(gckOS_MapUserPointer(
- Kernel->os, UserPointer, Size, &pointer
- ));
- /* Set the kernel pointer. */
- * KernelPointer = pointer;
- }
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->virtualBufferLock));
-OnError:
- /* Return the status. */
- gcmkFOOTER();
return status;
}
-/*******************************************************************************
-**
-** gckKERNEL_CloseUserData
-**
-** Release resources associated with the user data connection opened by
-** gckKERNEL_OpenUserData.
-**
-** INPUT:
-**
-** gckKERNEL Kernel
-** Pointer to an gckKERNEL object.
-**
-** gctBOOL NeedCopy
-** The flag indicating whether or not the data should be copied.
-**
-** gctBOOL FlushData
-** If gcvTRUE, the data is written back to the user.
-**
-** gctPOINTER UserPointer
-** User pointer to the data.
-**
-** gctSIZE_T Size
-** Size of the data.
-**
-** OUTPUT:
-**
-** gctPOINTER * KernelPointer
-** Kernel pointer to the data.
-*/
-gceSTATUS
-gckKERNEL_CloseUserData(
- IN gckKERNEL Kernel,
- IN gctBOOL NeedCopy,
- IN gctBOOL FlushData,
- IN gctPOINTER UserPointer,
- IN gctSIZE_T Size,
- OUT gctPOINTER * KernelPointer
+#if gcdLINK_QUEUE_SIZE
+static void
+gckLINKQUEUE_Dequeue(
+ IN gckLINKQUEUE LinkQueue
)
{
- gceSTATUS status = gcvSTATUS_OK;
- gctPOINTER pointer;
+ gcmkASSERT(LinkQueue->count == gcdLINK_QUEUE_SIZE);
- gcmkHEADER_ARG(
- "Kernel=0x%08X NeedCopy=%d FlushData=%d "
- "UserPointer=0x%08X Size=%lu KernelPointer=0x%08X",
- Kernel, NeedCopy, FlushData, UserPointer, Size, KernelPointer
- );
+ LinkQueue->count--;
+ LinkQueue->front = (LinkQueue->front + 1) % gcdLINK_QUEUE_SIZE;
+}
- /* Validate the arguemnts. */
- gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
- gcmkVERIFY_ARGUMENT(UserPointer != gcvNULL);
- gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
- gcmkVERIFY_ARGUMENT(Size > 0);
+void
+gckLINKQUEUE_Enqueue(
+ IN gckLINKQUEUE LinkQueue,
+ IN gctUINT32 start,
+ IN gctUINT32 end
+ )
+{
+ if (LinkQueue->count == gcdLINK_QUEUE_SIZE)
+ {
+ gckLINKQUEUE_Dequeue(LinkQueue);
+ }
- /* Get a shortcut to the kernel pointer. */
- pointer = * KernelPointer;
+ gcmkASSERT(LinkQueue->count < gcdLINK_QUEUE_SIZE);
- if (pointer != gcvNULL)
- {
- if (NeedCopy)
- {
- if (FlushData)
- {
- gcmkONERROR(gckOS_CopyToUserData(
- Kernel->os, * KernelPointer, UserPointer, Size
- ));
- }
- }
- else
- {
- /* Unmap record from kernel memory. */
- gcmkONERROR(gckOS_UnmapUserPointer(
- Kernel->os,
- UserPointer,
- Size,
- * KernelPointer
- ));
- }
+ LinkQueue->count++;
- /* Reset the kernel pointer. */
- * KernelPointer = gcvNULL;
- }
+ LinkQueue->data[LinkQueue->rear].start = start;
+ LinkQueue->data[LinkQueue->rear].end = end;
-OnError:
- /* Return the status. */
- gcmkFOOTER();
- return status;
+ gcmkVERIFY_OK(
+ gckOS_GetProcessID(&LinkQueue->data[LinkQueue->rear].pid));
+
+ LinkQueue->rear = (LinkQueue->rear + 1) % gcdLINK_QUEUE_SIZE;
}
void
-gckKERNEL_SetTimeOut(
- IN gckKERNEL Kernel,
- IN gctUINT32 timeOut
+gckLINKQUEUE_GetData(
+ IN gckLINKQUEUE LinkQueue,
+ IN gctUINT32 Index,
+ OUT gckLINKDATA * Data
)
{
- gcmkHEADER_ARG("Kernel=0x%x timeOut=%d", Kernel, timeOut);
-#if gcdGPU_TIMEOUT
- Kernel->timeOut = timeOut;
-#endif
- gcmkFOOTER_NO();
+ gcmkASSERT(Index >= 0 && Index < gcdLINK_QUEUE_SIZE);
+
+ *Data = &LinkQueue->data[(Index + LinkQueue->front) % gcdLINK_QUEUE_SIZE];
}
+#endif
-#if gcdVIRTUAL_COMMAND_BUFFER
+/*
+* gckENTRYQUEUE_Enqueue is called with Command->mutexQueue acquired.
+*/
gceSTATUS
-gckKERNEL_AllocateVirtualCommandBuffer(
+gckENTRYQUEUE_Enqueue(
IN gckKERNEL Kernel,
- IN gctBOOL InUserSpace,
- IN OUT gctSIZE_T * Bytes,
- OUT gctPHYS_ADDR * Physical,
- OUT gctPOINTER * Logical
+ IN gckENTRYQUEUE Queue,
+ IN gctUINT32 physical,
+ IN gctUINT32 bytes
)
{
- gckOS os = Kernel->os;
- gceSTATUS status;
- gctPOINTER logical;
- gctSIZE_T pageCount;
- gctSIZE_T bytes = *Bytes;
- gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
-
- gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
- os, InUserSpace, gcmOPT_VALUE(Bytes));
+ gctUINT32 next = (Queue->rear + 1) % gcdENTRY_QUEUE_SIZE;
- /* Verify the arguments. */
- gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
- gcmkVERIFY_ARGUMENT(Bytes != gcvNULL);
- gcmkVERIFY_ARGUMENT(*Bytes > 0);
- gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
- gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+ if (next == Queue->front)
+ {
+ /* Queue is full. */
+ return gcvSTATUS_INVALID_REQUEST;
+ }
- gcmkONERROR(gckOS_Allocate(os,
- sizeof(gckVIRTUAL_COMMAND_BUFFER),
- (gctPOINTER)&buffer));
+ /* Copy data. */
+ Queue->data[Queue->rear].physical = physical;
+ Queue->data[Queue->rear].bytes = bytes;
- gcmkONERROR(gckOS_ZeroMemory(buffer, sizeof(gckVIRTUAL_COMMAND_BUFFER)));
+ gcmkVERIFY_OK(gckOS_MemoryBarrier(Kernel->os, &Queue->rear));
- gcmkONERROR(gckOS_AllocatePagedMemoryEx(os,
- gcvFALSE,
- bytes,
- &buffer->physical));
+ /* Update rear. */
+ Queue->rear = next;
- if (InUserSpace)
- {
- gcmkONERROR(gckOS_LockPages(os,
- buffer->physical,
- bytes,
- gcvFALSE,
- &logical,
- &pageCount));
+ return gcvSTATUS_OK;
+}
- *Logical =
- buffer->userLogical = logical;
- }
- else
+gceSTATUS
+gckENTRYQUEUE_Dequeue(
+ IN gckENTRYQUEUE Queue,
+ OUT gckENTRYDATA * Data
+ )
+{
+ if (Queue->front == Queue->rear)
{
- gcmkONERROR(
- gckOS_CreateKernelVirtualMapping(buffer->physical,
- &pageCount,
- &logical));
- *Logical =
- buffer->kernelLogical = logical;
+ /* Queue is empty. */
+ return gcvSTATUS_INVALID_REQUEST;
}
- buffer->pageCount = pageCount;
- buffer->kernel = Kernel;
+ /* Copy data. */
+ *Data = &Queue->data[Queue->front];
+
+ /* Update front. */
+ Queue->front = (Queue->front + 1) % gcdENTRY_QUEUE_SIZE;
+
+ return gcvSTATUS_OK;
+}
+
+/******************************************************************************\
+*************************** Pointer - ID translation ***************************
+\******************************************************************************/
+#define gcdID_TABLE_LENGTH 1024
+typedef struct _gcsINTEGERDB * gckINTEGERDB;
+typedef struct _gcsINTEGERDB
+{
+ gckOS os;
+ gctPOINTER* table;
+ gctPOINTER mutex;
+ gctUINT32 tableLen;
+ gctUINT32 currentID;
+ gctUINT32 unused;
+}
+gcsINTEGERDB;
+
+gceSTATUS
+gckKERNEL_CreateIntegerDatabase(
+ IN gckKERNEL Kernel,
+ OUT gctPOINTER * Database
+ )
+{
+ gceSTATUS status;
+ gckINTEGERDB database = gcvNULL;
- gcmkONERROR(gckOS_GetProcessID(&buffer->pid));
+ gcmkHEADER_ARG("Kernel=0x%08X Datbase=0x%08X", Kernel, Database);
- gcmkONERROR(gckMMU_AllocatePages(Kernel->mmu,
- pageCount,
- &buffer->pageTable,
- &buffer->gpuAddress));
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Database != gcvNULL);
- gcmkONERROR(gckOS_MapPagesEx(os,
- Kernel->core,
- buffer->physical,
- pageCount,
- buffer->pageTable));
+ /* Allocate a database. */
+ gcmkONERROR(gckOS_Allocate(
+ Kernel->os, gcmSIZEOF(gcsINTEGERDB), (gctPOINTER *)&database));
- gcmkONERROR(gckMMU_Flush(Kernel->mmu));
+ gcmkONERROR(gckOS_ZeroMemory(database, gcmSIZEOF(gcsINTEGERDB)));
- *Physical = buffer;
+ /* Allocate a pointer table. */
+ gcmkONERROR(gckOS_Allocate(
+ Kernel->os, gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH, (gctPOINTER *)&database->table));
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
- "gpuAddress = %x pageCount = %d kernelLogical = %x userLogical=%x",
- buffer->gpuAddress, buffer->pageCount,
- buffer->kernelLogical, buffer->userLogical);
+ gcmkONERROR(gckOS_ZeroMemory(database->table, gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH));
- gcmkVERIFY_OK(gckOS_AcquireMutex(os, Kernel->virtualBufferLock, gcvINFINITE));
+ /* Allocate a database mutex. */
+ gcmkONERROR(gckOS_CreateMutex(Kernel->os, &database->mutex));
- if (Kernel->virtualBufferHead == gcvNULL)
- {
- Kernel->virtualBufferHead =
- Kernel->virtualBufferTail = buffer;
- }
- else
- {
- buffer->prev = Kernel->virtualBufferTail;
- Kernel->virtualBufferTail->next = buffer;
- Kernel->virtualBufferTail = buffer;
- }
+ /* Initialize. */
+ database->currentID = 0;
+ database->unused = gcdID_TABLE_LENGTH;
+ database->os = Kernel->os;
+ database->tableLen = gcdID_TABLE_LENGTH;
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Kernel->virtualBufferLock));
+ *Database = database;
- gcmkFOOTER_NO();
+ gcmkFOOTER_ARG("*Database=0x%08X", *Database);
return gcvSTATUS_OK;
OnError:
- if (buffer->gpuAddress)
- {
- gcmkVERIFY_OK(
- gckMMU_FreePages(Kernel->mmu, buffer->pageTable, buffer->pageCount));
- }
-
- if (buffer->userLogical)
- {
- gcmkVERIFY_OK(
- gckOS_UnlockPages(os, buffer->physical, bytes, buffer->userLogical));
- }
-
- if (buffer->kernelLogical)
+ /* Rollback. */
+ if (database)
{
- gcmkVERIFY_OK(
- gckOS_DestroyKernelVirtualMapping(buffer->kernelLogical));
- }
+ if (database->table)
+ {
+ gcmkOS_SAFE_FREE(Kernel->os, database->table);
+ }
- if (buffer->physical)
- {
- gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, bytes));
+ gcmkOS_SAFE_FREE(Kernel->os, database);
}
- gcmkVERIFY_OK(gckOS_Free(os, buffer));
-
- /* Return the status. */
gcmkFOOTER();
return status;
}
gceSTATUS
-gckKERNEL_DestroyVirtualCommandBuffer(
+gckKERNEL_DestroyIntegerDatabase(
IN gckKERNEL Kernel,
- IN gctSIZE_T Bytes,
- IN gctPHYS_ADDR Physical,
- IN gctPOINTER Logical
+ IN gctPOINTER Database
)
{
- gckOS os;
- gckKERNEL kernel;
- gckVIRTUAL_COMMAND_BUFFER_PTR buffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)Physical;
+ gckINTEGERDB database = Database;
- gcmkHEADER();
- gcmkVERIFY_ARGUMENT(buffer != gcvNULL);
+ gcmkHEADER_ARG("Kernel=0x%08X Datbase=0x%08X", Kernel, Database);
- kernel = buffer->kernel;
- os = kernel->os;
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Database != gcvNULL);
- if (buffer->userLogical)
- {
- gcmkVERIFY_OK(gckOS_UnlockPages(os, buffer->physical, Bytes, Logical));
- }
- else
+ /* Destroy pointer table. */
+ gcmkOS_SAFE_FREE(Kernel->os, database->table);
+
+ /* Destroy database mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, database->mutex));
+
+ /* Destroy database. */
+ gcmkOS_SAFE_FREE(Kernel->os, database);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckKERNEL_AllocateIntegerId(
+ IN gctPOINTER Database,
+ IN gctPOINTER Pointer,
+ OUT gctUINT32 * Id
+ )
+{
+ gceSTATUS status;
+ gckINTEGERDB database = Database;
+ gctUINT32 i, unused, currentID, tableLen;
+ gctPOINTER * table;
+ gckOS os = database->os;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Database=0x%08X Pointer=0x%08X", Database, Pointer);
+
+ gcmkVERIFY_ARGUMENT(Id != gcvNULL);
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ if (database->unused < 1)
{
- gcmkVERIFY_OK(gckOS_DestroyKernelVirtualMapping(Logical));
+ /* Extend table. */
+ gcmkONERROR(
+ gckOS_Allocate(os,
+ gcmSIZEOF(gctPOINTER) * (database->tableLen + gcdID_TABLE_LENGTH),
+ (gctPOINTER *)&table));
+
+ gcmkONERROR(gckOS_ZeroMemory(table + database->tableLen,
+ gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH));
+
+ /* Copy data from old table. */
+ gckOS_MemCopy(table,
+ database->table,
+ database->tableLen * gcmSIZEOF(gctPOINTER));
+
+ gcmkOS_SAFE_FREE(os, database->table);
+
+ /* Update databse with new allocated table. */
+ database->table = table;
+ database->currentID = database->tableLen;
+ database->tableLen += gcdID_TABLE_LENGTH;
+ database->unused += gcdID_TABLE_LENGTH;
}
- gcmkVERIFY_OK(
- gckMMU_FreePages(kernel->mmu, buffer->pageTable, buffer->pageCount));
+ table = database->table;
+ currentID = database->currentID;
+ tableLen = database->tableLen;
+ unused = database->unused;
- gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, Bytes));
+ /* Connect id with pointer. */
+ table[currentID] = Pointer;
- gcmkVERIFY_OK(gckOS_AcquireMutex(os, kernel->virtualBufferLock, gcvINFINITE));
+ *Id = currentID + 1;
- if (buffer == kernel->virtualBufferHead)
+ /* Update the currentID. */
+ if (--unused > 0)
{
- if ((kernel->virtualBufferHead = buffer->next) == gcvNULL)
+ for (i = 0; i < tableLen; i++)
{
- kernel->virtualBufferTail = gcvNULL;
- }
- }
- else
- {
- buffer->prev->next = buffer->next;
+ if (++currentID >= tableLen)
+ {
+ /* Wrap to the begin. */
+ currentID = 0;
+ }
- if (buffer == kernel->virtualBufferTail)
- {
- kernel->virtualBufferTail = buffer->prev;
- }
- else
- {
- buffer->next->prev = buffer->prev;
+ if (table[currentID] == gcvNULL)
+ {
+ break;
+ }
}
}
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, kernel->virtualBufferLock));
+ database->table = table;
+ database->currentID = currentID;
+ database->tableLen = tableLen;
+ database->unused = unused;
- gcmkVERIFY_OK(gckOS_Free(os, buffer));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
+ acquired = gcvFALSE;
- gcmkFOOTER_NO();
+ gcmkFOOTER_ARG("*Id=%d", *Id);
return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
+ }
+
+ gcmkFOOTER();
+ return status;
}
gceSTATUS
-gckKERNEL_GetGPUAddress(
- IN gckKERNEL Kernel,
- IN gctPOINTER Logical,
- OUT gctUINT32 * Address
+gckKERNEL_FreeIntegerId(
+ IN gctPOINTER Database,
+ IN gctUINT32 Id
)
{
gceSTATUS status;
- gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
- gctPOINTER start;
- gctINT pid;
+ gckINTEGERDB database = Database;
+ gckOS os = database->os;
+ gctBOOL acquired = gcvFALSE;
- gcmkHEADER_ARG("Logical = %x", Logical);
+ gcmkHEADER_ARG("Database=0x%08X Id=%d", Database, Id);
- gckOS_GetProcessID(&pid);
+ gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
+ acquired = gcvTRUE;
- status = gcvSTATUS_INVALID_ADDRESS;
+ if (!(Id > 0 && Id <= database->tableLen))
+ {
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
- gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->virtualBufferLock, gcvINFINITE));
+ Id -= 1;
- /* Walk all command buffer. */
- for (buffer = Kernel->virtualBufferHead; buffer != gcvNULL; buffer = buffer->next)
+ database->table[Id] = gcvNULL;
+
+ if (database->unused++ == 0)
{
- if (buffer->userLogical)
- {
- start = buffer->userLogical;
- }
- else
- {
- start = buffer->kernelLogical;
- }
+ database->currentID = Id;
+ }
- if (Logical >= start
- && (Logical < (start + buffer->pageCount * 4096))
- && pid == buffer->pid
- )
- {
- * Address = buffer->gpuAddress + (Logical - start);
- status = gcvSTATUS_OK;
- break;
- }
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
+ acquired = gcvFALSE;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
}
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->virtualBufferLock));
-
- gcmkFOOTER_NO();
+ gcmkFOOTER();
return status;
}
gceSTATUS
-gckKERNEL_QueryGPUAddress(
- IN gckKERNEL Kernel,
- IN gctUINT32 GpuAddress,
- OUT gckVIRTUAL_COMMAND_BUFFER_PTR * Buffer
+gckKERNEL_QueryIntegerId(
+ IN gctPOINTER Database,
+ IN gctUINT32 Id,
+ OUT gctPOINTER * Pointer
)
{
- gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
- gctUINT32 start;
- gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
+ gceSTATUS status;
+ gckINTEGERDB database = Database;
+ gctPOINTER pointer;
+ gckOS os = database->os;
+ gctBOOL acquired = gcvFALSE;
- gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->virtualBufferLock, gcvINFINITE));
+ gcmkHEADER_ARG("Database=0x%08X Id=%d", Database, Id);
+ gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
- /* Walk all command buffers. */
- for (buffer = Kernel->virtualBufferHead; buffer != gcvNULL; buffer = buffer->next)
+ gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ if (!(Id > 0 && Id <= database->tableLen))
{
- start = (gctUINT32)buffer->gpuAddress;
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
- if (GpuAddress >= start && GpuAddress < (start + buffer->pageCount * 4096))
- {
- /* Find a range matched. */
- *Buffer = buffer;
- status = gcvSTATUS_OK;
- break;
- }
+ Id -= 1;
+
+ pointer = database->table[Id];
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
+ acquired = gcvFALSE;
+
+ if (pointer)
+ {
+ *Pointer = pointer;
+ }
+ else
+ {
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
}
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->virtualBufferLock));
+ gcmkFOOTER_ARG("*Pointer=0x%08X", *Pointer);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
+ }
+ gcmkFOOTER();
return status;
}
-#endif
-#if gcdLINK_QUEUE_SIZE
-static void
-gckLINKQUEUE_Dequeue(
- IN gckLINKQUEUE LinkQueue
+
+gctUINT32
+gckKERNEL_AllocateNameFromPointer(
+ IN gckKERNEL Kernel,
+ IN gctPOINTER Pointer
)
{
- gcmkASSERT(LinkQueue->count == gcdLINK_QUEUE_SIZE);
+ gceSTATUS status;
+ gctUINT32 name;
+ gctPOINTER database = Kernel->db->pointerDatabase;
- LinkQueue->count--;
- LinkQueue->front = (LinkQueue->front + 1) % gcdLINK_QUEUE_SIZE;
+ gcmkHEADER_ARG("Kernel=0x%X Pointer=0x%X", Kernel, Pointer);
+
+ gcmkONERROR(
+ gckKERNEL_AllocateIntegerId(database, Pointer, &name));
+
+ gcmkFOOTER_ARG("name=%d", name);
+ return name;
+
+OnError:
+ gcmkFOOTER();
+ return 0;
}
-void
-gckLINKQUEUE_Enqueue(
- IN gckLINKQUEUE LinkQueue,
- IN gctUINT32 start,
- IN gctUINT32 end
+gctPOINTER
+gckKERNEL_QueryPointerFromName(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Name
)
{
- if (LinkQueue->count == gcdLINK_QUEUE_SIZE)
- {
- gckLINKQUEUE_Dequeue(LinkQueue);
- }
-
- gcmkASSERT(LinkQueue->count < gcdLINK_QUEUE_SIZE);
+ gceSTATUS status;
+ gctPOINTER pointer = gcvNULL;
+ gctPOINTER database = Kernel->db->pointerDatabase;
- LinkQueue->count++;
+ gcmkHEADER_ARG("Kernel=0x%X Name=%d", Kernel, Name);
- LinkQueue->data[LinkQueue->rear].start = start;
- LinkQueue->data[LinkQueue->rear].end = end;
+ /* Lookup in database to get pointer. */
+ gcmkONERROR(gckKERNEL_QueryIntegerId(database, Name, &pointer));
- gcmkVERIFY_OK(
- gckOS_GetProcessID(&LinkQueue->data[LinkQueue->rear].pid));
+ gcmkFOOTER_ARG("pointer=0x%X", pointer);
+ return pointer;
- LinkQueue->rear = (LinkQueue->rear + 1) % gcdLINK_QUEUE_SIZE;
+OnError:
+ gcmkFOOTER();
+ return gcvNULL;
}
-void
-gckLINKQUEUE_GetData(
- IN gckLINKQUEUE LinkQueue,
- IN gctUINT32 Index,
- OUT gckLINKDATA * Data
+gceSTATUS
+gckKERNEL_DeleteName(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Name
)
{
- gcmkASSERT(Index >= 0 && Index < gcdLINK_QUEUE_SIZE);
+ gctPOINTER database = Kernel->db->pointerDatabase;
- *Data = &LinkQueue->data[(Index + LinkQueue->front) % gcdLINK_QUEUE_SIZE];
+ gcmkHEADER_ARG("Kernel=0x%X Name=0x%X", Kernel, Name);
+
+ /* Free name if exists. */
+ gcmkVERIFY_OK(gckKERNEL_FreeIntegerId(database, Name));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
}
-#endif
-/******************************************************************************\
-*************************** Pointer - ID translation ***************************
-\******************************************************************************/
-#define gcdID_TABLE_LENGTH 1024
-typedef struct _gcsINTEGERDB * gckINTEGERDB;
-typedef struct _gcsINTEGERDB
+gceSTATUS
+gckKERNEL_SetRecovery(
+ IN gckKERNEL Kernel,
+ IN gctBOOL Recovery,
+ IN gctUINT32 StuckDump
+ )
{
- gckOS os;
- gctPOINTER* table;
- gctPOINTER mutex;
- gctUINT32 tableLen;
- gctUINT32 currentID;
- gctUINT32 unused;
+ Kernel->recovery = Recovery;
+
+ if (Recovery == gcvFALSE)
+ {
+ /* Dump stuck information if Recovery is disabled. */
+ Kernel->stuckDump = gcmMAX(StuckDump, gcdSTUCK_DUMP_MIDDLE);
+ }
+
+ return gcvSTATUS_OK;
}
-gcsINTEGERDB;
+
+/*******************************************************************************
+***** Shared Buffer ************************************************************
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** gckKERNEL_CreateShBuffer
+**
+** Create shared buffer.
+** The shared buffer can be used across processes. Other process needs call
+** gckKERNEL_MapShBuffer before use it.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctUINT32 Size
+** Specify the shared buffer size.
+**
+** OUTPUT:
+**
+** gctSHBUF * ShBuf
+** Pointer to hold return shared buffer handle.
+*/
gceSTATUS
-gckKERNEL_CreateIntegerDatabase(
+gckKERNEL_CreateShBuffer(
IN gckKERNEL Kernel,
- OUT gctPOINTER * Database
+ IN gctUINT32 Size,
+ OUT gctSHBUF * ShBuf
)
{
gceSTATUS status;
- gckINTEGERDB database = gcvNULL;
+ gcsSHBUF_PTR shBuf = gcvNULL;
- gcmkHEADER_ARG("Kernel=0x%08X Datbase=0x%08X", Kernel, Database);
+ gcmkHEADER_ARG("Kernel=0x%X, Size=%u", Kernel, Size);
+ /* Verify the arguments. */
gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
- gcmkVERIFY_ARGUMENT(Database != gcvNULL);
- /* Allocate a database. */
- gcmkONERROR(gckOS_Allocate(
- Kernel->os, gcmSIZEOF(gcsINTEGERDB), (gctPOINTER *)&database));
+ if (Size == 0)
+ {
+ /* Invalid size. */
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+ else if (Size > 1024)
+ {
+ /* Limite shared buffer size. */
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
- gckOS_ZeroMemory(database, gcmSIZEOF(gcsINTEGERDB));
+ /* Create a shared buffer structure. */
+ gcmkONERROR(
+ gckOS_Allocate(Kernel->os,
+ sizeof (gcsSHBUF),
+ (gctPOINTER *)&shBuf));
- /* Allocate a pointer table. */
- gcmkONERROR(gckOS_Allocate(
- Kernel->os, gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH, (gctPOINTER *)&database->table));
+ /* Initialize shared buffer. */
+ shBuf->id = 0;
+ shBuf->reference = gcvNULL;
+ shBuf->size = Size;
+ shBuf->data = gcvNULL;
- gckOS_ZeroMemory(database->table, gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH);
+ /* Allocate integer id for this shared buffer. */
+ gcmkONERROR(
+ gckKERNEL_AllocateIntegerId(Kernel->db->pointerDatabase,
+ shBuf,
+ &shBuf->id));
- /* Allocate a database mutex. */
- gcmkONERROR(gckOS_CreateMutex(Kernel->os, &database->mutex));
+ /* Allocate atom. */
+ gcmkONERROR(gckOS_AtomConstruct(Kernel->os, &shBuf->reference));
- /* Initialize. */
- database->currentID = 0;
- database->unused = gcdID_TABLE_LENGTH;
- database->os = Kernel->os;
- database->tableLen = gcdID_TABLE_LENGTH;
+ /* Set default reference count to 1. */
+ gcmkVERIFY_OK(gckOS_AtomSet(Kernel->os, shBuf->reference, 1));
- *Database = database;
+ /* Return integer id. */
+ *ShBuf = (gctSHBUF)(gctUINTPTR_T)shBuf->id;
- gcmkFOOTER_ARG("*Database=0x%08X", *Database);
+ gcmkFOOTER_ARG("*ShBuf=%u", shBuf->id);
return gcvSTATUS_OK;
OnError:
- /* Rollback. */
- if (database)
+ /* Error roll back. */
+ if (shBuf != gcvNULL)
{
- if (database->table)
+ if (shBuf->id != 0)
{
- gcmkOS_SAFE_FREE(Kernel->os, database->table);
+ gcmkVERIFY_OK(
+ gckKERNEL_FreeIntegerId(Kernel->db->pointerDatabase,
+ shBuf->id));
}
- gcmkOS_SAFE_FREE(Kernel->os, database);
+ gcmkOS_SAFE_FREE(Kernel->os, shBuf);
}
gcmkFOOTER();
return status;
}
+/*******************************************************************************
+**
+** gckKERNEL_DestroyShBuffer
+**
+** Destroy shared buffer.
+** This will decrease reference of specified shared buffer and do actual
+** destroy when no reference on it.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctSHBUF ShBuf
+** Specify the shared buffer to be destroyed.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
gceSTATUS
-gckKERNEL_DestroyIntegerDatabase(
- IN gckKERNEL Kernel,
- IN gctPOINTER Database
- )
-{
- gckINTEGERDB database = Database;
-
- gcmkHEADER_ARG("Kernel=0x%08X Datbase=0x%08X", Kernel, Database);
-
- gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
- gcmkVERIFY_ARGUMENT(Database != gcvNULL);
-
- /* Destroy pointer table. */
- gcmkOS_SAFE_FREE(Kernel->os, database->table);
-
- /* Destroy database mutex. */
- gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, database->mutex));
-
- /* Destroy database. */
- gcmkOS_SAFE_FREE(Kernel->os, database);
-
- gcmkFOOTER_NO();
- return gcvSTATUS_OK;
-}
-
-gceSTATUS
-gckKERNEL_AllocateIntegerId(
- IN gctPOINTER Database,
- IN gctPOINTER Pointer,
- OUT gctUINT32 * Id
+gckKERNEL_DestroyShBuffer(
+ IN gckKERNEL Kernel,
+ IN gctSHBUF ShBuf
)
{
gceSTATUS status;
- gckINTEGERDB database = Database;
- gctUINT32 i, unused, currentID, tableLen;
- gctPOINTER * table;
- gckOS os = database->os;
+ gcsSHBUF_PTR shBuf;
+ gctINT32 oldValue = 0;
gctBOOL acquired = gcvFALSE;
- gcmkHEADER_ARG("Database=0x%08X Pointer=0x%08X", Database, Pointer);
+ gcmkHEADER_ARG("Kernel=0x%X ShBuf=%u",
+ Kernel, (gctUINT32)(gctUINTPTR_T) ShBuf);
- gcmkVERIFY_ARGUMENT(Id != gcvNULL);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(ShBuf != gcvNULL);
- gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
+ /* Acquire mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os,
+ Kernel->db->pointerDatabaseMutex,
+ gcvINFINITE));
acquired = gcvTRUE;
- if (database->unused < 1)
- {
- /* Extend table. */
- gcmkONERROR(
- gckOS_Allocate(os,
- gcmSIZEOF(gctPOINTER) * (database->tableLen + gcdID_TABLE_LENGTH),
- (gctPOINTER *)&table));
-
- gckOS_ZeroMemory(table + database->tableLen,
- gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH);
-
- /* Copy data from old table. */
- gckOS_MemCopy(table,
- database->table,
- database->tableLen * gcmSIZEOF(gctPOINTER));
-
- gcmkOS_SAFE_FREE(os, database->table);
+ /* Find shared buffer structure. */
+ gcmkONERROR(
+ gckKERNEL_QueryIntegerId(Kernel->db->pointerDatabase,
+ (gctUINT32)(gctUINTPTR_T)ShBuf,
+ (gctPOINTER)&shBuf));
- /* Update databse with new allocated table. */
- database->table = table;
- database->currentID = database->tableLen;
- database->tableLen += gcdID_TABLE_LENGTH;
- database->unused += gcdID_TABLE_LENGTH;
- }
+ gcmkASSERT(shBuf->id == (gctUINT32)(gctUINTPTR_T)ShBuf);
- table = database->table;
- currentID = database->currentID;
- tableLen = database->tableLen;
- unused = database->unused;
+ /* Decrease the reference count. */
+ gckOS_AtomDecrement(Kernel->os, shBuf->reference, &oldValue);
- /* Connect id with pointer. */
- table[currentID] = Pointer;
+ if (oldValue == 1)
+ {
+ /* Free integer id. */
+ gcmkVERIFY_OK(
+ gckKERNEL_FreeIntegerId(Kernel->db->pointerDatabase,
+ shBuf->id));
- *Id = currentID + 1;
+ /* Free atom. */
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, shBuf->reference));
- /* Update the currentID. */
- if (--unused > 0)
- {
- for (i = 0; i < tableLen; i++)
+ if (shBuf->data)
{
- if (++currentID >= tableLen)
- {
- /* Wrap to the begin. */
- currentID = 0;
- }
-
- if (table[currentID] == gcvNULL)
- {
- break;
- }
+ gcmkOS_SAFE_FREE(Kernel->os, shBuf->data);
+ shBuf->data = gcvNULL;
}
- }
- database->table = table;
- database->currentID = currentID;
- database->tableLen = tableLen;
- database->unused = unused;
+ /* Free the shared buffer. */
+ gcmkOS_SAFE_FREE(Kernel->os, shBuf);
+ }
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
+ /* Release the mutex. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
acquired = gcvFALSE;
- gcmkFOOTER_ARG("*Id=%d", *Id);
+ gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
if (acquired)
{
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
+ /* Release the mutex. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
}
gcmkFOOTER();
return status;
}
+/*******************************************************************************
+**
+** gckKERNEL_MapShBuffer
+**
+** Map shared buffer into this process so that it can be used in this process.
+** This will increase reference count on the specified shared buffer.
+** Call gckKERNEL_DestroyShBuffer to dereference.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctSHBUF ShBuf
+** Specify the shared buffer to be mapped.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
gceSTATUS
-gckKERNEL_FreeIntegerId(
- IN gctPOINTER Database,
- IN gctUINT32 Id
+gckKERNEL_MapShBuffer(
+ IN gckKERNEL Kernel,
+ IN gctSHBUF ShBuf
)
{
gceSTATUS status;
- gckINTEGERDB database = Database;
- gckOS os = database->os;
+ gcsSHBUF_PTR shBuf;
+ gctINT32 oldValue = 0;
gctBOOL acquired = gcvFALSE;
- gcmkHEADER_ARG("Database=0x%08X Id=%d", Database, Id);
+ gcmkHEADER_ARG("Kernel=0x%X ShBuf=%u",
+ Kernel, (gctUINT32)(gctUINTPTR_T) ShBuf);
- gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
- acquired = gcvTRUE;
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(ShBuf != gcvNULL);
- if (!(Id > 0 && Id <= database->tableLen))
- {
- gcmkONERROR(gcvSTATUS_NOT_FOUND);
- }
+ /* Acquire mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os,
+ Kernel->db->pointerDatabaseMutex,
+ gcvINFINITE));
+ acquired = gcvTRUE;
- Id -= 1;
+ /* Find shared buffer structure. */
+ gcmkONERROR(
+ gckKERNEL_QueryIntegerId(Kernel->db->pointerDatabase,
+ (gctUINT32)(gctUINTPTR_T)ShBuf,
+ (gctPOINTER)&shBuf));
- database->table[Id] = gcvNULL;
+ gcmkASSERT(shBuf->id == (gctUINT32)(gctUINTPTR_T)ShBuf);
- if (database->unused++ == 0)
- {
- database->currentID = Id;
- }
+ /* Increase the reference count. */
+ gckOS_AtomIncrement(Kernel->os, shBuf->reference, &oldValue);
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
+ /* Release the mutex. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
acquired = gcvFALSE;
gcmkFOOTER_NO();
OnError:
if (acquired)
{
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
+ /* Release the mutex. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
}
gcmkFOOTER();
return status;
}
+/*******************************************************************************
+**
+** gckKERNEL_WriteShBuffer
+**
+** Write user data into shared buffer.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctSHBUF ShBuf
+** Specify the shared buffer to be written to.
+**
+** gctPOINTER UserData
+** User mode pointer to hold the source data.
+**
+** gctUINT32 ByteCount
+** Specify number of bytes to write. If this is larger than
+** shared buffer size, gcvSTATUS_INVALID_ARGUMENT is returned.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
gceSTATUS
-gckKERNEL_QueryIntegerId(
- IN gctPOINTER Database,
- IN gctUINT32 Id,
- OUT gctPOINTER * Pointer
+gckKERNEL_WriteShBuffer(
+ IN gckKERNEL Kernel,
+ IN gctSHBUF ShBuf,
+ IN gctPOINTER UserData,
+ IN gctUINT32 ByteCount
)
{
gceSTATUS status;
- gckINTEGERDB database = Database;
- gctPOINTER pointer;
- gckOS os = database->os;
+ gcsSHBUF_PTR shBuf;
gctBOOL acquired = gcvFALSE;
- gcmkHEADER_ARG("Database=0x%08X Id=%d", Database, Id);
- gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
-
- gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
- acquired = gcvTRUE;
+ gcmkHEADER_ARG("Kernel=0x%X ShBuf=%u UserData=0x%X ByteCount=%u",
+ Kernel, (gctUINT32)(gctUINTPTR_T) ShBuf, UserData, ByteCount);
- if (!(Id > 0 && Id <= database->tableLen))
- {
- gcmkONERROR(gcvSTATUS_NOT_FOUND);
- }
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(ShBuf != gcvNULL);
- Id -= 1;
+ /* Acquire mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os,
+ Kernel->db->pointerDatabaseMutex,
+ gcvINFINITE));
+ acquired = gcvTRUE;
- pointer = database->table[Id];
+ /* Find shared buffer structure. */
+ gcmkONERROR(
+ gckKERNEL_QueryIntegerId(Kernel->db->pointerDatabase,
+ (gctUINT32)(gctUINTPTR_T)ShBuf,
+ (gctPOINTER)&shBuf));
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
- acquired = gcvFALSE;
+ gcmkASSERT(shBuf->id == (gctUINT32)(gctUINTPTR_T)ShBuf);
- if (pointer)
+ if ((ByteCount > shBuf->size) ||
+ (ByteCount == 0) ||
+ (UserData == gcvNULL))
{
- *Pointer = pointer;
+ /* Exceeds buffer max size or invalid. */
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
}
- else
+
+ if (shBuf->data == gcvNULL)
{
- gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ /* Allocate buffer data when first time write. */
+ gcmkONERROR(gckOS_Allocate(Kernel->os, ByteCount, &shBuf->data));
}
- gcmkFOOTER_ARG("*Pointer=0x%08X", *Pointer);
+ /* Copy data from user. */
+ gcmkONERROR(
+ gckOS_CopyFromUserData(Kernel->os,
+ shBuf->data,
+ UserData,
+ ByteCount));
+
+ /* Release the mutex. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
+ acquired = gcvFALSE;
+
+ gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
if (acquired)
{
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
+ /* Release the mutex. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
}
gcmkFOOTER();
return status;
}
-
-gctUINT32
-gckKERNEL_AllocateNameFromPointer(
+/*******************************************************************************
+**
+** gckKERNEL_ReadShBuffer
+**
+** Read data from shared buffer and copy to user pointer.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctSHBUF ShBuf
+** Specify the shared buffer to be read from.
+**
+** gctPOINTER UserData
+** User mode pointer to save output data.
+**
+** gctUINT32 ByteCount
+** Specify number of bytes to read.
+** If this is larger than shared buffer size, only avaiable bytes are
+** copied. If smaller, copy requested size.
+**
+** OUTPUT:
+**
+** gctUINT32 * BytesRead
+** Pointer to hold how many bytes actually read from shared buffer.
+*/
+gceSTATUS
+gckKERNEL_ReadShBuffer(
IN gckKERNEL Kernel,
- IN gctPOINTER Pointer
+ IN gctSHBUF ShBuf,
+ IN gctPOINTER UserData,
+ IN gctUINT32 ByteCount,
+ OUT gctUINT32 * BytesRead
)
{
gceSTATUS status;
- gctUINT32 name;
- gctPOINTER database = Kernel->db->pointerDatabase;
+ gcsSHBUF_PTR shBuf;
+ gctUINT32 bytes;
+ gctBOOL acquired = gcvFALSE;
- gcmkHEADER_ARG("Kernel=0x%X Pointer=0x%X", Kernel, Pointer);
+ gcmkHEADER_ARG("Kernel=0x%X ShBuf=%u UserData=0x%X ByteCount=%u",
+ Kernel, (gctUINT32)(gctUINTPTR_T) ShBuf, UserData, ByteCount);
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(ShBuf != gcvNULL);
+
+ /* Acquire mutex. */
gcmkONERROR(
- gckKERNEL_AllocateIntegerId(database, Pointer, &name));
+ gckOS_AcquireMutex(Kernel->os,
+ Kernel->db->pointerDatabaseMutex,
+ gcvINFINITE));
+ acquired = gcvTRUE;
- gcmkFOOTER_ARG("name=%d", name);
- return name;
+ /* Find shared buffer structure. */
+ gcmkONERROR(
+ gckKERNEL_QueryIntegerId(Kernel->db->pointerDatabase,
+ (gctUINT32)(gctUINTPTR_T)ShBuf,
+ (gctPOINTER)&shBuf));
-OnError:
- gcmkFOOTER();
- return 0;
-}
+ gcmkASSERT(shBuf->id == (gctUINT32)(gctUINTPTR_T)ShBuf);
-gctPOINTER
-gckKERNEL_QueryPointerFromName(
- IN gckKERNEL Kernel,
- IN gctUINT32 Name
- )
-{
- gceSTATUS status;
- gctPOINTER pointer = gcvNULL;
- gctPOINTER database = Kernel->db->pointerDatabase;
+ if (shBuf->data == gcvNULL)
+ {
+ *BytesRead = 0;
- gcmkHEADER_ARG("Kernel=0x%X Name=%d", Kernel, Name);
+ /* No data in shared buffer, skip copy. */
+ status = gcvSTATUS_SKIP;
+ goto OnError;
+ }
+ else if (ByteCount == 0)
+ {
+ /* Invalid size to read. */
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
- /* Lookup in database to get pointer. */
- gcmkONERROR(gckKERNEL_QueryIntegerId(database, Name, &pointer));
+ /* Determine bytes to copy. */
+ bytes = (ByteCount < shBuf->size) ? ByteCount : shBuf->size;
- gcmkFOOTER_ARG("pointer=0x%X", pointer);
- return pointer;
+ /* Copy data to user. */
+ gcmkONERROR(
+ gckOS_CopyToUserData(Kernel->os,
+ shBuf->data,
+ UserData,
+ bytes));
-OnError:
- gcmkFOOTER();
- return gcvNULL;
-}
+ /* Return copied size. */
+ *BytesRead = bytes;
-gceSTATUS
-gckKERNEL_DeleteName(
- IN gckKERNEL Kernel,
- IN gctUINT32 Name
- )
-{
- gctPOINTER database = Kernel->db->pointerDatabase;
+ /* Release the mutex. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
+ acquired = gcvFALSE;
- gcmkHEADER_ARG("Kernel=0x%X Name=0x%X", Kernel, Name);
+ gcmkFOOTER_ARG("*BytesRead=%u", bytes);
+ return gcvSTATUS_OK;
- /* Free name if exists. */
- gcmkVERIFY_OK(gckKERNEL_FreeIntegerId(database, Name));
+OnError:
+ if (acquired)
+ {
+ /* Release the mutex. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
+ }
- gcmkFOOTER_NO();
- return gcvSTATUS_OK;
+ gcmkFOOTER();
+ return status;
}
+
+
/*******************************************************************************
***** Test Code ****************************************************************
*******************************************************************************/
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#include "gc_hal_kernel_vg.h"
#endif
+#if gcdSECURITY
+#include "gc_hal_security_interface.h"
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
#define gcdMMU_OFFSET_16K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_16K_BITS)
#define gcdMMU_OFFSET_16K_MASK ((1U << gcdMMU_OFFSET_16K_BITS) - 1)
+#define gcdMMU_MTLB_PRESENT 0x00000001
+#define gcdMMU_MTLB_EXCEPTION 0x00000002
+#define gcdMMU_MTLB_4K_PAGE 0x00000000
+
+#define gcdMMU_STLB_PRESENT 0x00000001
+#define gcdMMU_STLB_EXCEPTION 0x00000002
+#define gcdMMU_STLB_4K_PAGE 0x00000000
+
+/*******************************************************************************
+***** Stuck Dump Level ********************************************************/
+
+#define gcdSTUCK_DUMP_MINIMAL 1
+#define gcdSTUCK_DUMP_MIDDLE 2
+#define gcdSTUCK_DUMP_MAXIMAL 3
+
/*******************************************************************************
***** Process Secure Cache ****************************************************/
#define gcdSECURE_CACHE_HASH 3
#define gcdSECURE_CACHE_TABLE 4
+#define gcvPAGE_TABLE_DIRTY_BIT_OTHER (1 << 0)
+#define gcvPAGE_TABLE_DIRTY_BIT_FE (1 << 1)
+
typedef struct _gcskLOGICAL_CACHE * gcskLOGICAL_CACHE_PTR;
typedef struct _gcskLOGICAL_CACHE gcskLOGICAL_CACHE;
struct _gcskLOGICAL_CACHE
gcvDB_CONTEXT, /* Context */
gcvDB_IDLE, /* GPU idle. */
gcvDB_MAP_MEMORY, /* Map memory */
- gcvDB_SHARED_INFO, /* Private data */
gcvDB_MAP_USER_MEMORY, /* Map user memory */
gcvDB_SYNC_POINT, /* Sync point. */
- gcvDB_VIDEO_MEMORY_RESERVED, /* Reserved video memory */
- gcvDB_VIDEO_MEMORY_CONTIGUOUS, /* Contiguous video memory */
- gcvDB_VIDEO_MEMORY_VIRTUAL, /* Virtual video memory */
+ gcvDB_SHBUF, /* Shared buffer. */
}
gceDATABASE_TYPE;
+#define gcdDATABASE_TYPE_MASK 0x000000FF
+#define gcdDB_VIDEO_MEMORY_TYPE_MASK 0x0000FF00
+#define gcdDB_VIDEO_MEMORY_TYPE_SHIFT 8
+
+#define gcdDB_VIDEO_MEMORY_POOL_MASK 0x00FF0000
+#define gcdDB_VIDEO_MEMORY_POOL_SHIFT 16
+
typedef struct _gcsDATABASE_RECORD * gcsDATABASE_RECORD_PTR;
typedef struct _gcsDATABASE_RECORD
{
gcsDATABASE_COUNTERS contiguous;
gcsDATABASE_COUNTERS mapUserMemory;
gcsDATABASE_COUNTERS mapMemory;
- gcsDATABASE_COUNTERS vidMemResv;
- gcsDATABASE_COUNTERS vidMemCont;
- gcsDATABASE_COUNTERS vidMemVirt;
+ gcsDATABASE_COUNTERS virtualCommandBuffer;
+
+ gcsDATABASE_COUNTERS vidMemType[gcvSURF_NUM_TYPES];
+ /* Counter for each video memory pool. */
+ gcsDATABASE_COUNTERS vidMemPool[gcvPOOL_NUMBER_OF_POOLS];
+ gctPOINTER counterMutex;
/* Idle time management. */
gctUINT64 lastIdle;
gctPOINTER handleDatabase;
gctPOINTER handleDatabaseMutex;
+
+#if gcdPROCESS_ADDRESS_SPACE
+ gckMMU mmu;
+#endif
}
gcsDATABASE;
+typedef struct _gcsRECORDER * gckRECORDER;
+
+typedef struct _gcsFDPRIVATE * gcsFDPRIVATE_PTR;
+typedef struct _gcsFDPRIVATE
+{
+ gctINT (* release) (gcsFDPRIVATE_PTR Private);
+}
+gcsFDPRIVATE;
+
/* Create a process database that will contain all its allocations. */
gceSTATUS
gckKERNEL_CreateProcessDB(
IN gckKERNEL Kernel
);
-/* ID database */
+/* Dump the video memory usage for process specified. */
+gceSTATUS
+gckKERNEL_DumpVidMemUsage(
+ IN gckKERNEL Kernel,
+ IN gctINT32 ProcessID
+ );
+
+gceSTATUS
+gckKERNEL_FindDatabase(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctBOOL LastProcessID,
+ OUT gcsDATABASE_PTR * Database
+ );
+
+gceSTATUS
+gckKERNEL_FindHandleDatbase(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ OUT gctPOINTER * HandleDatabase,
+ OUT gctPOINTER * HandleDatabaseMutex
+ );
+
+gceSTATUS
+gckKERNEL_GetProcessMMU(
+ IN gckKERNEL Kernel,
+ OUT gckMMU * Mmu
+ );
+
+gceSTATUS
+gckKERNEL_SetRecovery(
+ IN gckKERNEL Kernel,
+ IN gctBOOL Recovery,
+ IN gctUINT32 StuckDump
+ );
+
+gceSTATUS
+gckMMU_FlatMapping(
+ IN gckMMU Mmu,
+ IN gctUINT32 Physical
+ );
+
+gceSTATUS
+gckMMU_GetPageEntry(
+ IN gckMMU Mmu,
+ IN gctUINT32 Address,
+ IN gctUINT32_PTR *PageTable
+ );
+
+gceSTATUS
+gckMMU_FreePagesEx(
+ IN gckMMU Mmu,
+ IN gctUINT32 Address,
+ IN gctSIZE_T PageCount
+ );
+
gceSTATUS
gckKERNEL_CreateIntegerDatabase(
IN gckKERNEL Kernel,
OUT gctPOINTER * Pointer
);
+/* Pointer rename */
gctUINT32
gckKERNEL_AllocateNameFromPointer(
IN gckKERNEL Kernel,
gctUINT64 idleTime;
gctUINT64 lastSlowdown;
gctUINT64 lastSlowdownIdle;
- /* ID - Pointer database*/
+ gctPOINTER nameDatabase;
+ gctPOINTER nameDatabaseMutex;
+
gctPOINTER pointerDatabase;
gctPOINTER pointerDatabaseMutex;
};
-#if gcdVIRTUAL_COMMAND_BUFFER
typedef struct _gckVIRTUAL_COMMAND_BUFFER * gckVIRTUAL_COMMAND_BUFFER_PTR;
typedef struct _gckVIRTUAL_COMMAND_BUFFER
{
gctPHYS_ADDR physical;
gctPOINTER userLogical;
gctPOINTER kernelLogical;
+ gctSIZE_T bytes;
gctSIZE_T pageCount;
gctPOINTER pageTable;
gctUINT32 gpuAddress;
gckVIRTUAL_COMMAND_BUFFER_PTR next;
gckVIRTUAL_COMMAND_BUFFER_PTR prev;
gckKERNEL kernel;
+#if gcdPROCESS_ADDRESS_SPACE
+ gckMMU mmu;
+#endif
}
gckVIRTUAL_COMMAND_BUFFER;
-#endif
/* gckKERNEL object. */
struct _gckKERNEL
#if VIVANTE_PROFILER
/* Enable profiling */
gctBOOL profileEnable;
-
/* Clear profile register or not*/
gctBOOL profileCleanRegister;
-
#endif
#ifdef QNX_SINGLE_THREADED_DEBUGGING
gckDB db;
gctBOOL dbCreated;
-#if gcdENABLE_RECOVERY
- gctPOINTER resetFlagClearTimer;
- gctPOINTER resetAtom;
gctUINT64 resetTimeStamp;
-#endif
/* Pointer to gckEVENT object. */
gcsTIMER timers[8];
gckVGKERNEL vg;
#endif
-#if gcdVIRTUAL_COMMAND_BUFFER
+ /* Virtual command buffer list. */
gckVIRTUAL_COMMAND_BUFFER_PTR virtualBufferHead;
gckVIRTUAL_COMMAND_BUFFER_PTR virtualBufferTail;
gctPOINTER virtualBufferLock;
-#endif
+
+ /* Enable virtual command buffer. */
+ gctBOOL virtualCommandBuffer;
#if gcdDVFS
gckDVFS dvfs;
#if gcdANDROID_NATIVE_FENCE_SYNC
gctHANDLE timeline;
#endif
+
+ /* Enable recovery. */
+ gctBOOL recovery;
+
+ /* Level of dump information after stuck. */
+ gctUINT stuckDump;
+
+#if gcdSECURITY
+ gctUINT32 securityChannel;
+#endif
+
+ /* Timer to monitor GPU stuck. */
+ gctPOINTER monitorTimer;
+
+ /* Flag to quit monitor timer. */
+ gctBOOL monitorTimerStop;
+
+ /* Monitor states. */
+ gctBOOL monitoring;
+ gctUINT32 lastCommitStamp;
+ gctUINT32 timer;
+ gctUINT32 restoreAddress;
+ gctUINT32 restoreMask;
};
struct _FrequencyHistory
gckOS os;
/* Number of bytes per page. */
- gctSIZE_T pageSize;
+ gctUINT32 pageSize;
/* Current pipe select. */
gcePIPE_SELECT pipeSelect;
gctSIGNAL signal;
gctPHYS_ADDR physical;
gctPOINTER logical;
+ gctUINT32 address;
}
queues[gcdCOMMAND_QUEUES];
gctPHYS_ADDR physical;
gctPOINTER logical;
+ gctUINT32 address;
gctUINT32 offset;
gctINT index;
#if gcmIS_DEBUG(gcdDEBUG_TRACE)
/* Pointer to last WAIT command. */
gctPHYS_ADDR waitPhysical;
gctPOINTER waitLogical;
- gctSIZE_T waitSize;
+ gctUINT32 waitSize;
/* Command buffer alignment. */
- gctSIZE_T alignment;
- gctSIZE_T reservedHead;
- gctSIZE_T reservedTail;
+ gctUINT32 alignment;
+ gctUINT32 reservedHead;
+ gctUINT32 reservedTail;
/* Commit counter. */
gctPOINTER atomCommit;
gctUINT hintArraySize;
gctUINT32_PTR hintArray;
#endif
+
+#if gcdPROCESS_ADDRESS_SPACE
+ gckMMU currentMmu;
+#endif
+ struct _gckENTRYQUEUE queue;
};
typedef struct _gcsEVENT * gcsEVENT_PTR;
/* Source of the event. */
gceKERNEL_WHERE source;
+#if gcdMULTI_GPU
+ /* Which chip(s) of the event */
+ gceCORE_3D_MASK chipEnable;
+#endif
+
/* Pointer to head of event queue. */
gcsEVENT_PTR head;
/* Time stamp. */
gctUINT64 stamp;
- gctUINT64 lastCommitStamp;
+ gctUINT32 lastCommitStamp;
/* Queue mutex. */
gctPOINTER eventQueueMutex;
/* Array of event queues. */
- gcsEVENT_QUEUE queues[30];
+ gcsEVENT_QUEUE queues[29];
gctUINT8 lastID;
gctPOINTER freeAtom;
/* Pending events. */
#if gcdSMP
+#if gcdMULTI_GPU
+ gctPOINTER pending3D[gcdMULTI_GPU];
+ gctPOINTER pending3DMask[gcdMULTI_GPU];
+ gctPOINTER pendingMask;
+#endif
gctPOINTER pending;
#else
+#if gcdMULTI_GPU
+ volatile gctUINT pending3D[gcdMULTI_GPU];
+ volatile gctUINT pending3DMask[gcdMULTI_GPU];
+ volatile gctUINT pendingMask;
+#endif
volatile gctUINT pending;
#endif
+#if gcdMULTI_GPU
+ gctUINT32 busy;
+#endif
/* List of free event structures and its mutex. */
gcsEVENT_PTR freeEventList;
gctPOINTER submitTimer;
- volatile gctBOOL inNotify;
+#if gcdINTERRUPT_STATISTIC
+ gctPOINTER interruptCount;
+#endif
+
+#if gcdRECORD_COMMAND
+ gckRECORDER recorder;
+#endif
};
/* Free all events belonging to a process. */
IN gctPHYS_ADDR Handle,
IN gctPOINTER Logical,
IN gctSIGNAL Signal,
- IN OUT gctSIZE_T * waitSize
+ IN OUT gctUINT32 * waitSize
);
-gceSTATUS
-gckEVENT_WaitEmpty(
- IN gckEVENT Event
- );
+typedef struct _gcsLOCK_INFO * gcsLOCK_INFO_PTR;
+typedef struct _gcsLOCK_INFO
+{
+ gctUINT32 GPUAddresses[gcdMAX_GPU_COUNT];
+ gctPOINTER pageTables[gcdMAX_GPU_COUNT];
+ gctUINT32 lockeds[gcdMAX_GPU_COUNT];
+ gckKERNEL lockKernels[gcdMAX_GPU_COUNT];
+ gckMMU lockMmus[gcdMAX_GPU_COUNT];
+}
+gcsLOCK_INFO;
+
+typedef struct _gcsGPU_MAP * gcsGPU_MAP_PTR;
+typedef struct _gcsGPU_MAP
+{
+ gctINT pid;
+ gcsLOCK_INFO lockInfo;
+ gcsGPU_MAP_PTR prev;
+ gcsGPU_MAP_PTR next;
+}
+gcsGPU_MAP;
/* gcuVIDMEM_NODE structure. */
typedef union _gcuVIDMEM_NODE
gcuVIDMEM_NODE_PTR prevFree;
/* Information for this node. */
- gctUINT32 offset;
+ gctSIZE_T offset;
gctSIZE_T bytes;
gctUINT32 alignment;
#ifdef __QNXNTO__
- /* Client/server vaddr (mapped using mmap_join). */
+ /* Client virtual address. */
gctPOINTER logical;
#endif
/* Process ID owning this memory. */
gctUINT32 processID;
- /* Prevent compositor from freeing until client unlocks. */
- gctBOOL freePending;
-
- /* */
- gcsVIDMEM_NODE_SHARED_INFO sharedInfo;
-
-#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
+#if gcdENABLE_VG
gctPOINTER kernelVirtual;
#endif
-
- /* Surface type. */
- gceSURF_TYPE type;
}
VidMem;
/* do_mmap_pgoff address... mapped per-process. */
gctPOINTER logical;
+#if gcdENABLE_VG
+ /* Physical address of this node, only meaningful when it is contiguous. */
+ gctUINT32 physicalAddress;
+
+ /* Kernel logical of this node. */
+ gctPOINTER kernelVirtual;
+#endif
+
+ /* Customer private handle */
+ gctUINT32 gid;
+
/* Page table information. */
/* Used only when node is not contiguous */
gctSIZE_T pageCount;
/* Actual physical address */
gctUINT32 addresses[gcdMAX_GPU_COUNT];
- /* Mutex. */
- gctPOINTER mutex;
-
/* Locked counter. */
gctINT32 lockeds[gcdMAX_GPU_COUNT];
-#ifdef __QNXNTO__
- /* Single linked list of nodes. */
- gcuVIDMEM_NODE_PTR next;
-
- /* Unlock pending flag. */
- gctBOOL unlockPendings[gcdMAX_GPU_COUNT];
-
- /* Free pending flag. */
- gctBOOL freePending;
-#endif
-
/* Process ID owning this memory. */
gctUINT32 processID;
- /* Owner process sets freed to true
- * when it trys to free a locked
- * node */
- gctBOOL freed;
-
- /* */
- gcsVIDMEM_NODE_SHARED_INFO sharedInfo;
-
/* Surface type. */
gceSURF_TYPE type;
}
/* The heap mutex. */
gctPOINTER mutex;
+};
+
+typedef struct _gcsVIDMEM_NODE
+{
+ /* Pointer to gcuVIDMEM_NODE. */
+ gcuVIDMEM_NODE_PTR node;
+
+ /* Mutex to protect node. */
+ gctPOINTER mutex;
+
+ /* Reference count. */
+ gctPOINTER reference;
+
+ /* Name for client to import. */
+ gctUINT32 name;
-#if gcdUSE_VIDMEM_PER_PID
- /* The Pid this VidMem belongs to. */
- gctUINT32 pid;
+#if gcdPROCESS_ADDRESS_SPACE
+ /* Head of mapping list. */
+ gcsGPU_MAP_PTR mapHead;
- struct _gckVIDMEM* next;
+ /* Tail of mapping list. */
+ gcsGPU_MAP_PTR mapTail;
+
+ gctPOINTER mapMutex;
+#endif
+
+ /* Surface Type. */
+ gceSURF_TYPE type;
+
+ /* Pool from which node is allocated. */
+ gcePOOL pool;
+}
+gcsVIDMEM_NODE;
+
+typedef struct _gcsVIDMEM_HANDLE * gckVIDMEM_HANDLE;
+typedef struct _gcsVIDMEM_HANDLE
+{
+ /* Pointer to gckVIDMEM_NODE. */
+ gckVIDMEM_NODE node;
+
+ /* Handle for current process. */
+ gctUINT32 handle;
+
+ /* Reference count for this handle. */
+ gctPOINTER reference;
+}
+gcsVIDMEM_HANDLE;
+
+typedef struct _gcsSHBUF * gcsSHBUF_PTR;
+typedef struct _gcsSHBUF
+{
+ /* ID. */
+ gctUINT32 id;
+
+ /* Reference count. */
+ gctPOINTER reference;
+
+ /* Data size. */
+ gctUINT32 size;
+
+ /* Data. */
+ gctPOINTER data;
+}
+gcsSHBUF;
+
+gceSTATUS
+gckVIDMEM_HANDLE_Reference(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 Handle
+ );
+
+gceSTATUS
+gckVIDMEM_HANDLE_Dereference(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 Handle
+ );
+
+gceSTATUS
+gckVIDMEM_NODE_Allocate(
+ IN gckKERNEL Kernel,
+ IN gcuVIDMEM_NODE_PTR VideoNode,
+ IN gceSURF_TYPE Type,
+ IN gcePOOL Pool,
+ IN gctUINT32 * Handle
+ );
+
+gceSTATUS
+gckVIDMEM_Node_Lock(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node,
+ OUT gctUINT32 *Address
+ );
+
+gceSTATUS
+gckVIDMEM_NODE_Unlock(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node,
+ IN gctUINT32 ProcessID
+ );
+
+gceSTATUS
+gckVIDMEM_NODE_Dereference(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node
+ );
+
+gceSTATUS
+gckVIDMEM_NODE_Name(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ IN gctUINT32 * Name
+ );
+
+gceSTATUS
+gckVIDMEM_NODE_Import(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Name,
+ IN gctUINT32 * Handle
+ );
+
+gceSTATUS
+gckVIDMEM_HANDLE_LookupAndReference(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ OUT gckVIDMEM_NODE * Node
+ );
+
+gceSTATUS
+gckVIDMEM_HANDLE_Lookup(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 Handle,
+ OUT gckVIDMEM_NODE * Node
+ );
+
+gceSTATUS
+gckVIDMEM_NODE_GetFd(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ OUT gctINT * Fd
+ );
+
+#if gcdPROCESS_ADDRESS_SPACE
+gceSTATUS
+gckEVENT_DestroyMmu(
+ IN gckEVENT Event,
+ IN gckMMU Mmu,
+ IN gceKERNEL_WHERE FromWhere
+ );
#endif
-};
/* gckMMU object. */
struct _gckMMU
gctUINT32 dynamicMappingStart;
-#ifdef __QNXNTO__
- /* Single linked list of all allocated nodes. */
- gctPOINTER nodeMutex;
- gcuVIDMEM_NODE_PTR nodeList;
+ gctUINT32_PTR mapLogical;
+#if gcdPROCESS_ADDRESS_SPACE
+ gctPOINTER pageTableDirty[gcdMAX_GPU_COUNT];
+ gctPOINTER stlbs;
#endif
};
-#if gcdVIRTUAL_COMMAND_BUFFER
gceSTATUS
gckOS_CreateKernelVirtualMapping(
+ IN gckOS Os,
IN gctPHYS_ADDR Physical,
- OUT gctSIZE_T * PageCount,
- OUT gctPOINTER * Logical
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Logical,
+ OUT gctSIZE_T * PageCount
);
gceSTATUS
gckOS_DestroyKernelVirtualMapping(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
IN gctPOINTER Logical
);
+gceSTATUS
+gckOS_CreateUserVirtualMapping(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Logical,
+ OUT gctSIZE_T * PageCount
+ );
+
+gceSTATUS
+gckOS_DestroyUserVirtualMapping(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical
+ );
+
+gceSTATUS
+gckOS_GetFd(
+ IN gctSTRING Name,
+ IN gcsFDPRIVATE_PTR Private,
+ OUT gctINT *Fd
+ );
+
gceSTATUS
gckKERNEL_AllocateVirtualCommandBuffer(
IN gckKERNEL Kernel,
gckKERNEL_GetGPUAddress(
IN gckKERNEL Kernel,
IN gctPOINTER Logical,
+ IN gctBOOL InUserSpace,
OUT gctUINT32 * Address
);
IN gctUINT32 GpuAddress,
OUT gckVIRTUAL_COMMAND_BUFFER_PTR * Buffer
);
-#endif
gceSTATUS
gckKERNEL_AttachProcess(
OUT gctBOOL_PTR IsIdle
);
+#if gcdSECURITY
+gceSTATUS
+gckKERNEL_SecurityOpen(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 GPU,
+ OUT gctUINT32 *Channel
+ );
+
+/*
+** Close a security service channel
+*/
+gceSTATUS
+gckKERNEL_SecurityClose(
+ IN gctUINT32 Channel
+ );
+
+/*
+** Security service interface.
+*/
+gceSTATUS
+gckKERNEL_SecurityCallService(
+ IN gctUINT32 Channel,
+ IN OUT gcsTA_INTERFACE * Interface
+ );
+
+gceSTATUS
+gckKERNEL_SecurityStartCommand(
+ IN gckKERNEL Kernel
+ );
+
+gceSTATUS
+gckKERNEL_SecurityAllocateSecurityMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Bytes,
+ OUT gctUINT32 * Handle
+ );
+
+gceSTATUS
+gckKERNEL_SecurityExecute(
+ IN gckKERNEL Kernel,
+ IN gctPOINTER Buffer,
+ IN gctUINT32 Bytes
+ );
+
+gceSTATUS
+gckKERNEL_SecurityMapMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 *PhysicalArray,
+ IN gctUINT32 PageCount,
+ OUT gctUINT32 * GPUAddress
+ );
+
+gceSTATUS
+gckKERNEL_SecurityUnmapMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 GPUAddress,
+ IN gctUINT32 PageCount
+ );
+
+#endif
+
+gceSTATUS
+gckKERNEL_CreateShBuffer(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Size,
+ OUT gctSHBUF * ShBuf
+ );
+
+gceSTATUS
+gckKERNEL_DestroyShBuffer(
+ IN gckKERNEL Kernel,
+ IN gctSHBUF ShBuf
+ );
+
+gceSTATUS
+gckKERNEL_MapShBuffer(
+ IN gckKERNEL Kernel,
+ IN gctSHBUF ShBuf
+ );
+
+gceSTATUS
+gckKERNEL_WriteShBuffer(
+ IN gckKERNEL Kernel,
+ IN gctSHBUF ShBuf,
+ IN gctPOINTER UserData,
+ IN gctUINT32 ByteCount
+ );
+
+gceSTATUS
+gckKERNEL_ReadShBuffer(
+ IN gckKERNEL Kernel,
+ IN gctSHBUF ShBuf,
+ IN gctPOINTER UserData,
+ IN gctUINT32 ByteCount,
+ OUT gctUINT32 * BytesRead
+ );
+
+
/******************************************************************************\
******************************* gckCONTEXT Object *******************************
\******************************************************************************/
IN gcsSTATE_DELTA_PTR StateDelta
);
+gceSTATUS
+gckCONTEXT_MapBuffer(
+ IN gckCONTEXT Context,
+ OUT gctUINT32 *Physicals,
+ OUT gctUINT64 *Logicals,
+ OUT gctUINT32 *Bytes
+ );
+
#if gcdLINK_QUEUE_SIZE
void
gckLINKQUEUE_Enqueue(
);
#endif
+gceSTATUS
+gckENTRYQUEUE_Enqueue(
+ IN gckKERNEL Kernel,
+ IN gckENTRYQUEUE Queue,
+ IN gctUINT32 physical,
+ IN gctUINT32 bytes
+ );
+
+gceSTATUS
+gckENTRYQUEUE_Dequeue(
+ IN gckENTRYQUEUE Queue,
+ OUT gckENTRYDATA * Data
+ );
+
+/******************************************************************************\
+****************************** gckRECORDER Object ******************************
+\******************************************************************************/
+gceSTATUS
+gckRECORDER_Construct(
+ IN gckOS Os,
+ IN gckHARDWARE Hardware,
+ OUT gckRECORDER * Recorder
+ );
+
+gceSTATUS
+gckRECORDER_Destory(
+ IN gckOS Os,
+ IN gckRECORDER Recorder
+ );
+
+void
+gckRECORDER_AdvanceIndex(
+ gckRECORDER Recorder,
+ gctUINT64 CommitStamp
+ );
+
+void
+gckRECORDER_Record(
+ gckRECORDER Recorder,
+ gctUINT8_PTR CommandBuffer,
+ gctUINT32 CommandBytes,
+ gctUINT8_PTR ContextBuffer,
+ gctUINT32 ContextBytes
+ );
+
+void
+gckRECORDER_Dump(
+ gckRECORDER Recorder
+ );
+
+gceSTATUS
+gckRECORDER_UpdateMirror(
+ gckRECORDER Recorder,
+ gctUINT32 State,
+ gctUINT32 Data
+ );
#ifdef __cplusplus
}
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#include "gc_hal_kernel_precomp.h"
#include "gc_hal_kernel_context.h"
-#ifdef __QNXNTO__
-#include <sys/slog.h>
-#endif
-
#define _GC_OBJ_ZONE gcvZONE_COMMAND
/******************************************************************************\
Command->index = newIndex;
Command->newQueue = gcvTRUE;
Command->logical = Command->queues[newIndex].logical;
+ Command->address = Command->queues[newIndex].address;
Command->offset = 0;
- gcmkONERROR(
- gckOS_GetPhysicalAddress(
- Command->os,
- Command->logical,
- (gctUINT32 *) &Command->physical
- ));
+ gcmkONERROR(gckOS_GetPhysicalAddress(
+ Command->os,
+ Command->logical,
+ (gctUINT32 *) &Command->physical
+ ));
if (currentIndex != -1)
{
IN gckCOMMAND Command
)
{
+#if gcdSECURITY
+ return gcvSTATUS_OK;
+#else
gceSTATUS status;
gctUINT32 oldValue;
gckHARDWARE hardware = Command->kernel->hardware;
+ gctBOOL pause = gcvFALSE;
+
+ gctUINT8_PTR pointer;
+ gctUINT32 eventBytes;
+ gctUINT32 endBytes;
+ gctUINT32 bufferSize;
+ gctUINT32 executeBytes;
+ gctUINT32 waitLinkBytes;
gcmkONERROR(gckOS_AtomicExchange(Command->os,
hardware->pageTableDirty,
{
/* Page Table is upated, flush mmu before commit. */
gcmkONERROR(gckHARDWARE_FlushMMU(hardware));
+
+ if ((oldValue & gcvPAGE_TABLE_DIRTY_BIT_FE)
+ && (hardware->endAfterFlushMmuCache)
+ )
+ {
+ pause = gcvTRUE;
+ }
+ }
+
+ if (pause)
+ {
+ /* Query size. */
+ gcmkONERROR(gckHARDWARE_Event(hardware, gcvNULL, 0, gcvKERNEL_PIXEL, &eventBytes));
+ gcmkONERROR(gckHARDWARE_End(hardware, gcvNULL, &endBytes));
+
+ executeBytes = eventBytes + endBytes;
+
+ gcmkONERROR(gckHARDWARE_WaitLink(
+ hardware,
+ gcvNULL,
+ Command->offset + executeBytes,
+ &waitLinkBytes,
+ gcvNULL,
+ gcvNULL
+ ));
+
+ /* Reserve space. */
+ gcmkONERROR(gckCOMMAND_Reserve(
+ Command,
+ executeBytes,
+ (gctPOINTER *)&pointer,
+ &bufferSize
+ ));
+
+ /* Append EVENT(29). */
+ gcmkONERROR(gckHARDWARE_Event(
+ hardware,
+ pointer,
+ 29,
+ gcvKERNEL_PIXEL,
+ &eventBytes
+ ));
+
+ /* Append END. */
+ pointer += eventBytes;
+ gcmkONERROR(gckHARDWARE_End(hardware, pointer, &endBytes));
+
+ /* Store address to queue. */
+ gcmkONERROR(gckENTRYQUEUE_Enqueue(
+ Command->kernel,
+ &Command->queue,
+ Command->address + Command->offset + executeBytes,
+ waitLinkBytes
+ ));
+
+ gcmkONERROR(gckCOMMAND_Execute(Command, executeBytes));
}
return gcvSTATUS_OK;
OnError:
return status;
+#endif
}
-#if gcdVIRTUAL_COMMAND_BUFFER
static void
_DumpBuffer(
IN gctPOINTER Buffer,
IN gctSIZE_T Size
)
{
- gctINT i, line, left;
+ gctSIZE_T i, line, left;
gctUINT32_PTR data = Buffer;
line = Size / 32;
left = Size % 32;
-
for (i = 0; i < line; i++)
{
gcmkPRINT("%X : %08X %08X %08X %08X %08X %08X %08X %08X ",
static void
_DumpKernelCommandBuffer(
IN gckCOMMAND Command
-)
+ )
{
gctINT i;
- gctUINT32 physical;
- gctPOINTER entry;
+ gctUINT32 physical = 0;
+ gctPOINTER entry = gcvNULL;
for (i = 0; i < gcdCOMMAND_QUEUES; i++)
{
_DumpBuffer(entry, physical, Command->pageSize);
}
}
-#endif
/******************************************************************************\
****************************** gckCOMMAND API Code ******************************
gceSTATUS status;
gctINT i;
gctPOINTER pointer = gcvNULL;
+ gctSIZE_T pageSize;
gcmkHEADER_ARG("Kernel=0x%x", Kernel);
gcmkONERROR(gckOS_AtomConstruct(os, &command->atomCommit));
/* Get the page size from teh OS. */
- gcmkONERROR(gckOS_GetPageSize(os, &command->pageSize));
+ gcmkONERROR(gckOS_GetPageSize(os, &pageSize));
+
+ gcmkSAFECASTSIZET(command->pageSize, pageSize);
/* Get process ID. */
gcmkONERROR(gckOS_GetProcessID(&command->kernelProcessID));
gcmkONERROR(gckOS_AllocateNonPagedMemory(
os,
gcvFALSE,
- &command->pageSize,
+ &pageSize,
&command->queues[i].physical,
&command->queues[i].logical
));
+ gcmkONERROR(gckHARDWARE_ConvertLogical(
+ Kernel->hardware,
+ command->queues[i].logical,
+ gcvFALSE,
+ &command->queues[i].address
+ ));
+
gcmkONERROR(gckOS_CreateSignal(
os, gcvFALSE, &command->queues[i].signal
));
));
}
+#if gcdRECORD_COMMAND
+ gcmkONERROR(gckRECORDER_Construct(os, Kernel->hardware, &command->recorder));
+#endif
+
/* No command queue in use yet. */
command->index = -1;
command->logical = gcvNULL;
/* END event signal not created. */
command->endEventSignal = gcvNULL;
+ command->queue.front = 0;
+ command->queue.rear = 0;
+ command->queue.count = 0;
+
/* Return pointer to the gckCOMMAND object. */
*Command = command;
}
#endif
+#if gcdRECORD_COMMAND
+ gckRECORDER_Destory(Command->os, Command->recorder);
+#endif
+
/* Mark object as unknown. */
Command->object.type = gcvOBJ_UNKNOWN;
{
gceSTATUS status;
gckHARDWARE hardware;
- gctUINT32 waitOffset;
- gctSIZE_T waitLinkBytes;
+ gctUINT32 waitOffset = 0;
+ gctUINT32 waitLinkBytes;
gcmkHEADER_ARG("Command=0x%x", Command);
Command->os,
Command->kernelProcessID,
gcvNULL,
- Command->physical,
+ (gctUINT32)Command->physical,
Command->logical,
waitLinkBytes
));
Command->offset = waitLinkBytes;
Command->newQueue = gcvFALSE;
- /* Enable command processor. */
-#ifdef __QNXNTO__
- gcmkONERROR(gckHARDWARE_Execute(
- hardware,
- Command->logical,
- Command->physical,
- gcvTRUE,
- waitLinkBytes
- ));
+#if gcdSECURITY
+ /* Start FE by calling security service. */
+ gckKERNEL_SecurityStartCommand(
+ Command->kernel
+ );
#else
+ /* Enable command processor. */
gcmkONERROR(gckHARDWARE_Execute(
hardware,
- Command->logical,
+ Command->address,
waitLinkBytes
));
#endif
Command->waitPhysical,
Command->waitLogical,
Command->endEventSignal,
- &Command->waitSize));
+ &Command->waitSize));
}
else
{
hardware, Command->waitLogical, &Command->waitSize
));
+#if gcdSECURITY
+ gcmkONERROR(gckKERNEL_SecurityExecute(
+ Command->kernel, Command->waitLogical, 8
+ ));
+#endif
+
/* Update queue tail pointer. */
gcmkONERROR(gckHARDWARE_UpdateQueueTail(Command->kernel->hardware,
Command->logical,
Command->os,
Command->kernelProcessID,
gcvNULL,
- Command->waitPhysical,
+ (gctUINT32)Command->waitPhysical,
Command->waitLogical,
Command->waitSize
));
**
** Nothing.
*/
+#if gcdMULTI_GPU
+gceSTATUS
+gckCOMMAND_Commit(
+ IN gckCOMMAND Command,
+ IN gckCONTEXT Context,
+ IN gcoCMDBUF CommandBuffer,
+ IN gcsSTATE_DELTA_PTR StateDelta,
+ IN gcsQUEUE_PTR EventQueue,
+ IN gctUINT32 ProcessID,
+ IN gceCORE_3D_MASK ChipEnable
+ )
+#else
gceSTATUS
gckCOMMAND_Commit(
IN gckCOMMAND Command,
IN gcsQUEUE_PTR EventQueue,
IN gctUINT32 ProcessID
)
+#endif
{
gceSTATUS status;
gctBOOL commitEntered = gcvFALSE;
gcsCONTEXT_PTR contextBuffer;
struct _gcoCMDBUF _commandBufferObject;
gctPHYS_ADDR commandBufferPhysical;
- gctUINT8_PTR commandBufferLogical;
- gctUINT8_PTR commandBufferLink;
+ gctUINT8_PTR commandBufferLogical = gcvNULL;
+ gctUINT32 commandBufferAddress = 0;
+ gctUINT8_PTR commandBufferLink = gcvNULL;
gctUINT commandBufferSize;
gctSIZE_T nopBytes;
- gctSIZE_T pipeBytes;
- gctSIZE_T linkBytes;
+ gctUINT32 pipeBytes;
+ gctUINT32 linkBytes;
gctSIZE_T bytes;
gctUINT32 offset;
#if gcdNONPAGED_MEMORY_CACHEABLE
gctPHYS_ADDR entryPhysical;
#endif
gctPOINTER entryLogical;
- gctSIZE_T entryBytes;
+ gctUINT32 entryAddress;
+ gctUINT32 entryBytes;
#if gcdNONPAGED_MEMORY_CACHEABLE
gctPHYS_ADDR exitPhysical;
#endif
gctPOINTER exitLogical;
- gctSIZE_T exitBytes;
+ gctUINT32 exitAddress;
+ gctUINT32 exitBytes;
gctPHYS_ADDR waitLinkPhysical;
gctPOINTER waitLinkLogical;
- gctSIZE_T waitLinkBytes;
+ gctUINT32 waitLinkAddress;
+ gctUINT32 waitLinkBytes;
gctPHYS_ADDR waitPhysical;
gctPOINTER waitLogical;
gctUINT32 waitOffset;
- gctSIZE_T waitSize;
+ gctUINT32 waitSize;
+
+#ifdef __QNXNTO__
+ gctPOINTER userCommandBufferLogical = gcvNULL;
+ gctBOOL userCommandBufferLogicalMapped = gcvFALSE;
+ gctPOINTER userCommandBufferLink = gcvNULL;
+ gctBOOL userCommandBufferLinkMapped = gcvFALSE;
+#endif
+
+#if gcdPROCESS_ADDRESS_SPACE
+ gctSIZE_T mmuConfigureBytes;
+ gctPOINTER mmuConfigureLogical = gcvNULL;
+ gctUINT32 mmuConfigureAddress;
+ gctPOINTER mmuConfigurePhysical = 0;
+ gctSIZE_T mmuConfigureWaitLinkOffset;
+ gckMMU mmu;
+ gctSIZE_T reservedBytes;
+ gctUINT32 oldValue;
+#endif
#if gcdDUMP_COMMAND
gctPOINTER contextDumpLogical = gcvNULL;
gctPOINTER pointer = gcvNULL;
+#if gcdMULTI_GPU
+ gctSIZE_T chipEnableBytes;
+#endif
+
gcmkHEADER_ARG(
"Command=0x%x CommandBuffer=0x%x ProcessID=%d",
Command, CommandBuffer, ProcessID
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
- if (Command->kernel->core == gcvCORE_2D)
+ if (Command->kernel->hardware->type== gcvHARDWARE_2D)
{
/* There is no context for 2D. */
Context = gcvNULL;
}
- gcmkONERROR(_FlushMMU(Command));
+#if gcdPROCESS_ADDRESS_SPACE
+ gcmkONERROR(gckKERNEL_GetProcessMMU(Command->kernel, &mmu));
+
+ gcmkONERROR(gckOS_AtomicExchange(Command->os,
+ mmu->pageTableDirty[Command->kernel->core],
+ 0,
+ &oldValue));
+#else
+#endif
#if VIVANTE_PROFILER_CONTEXT
if((Command->kernel->hardware->gpuProfiler) && (Command->kernel->profileEnable))
/* Yes, merge in the deltas. */
gckCONTEXT_Update(Context, ProcessID, StateDelta);
- /* Update the current context. */
- Command->currContext = Context;
- }
+ /* Update the current context. */
+ Command->currContext = Context;
+ }
#else
if (needCopy)
{
/* Query the size of LINK command. */
gcmkONERROR(gckHARDWARE_Link(
- hardware, gcvNULL, gcvNULL, 0, &linkBytes
+ hardware, gcvNULL, 0, 0, &linkBytes
));
+#if gcdMULTI_GPU
+ /* Query the size of chip enable command sequence. */
+ gcmkONERROR(gckHARDWARE_ChipEnable(
+ hardware, gcvNULL, 0, &chipEnableBytes
+ ));
+#endif
+
/* Compute the command buffer entry and the size. */
commandBufferLogical
= (gctUINT8_PTR) gcmUINT64_TO_PTR(commandBufferObject->logical)
+ commandBufferObject->startOffset;
- gcmkONERROR(gckOS_GetPhysicalAddress(
+ /* Get the hardware address. */
+ if (Command->kernel->virtualCommandBuffer)
+ {
+ gcmkONERROR(gckKERNEL_GetGPUAddress(
+ Command->kernel,
+ commandBufferLogical,
+ gcvTRUE,
+ &commandBufferAddress
+ ));
+ }
+ else
+ {
+ gcmkONERROR(gckHARDWARE_ConvertLogical(
+ hardware,
+ commandBufferLogical,
+ gcvTRUE,
+ &commandBufferAddress
+ ));
+ }
+
+ /* Get the physical address. */
+ gcmkONERROR(gckOS_UserLogicalToPhysical(
Command->os,
commandBufferLogical,
(gctUINT32_PTR)&commandBufferPhysical
));
+#ifdef __QNXNTO__
+ userCommandBufferLogical = (gctPOINTER) commandBufferLogical;
+
+ gcmkONERROR(gckOS_MapUserPointer(
+ Command->os,
+ userCommandBufferLogical,
+ 0,
+ &pointer));
+
+ commandBufferLogical = pointer;
+
+ userCommandBufferLogicalMapped = gcvTRUE;
+#endif
+
commandBufferSize
= commandBufferObject->offset
+ Command->reservedTail
- commandBufferObject->startOffset;
+ gcmkONERROR(_FlushMMU(Command));
+
/* Get the current offset. */
offset = Command->offset;
/* Compute number of bytes left in current kernel command queue. */
bytes = Command->pageSize - offset;
+#if gcdMULTI_GPU
+ if (Command->kernel->core == gcvCORE_MAJOR)
+ {
+ commandBufferSize += chipEnableBytes;
+
+ gcmkONERROR(gckHARDWARE_ChipEnable(
+ hardware,
+ commandBufferLogical + pipeBytes,
+ ChipEnable,
+ &chipEnableBytes
+ ));
+
+ gcmkONERROR(gckHARDWARE_ChipEnable(
+ hardware,
+ commandBufferLogical + commandBufferSize - linkBytes - chipEnableBytes,
+ gcvCORE_3D_ALL_MASK,
+ &chipEnableBytes
+ ));
+ }
+ else
+ {
+ commandBufferSize += nopBytes;
+
+ gcmkONERROR(gckHARDWARE_Nop(
+ hardware,
+ commandBufferLogical + pipeBytes,
+ &nopBytes
+ ));
+
+ gcmkONERROR(gckHARDWARE_Nop(
+ hardware,
+ commandBufferLogical + commandBufferSize - linkBytes - nopBytes,
+ &nopBytes
+ ));
+ }
+#endif
+
/* Query the size of WAIT/LINK command sequence. */
gcmkONERROR(gckHARDWARE_WaitLink(
hardware,
/* Compute the location if WAIT/LINK command sequence. */
waitLinkPhysical = (gctUINT8_PTR) Command->physical + offset;
waitLinkLogical = (gctUINT8_PTR) Command->logical + offset;
+ waitLinkAddress = Command->address + offset;
/* Context switch required? */
if (Context == gcvNULL)
entryPhysical = (gctUINT8_PTR) commandBufferPhysical + offset;
#endif
entryLogical = commandBufferLogical + offset;
+ entryAddress = commandBufferAddress + offset;
entryBytes = commandBufferSize - offset;
+
+ Command->currContext = gcvNULL;
}
else if (Command->currContext != Context)
{
entryPhysical = (gctUINT8_PTR) contextBuffer->physical + pipeBytes;
#endif
entryLogical = (gctUINT8_PTR) contextBuffer->logical + pipeBytes;
+ entryAddress = contextBuffer->address + pipeBytes;
entryBytes = Context->bufferSize - pipeBytes;
}
else
entryPhysical = (gctUINT8_PTR) contextBuffer->physical;
#endif
entryLogical = (gctUINT8_PTR) contextBuffer->logical;
+ entryAddress = contextBuffer->address;
entryBytes = Context->bufferSize;
}
gcmkONERROR(gckHARDWARE_Link(
hardware,
contextBuffer->link3D,
- commandBufferLogical + offset,
+ commandBufferAddress + offset,
commandBufferSize - offset,
&linkBytes
));
entryPhysical = (gctUINT8_PTR) contextBuffer->physical + pipeBytes;
#endif
entryLogical = (gctUINT8_PTR) contextBuffer->logical + pipeBytes;
+ entryAddress = contextBuffer->address + pipeBytes;
entryBytes = Context->entryOffset3D - pipeBytes;
}
else
entryPhysical = (gctUINT8_PTR) contextBuffer->physical;
#endif
entryLogical = (gctUINT8_PTR) contextBuffer->logical;
+ entryAddress = contextBuffer->address;
entryBytes = Context->entryOffset3D;
}
gcmkONERROR(gckHARDWARE_Link(
hardware,
contextBuffer->link2D,
- commandBufferLogical + offset,
+ commandBufferAddress + offset,
commandBufferSize - offset,
&linkBytes
));
/* Not using 2D. */
else
{
- /* Mark 2D as dirty. */
- Context->dirty2D = gcvTRUE;
/* Store the current context buffer. */
Context->dirtyBuffer = contextBuffer;
offset = (Command->pipeSelect == gcvPIPE_3D)
/* Skip pipe switching sequence. */
- ? Context->entryOffset3D + pipeBytes
+ ? Context->entryOffset3D + Context->pipeSelectBytes
/* Do not skip pipe switching sequence. */
: Context->entryOffset3D;
entryPhysical = (gctUINT8_PTR) contextBuffer->physical + offset;
#endif
entryLogical = (gctUINT8_PTR) contextBuffer->logical + offset;
+ entryAddress = contextBuffer->address + offset;
entryBytes = Context->bufferSize - offset;
/* See if we have to switch pipes between the context
gcmkONERROR(gckHARDWARE_Link(
hardware,
contextBuffer->link3D,
- commandBufferLogical + offset,
+ commandBufferAddress + offset,
commandBufferSize - offset,
&linkBytes
));
= (gctUINT8_PTR) contextBuffer->logical
+ Context->entryOffsetXDFrom3D;
+ entryAddress
+ = contextBuffer->address
+ + Context->entryOffsetXDFrom3D;
+
entryBytes
= Context->bufferSize
- Context->entryOffsetXDFrom3D;
= (gctUINT8_PTR) contextBuffer->logical
+ Context->entryOffsetXDFrom2D;
+ entryAddress
+ = contextBuffer->address
+ + Context->entryOffsetXDFrom2D;
+
entryBytes
= Context->totalSize
- Context->entryOffsetXDFrom2D;
gcmkONERROR(gckHARDWARE_Link(
hardware,
contextBuffer->link3D,
- commandBufferLogical + offset,
+ commandBufferAddress + offset,
commandBufferSize - offset,
&linkBytes
));
Command->os,
Command->kernelProcessID,
gcvNULL,
- entryPhysical,
+ (gctUINT32)entryPhysical,
entryLogical,
entryBytes
));
contextDumpLogical = entryLogical;
contextDumpBytes = entryBytes;
#endif
+
+#if gcdSECURITY
+ /* Commit context buffer to trust zone. */
+ gckKERNEL_SecurityExecute(
+ Command->kernel,
+ entryLogical,
+ entryBytes - 8
+ );
+#endif
+
+#if gcdRECORD_COMMAND
+ gckRECORDER_Record(
+ Command->recorder,
+ gcvNULL,
+ 0xFFFFFFFF,
+ entryLogical,
+ entryBytes - 8
+ );
+#endif
}
/* Same context. */
entryPhysical = (gctUINT8_PTR) contextBuffer->physical + pipeBytes;
#endif
entryLogical = (gctUINT8_PTR) contextBuffer->logical + pipeBytes;
+ entryAddress = contextBuffer->address + pipeBytes;
entryBytes = Context->bufferSize - pipeBytes;
}
else
entryPhysical = (gctUINT8_PTR) contextBuffer->physical;
#endif
entryLogical = (gctUINT8_PTR) contextBuffer->logical;
+ entryAddress = contextBuffer->address;
entryBytes = Context->bufferSize;
}
gcmkONERROR(gckHARDWARE_Link(
hardware,
contextBuffer->link3D,
- commandBufferLogical + offset,
+ commandBufferAddress + offset,
commandBufferSize - offset,
&linkBytes
));
entryPhysical = (gctUINT8_PTR) contextBuffer->physical + pipeBytes;
#endif
entryLogical = (gctUINT8_PTR) contextBuffer->logical + pipeBytes;
+ entryAddress = contextBuffer->address + pipeBytes;
entryBytes = Context->entryOffset3D - pipeBytes;
}
else
entryPhysical = (gctUINT8_PTR) contextBuffer->physical;
#endif
entryLogical = (gctUINT8_PTR) contextBuffer->logical;
+ entryAddress = contextBuffer->address;
entryBytes = Context->entryOffset3D;
}
gcmkONERROR(gckHARDWARE_Link(
hardware,
contextBuffer->link2D,
- commandBufferLogical + offset,
+ commandBufferAddress + offset,
commandBufferSize - offset,
&linkBytes
));
entryPhysical = (gctUINT8_PTR) contextBuffer->physical + offset;
#endif
entryLogical = (gctUINT8_PTR) contextBuffer->logical + offset;
+ entryAddress = contextBuffer->address + offset;
entryBytes = Context->bufferSize - offset;
/* See if we have to switch pipes between the context
gcmkONERROR(gckHARDWARE_Link(
hardware,
contextBuffer->link3D,
- commandBufferLogical + offset,
+ commandBufferAddress + offset,
commandBufferSize - offset,
&linkBytes
));
entryPhysical = (gctUINT8_PTR) commandBufferPhysical + offset;
#endif
entryLogical = commandBufferLogical + offset;
+ entryAddress = commandBufferAddress + offset;
entryBytes = commandBufferSize - offset;
}
}
#if gcdNONPAGED_MEMORY_CACHEABLE
exitPhysical = Command->physical;
#endif
+
exitLogical = Command->logical;
+ exitAddress = Command->address;
exitBytes = Command->offset + waitLinkBytes;
}
else
exitPhysical = waitLinkPhysical;
#endif
exitLogical = waitLinkLogical;
+ exitAddress = waitLinkAddress;
exitBytes = waitLinkBytes;
}
Command->os,
Command->kernelProcessID,
gcvNULL,
- exitPhysical,
+ (gctUINT32)exitPhysical,
exitLogical,
exitBytes
));
= (gctUINT8_PTR) gcmUINT64_TO_PTR(commandBufferObject->logical)
+ commandBufferObject->offset;
+#ifdef __QNXNTO__
+ userCommandBufferLink = (gctPOINTER) commandBufferLink;
+
+ gcmkONERROR(gckOS_MapUserPointer(
+ Command->os,
+ userCommandBufferLink,
+ 0,
+ &pointer));
+
+ commandBufferLink = pointer;
+
+ userCommandBufferLinkMapped = gcvTRUE;
+#endif
+
+#if gcdMULTI_GPU
+ if (Command->kernel->core == gcvCORE_MAJOR)
+ {
+ commandBufferLink += chipEnableBytes;
+ }
+ else
+ {
+ commandBufferLink += nopBytes;
+ }
+#endif
+
/* Generate a LINK from the end of the command buffer being scheduled
back to the kernel command queue. */
+#if !gcdSECURITY
gcmkONERROR(gckHARDWARE_Link(
hardware,
commandBufferLink,
- exitLogical,
+ exitAddress,
exitBytes,
&linkBytes
));
+#endif
+
+#ifdef __QNXNTO__
+ gcmkONERROR(gckOS_UnmapUserPointer(
+ Command->os,
+ userCommandBufferLink,
+ 0,
+ commandBufferLink));
+
+ userCommandBufferLinkMapped = gcvFALSE;
+#endif
#if gcdNONPAGED_MEMORY_CACHEABLE
/* Flush the command buffer cache. */
Command->os,
ProcessID,
gcvNULL,
- commandBufferPhysical,
+ (gctUINT32)commandBufferPhysical,
commandBufferLogical,
commandBufferSize
));
#endif
+#if gcdRECORD_COMMAND
+ gckRECORDER_Record(
+ Command->recorder,
+ commandBufferLogical + offset,
+ commandBufferSize - offset - 8,
+ gcvNULL,
+ 0xFFFFFFFF
+ );
+
+ gckRECORDER_AdvanceIndex(Command->recorder, Command->commitStamp);
+
+ Command->commitStamp++;
+#endif
+
+#if gcdSECURITY
+ /* Submit command buffer to trust zone. */
+ gckKERNEL_SecurityExecute(
+ Command->kernel,
+ commandBufferLogical + offset,
+ commandBufferSize - offset - 8
+ );
+#else
/* Generate a LINK from the previous WAIT/LINK command sequence to the
entry determined above (either the context or the command buffer).
This LINK replaces the WAIT instruction from the previous WAIT/LINK
gcmkONERROR(gckHARDWARE_Link(
hardware,
Command->waitLogical,
- entryLogical,
+ entryAddress,
entryBytes,
&Command->waitSize
));
+#endif
#if gcdNONPAGED_MEMORY_CACHEABLE
/* Flush the cache for the link. */
Command->os,
Command->kernelProcessID,
gcvNULL,
- Command->waitPhysical,
+ (gctUINT32)Command->waitPhysical,
Command->waitLogical,
Command->waitSize
));
#if VIVANTE_PROFILER_CONTEXT
if(sequenceAcquired)
{
+#if gcdMULTI_GPU
+ gcmkONERROR(gckCOMMAND_Stall(Command, gcvTRUE, ChipEnable));
+#else
gcmkONERROR(gckCOMMAND_Stall(Command, gcvTRUE));
+#endif
if (Command->currContext)
{
gcmkONERROR(gckHARDWARE_UpdateContextProfile(
}
/* Submit events. */
+#if gcdMULTI_GPU
+ status = gckEVENT_Submit(Command->kernel->eventObj, gcvTRUE, gcvFALSE, ChipEnable);
+#else
status = gckEVENT_Submit(Command->kernel->eventObj, gcvTRUE, gcvFALSE);
-
+#endif
if (status == gcvSTATUS_INTERRUPTED)
{
gcmkTRACE(
gcmkONERROR(status);
}
+#ifdef __QNXNTO__
+ if (userCommandBufferLogicalMapped)
+ {
+ gcmkONERROR(gckOS_UnmapUserPointer(
+ Command->os,
+ userCommandBufferLogical,
+ 0,
+ commandBufferLogical));
+
+ userCommandBufferLogicalMapped = gcvFALSE;
+ }
+#endif
+
/* Unmap the command buffer pointer. */
if (commandBufferMapped)
{
}
#endif
+#ifdef __QNXNTO__
+ if (userCommandBufferLinkMapped)
+ {
+ gcmkONERROR(gckOS_UnmapUserPointer(
+ Command->os,
+ userCommandBufferLink,
+ 0,
+ commandBufferLink));
+ }
+
+ if (userCommandBufferLogicalMapped)
+ {
+ gcmkVERIFY_OK(gckOS_UnmapUserPointer(
+ Command->os,
+ userCommandBufferLogical,
+ 0,
+ commandBufferLogical));
+ }
+#endif
+
/* Unmap the command buffer pointer. */
if (commandBufferMapped)
{
gceSTATUS
gckCOMMAND_Reserve(
IN gckCOMMAND Command,
- IN gctSIZE_T RequestedBytes,
+ IN gctUINT32 RequestedBytes,
OUT gctPOINTER * Buffer,
- OUT gctSIZE_T * BufferSize
+ OUT gctUINT32 * BufferSize
)
{
gceSTATUS status;
- gctSIZE_T bytes;
- gctSIZE_T requiredBytes;
+ gctUINT32 bytes;
+ gctUINT32 requiredBytes;
gctUINT32 requestedAligned;
gcmkHEADER_ARG("Command=0x%x RequestedBytes=%lu", Command, RequestedBytes);
gceSTATUS
gckCOMMAND_Execute(
IN gckCOMMAND Command,
- IN gctSIZE_T RequestedBytes
+ IN gctUINT32 RequestedBytes
)
{
gceSTATUS status;
gctPHYS_ADDR waitLinkPhysical;
gctUINT8_PTR waitLinkLogical;
gctUINT32 waitLinkOffset;
- gctSIZE_T waitLinkBytes;
+ gctUINT32 waitLinkBytes;
gctPHYS_ADDR waitPhysical;
gctPOINTER waitLogical;
gctUINT32 waitOffset;
- gctSIZE_T waitBytes;
+ gctUINT32 waitBytes;
#if gcdNONPAGED_MEMORY_CACHEABLE
gctPHYS_ADDR execPhysical;
#endif
gctPOINTER execLogical;
- gctSIZE_T execBytes;
+ gctUINT32 execAddress;
+ gctUINT32 execBytes;
gcmkHEADER_ARG("Command=0x%x RequestedBytes=%lu", Command, RequestedBytes);
execPhysical = Command->physical;
#endif
execLogical = Command->logical;
+ execAddress = Command->address;
execBytes = waitLinkOffset + waitLinkBytes;
}
else
execPhysical = (gctUINT8 *) Command->physical + Command->offset;
#endif
execLogical = (gctUINT8 *) Command->logical + Command->offset;
+ execAddress = Command->address + Command->offset;
execBytes = RequestedBytes + waitLinkBytes;
}
Command->os,
Command->kernelProcessID,
gcvNULL,
- execPhysical,
+ (gctUINT32)execPhysical,
execLogical,
execBytes
));
gcmkONERROR(gckHARDWARE_Link(
Command->kernel->hardware,
Command->waitLogical,
- execLogical,
+ execAddress,
execBytes,
&Command->waitSize
));
Command->os,
Command->kernelProcessID,
gcvNULL,
- Command->waitPhysical,
+ (gctUINT32)Command->waitPhysical,
Command->waitLogical,
Command->waitSize
));
**
** Nothing.
*/
+#if gcdMULTI_GPU
+gceSTATUS
+gckCOMMAND_Stall(
+ IN gckCOMMAND Command,
+ IN gctBOOL FromPower,
+ IN gceCORE_3D_MASK ChipEnable
+ )
+#else
gceSTATUS
gckCOMMAND_Stall(
IN gckCOMMAND Command,
IN gctBOOL FromPower
)
+#endif
{
#if gcdNULL_DRIVER
/* Do nothing with infinite hardware. */
gcmkONERROR(gckEVENT_Signal(eventObject, signal, gcvKERNEL_PIXEL));
/* Submit the event queue. */
+#if gcdMULTI_GPU
+ gcmkONERROR(gckEVENT_Submit(eventObject, gcvTRUE, FromPower, ChipEnable));
+#else
gcmkONERROR(gckEVENT_Submit(eventObject, gcvTRUE, FromPower));
+#endif
#if gcdDUMP_COMMAND
gcmkPRINT("@[kernel.stall]");
__FUNCTION__, __LINE__, idle
);
- gcmkONERROR(gckOS_MemoryBarrier(os, gcvNULL));
-
-#ifdef __QNXNTO__
- gctUINT32 reg_cmdbuf_fetch;
- gctUINT32 reg_intr;
-
- gcmkVERIFY_OK(gckOS_ReadRegisterEx(
- Command->kernel->hardware->os, Command->kernel->core, 0x0664, ®_cmdbuf_fetch
- ));
-
- if (idle == 0x7FFFFFFE)
- {
- /*
- * GPU is idle so there should not be pending interrupts.
- * Just double check.
- *
- * Note that reading interrupt register clears it.
- * That's why we don't read it in all cases.
- */
- gcmkVERIFY_OK(gckOS_ReadRegisterEx(
- Command->kernel->hardware->os, Command->kernel->core, 0x10, ®_intr
- ));
-
- slogf(
- _SLOG_SETCODE(1, 0),
- _SLOG_CRITICAL,
- "GALcore: Stall timeout (idle = 0x%X, command buffer fetch = 0x%X, interrupt = 0x%X)",
- idle, reg_cmdbuf_fetch, reg_intr
- );
- }
- else
- {
- slogf(
- _SLOG_SETCODE(1, 0),
- _SLOG_CRITICAL,
- "GALcore: Stall timeout (idle = 0x%X, command buffer fetch = 0x%X)",
- idle, reg_cmdbuf_fetch
- );
- }
-#endif
+ gcmkVERIFY_OK(gckOS_MemoryBarrier(os, gcvNULL));
#endif
+
/* Advance timer. */
timer += gcdGPU_ADVANCETIMER;
}
}
}
- while (gcmIS_ERROR(status)
-#if gcdGPU_TIMEOUT
- && (timer < Command->kernel->timeOut)
-#endif
- );
+ while (gcmIS_ERROR(status));
/* Bail out on timeout. */
if (gcmIS_ERROR(status))
** Pointer to a variable that will receive the number of states
** in the context buffer.
*/
+#if (gcdENABLE_3D || gcdENABLE_2D)
gceSTATUS
gckCOMMAND_Attach(
IN gckCOMMAND Command,
gcmkFOOTER();
return status;
}
+#endif
/*******************************************************************************
**
return status;
}
-#if gcdVIRTUAL_COMMAND_BUFFER
/*******************************************************************************
**
** gckCOMMAND_DumpExecutingBuffer
gctPOINTER entry;
gckOS os = Command->os;
gckKERNEL kernel = Command->kernel;
-#if gcdLINK_QUEUE_SIZE
gctINT pid;
- gctINT i, rear;
+ gctUINT32 i, rear;
gctUINT32 start, end;
gctUINT32 dumpFront, dumpRear;
gckLINKQUEUE queue = &kernel->hardware->linkQueue;
gckLINKQUEUE queueMirror;
gctUINT32 bytes;
gckLINKDATA linkData;
-#endif
gcmkPRINT("**************************\n");
gcmkPRINT("**** COMMAND BUF DUMP ****\n");
gcmkPRINT("DMA Address 0x%08X", gpuAddress);
-#if gcdLINK_QUEUE_SIZE
- /* Duplicate queue because it will be changed.*/
- gcmkONERROR(gckOS_AllocateMemory(os,
- sizeof(struct _gckLINKQUEUE),
- (gctPOINTER *)&queueMirror));
-
- gcmkONERROR(gckOS_MemCopy(queueMirror,
- queue,
- sizeof(struct _gckLINKQUEUE)));
-
- /* If kernel command buffer link to a context buffer, then link to a user command
- ** buffer, the second link will be in queue first, so we must fix this.
- ** In Queue: C1 U1 U2 C2 U3 U4 U5 C3
- ** Real: C1 X1 U1 C2 U2 U3 U4 C3 U5
- ** Command buffer X1 which is after C1 is out of queue, so C1 is meaningless.
- */
- for (i = 0; i < gcdLINK_QUEUE_SIZE; i++)
+ if (Command->kernel->stuckDump > gcdSTUCK_DUMP_MIDDLE)
{
- gckLINKQUEUE_GetData(queueMirror, i, &linkData);
+ gcmkPRINT("Dump Level is %d", Command->kernel->stuckDump);
- status = gckKERNEL_QueryGPUAddress(kernel, linkData->start, &buffer);
+ /* Duplicate queue because it will be changed.*/
+ gcmkONERROR(gckOS_AllocateMemory(os,
+ sizeof(struct _gckLINKQUEUE),
+ (gctPOINTER *)&queueMirror));
- if (gcmIS_ERROR(status))
- {
- /* Can't find it in virtual command buffer list, ignore it. */
- continue;
- }
+ gckOS_MemCopy(queueMirror,
+ queue,
+ sizeof(struct _gckLINKQUEUE));
- if (buffer->kernelLogical)
+ /* If kernel command buffer link to a context buffer, then link to a user command
+ ** buffer, the second link will be in queue first, so we must fix this.
+ ** In Queue: C1 U1 U2 C2 U3 U4 U5 C3
+ ** Real: C1 X1 U1 C2 U2 U3 U4 C3 U5
+ ** Command buffer X1 which is after C1 is out of queue, so C1 is meaningless.
+ */
+ for (i = 0; i < gcdLINK_QUEUE_SIZE; i++)
{
- /* It is a context buffer. */
- if (i == 0)
+ gckLINKQUEUE_GetData(queueMirror, i, &linkData);
+
+ status = gckKERNEL_QueryGPUAddress(kernel, linkData->start, &buffer);
+
+ if (gcmIS_ERROR(status))
{
- /* The real command buffer is out, so clear this slot. */
- linkData->start = 0;
- linkData->end = 0;
- linkData->pid = 0;
+ /* Can't find it in virtual command buffer list, ignore it. */
+ continue;
}
- else
+
+ if (buffer->kernelLogical)
{
- /* switch context buffer and command buffer. */
- struct _gckLINKDATA tmp = *linkData;
- gckLINKDATA linkDataPrevious;
-
- gckLINKQUEUE_GetData(queueMirror, i - 1, &linkDataPrevious);
- *linkData = *linkDataPrevious;
- *linkDataPrevious = tmp;
- }
+ /* It is a context buffer. */
+ if (i == 0)
+ {
+ /* The real command buffer is out, so clear this slot. */
+ linkData->start = 0;
+ linkData->end = 0;
+ linkData->pid = 0;
+ }
+ else
+ {
+ /* switch context buffer and command buffer. */
+ struct _gckLINKDATA tmp = *linkData;
+ gckLINKDATA linkDataPrevious;
+
+ gckLINKQUEUE_GetData(queueMirror, i - 1, &linkDataPrevious);
+ *linkData = *linkDataPrevious;
+ *linkDataPrevious = tmp;
+ }
+ }
}
- }
- /* Clear search result. */
- dumpFront = dumpRear = gcvINFINITE;
+ /* Clear search result. */
+ dumpFront = dumpRear = gcvINFINITE;
- gcmkPRINT("Link Stack:");
+ gcmkPRINT("Link Stack:");
- /* Search stuck address in link queue from rear. */
- rear = gcdLINK_QUEUE_SIZE - 1;
- for (i = 0; i < gcdLINK_QUEUE_SIZE; i++)
- {
- gckLINKQUEUE_GetData(queueMirror, rear, &linkData);
+ /* Search stuck address in link queue from rear. */
+ rear = gcdLINK_QUEUE_SIZE - 1;
+ for (i = 0; i < gcdLINK_QUEUE_SIZE; i++)
+ {
+ gckLINKQUEUE_GetData(queueMirror, rear, &linkData);
- start = linkData->start;
- end = linkData->end;
- pid = linkData->pid;
+ start = linkData->start;
+ end = linkData->end;
+ pid = linkData->pid;
- if (gpuAddress >= start && gpuAddress < end)
- {
- /* Find latest matched command buffer. */
- gcmkPRINT(" %d, [%08X - %08X]", pid, start, end);
+ if (gpuAddress >= start && gpuAddress < end)
+ {
+ /* Find latest matched command buffer. */
+ gcmkPRINT(" %d, [%08X - %08X]", pid, start, end);
- /* Initiliaze dump information. */
- dumpFront = dumpRear = rear;
- }
+ /* Initiliaze dump information. */
+ dumpFront = dumpRear = rear;
+ }
- /* Advance to previous one. */
- rear--;
+ /* Advance to previous one. */
+ rear--;
+
+ if (dumpFront != gcvINFINITE)
+ {
+ break;
+ }
+ }
- if (dumpFront != gcvINFINITE)
+ if (dumpFront == gcvINFINITE)
{
- break;
+ /* Can't find matched record in link queue, dump kernel command buffer. */
+ _DumpKernelCommandBuffer(Command);
+
+ /* Free local copy. */
+ gcmkOS_SAFE_FREE(os, queueMirror);
+ return gcvSTATUS_OK;
}
- }
- if (dumpFront == gcvINFINITE)
- {
- /* Can't find matched record in link queue, dump kernel command buffer. */
- _DumpKernelCommandBuffer(Command);
+ /* Search the last context buffer linked. */
+ while (rear > 0)
+ {
+ gckLINKQUEUE_GetData(queueMirror, rear, &linkData);
- /* Free local copy. */
- gcmkOS_SAFE_FREE(os, queueMirror);
- return gcvSTATUS_OK;
- }
+ gcmkPRINT(" %d, [%08X - %08X]",
+ linkData->pid,
+ linkData->start,
+ linkData->end);
- /* Search the last context buffer linked. */
- while (rear >= 0)
- {
- gckLINKQUEUE_GetData(queueMirror, rear, &linkData);
+ status = gckKERNEL_QueryGPUAddress(kernel, linkData->start, &buffer);
- gcmkPRINT(" %d, [%08X - %08X]",
- linkData->pid,
- linkData->start,
- linkData->end);
+ if (gcmIS_SUCCESS(status) && buffer->kernelLogical)
+ {
+ /* Find a context buffer. */
+ dumpFront = rear;
+ break;
+ }
- status = gckKERNEL_QueryGPUAddress(kernel, linkData->start, &buffer);
+ rear--;
+ }
- if (gcmIS_SUCCESS(status) && buffer->kernelLogical)
+ if (dumpFront == dumpRear)
{
- /* Find a context buffer. */
- dumpFront = rear;
- break;
+ /* No context buffer is found, dump all we got.*/
+ dumpFront = 0;
}
- rear--;
- }
-
- /* Dump from last context buffer to last command buffer where hang happens. */
- for (i = dumpFront; i <= dumpRear; i++)
- {
- gckLINKQUEUE_GetData(queueMirror, i, &linkData);
+ /* Dump from last context buffer to last command buffer where hang happens. */
+ for (i = dumpFront; i <= dumpRear; i++)
+ {
+ gckLINKQUEUE_GetData(queueMirror, i, &linkData);
- /* Get gpu address of this command buffer. */
- gpuAddress = linkData->start;
- bytes = linkData->end - gpuAddress;
+ /* Get gpu address of this command buffer. */
+ gpuAddress = linkData->start;
+ bytes = linkData->end - gpuAddress;
- /* Get the whole buffer. */
- status = gckKERNEL_QueryGPUAddress(kernel, gpuAddress, &buffer);
+ /* Get the whole buffer. */
+ status = gckKERNEL_QueryGPUAddress(kernel, gpuAddress, &buffer);
- if (gcmIS_ERROR(status))
- {
- gcmkPRINT("Buffer [%08X - %08X] is lost",
- linkData->start,
- linkData->end);
- continue;
- }
+ if (gcmIS_ERROR(status))
+ {
+ gcmkPRINT("Buffer [%08X - %08X] is lost or not belong to current process",
+ linkData->start,
+ linkData->end);
+ continue;
+ }
- /* Get kernel logical for dump. */
- if (buffer->kernelLogical)
- {
- /* Get kernel logical directly if it is a context buffer. */
- entry = buffer->kernelLogical;
- gcmkPRINT("Context Buffer:");
- }
- else
- {
- /* Make it accessiable by kernel if it is a user command buffer. */
- gcmkVERIFY_OK(
- gckOS_CreateKernelVirtualMapping(buffer->physical,
- &pageCount,
- &entry));
- gcmkPRINT("User Command Buffer:");
- }
+ /* Get kernel logical for dump. */
+ if (buffer->kernelLogical)
+ {
+ /* Get kernel logical directly if it is a context buffer. */
+ entry = buffer->kernelLogical;
+ gcmkPRINT("Context Buffer:");
+ }
+ else
+ {
+ /* Make it accessiable by kernel if it is a user command buffer. */
+ gcmkVERIFY_OK(
+ gckOS_CreateKernelVirtualMapping(os,
+ buffer->physical,
+ buffer->bytes,
+ &entry,
+ &pageCount));
+ gcmkPRINT("User Command Buffer:");
+ }
- /* Dump from the entry. */
- _DumpBuffer(entry + (gpuAddress - buffer->gpuAddress), gpuAddress, bytes);
+ /* Dump from the entry. */
+ _DumpBuffer((gctUINT8_PTR)entry + (gpuAddress - buffer->gpuAddress), gpuAddress, bytes);
- /* Release kernel logical address if neccessary. */
- if (!buffer->kernelLogical)
- {
- gcmkVERIFY_OK(gckOS_DestroyKernelVirtualMapping(entry));
+ /* Release kernel logical address if neccessary. */
+ if (!buffer->kernelLogical)
+ {
+ gcmkVERIFY_OK(
+ gckOS_DestroyKernelVirtualMapping(os,
+ buffer->physical,
+ buffer->bytes,
+ entry));
+ }
}
- }
- /* Free local copy. */
- gcmkOS_SAFE_FREE(os, queueMirror);
- return gcvSTATUS_OK;
-OnError:
- return status;
-#else
- /* Without link queue information, we don't know the entry of last command
- ** buffer, just dump the page where GPU stuck. */
- status = gckKERNEL_QueryGPUAddress(kernel, gpuAddress, &buffer);
-
- if (gcmIS_SUCCESS(status))
+ /* Free local copy. */
+ gcmkOS_SAFE_FREE(os, queueMirror);
+ return gcvSTATUS_OK;
+ OnError:
+ return status;
+ }
+ else
{
- gcmkVERIFY_OK(
- gckOS_CreateKernelVirtualMapping(buffer->physical, &pageCount, &entry));
+ gcmkPRINT("Dump Level is %d, dump memory near the stuck address",
+ Command->kernel->stuckDump);
- if (entry)
+ /* Without link queue information, we don't know the entry of last command
+ ** buffer, just dump the page where GPU stuck. */
+ status = gckKERNEL_QueryGPUAddress(kernel, gpuAddress, &buffer);
+
+ if (gcmIS_SUCCESS(status))
{
- gctUINT32 offset = gpuAddress - buffer->gpuAddress;
- gctPOINTER entryDump = entry;
+ gcmkVERIFY_OK(
+ gckOS_CreateKernelVirtualMapping(os,
+ buffer->physical,
+ buffer->bytes,
+ &entry,
+ &pageCount));
- /* Dump one pages. */
- gctUINT32 bytes = 4096;
+ if (entry)
+ {
+ gctUINT32 offset = gpuAddress - buffer->gpuAddress;
+ gctPOINTER entryDump = entry;
+
+ /* Dump one pages. */
+ gctUINT32 bytes = 4096;
- /* Align to page. */
- offset &= 0xfffff000;
+ /* Align to page. */
+ offset &= 0xfffff000;
- /* Kernel address of page where stall point stay. */
- entryDump += offset;
+ /* Kernel address of page where stall point stay. */
+ entryDump = (gctUINT8_PTR)entryDump + offset;
- /* Align to page. */
- gpuAddress &= 0xfffff000;
+ /* Align to page. */
+ gpuAddress &= 0xfffff000;
- gcmkPRINT("User Command Buffer:\n");
- _DumpBuffer(entryDump, gpuAddress, bytes);
+ gcmkPRINT("User Command Buffer:\n");
+ _DumpBuffer(entryDump, gpuAddress, bytes);
+ }
+
+ gcmkVERIFY_OK(
+ gckOS_DestroyKernelVirtualMapping(os,
+ buffer->physical,
+ buffer->bytes,
+ entry));
+ }
+ else
+ {
+ _DumpKernelCommandBuffer(Command);
}
- gcmkVERIFY_OK(
- gckOS_DestroyKernelVirtualMapping(entry));
+ return gcvSTATUS_OK;
}
- else
+}
+
+gceSTATUS
+gckCOMMAND_AddressInKernelCommandBuffer(
+ IN gckCOMMAND Command,
+ IN gctUINT32 Address,
+ OUT gctBOOL *In
+ )
+{
+ gctBOOL in = gcvFALSE;
+ gctINT i;
+
+ for (i = 0; i < gcdCOMMAND_QUEUES; i++)
{
- _DumpKernelCommandBuffer(Command);
+ if ((Address >= Command->queues[i].address)
+ && (Address < (Command->queues[i].address + Command->pageSize))
+ )
+ {
+ in = gcvTRUE;
+ break;
+ }
}
+ *In = in;
return gcvSTATUS_OK;
-#endif
}
-#endif
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
gcsTASK_CONTAINER_PTR next;
gcsTASK_CONTAINER_PTR merged;
- gctSIZE_T mergedSize;
+ gctUINT32 mergedSize;
/* Verify arguments. */
gcmkASSERT(Buffer != gcvNULL);
IN gcsTASK_HEADER_PTR Task
)
{
+ gceSTATUS status;
gcsTASK_PTR task = (gcsTASK_PTR)((gctUINT8_PTR)Task - sizeof(gcsTASK));
gcsTASK_FREE_VIDEO_MEMORY_PTR freeVideoMemory;
gcsTASK_UNLOCK_VIDEO_MEMORY_PTR unlockVideoMemory;
gctINT pid;
gctUINT32 size;
+ gctUINT32 handle;
+ gckKERNEL kernel = Command->kernel->kernel;
+ gckVIDMEM_NODE unlockNode = gcvNULL;
+ gckVIDMEM_NODE nodeObject = gcvNULL;
+ gceDATABASE_TYPE type;
/* Get the total size of all tasks. */
size = task->size;
case gcvTASK_FREE_VIDEO_MEMORY:
freeVideoMemory = (gcsTASK_FREE_VIDEO_MEMORY_PTR)Task;
+ handle = (gctUINT32)freeVideoMemory->node;
+
+ status = gckVIDMEM_HANDLE_Lookup(
+ Command->kernel->kernel,
+ pid,
+ handle,
+ &nodeObject);
+
+ if (gcmIS_ERROR(status))
+ {
+ return status;
+ }
+
+ gckVIDMEM_HANDLE_Dereference(kernel, pid, handle);
+ freeVideoMemory->node = gcmALL_TO_UINT32(nodeObject);
+
+ type = gcvDB_VIDEO_MEMORY
+ | (nodeObject->type << gcdDB_VIDEO_MEMORY_TYPE_SHIFT)
+ | (nodeObject->pool << gcdDB_VIDEO_MEMORY_POOL_SHIFT);
+
/* Remove record from process db. */
gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
Command->kernel->kernel,
pid,
- gcvDB_VIDEO_MEMORY,
- gcmUINT64_TO_PTR(freeVideoMemory->node)));
+ type,
+ gcmINT2PTR(handle)));
/* Advance to next task. */
size -= sizeof(gcsTASK_FREE_VIDEO_MEMORY);
gcvDB_VIDEO_MEMORY_LOCKED,
gcmUINT64_TO_PTR(unlockVideoMemory->node)));
+ handle = (gctUINT32)unlockVideoMemory->node;
+
+ status = gckVIDMEM_HANDLE_Lookup(
+ Command->kernel->kernel,
+ pid,
+ handle,
+ &unlockNode);
+
+ if (gcmIS_ERROR(status))
+ {
+ return status;
+ }
+
+ gckVIDMEM_HANDLE_Dereference(kernel, pid, handle);
+ unlockVideoMemory->node = gcmPTR_TO_UINT64(unlockNode);
+
/* Advance to next task. */
size -= sizeof(gcsTASK_UNLOCK_VIDEO_MEMORY);
Task = (gcsTASK_HEADER_PTR)(unlockVideoMemory + 1);
gctINT32 interrupt;
gctUINT8_PTR eventCommand;
+#ifdef __QNXNTO__
+ gcsTASK_PTR oldUserTask = gcvNULL;
+ gctPOINTER pointer;
+#endif
+
/* Nothing to schedule? */
if (TaskTable->size == 0)
{
/* Copy tasks. */
do
{
- gcsTASK_HEADER_PTR taskHeader = (gcsTASK_HEADER_PTR) (userTask + 1);
+ gcsTASK_HEADER_PTR taskHeader;
+
+#ifdef __QNXNTO__
+ oldUserTask = userTask;
+
+ gcmkERR_BREAK(gckOS_MapUserPointer(
+ Command->os,
+ oldUserTask,
+ 0,
+ &pointer));
+
+ userTask = pointer;
+#endif
+
+ taskHeader = (gcsTASK_HEADER_PTR) (userTask + 1);
gcmkVERIFY_OK(_RemoveRecordFromProcesDB(Command, taskHeader));
((gcsTASK_SIGNAL_PTR)taskHeader)->coid = TaskTable->coid;
((gcsTASK_SIGNAL_PTR)taskHeader)->rcvid = TaskTable->rcvid;
}
-#endif /* __QNXNTO__ */
+#endif
+
/* Copy the task data. */
gcmkVERIFY_OK(gckOS_MemCopy(
kernelTask, taskHeader, userTask->size
/* Advance to the next task. */
kernelTask += userTask->size;
userTask = userTask->next;
+
+#ifdef __QNXNTO__
+ gcmkERR_BREAK(gckOS_UnmapUserPointer(
+ Command->os,
+ oldUserTask,
+ 0,
+ pointer));
+#endif
}
while (userTask != gcvNULL);
gceSTATUS status;
gckVIDMEM memory;
gctUINT32 offset;
-#if gcdDYNAMIC_MAP_RESERVED_MEMORY
gctUINT32 nodePhysical;
-#endif
+ gctPOINTER *logical;
+ gctSIZE_T bytes;
status = gcvSTATUS_OK;
- /* Assume a non-virtual node and get the pool manager object. */
+
memory = Node->VidMem.memory;
-#if gcdDYNAMIC_MAP_RESERVED_MEMORY
- nodePhysical = memory->baseAddress
- + Node->VidMem.offset
- + Node->VidMem.alignment;
+ if (memory->object.type == gcvOBJ_VIDMEM)
+ {
+ nodePhysical = memory->baseAddress
+ + (gctUINT32)Node->VidMem.offset
+ + Node->VidMem.alignment;
+ bytes = Node->VidMem.bytes;
+ logical = &Node->VidMem.kernelVirtual;
+ }
+ else
+ {
+ nodePhysical = Node->Virtual.physicalAddress;
+ bytes = Node->Virtual.bytes;
+ logical = &Node->Virtual.kernelVirtual;
+ }
- if (Node->VidMem.kernelVirtual == gcvNULL)
+ if (*logical == gcvNULL)
{
- status = gckOS_MapPhysical(Os,
- nodePhysical,
- Node->VidMem.bytes,
- (gctPOINTER *)&Node->VidMem.kernelVirtual);
+ status = gckOS_MapPhysical(Os, nodePhysical, bytes, logical);
if (gcmkIS_ERROR(status))
{
}
offset = Address - nodePhysical;
- *KernelPointer = (gctPOINTER)((gctUINT8_PTR)Node->VidMem.kernelVirtual + offset);
-#else
- /* Determine the header offset within the pool it is allocated in. */
- offset = Address - memory->baseAddress;
-
- /* Translate the offset into the kernel side pointer. */
- status = gckOS_GetKernelLogicalEx(
- Os,
- gcvCORE_VG,
- offset,
- KernelPointer
- );
-#endif
+ *KernelPointer = (gctPOINTER)((gctUINT8_PTR)(*logical) + offset);
/* Return status. */
return status;
{
gceSTATUS status, last;
gcsCMDBUFFER_PTR mappedUserCommandBuffer = gcvNULL;
+ gckKERNEL kernel = Command->kernel->kernel;
+ gctUINT32 pid;
+ gckVIDMEM_NODE node;
+
+ gckOS_GetProcessID(&pid);
do
{
= mappedUserCommandBuffer->address
- mappedUserCommandBuffer->bufferOffset;
+ gcmkERR_BREAK(gckVIDMEM_HANDLE_Lookup(
+ kernel,
+ pid,
+ gcmPTR2INT32(mappedUserCommandBuffer->node),
+ &node));
+
/* Translate the logical address to the kernel space. */
gcmkERR_BREAK(_HardwareToKernel(
Command->os,
- gcmUINT64_TO_PTR(mappedUserCommandBuffer->node),
+ node->node,
headerAddress,
(gctPOINTER *) KernelCommandBuffer
));
)
{
gceSTATUS status, last;
- gcuVIDMEM_NODE_PTR node = gcvNULL;
- gctUINT32 address = (gctUINT32)~0;
+ gctPOINTER logical;
+ gctPHYS_ADDR physical;
+ gctUINT32 address;
+ gctSIZE_T size = Size;
do
{
- gcePOOL pool;
- gctPOINTER logical;
-
- /* Allocate from the system pool. */
- pool = gcvPOOL_SYSTEM;
-
- /* Allocate memory. */
- gcmkERR_BREAK(gckKERNEL_AllocateLinearMemory(
- Command->kernel->kernel, &pool,
- Size, Alignment,
- gcvSURF_TYPE_UNKNOWN,
- &node
- ));
-
- /* Do not accept virtual pools for now because we don't handle the
- kernel pointer translation at the moment. */
- if (pool == gcvPOOL_VIRTUAL)
- {
- status = gcvSTATUS_OUT_OF_MEMORY;
- break;
- }
-
- /* Lock the command buffer. */
- gcmkERR_BREAK(gckVIDMEM_Lock(
- Command->kernel->kernel,
- node,
- gcvFALSE,
- &address
- ));
-
- /* Translate the logical address to the kernel space. */
- gcmkERR_BREAK(_HardwareToKernel(
+ gcmkERR_BREAK(gckOS_AllocateContiguous(
Command->os,
- node,
- address,
+ gcvFALSE,
+ &size,
+ &physical,
&logical
));
+ gcmkERR_BREAK(gckOS_GetPhysicalAddress(Command->os, logical, &address));
+
/* Set return values. */
- * Node = node;
+ * Node = physical;
* Address = address;
* Logical = logical;
while (gcvFALSE);
/* Roll back. */
- if (node != gcvNULL)
+ if (physical != gcvNULL)
{
- /* Unlock the command buffer. */
- if (address != ~0)
- {
- gcmkCHECK_STATUS(gckVIDMEM_Unlock(
- Command->kernel->kernel, node, gcvSURF_TYPE_UNKNOWN, gcvNULL
- ));
- }
-
/* Free the command buffer. */
- gcmkCHECK_STATUS(gckVIDMEM_Free(
- node
- ));
+ gcmkCHECK_STATUS(gckOS_FreeContiguous(Command->os, physical, logical, size));
}
/* Return status. */
static gceSTATUS
_FreeLinear(
IN gckVGKERNEL Kernel,
- IN gcuVIDMEM_NODE_PTR Node
+ IN gcuVIDMEM_NODE_PTR Node,
+ IN gctPOINTER Logical
)
{
- gceSTATUS status;
+ gceSTATUS status = gcvSTATUS_OK;
do
{
- /* Unlock the linear buffer. */
- gcmkERR_BREAK(gckVIDMEM_Unlock(Kernel->kernel, Node, gcvSURF_TYPE_UNKNOWN, gcvNULL));
-
- /* Free the linear buffer. */
- gcmkERR_BREAK(gckVIDMEM_Free(Node));
+ gcmkERR_BREAK(gckOS_FreeContiguous(Kernel->os, Node, Logical, 1));
}
while (gcvFALSE);
{
gceSTATUS status, last;
gcuVIDMEM_NODE_PTR node = gcvNULL;
+ gcsCMDBUFFER_PTR commandBuffer = gcvNULL;
do
{
gctUINT requestedSize;
gctUINT allocationSize;
gctUINT32 address = 0;
- gcsCMDBUFFER_PTR commandBuffer;
gctUINT8_PTR endCommand;
/* Determine the aligned header size. */
alignedHeaderSize
- = gcmALIGN(gcmSIZEOF(gcsCMDBUFFER), Command->info.addressAlignment);
+ = (gctUINT32)gcmALIGN(gcmSIZEOF(gcsCMDBUFFER), Command->info.addressAlignment);
/* Align the requested size. */
requestedSize
- = gcmALIGN(Size, Command->info.commandAlignment);
+ = (gctUINT32)gcmALIGN(Size, Command->info.commandAlignment);
/* Determine the size of the buffer to allocate. */
allocationSize
= alignedHeaderSize
+ requestedSize
- + Command->info.staticTailSize;
+ + (gctUINT32)Command->info.staticTailSize;
/* Allocate the command buffer. */
gcmkERR_BREAK(_AllocateLinear(
/* Initialize the structure. */
commandBuffer->completion = gcvVACANT_BUFFER;
- commandBuffer->node = gcmPTR_TO_UINT64(node);
+ commandBuffer->node = node;
commandBuffer->address = address + alignedHeaderSize;
commandBuffer->bufferOffset = alignedHeaderSize;
commandBuffer->size = requestedSize;
if (node != gcvNULL)
{
/* Free the command buffer. */
- gcmkCHECK_STATUS(_FreeLinear(Command->kernel, node));
+ gcmkCHECK_STATUS(_FreeLinear(Command->kernel, node, commandBuffer));
}
/* Return status. */
gceSTATUS status;
/* Free the buffer. */
- status = _FreeLinear(Kernel, gcmUINT64_TO_PTR(CommandBuffer->node));
+ status = _FreeLinear(Kernel, CommandBuffer->node, CommandBuffer);
/* Return status. */
return status;
/* Unlock video memory. */
gcmkERR_BREAK(gckVIDMEM_Unlock(
Command->kernel->kernel,
- gcmUINT64_TO_PTR(task->node),
+ (gckVIDMEM_NODE)gcmUINT64_TO_PTR(task->node),
gcvSURF_TYPE_UNKNOWN,
gcvNULL));
+ gcmkERR_BREAK(gckVIDMEM_NODE_Dereference(
+ Command->kernel->kernel,
+ gcmUINT64_TO_PTR(task->node)));
+
/* Update the reference counter. */
TaskHeader->container->referenceCount -= 1;
= (gcsTASK_FREE_VIDEO_MEMORY_PTR) TaskHeader->task;
/* Free video memory. */
- gcmkERR_BREAK(gckVIDMEM_Free(gcmUINT64_TO_PTR(task->node)));
+ gcmkERR_BREAK(gckVIDMEM_NODE_Dereference(
+ Command->kernel->kernel,
+ gcmINT2PTR(task->node)));
/* Update the reference counter. */
TaskHeader->container->referenceCount -= 1;
)
{
gceSTATUS status;
+ gctPOINTER info;
do
{
gcsTASK_UNMAP_USER_MEMORY_PTR task
= (gcsTASK_UNMAP_USER_MEMORY_PTR) TaskHeader->task;
+ info = gckKERNEL_QueryPointerFromName(
+ Command->kernel->kernel, gcmALL_TO_UINT32(task->info));
+
/* Unmap the user memory. */
gcmkERR_BREAK(gckOS_UnmapUserMemory(
- Command->os, gcvCORE_VG, task->memory, task->size, task->info, task->address
+ Command->os, gcvCORE_VG, task->memory, task->size, info, task->address
));
/* Update the reference counter. */
IN gctBOOL ProcessAll
)
{
- gceSTATUS status, last;
+ gceSTATUS status = gcvSTATUS_OK, last;
gcmkHEADER_ARG("Kernel=0x%x TaskHeader=0x%x ProcessAll=0x%x", Kernel, TaskHeader, ProcessAll);
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ if (TaskHeader->task == gcvNULL)
+ {
+ gcmkFOOTER();
+ return gcvSTATUS_OK;
+ }
+
do
{
gckVGCOMMAND command;
gceSTATUS status, last;
+#ifdef __QNXNTO__
+ gcsVGCONTEXT_PTR userContext = gcvNULL;
+ gctBOOL userContextMapped = gcvFALSE;
+ gcsTASK_MASTER_TABLE_PTR userTaskTable = gcvNULL;
+ gctBOOL userTaskTableMapped = gcvFALSE;
+ gctPOINTER pointer = gcvNULL;
+#endif
+
gcmkHEADER_ARG("Command=0x%x Context=0x%x Queue=0x%x EntryCount=0x%x TaskTable=0x%x",
Command, Context, Queue, EntryCount, TaskTable);
gcmkVERIFY_ARGUMENT(Queue != gcvNULL);
gcmkVERIFY_ARGUMENT(EntryCount > 1);
-#ifdef __QNXNTO__
- TaskTable->coid = Context->coid;
- TaskTable->rcvid = Context->rcvid;
-#endif /* __QNXNTO__ */
-
do
{
gctBOOL haveFETasks;
gctBOOL previousExecuted;
gctUINT controlIndex;
+#ifdef __QNXNTO__
+ /* Map the context into the kernel space. */
+ userContext = Context;
+
+ gcmkERR_BREAK(gckOS_MapUserPointer(
+ Command->os,
+ userContext,
+ gcmSIZEOF(*userContext),
+ &pointer));
+
+ Context = pointer;
+
+ userContextMapped = gcvTRUE;
+
+ /* Map the taskTable into the kernel space. */
+ userTaskTable = TaskTable;
+
+ gcmkERR_BREAK(gckOS_MapUserPointer(
+ Command->os,
+ userTaskTable,
+ gcmSIZEOF(*userTaskTable),
+ &pointer));
+
+ TaskTable = pointer;
+
+ userTaskTableMapped = gcvTRUE;
+
+ /* Update the signal info. */
+ TaskTable->coid = Context->coid;
+ TaskTable->rcvid = Context->rcvid;
+#endif
+
gcmkERR_BREAK(gckVGHARDWARE_SetPowerManagementState(
Command->hardware, gcvPOWER_ON_AUTO
));
}
while (gcvFALSE);
+#ifdef __QNXNTO__
+ if (userContextMapped)
+ {
+ /* Unmap the user context. */
+ gcmkVERIFY_OK(gckOS_UnmapUserPointer(
+ Command->os,
+ userContext,
+ gcmSIZEOF(*userContext),
+ Context));
+ }
+
+ if (userTaskTableMapped)
+ {
+ /* Unmap the user taskTable. */
+ gcmkVERIFY_OK(gckOS_UnmapUserPointer(
+ Command->os,
+ userTaskTable,
+ gcmSIZEOF(*userTaskTable),
+ TaskTable));
+ }
+#endif
+
gcmkFOOTER();
/* Return status. */
return status;
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
***** Private fuctions ********************************************************/
#define _GetSlot(database, x) \
- (gctUINT32)(((gcmPTR_TO_UINT64(x) >> 7) % gcmCOUNTOF(database->list)))
+ (gctUINT32)(gcmPTR_TO_UINT64(x) % gcmCOUNTOF(database->list))
/*******************************************************************************
** gckKERNEL_NewDatabase
gcmSIZEOF(gcsDATABASE),
&pointer));
+ gckOS_ZeroMemory(pointer, gcmSIZEOF(gcsDATABASE));
+
database = pointer;
+
+ gcmkONERROR(gckOS_CreateMutex(Kernel->os, &database->counterMutex));
}
/* Insert the database into the hash. */
** Pointer to a variable receiving the database structure pointer on
** success.
*/
-static gceSTATUS
+gceSTATUS
gckKERNEL_FindDatabase(
IN gckKERNEL Kernel,
IN gctUINT32 ProcessID,
/* Keep database as the last database. */
Kernel->db->lastDatabase = Database;
+ /* Destory handle db. */
+ gcmkVERIFY_OK(gckKERNEL_DestroyIntegerDatabase(Kernel, Database->handleDatabase));
+ Database->handleDatabase = gcvNULL;
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Database->handleDatabaseMutex));
+ Database->handleDatabaseMutex = gcvNULL;
+
+#if gcdPROCESS_ADDRESS_SPACE
+ /* Destory process MMU. */
+ gcmkVERIFY_OK(gckEVENT_DestroyMmu(Kernel->eventObj, Database->mmu, gcvKERNEL_PIXEL));
+ Database->mmu = gcvNULL;
+#endif
+
/* Release the database mutex. */
gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
acquired = gcvTRUE;
-
/* Scan the database for this record. */
for (record = Database->list[slot], previous = gcvNULL;
record != gcvNULL;
return status;
}
-
/*******************************************************************************
***** Public API **************************************************************/
database->mapUserMemory.bytes = 0;
database->mapUserMemory.maxBytes = 0;
database->mapUserMemory.totalBytes = 0;
- database->vidMemResv.bytes = 0;
- database->vidMemResv.maxBytes = 0;
- database->vidMemResv.totalBytes = 0;
- database->vidMemCont.bytes = 0;
- database->vidMemCont.maxBytes = 0;
- database->vidMemCont.totalBytes = 0;
- database->vidMemVirt.bytes = 0;
- database->vidMemVirt.maxBytes = 0;
- database->vidMemVirt.totalBytes = 0;
+ database->virtualCommandBuffer.bytes = 0;
+ database->virtualCommandBuffer.maxBytes = 0;
+ database->virtualCommandBuffer.totalBytes = 0;
for (i = 0; i < gcmCOUNTOF(database->list); i++)
{
database->list[i] = gcvNULL;
}
+ for (i = 0; i < gcvSURF_NUM_TYPES; i++)
+ {
+ database->vidMemType[i].bytes = 0;
+ database->vidMemType[i].maxBytes = 0;
+ database->vidMemType[i].totalBytes = 0;
+ }
+
+ for (i = 0; i < gcvPOOL_NUMBER_OF_POOLS; i++)
+ {
+ database->vidMemPool[i].bytes = 0;
+ database->vidMemPool[i].maxBytes = 0;
+ database->vidMemPool[i].totalBytes = 0;
+ }
+
+ gcmkASSERT(database->handleDatabase == gcvNULL);
+ gcmkONERROR(
+ gckKERNEL_CreateIntegerDatabase(Kernel, &database->handleDatabase));
+
+ gcmkASSERT(database->handleDatabaseMutex == gcvNULL);
+ gcmkONERROR(
+ gckOS_CreateMutex(Kernel->os, &database->handleDatabaseMutex));
+
+#if gcdPROCESS_ADDRESS_SPACE
+ gcmkASSERT(database->mmu == gcvNULL);
+ gcmkONERROR(
+ gckMMU_Construct(Kernel, gcdMMU_SIZE, &database->mmu));
+#endif
+
#if gcdSECURE_USER
{
gctINT slot;
gcsDATABASE_PTR database;
gcsDATABASE_RECORD_PTR record = gcvNULL;
gcsDATABASE_COUNTERS * count;
+ gctUINT32 vidMemType;
+ gcePOOL vidMemPool;
gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x "
"Physical=0x%x Size=%lu",
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ /* Decode type. */
+ vidMemType = (Type & gcdDB_VIDEO_MEMORY_TYPE_MASK) >> gcdDB_VIDEO_MEMORY_TYPE_SHIFT;
+ vidMemPool = (Type & gcdDB_VIDEO_MEMORY_POOL_MASK) >> gcdDB_VIDEO_MEMORY_POOL_SHIFT;
+
+ Type &= gcdDATABASE_TYPE_MASK;
+
/* Special case the idle record. */
if (Type == gcvDB_IDLE)
{
count = &database->mapUserMemory;
break;
- case gcvDB_VIDEO_MEMORY_RESERVED:
- count = &database->vidMemResv;
- break;
-
- case gcvDB_VIDEO_MEMORY_CONTIGUOUS:
- count = &database->vidMemCont;
- break;
-
- case gcvDB_VIDEO_MEMORY_VIRTUAL:
- count = &database->vidMemVirt;
+ case gcvDB_COMMAND_BUFFER:
+ count = &database->virtualCommandBuffer;
break;
default:
break;
}
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, database->counterMutex, gcvINFINITE));
+
if (count != gcvNULL)
{
/* Adjust counters. */
}
}
+ if (Type == gcvDB_VIDEO_MEMORY)
+ {
+ count = &database->vidMemType[vidMemType];
+
+ /* Adjust counters. */
+ count->totalBytes += Size;
+ count->bytes += Size;
+
+ if (count->bytes > count->maxBytes)
+ {
+ count->maxBytes = count->bytes;
+ }
+
+ count = &database->vidMemPool[vidMemPool];
+
+ /* Adjust counters. */
+ count->totalBytes += Size;
+ count->bytes += Size;
+
+ if (count->bytes > count->maxBytes)
+ {
+ count->maxBytes = count->bytes;
+ }
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, database->counterMutex));
+
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
gceSTATUS status;
gcsDATABASE_PTR database;
gctSIZE_T bytes = 0;
+ gctUINT32 vidMemType;
+ gcePOOL vidMempool;
gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x",
Kernel, ProcessID, Type, Pointer);
gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
+ /* Decode type. */
+ vidMemType = (Type & gcdDB_VIDEO_MEMORY_TYPE_MASK) >> gcdDB_VIDEO_MEMORY_TYPE_SHIFT;
+ vidMempool = (Type & gcdDB_VIDEO_MEMORY_POOL_MASK) >> gcdDB_VIDEO_MEMORY_POOL_SHIFT;
+
+ Type &= gcdDATABASE_TYPE_MASK;
+
/* Find the database. */
gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
gcmkONERROR(
gckKERNEL_DeleteRecord(Kernel, database, Type, Pointer, &bytes));
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, database->counterMutex, gcvINFINITE));
+
/* Update counters. */
switch (Type)
{
case gcvDB_VIDEO_MEMORY:
database->vidMem.bytes -= bytes;
+ database->vidMemType[vidMemType].bytes -= bytes;
+ database->vidMemPool[vidMempool].bytes -= bytes;
break;
case gcvDB_NON_PAGED:
database->mapUserMemory.bytes -= bytes;
break;
- case gcvDB_VIDEO_MEMORY_RESERVED:
- database->vidMemResv.bytes -= bytes;
- break;
-
- case gcvDB_VIDEO_MEMORY_CONTIGUOUS:
- database->vidMemCont.bytes -= bytes;
- break;
-
- case gcvDB_VIDEO_MEMORY_VIRTUAL:
- database->vidMemVirt.bytes -= bytes;
+ case gcvDB_COMMAND_BUFFER:
+ database->virtualCommandBuffer.bytes -= bytes;
break;
default:
break;
}
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, database->counterMutex));
+
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
gceSTATUS status;
gcsDATABASE_PTR database;
gcsDATABASE_RECORD_PTR record, next;
- gctBOOL asynchronous;
+ gctBOOL asynchronous = gcvTRUE;
+ gckVIDMEM_NODE nodeObject;
gctPHYS_ADDR physical;
- gcuVIDMEM_NODE_PTR node;
gckKERNEL kernel = Kernel;
+ gctUINT32 handle;
gctUINT32 i;
gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
switch (record->type)
{
case gcvDB_VIDEO_MEMORY:
+ gcmkERR_BREAK(gckVIDMEM_HANDLE_Lookup(record->kernel,
+ ProcessID,
+ gcmPTR2INT32(record->data),
+ &nodeObject));
+
/* Free the video memory. */
- status = gckVIDMEM_Free(gcmUINT64_TO_PTR(record->data));
+ gcmkVERIFY_OK(gckVIDMEM_HANDLE_Dereference(record->kernel,
+ ProcessID,
+ gcmPTR2INT32(record->data)));
+
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(record->kernel,
+ nodeObject));
gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
"DB: VIDEO_MEMORY 0x%x (status=%d)",
record->data);
/* Free the non paged memory. */
- status = gckOS_FreeNonPagedMemory(Kernel->os,
- record->bytes,
- physical,
- record->data);
+ status = gckEVENT_FreeNonPagedMemory(Kernel->eventObj,
+ record->bytes,
+ physical,
+ record->data,
+ gcvKERNEL_PIXEL);
gcmRELEASE_NAME(record->physical);
gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
record->data, record->bytes, status);
break;
-#if gcdVIRTUAL_COMMAND_BUFFER
case gcvDB_COMMAND_BUFFER:
/* Free the command buffer. */
status = gckEVENT_DestroyVirtualCommandBuffer(record->kernel->eventObj,
"DB: COMMAND_BUFFER 0x%x, bytes=%lu (status=%d)",
record->data, record->bytes, status);
break;
-#endif
case gcvDB_CONTIGUOUS:
physical = gcmNAME_TO_PTR(record->physical);
#else
/* Free the user signal. */
status = gckOS_DestroyUserSignal(Kernel->os,
- gcmPTR2INT(record->data));
+ gcmPTR2INT32(record->data));
#endif /* USE_NEW_LINUX_SIGNAL */
gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
break;
case gcvDB_VIDEO_MEMORY_LOCKED:
- node = gcmUINT64_TO_PTR(record->data);
+ handle = gcmPTR2INT32(record->data);
+
+ gcmkERR_BREAK(gckVIDMEM_HANDLE_Lookup(record->kernel,
+ ProcessID,
+ handle,
+ &nodeObject));
+
/* Unlock what we still locked */
status = gckVIDMEM_Unlock(record->kernel,
- node,
- gcvSURF_TYPE_UNKNOWN,
+ nodeObject,
+ nodeObject->type,
&asynchronous);
- if (gcmIS_SUCCESS(status) && (gcvTRUE == asynchronous))
+#if gcdENABLE_VG
+ if (record->kernel->core == gcvCORE_VG)
+ {
+ if (gcmIS_SUCCESS(status) && (gcvTRUE == asynchronous))
+ {
+ /* TODO: we maybe need to schedule a event here */
+ status = gckVIDMEM_Unlock(record->kernel,
+ nodeObject,
+ nodeObject->type,
+ gcvNULL);
+ }
+
+ gcmkVERIFY_OK(gckVIDMEM_HANDLE_Dereference(record->kernel,
+ ProcessID,
+ handle));
+
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(record->kernel,
+ nodeObject));
+ }
+ else
+#endif
{
- /* TODO: we maybe need to schedule a event here */
- status = gckVIDMEM_Unlock(record->kernel,
- node,
- gcvSURF_TYPE_UNKNOWN,
- gcvNULL);
+ gcmkVERIFY_OK(gckVIDMEM_HANDLE_Dereference(record->kernel,
+ ProcessID,
+ handle));
+
+ if (gcmIS_SUCCESS(status) && (gcvTRUE == asynchronous))
+ {
+ status = gckEVENT_Unlock(record->kernel->eventObj,
+ gcvKERNEL_PIXEL,
+ nodeObject,
+ nodeObject->type);
+ }
+ else
+ {
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(record->kernel,
+ nodeObject));
+ }
}
gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
"DB: VIDEO_MEMORY_LOCKED 0x%x (status=%d)",
- node, status);
+ record->data, status);
break;
case gcvDB_CONTEXT:
gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
"DB: MAP MEMORY %d (status=%d)",
- gcmPTR2INT(record->data), status);
+ gcmPTR2INT32(record->data), status);
break;
case gcvDB_MAP_USER_MEMORY:
gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
"DB: MAP USER MEMORY %d (status=%d)",
- gcmPTR2INT(record->data), status);
- break;
-
- case gcvDB_SHARED_INFO:
- status = gckOS_FreeMemory(Kernel->os, record->physical);
+ gcmPTR2INT32(record->data), status);
break;
#if gcdANDROID_NATIVE_FENCE_SYNC
break;
#endif
- case gcvDB_VIDEO_MEMORY_RESERVED:
- case gcvDB_VIDEO_MEMORY_CONTIGUOUS:
- case gcvDB_VIDEO_MEMORY_VIRTUAL:
- break;//Nothing to do
+ case gcvDB_SHBUF:
+ /* Free shared buffer. */
+ status = gckKERNEL_DestroyShBuffer(Kernel,
+ (gctSHBUF) record->data);
+
+ gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
+ "DB: SHBUF %u (status=%d)",
+ (gctUINT32)(gctUINTPTR_T) record->data, status);
+ break;
default:
gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DATABASE,
{
gceSTATUS status;
gcsDATABASE_PTR database;
+ gcePOOL vidMemPool;
gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Info=0x%x",
Kernel, ProcessID, Type, Info);
gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
gcmkVERIFY_ARGUMENT(Info != gcvNULL);
- /* Find the database. */
- gcmkONERROR(
- gckKERNEL_FindDatabase(Kernel, ProcessID, LastProcessID, &database));
+ /* Deocde pool. */
+ vidMemPool = (Type & gcdDB_VIDEO_MEMORY_POOL_MASK) >> gcdDB_VIDEO_MEMORY_POOL_SHIFT;
- /* Get pointer to counters. */
- switch (Type)
+ Type &= gcdDATABASE_TYPE_MASK;
+
+ /* Find the database. */
+ if(Type != gcvDB_IDLE)
{
- case gcvDB_VIDEO_MEMORY:
- gckOS_MemCopy(&Info->counters,
- &database->vidMem,
- gcmSIZEOF(database->vidMem));
- break;
+ gcmkONERROR(
+ gckKERNEL_FindDatabase(Kernel, ProcessID, LastProcessID, &database));
- case gcvDB_NON_PAGED:
- gckOS_MemCopy(&Info->counters,
- &database->nonPaged,
- gcmSIZEOF(database->vidMem));
- break;
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, database->counterMutex, gcvINFINITE));
- case gcvDB_CONTIGUOUS:
- gckOS_MemCopy(&Info->counters,
- &database->contiguous,
- gcmSIZEOF(database->vidMem));
- break;
+ /* Get pointer to counters. */
+ switch (Type)
+ {
+ case gcvDB_VIDEO_MEMORY:
+ if (vidMemPool != gcvPOOL_UNKNOWN)
+ {
+ gckOS_MemCopy(&Info->counters,
+ &database->vidMemPool[vidMemPool],
+ gcmSIZEOF(database->vidMemPool[vidMemPool]));
+ }
+ else
+ {
+ gckOS_MemCopy(&Info->counters,
+ &database->vidMem,
+ gcmSIZEOF(database->vidMem));
+ }
+ break;
- case gcvDB_IDLE:
+ case gcvDB_NON_PAGED:
+ gckOS_MemCopy(&Info->counters,
+ &database->nonPaged,
+ gcmSIZEOF(database->vidMem));
+ break;
+
+ case gcvDB_CONTIGUOUS:
+ gckOS_MemCopy(&Info->counters,
+ &database->contiguous,
+ gcmSIZEOF(database->vidMem));
+ break;
+
+ case gcvDB_MAP_MEMORY:
+ gckOS_MemCopy(&Info->counters,
+ &database->mapMemory,
+ gcmSIZEOF(database->mapMemory));
+ break;
+
+ case gcvDB_MAP_USER_MEMORY:
+ gckOS_MemCopy(&Info->counters,
+ &database->mapUserMemory,
+ gcmSIZEOF(database->mapUserMemory));
+ break;
+
+ case gcvDB_COMMAND_BUFFER:
+ gckOS_MemCopy(&Info->counters,
+ &database->virtualCommandBuffer,
+ gcmSIZEOF(database->virtualCommandBuffer));
+ break;
+
+ default:
+ break;
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, database->counterMutex));
+ }
+ else
+ {
Info->time = Kernel->db->idleTime;
Kernel->db->idleTime = 0;
- break;
+ }
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
- case gcvDB_MAP_MEMORY:
- gckOS_MemCopy(&Info->counters,
- &database->mapMemory,
- gcmSIZEOF(database->mapMemory));
- break;
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
- case gcvDB_MAP_USER_MEMORY:
- gckOS_MemCopy(&Info->counters,
- &database->mapUserMemory,
- gcmSIZEOF(database->mapUserMemory));
- break;
+gceSTATUS
+gckKERNEL_FindHandleDatbase(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ OUT gctPOINTER * HandleDatabase,
+ OUT gctPOINTER * HandleDatabaseMutex
+ )
+{
+ gceSTATUS status;
+ gcsDATABASE_PTR database;
- case gcvDB_VIDEO_MEMORY_RESERVED:
- gckOS_MemCopy(&Info->counters,
- &database->vidMemResv,
- gcmSIZEOF(database->vidMemResv));
- break;
+ gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d",
+ Kernel, ProcessID);
- case gcvDB_VIDEO_MEMORY_CONTIGUOUS:
- gckOS_MemCopy(&Info->counters,
- &database->vidMemCont,
- gcmSIZEOF(database->vidMemCont));
- break;
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
- case gcvDB_VIDEO_MEMORY_VIRTUAL:
- gckOS_MemCopy(&Info->counters,
- &database->vidMemVirt,
- gcmSIZEOF(database->vidMemVirt));
- break;
+ /* Find the database. */
+ gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
- default:
- break;
- }
+ *HandleDatabase = database->handleDatabase;
+ *HandleDatabaseMutex = database->handleDatabaseMutex;
/* Success. */
gcmkFOOTER_NO();
return status;
}
+#if gcdPROCESS_ADDRESS_SPACE
+gceSTATUS
+gckKERNEL_GetProcessMMU(
+ IN gckKERNEL Kernel,
+ OUT gckMMU * Mmu
+ )
+{
+ gceSTATUS status;
+ gcsDATABASE_PTR database;
+ gctUINT32 processID;
+
+ gcmkONERROR(gckOS_GetProcessID(&processID));
+
+ gcmkONERROR(gckKERNEL_FindDatabase(Kernel, processID, gcvFALSE, &database));
+
+ *Mmu = database->mmu;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+#endif
+
#if gcdSECURE_USER
/*******************************************************************************
** gckKERNEL_GetProcessDBCache
gcmkFOOTER_NO();
return gcvSTATUS_OK;
}
+
+void
+_DumpCounter(
+ IN gcsDATABASE_COUNTERS * Counter,
+ IN gctCONST_STRING Name
+ )
+{
+ gcmkPRINT("%s:", Name);
+ gcmkPRINT(" Currently allocated : %10lld", Counter->bytes);
+ gcmkPRINT(" Maximum allocated : %10lld", Counter->maxBytes);
+ gcmkPRINT(" Total allocated : %10lld", Counter->totalBytes);
+}
+
+gceSTATUS
+gckKERNEL_DumpVidMemUsage(
+ IN gckKERNEL Kernel,
+ IN gctINT32 ProcessID
+ )
+{
+ gceSTATUS status;
+ gcsDATABASE_PTR database;
+ gcsDATABASE_COUNTERS * counter;
+ gctUINT32 i = 0;
+
+ static gctCONST_STRING surfaceTypes[] = {
+ "UNKNOWN",
+ "INDEX",
+ "VERTEX",
+ "TEXTURE",
+ "RENDER_TARGET",
+ "DEPTH",
+ "BITMAP",
+ "TILE_STATUS",
+ "IMAGE",
+ "MASK",
+ "SCISSOR",
+ "HIERARCHICAL_DEPTH",
+ };
+
+ gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d",
+ Kernel, ProcessID);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+
+ /* Find the database. */
+ gcmkONERROR(
+ gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
+
+ gcmkPRINT("VidMem Usage (Process %d):", ProcessID);
+
+ /* Get pointer to counters. */
+ counter = &database->vidMem;
+
+ _DumpCounter(counter, "Total Video Memory");
+
+ for (i = 0; i < gcvSURF_NUM_TYPES; i++)
+ {
+ counter = &database->vidMemType[i];
+
+ _DumpCounter(counter, surfaceTypes[i]);
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#define gcmPTRALIGNMENT(Pointer, Alignemnt) \
( \
- gcmALIGN(gcmPTR2INT(Pointer), Alignemnt) - gcmPTR2INT(Pointer) \
+ gcmALIGN(gcmPTR2INT32(Pointer), Alignemnt) - gcmPTR2INT32(Pointer) \
)
#if gcdALIGNBYSIZE
(((Offset) & ((Alignment) - 1)) == 0)
# define gcmkALIGNPTR(Type, Pointer, Alignment) \
- Pointer = (Type) gcmINT2PTR(gcmALIGN(gcmPTR2INT(Pointer), Alignment))
+ Pointer = (Type) gcmINT2PTR(gcmALIGN(gcmPTR2INT32(Pointer), Alignment))
#else
# define gcmISALIGNED(Offset, Alignment) \
gcvTRUE
gctARGUMENTS arguments;
gcmkARGUMENTS_START(arguments, Message);
- len = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), Message, arguments);
+ len = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), Message, &arguments);
gcmkARGUMENTS_END(arguments);
buffer[len] = '\0';
IN gctUINT ArgumentSize,
IN gctBOOL CopyMessage,
IN gctCONST_STRING Message,
- IN gctARGUMENTS Arguments
+ IN gctARGUMENTS * Arguments
)
{
gcsBUFFERED_OUTPUT_PTR outputBuffer;
{
gcdOUTPUTCOPY(
outputBuffer, outputBuffer->indent,
- Message, ArgumentSize, * (gctPOINTER *) &Arguments
+ Message, ArgumentSize, (gctPOINTER) Arguments
);
}
else
{
gcdOUTPUTSTRING(
outputBuffer, outputBuffer->indent,
- Message, ArgumentSize, * (gctPOINTER *) &Arguments
+ Message, ArgumentSize, ((gctPOINTER) Arguments)
);
}
{ \
gctARGUMENTS __arguments__; \
gcmkARGUMENTS_START(__arguments__, Message); \
- _Print(ArgumentSize, CopyMessage, Message, __arguments__); \
+ _Print(ArgumentSize, CopyMessage, Message, &__arguments__); \
gcmkARGUMENTS_END(__arguments__); \
} \
atomic_sub(&g_nQnxInIsrs, 1); \
{ \
gctARGUMENTS __arguments__; \
gcmkARGUMENTS_START(__arguments__, Message); \
- _Print(ArgumentSize, CopyMessage, Message, __arguments__); \
+ _Print(ArgumentSize, CopyMessage, Message, &__arguments__); \
gcmkARGUMENTS_END(__arguments__); \
}
IN gctBOOL CopyMessage
)
{
- gctUINT32 address;
- gcsBUFFERED_OUTPUT_PTR outputBuffer;
+ gctUINT32 address = 0;
+ gcsBUFFERED_OUTPUT_PTR outputBuffer = gcvNULL;
static gctBOOL userLocked;
- gctCHAR *buffer = (gctCHAR*)Buffer;
+ gctCHAR *buffer = (gctCHAR*)Buffer;
gcmkDECLARE_LOCK(lockHandle);
}
gctCONST_STRING
gckOS_DebugStatus2Name(
- gceSTATUS status
- )
+ gceSTATUS status
+ )
{
- switch (status)
- {
- case gcvSTATUS_OK:
- return "gcvSTATUS_OK";
- case gcvSTATUS_TRUE:
- return "gcvSTATUS_TRUE";
- case gcvSTATUS_NO_MORE_DATA:
- return "gcvSTATUS_NO_MORE_DATA";
- case gcvSTATUS_CACHED:
- return "gcvSTATUS_CACHED";
- case gcvSTATUS_MIPMAP_TOO_LARGE:
- return "gcvSTATUS_MIPMAP_TOO_LARGE";
- case gcvSTATUS_NAME_NOT_FOUND:
- return "gcvSTATUS_NAME_NOT_FOUND";
- case gcvSTATUS_NOT_OUR_INTERRUPT:
- return "gcvSTATUS_NOT_OUR_INTERRUPT";
- case gcvSTATUS_MISMATCH:
- return "gcvSTATUS_MISMATCH";
- case gcvSTATUS_MIPMAP_TOO_SMALL:
- return "gcvSTATUS_MIPMAP_TOO_SMALL";
- case gcvSTATUS_LARGER:
- return "gcvSTATUS_LARGER";
- case gcvSTATUS_SMALLER:
- return "gcvSTATUS_SMALLER";
- case gcvSTATUS_CHIP_NOT_READY:
- return "gcvSTATUS_CHIP_NOT_READY";
- case gcvSTATUS_NEED_CONVERSION:
- return "gcvSTATUS_NEED_CONVERSION";
- case gcvSTATUS_SKIP:
- return "gcvSTATUS_SKIP";
- case gcvSTATUS_DATA_TOO_LARGE:
- return "gcvSTATUS_DATA_TOO_LARGE";
- case gcvSTATUS_INVALID_CONFIG:
- return "gcvSTATUS_INVALID_CONFIG";
- case gcvSTATUS_CHANGED:
- return "gcvSTATUS_CHANGED";
- case gcvSTATUS_NOT_SUPPORT_DITHER:
- return "gcvSTATUS_NOT_SUPPORT_DITHER";
-
- case gcvSTATUS_INVALID_ARGUMENT:
- return "gcvSTATUS_INVALID_ARGUMENT";
- case gcvSTATUS_INVALID_OBJECT:
- return "gcvSTATUS_INVALID_OBJECT";
- case gcvSTATUS_OUT_OF_MEMORY:
- return "gcvSTATUS_OUT_OF_MEMORY";
- case gcvSTATUS_MEMORY_LOCKED:
- return "gcvSTATUS_MEMORY_LOCKED";
- case gcvSTATUS_MEMORY_UNLOCKED:
- return "gcvSTATUS_MEMORY_UNLOCKED";
- case gcvSTATUS_HEAP_CORRUPTED:
- return "gcvSTATUS_HEAP_CORRUPTED";
- case gcvSTATUS_GENERIC_IO:
- return "gcvSTATUS_GENERIC_IO";
- case gcvSTATUS_INVALID_ADDRESS:
- return "gcvSTATUS_INVALID_ADDRESS";
- case gcvSTATUS_CONTEXT_LOSSED:
- return "gcvSTATUS_CONTEXT_LOSSED";
- case gcvSTATUS_TOO_COMPLEX:
- return "gcvSTATUS_TOO_COMPLEX";
- case gcvSTATUS_BUFFER_TOO_SMALL:
- return "gcvSTATUS_BUFFER_TOO_SMALL";
- case gcvSTATUS_INTERFACE_ERROR:
- return "gcvSTATUS_INTERFACE_ERROR";
- case gcvSTATUS_NOT_SUPPORTED:
- return "gcvSTATUS_NOT_SUPPORTED";
- case gcvSTATUS_MORE_DATA:
- return "gcvSTATUS_MORE_DATA";
- case gcvSTATUS_TIMEOUT:
- return "gcvSTATUS_TIMEOUT";
- case gcvSTATUS_OUT_OF_RESOURCES:
- return "gcvSTATUS_OUT_OF_RESOURCES";
- case gcvSTATUS_INVALID_DATA:
- return "gcvSTATUS_INVALID_DATA";
- case gcvSTATUS_INVALID_MIPMAP:
- return "gcvSTATUS_INVALID_MIPMAP";
- case gcvSTATUS_NOT_FOUND:
- return "gcvSTATUS_NOT_FOUND";
- case gcvSTATUS_NOT_ALIGNED:
- return "gcvSTATUS_NOT_ALIGNED";
- case gcvSTATUS_INVALID_REQUEST:
- return "gcvSTATUS_INVALID_REQUEST";
- case gcvSTATUS_GPU_NOT_RESPONDING:
- return "gcvSTATUS_GPU_NOT_RESPONDING";
- case gcvSTATUS_TIMER_OVERFLOW:
- return "gcvSTATUS_TIMER_OVERFLOW";
- case gcvSTATUS_VERSION_MISMATCH:
- return "gcvSTATUS_VERSION_MISMATCH";
- case gcvSTATUS_LOCKED:
- return "gcvSTATUS_LOCKED";
+ switch (status)
+ {
+ case gcvSTATUS_OK:
+ return "gcvSTATUS_OK";
+ case gcvSTATUS_TRUE:
+ return "gcvSTATUS_TRUE";
+ case gcvSTATUS_NO_MORE_DATA:
+ return "gcvSTATUS_NO_MORE_DATA";
+ case gcvSTATUS_CACHED:
+ return "gcvSTATUS_CACHED";
+ case gcvSTATUS_MIPMAP_TOO_LARGE:
+ return "gcvSTATUS_MIPMAP_TOO_LARGE";
+ case gcvSTATUS_NAME_NOT_FOUND:
+ return "gcvSTATUS_NAME_NOT_FOUND";
+ case gcvSTATUS_NOT_OUR_INTERRUPT:
+ return "gcvSTATUS_NOT_OUR_INTERRUPT";
+ case gcvSTATUS_MISMATCH:
+ return "gcvSTATUS_MISMATCH";
+ case gcvSTATUS_MIPMAP_TOO_SMALL:
+ return "gcvSTATUS_MIPMAP_TOO_SMALL";
+ case gcvSTATUS_LARGER:
+ return "gcvSTATUS_LARGER";
+ case gcvSTATUS_SMALLER:
+ return "gcvSTATUS_SMALLER";
+ case gcvSTATUS_CHIP_NOT_READY:
+ return "gcvSTATUS_CHIP_NOT_READY";
+ case gcvSTATUS_NEED_CONVERSION:
+ return "gcvSTATUS_NEED_CONVERSION";
+ case gcvSTATUS_SKIP:
+ return "gcvSTATUS_SKIP";
+ case gcvSTATUS_DATA_TOO_LARGE:
+ return "gcvSTATUS_DATA_TOO_LARGE";
+ case gcvSTATUS_INVALID_CONFIG:
+ return "gcvSTATUS_INVALID_CONFIG";
+ case gcvSTATUS_CHANGED:
+ return "gcvSTATUS_CHANGED";
+ case gcvSTATUS_NOT_SUPPORT_DITHER:
+ return "gcvSTATUS_NOT_SUPPORT_DITHER";
+
+ case gcvSTATUS_INVALID_ARGUMENT:
+ return "gcvSTATUS_INVALID_ARGUMENT";
+ case gcvSTATUS_INVALID_OBJECT:
+ return "gcvSTATUS_INVALID_OBJECT";
+ case gcvSTATUS_OUT_OF_MEMORY:
+ return "gcvSTATUS_OUT_OF_MEMORY";
+ case gcvSTATUS_MEMORY_LOCKED:
+ return "gcvSTATUS_MEMORY_LOCKED";
+ case gcvSTATUS_MEMORY_UNLOCKED:
+ return "gcvSTATUS_MEMORY_UNLOCKED";
+ case gcvSTATUS_HEAP_CORRUPTED:
+ return "gcvSTATUS_HEAP_CORRUPTED";
+ case gcvSTATUS_GENERIC_IO:
+ return "gcvSTATUS_GENERIC_IO";
+ case gcvSTATUS_INVALID_ADDRESS:
+ return "gcvSTATUS_INVALID_ADDRESS";
+ case gcvSTATUS_CONTEXT_LOSSED:
+ return "gcvSTATUS_CONTEXT_LOSSED";
+ case gcvSTATUS_TOO_COMPLEX:
+ return "gcvSTATUS_TOO_COMPLEX";
+ case gcvSTATUS_BUFFER_TOO_SMALL:
+ return "gcvSTATUS_BUFFER_TOO_SMALL";
+ case gcvSTATUS_INTERFACE_ERROR:
+ return "gcvSTATUS_INTERFACE_ERROR";
+ case gcvSTATUS_NOT_SUPPORTED:
+ return "gcvSTATUS_NOT_SUPPORTED";
+ case gcvSTATUS_MORE_DATA:
+ return "gcvSTATUS_MORE_DATA";
+ case gcvSTATUS_TIMEOUT:
+ return "gcvSTATUS_TIMEOUT";
+ case gcvSTATUS_OUT_OF_RESOURCES:
+ return "gcvSTATUS_OUT_OF_RESOURCES";
+ case gcvSTATUS_INVALID_DATA:
+ return "gcvSTATUS_INVALID_DATA";
+ case gcvSTATUS_INVALID_MIPMAP:
+ return "gcvSTATUS_INVALID_MIPMAP";
+ case gcvSTATUS_NOT_FOUND:
+ return "gcvSTATUS_NOT_FOUND";
+ case gcvSTATUS_NOT_ALIGNED:
+ return "gcvSTATUS_NOT_ALIGNED";
+ case gcvSTATUS_INVALID_REQUEST:
+ return "gcvSTATUS_INVALID_REQUEST";
+ case gcvSTATUS_GPU_NOT_RESPONDING:
+ return "gcvSTATUS_GPU_NOT_RESPONDING";
+ case gcvSTATUS_TIMER_OVERFLOW:
+ return "gcvSTATUS_TIMER_OVERFLOW";
+ case gcvSTATUS_VERSION_MISMATCH:
+ return "gcvSTATUS_VERSION_MISMATCH";
+ case gcvSTATUS_LOCKED:
+ return "gcvSTATUS_LOCKED";
+ case gcvSTATUS_INTERRUPTED:
+ return "gcvSTATUS_INTERRUPTED";
+ case gcvSTATUS_DEVICE:
+ return "gcvSTATUS_DEVICE";
+ case gcvSTATUS_NOT_MULTI_PIPE_ALIGNED:
+ return "gcvSTATUS_NOT_MULTI_PIPE_ALIGNED";
/* Linker errors. */
- case gcvSTATUS_GLOBAL_TYPE_MISMATCH:
- return "gcvSTATUS_GLOBAL_TYPE_MISMATCH";
- case gcvSTATUS_TOO_MANY_ATTRIBUTES:
- return "gcvSTATUS_TOO_MANY_ATTRIBUTES";
- case gcvSTATUS_TOO_MANY_UNIFORMS:
- return "gcvSTATUS_TOO_MANY_UNIFORMS";
- case gcvSTATUS_TOO_MANY_VARYINGS:
- return "gcvSTATUS_TOO_MANY_VARYINGS";
- case gcvSTATUS_UNDECLARED_VARYING:
- return "gcvSTATUS_UNDECLARED_VARYING";
- case gcvSTATUS_VARYING_TYPE_MISMATCH:
- return "gcvSTATUS_VARYING_TYPE_MISMATCH";
- case gcvSTATUS_MISSING_MAIN:
- return "gcvSTATUS_MISSING_MAIN";
- case gcvSTATUS_NAME_MISMATCH:
- return "gcvSTATUS_NAME_MISMATCH";
- case gcvSTATUS_INVALID_INDEX:
- return "gcvSTATUS_INVALID_INDEX";
- default:
- return "nil";
- }
+ case gcvSTATUS_GLOBAL_TYPE_MISMATCH:
+ return "gcvSTATUS_GLOBAL_TYPE_MISMATCH";
+ case gcvSTATUS_TOO_MANY_ATTRIBUTES:
+ return "gcvSTATUS_TOO_MANY_ATTRIBUTES";
+ case gcvSTATUS_TOO_MANY_UNIFORMS:
+ return "gcvSTATUS_TOO_MANY_UNIFORMS";
+ case gcvSTATUS_TOO_MANY_SAMPLER:
+ return "gcvSTATUS_TOO_MANY_SAMPLER";
+ case gcvSTATUS_TOO_MANY_VARYINGS:
+ return "gcvSTATUS_TOO_MANY_VARYINGS";
+ case gcvSTATUS_UNDECLARED_VARYING:
+ return "gcvSTATUS_UNDECLARED_VARYING";
+ case gcvSTATUS_VARYING_TYPE_MISMATCH:
+ return "gcvSTATUS_VARYING_TYPE_MISMATCH";
+ case gcvSTATUS_MISSING_MAIN:
+ return "gcvSTATUS_MISSING_MAIN";
+ case gcvSTATUS_NAME_MISMATCH:
+ return "gcvSTATUS_NAME_MISMATCH";
+ case gcvSTATUS_INVALID_INDEX:
+ return "gcvSTATUS_INVALID_INDEX";
+ case gcvSTATUS_UNIFORM_MISMATCH:
+ return "gcvSTATUS_UNIFORM_MISMATCH";
+ case gcvSTATUS_UNSAT_LIB_SYMBOL:
+ return "gcvSTATUS_UNSAT_LIB_SYMBOL";
+ case gcvSTATUS_TOO_MANY_SHADERS:
+ return "gcvSTATUS_TOO_MANY_SHADERS";
+ case gcvSTATUS_LINK_INVALID_SHADERS:
+ return "gcvSTATUS_LINK_INVALID_SHADERS";
+ case gcvSTATUS_CS_NO_WORKGROUP_SIZE:
+ return "gcvSTATUS_CS_NO_WORKGROUP_SIZE";
+ case gcvSTATUS_LINK_LIB_ERROR:
+ return "gcvSTATUS_LINK_LIB_ERROR";
+ case gcvSTATUS_SHADER_VERSION_MISMATCH:
+ return "gcvSTATUS_SHADER_VERSION_MISMATCH";
+ case gcvSTATUS_TOO_MANY_INSTRUCTION:
+ return "gcvSTATUS_TOO_MANY_INSTRUCTION";
+ case gcvSTATUS_SSBO_MISMATCH:
+ return "gcvSTATUS_SSBO_MISMATCH";
+ case gcvSTATUS_TOO_MANY_OUTPUT:
+ return "gcvSTATUS_TOO_MANY_OUTPUT";
+ case gcvSTATUS_TOO_MANY_INPUT:
+ return "gcvSTATUS_TOO_MANY_INPUT";
+ case gcvSTATUS_NOT_SUPPORT_CL:
+ return "gcvSTATUS_NOT_SUPPORT_CL";
+ case gcvSTATUS_NOT_SUPPORT_INTEGER:
+ return "gcvSTATUS_NOT_SUPPORT_INTEGER";
+
+ /* Compiler errors. */
+ case gcvSTATUS_COMPILER_FE_PREPROCESSOR_ERROR:
+ return "gcvSTATUS_COMPILER_FE_PREPROCESSOR_ERROR";
+ case gcvSTATUS_COMPILER_FE_PARSER_ERROR:
+ return "gcvSTATUS_COMPILER_FE_PARSER_ERROR";
+
+ default:
+ return "nil";
+ }
}
+
+/*******************************************************************************
+***** Binary Trace *************************************************************
+*******************************************************************************/
+
+/*******************************************************************************
+** _VerifyMessage
+**
+** Verify a binary trace message, decode it to human readable string and print
+** it.
+**
+** ARGUMENTS:
+**
+** gctCONST_STRING Buffer
+** Pointer to buffer to store.
+**
+** gctSIZE_T Bytes
+** Buffer length.
+*/
+void
+_VerifyMessage(
+ IN gctCONST_STRING Buffer,
+ IN gctSIZE_T Bytes
+ )
+{
+ char arguments[150] = {0};
+ char format[100] = {0};
+
+ gctSTRING function;
+ gctPOINTER args;
+ gctUINT32 numArguments;
+ int i = 0;
+ gctUINT32 functionBytes;
+
+ gcsBINARY_TRACE_MESSAGE_PTR message = (gcsBINARY_TRACE_MESSAGE_PTR)Buffer;
+
+ /* Check signature. */
+ if (message->signature != 0x7FFFFFFF)
+ {
+ gcmkPRINT("Signature error");
+ return;
+ }
+
+ /* Get function name. */
+ function = (gctSTRING)&message->payload;
+ functionBytes = (gctUINT32)strlen(function) + 1;
+
+ /* Get arguments number. */
+ numArguments = message->numArguments;
+
+ /* Get arguments . */
+ args = function + functionBytes;
+
+ /* Prepare format string. */
+ while (numArguments--)
+ {
+ format[i++] = '%';
+ format[i++] = 'x';
+ format[i++] = ' ';
+ }
+
+ format[i] = '\0';
+
+ if (numArguments)
+ {
+ gcmkVSPRINTF(arguments, 150, format, (gctARGUMENTS *) &args);
+ }
+
+ gcmkPRINT("[%d](%d): %s(%d) %s",
+ message->pid,
+ message->tid,
+ function,
+ message->line,
+ arguments);
+}
+
+
+/*******************************************************************************
+** gckOS_WriteToRingBuffer
+**
+** Store a buffer to ring buffer.
+**
+** ARGUMENTS:
+**
+** gctCONST_STRING Buffer
+** Pointer to buffer to store.
+**
+** gctSIZE_T Bytes
+** Buffer length.
+*/
+void
+gckOS_WriteToRingBuffer(
+ IN gctCONST_STRING Buffer,
+ IN gctSIZE_T Bytes
+ )
+{
+
+}
+
+/*******************************************************************************
+** gckOS_BinaryTrace
+**
+** Output a binary trace message.
+**
+** ARGUMENTS:
+**
+** gctCONST_STRING Function
+** Pointer to function name.
+**
+** gctINT Line
+** Line number.
+**
+** gctCONST_STRING Text OPTIONAL
+** Optional pointer to a descriptive text.
+**
+** ...
+** Optional arguments to the descriptive text.
+*/
+void
+gckOS_BinaryTrace(
+ IN gctCONST_STRING Function,
+ IN gctINT Line,
+ IN gctCONST_STRING Text OPTIONAL,
+ ...
+ )
+{
+ static gctUINT32 messageSignature = 0x7FFFFFFF;
+ char buffer[gcdBINARY_TRACE_MESSAGE_SIZE];
+ gctUINT32 numArguments = 0;
+ gctUINT32 functionBytes;
+ gctUINT32 i = 0;
+ gctSTRING payload;
+ gcsBINARY_TRACE_MESSAGE_PTR message = (gcsBINARY_TRACE_MESSAGE_PTR)buffer;
+
+ /* Calculate arguments number. */
+ if (Text)
+ {
+ while (Text[i] != '\0')
+ {
+ if (Text[i] == '%')
+ {
+ numArguments++;
+ }
+ i++;
+ }
+ }
+
+ message->signature = messageSignature;
+ message->pid = gcmkGETPROCESSID();
+ message->tid = gcmkGETTHREADID();
+ message->line = Line;
+ message->numArguments = numArguments;
+
+ payload = (gctSTRING)&message->payload;
+
+ /* Function name. */
+ functionBytes = (gctUINT32)gcmkSTRLEN(Function) + 1;
+ gcmkMEMCPY(payload, Function, functionBytes);
+
+ /* Advance to next payload. */
+ payload += functionBytes;
+
+ /* Arguments value. */
+ if (numArguments)
+ {
+ gctARGUMENTS p;
+ gcmkARGUMENTS_START(p, Text);
+
+ for (i = 0; i < numArguments; ++i)
+ {
+ gctPOINTER value = gcmkARGUMENTS_ARG(p, gctPOINTER);
+ gcmkMEMCPY(payload, &value, gcmSIZEOF(gctPOINTER));
+ payload += gcmSIZEOF(gctPOINTER);
+ }
+
+ gcmkARGUMENTS_END(p);
+ }
+
+ gcmkASSERT(payload - buffer <= gcdBINARY_TRACE_MESSAGE_SIZE);
+
+
+ /* Send buffer to ring buffer. */
+ gckOS_WriteToRingBuffer(buffer, (gctUINT32)(payload - buffer));
+}
+
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
if (powerLocked)
{
gcmkONERROR(gckOS_ReleaseMutex(hardware->os, hardware->powerMutex));
- powerLocked = gcvFALSE;
}
gcmkFOOTER();
gcmUINT64_TO_PTR(Record->info.u.FreeContiguousMemory.logical)));
break;
- case gcvHAL_FREE_VIDEO_MEMORY:
- gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
- Event->kernel,
- Record->processID,
- gcvDB_VIDEO_MEMORY,
- gcmUINT64_TO_PTR(Record->info.u.FreeVideoMemory.node)));
-
- {
- gcuVIDMEM_NODE_PTR node = (gcuVIDMEM_NODE_PTR)(gcmUINT64_TO_PTR(Record->info.u.FreeVideoMemory.node));
-
- if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
- {
- gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(Event->kernel,
- Record->processID,
- gcvDB_VIDEO_MEMORY_RESERVED,
- node));
- }
- else if(node->Virtual.contiguous)
- {
- gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(Event->kernel,
- Record->processID,
- gcvDB_VIDEO_MEMORY_CONTIGUOUS,
- node));
- }
- else
- {
- gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(Event->kernel,
- Record->processID,
- gcvDB_VIDEO_MEMORY_VIRTUAL,
- node));
- }
- }
-
- break;
-
case gcvHAL_UNLOCK_VIDEO_MEMORY:
gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
Event->kernel,
return gcvSTATUS_OK;
}
+gceSTATUS
+_ReleaseVideoMemoryHandle(
+ IN gckKERNEL Kernel,
+ IN OUT gcsEVENT_PTR Record,
+ IN OUT gcsHAL_INTERFACE * Interface
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE nodeObject;
+ gctUINT32 handle;
+
+ switch(Interface->command)
+ {
+ case gcvHAL_UNLOCK_VIDEO_MEMORY:
+ handle = (gctUINT32)Interface->u.UnlockVideoMemory.node;
+
+ gcmkONERROR(gckVIDMEM_HANDLE_Lookup(
+ Kernel, Record->processID, handle, &nodeObject));
+
+ Record->info.u.UnlockVideoMemory.node = gcmPTR_TO_UINT64(nodeObject);
+
+ gckVIDMEM_HANDLE_Dereference(Kernel, Record->processID, handle);
+ break;
+
+ default:
+ break;
+ }
+
+ return gcvSTATUS_OK;
+OnError:
+ return status;
+}
+
+/*******************************************************************************
+**
+** _QueryFlush
+**
+** Check the type of surfaces which will be released by current event and
+** determine the cache needed to flush.
+**
+*/
+static gceSTATUS
+_QueryFlush(
+ IN gckEVENT Event,
+ IN gcsEVENT_PTR Record,
+ OUT gceKERNEL_FLUSH *Flush
+ )
+{
+ gceKERNEL_FLUSH flush = 0;
+ gcmkHEADER_ARG("Event=0x%x Record=0x%x", Event, Record);
+ gcmkVERIFY_ARGUMENT(Record != gcvNULL);
+
+ while (Record != gcvNULL)
+ {
+ switch (Record->info.command)
+ {
+ case gcvHAL_UNLOCK_VIDEO_MEMORY:
+ switch(Record->info.u.UnlockVideoMemory.type)
+ {
+ case gcvSURF_TILE_STATUS:
+ flush |= gcvFLUSH_TILE_STATUS;
+ break;
+ case gcvSURF_RENDER_TARGET:
+ flush |= gcvFLUSH_COLOR;
+ break;
+ case gcvSURF_DEPTH:
+ flush |= gcvFLUSH_DEPTH;
+ break;
+ case gcvSURF_TEXTURE:
+ flush |= gcvFLUSH_TEXTURE;
+ break;
+ case gcvSURF_TYPE_UNKNOWN:
+ gcmkASSERT(0);
+ break;
+ default:
+ break;
+ }
+ break;
+ case gcvHAL_UNMAP_USER_MEMORY:
+ *Flush = gcvFLUSH_ALL;
+ return gcvSTATUS_OK;
+
+ default:
+ break;
+ }
+
+ Record = Record->next;
+ }
+
+ *Flush = flush;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
void
_SubmitTimerFunction(
gctPOINTER Data
)
{
gckEVENT event = (gckEVENT)Data;
+#if gcdMULTI_GPU
+ gcmkVERIFY_OK(gckEVENT_Submit(event, gcvTRUE, gcvFALSE, gcvCORE_3D_ALL_MASK));
+#else
gcmkVERIFY_OK(gckEVENT_Submit(event, gcvTRUE, gcvFALSE));
+#endif
}
/******************************************************************************\
#if gcdSMP
gcmkONERROR(gckOS_AtomConstruct(os, &eventObj->pending));
+
+#if gcdMULTI_GPU
+ for (i = 0; i < gcdMULTI_GPU; i++)
+ {
+ gcmkONERROR(gckOS_AtomConstruct(os, &eventObj->pending3D[i]));
+ gcmkONERROR(gckOS_AtomConstruct(os, &eventObj->pending3DMask[i]));
+ }
+
+ gcmkONERROR(gckOS_AtomConstruct(os, &eventObj->pendingMask));
+#endif
+
#endif
gcmkVERIFY_OK(gckOS_CreateTimer(os,
(gctPOINTER)eventObj,
&eventObj->submitTimer));
+#if gcdINTERRUPT_STATISTIC
+ gcmkONERROR(gckOS_AtomConstruct(os, &eventObj->interruptCount));
+ gcmkONERROR(gckOS_AtomSet(os,eventObj->interruptCount, 0));
+#endif
+
/* Return pointer to the gckEVENT object. */
*Event = eventObj;
{
gcmkVERIFY_OK(gckOS_AtomDestroy(os, eventObj->pending));
}
+
+#if gcdMULTI_GPU
+ for (i = 0; i < gcdMULTI_GPU; i++)
+ {
+ if (eventObj->pending3D[i] != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(os, eventObj->pending3D[i]));
+ }
+
+ if (eventObj->pending3DMask[i] != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(os, eventObj->pending3DMask[i]));
+ }
+ }
+#endif
+#endif
+
+#if gcdINTERRUPT_STATISTIC
+ if (eventObj->interruptCount)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(os, eventObj->interruptCount));
+ }
#endif
gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, eventObj));
}
#if gcdSMP
gcmkVERIFY_OK(gckOS_AtomDestroy(Event->os, Event->pending));
+
+#if gcdMULTI_GPU
+ {
+ gctINT i;
+ for (i = 0; i < gcdMULTI_GPU; i++)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Event->os, Event->pending3D[i]));
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Event->os, Event->pending3DMask[i]));
+ }
+ }
+#endif
+#endif
+
+#if gcdINTERRUPT_STATISTIC
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Event->os, Event->interruptCount));
#endif
/* Mark the gckEVENT object as unknown. */
** gctUINT8 * EventID
** Reserved event ID.
*/
+#define gcdINVALID_EVENT_PTR ((gcsEVENT_PTR)gcvMAXUINTPTR_T)
+
+#if gcdMULTI_GPU
+gceSTATUS
+gckEVENT_GetEvent(
+ IN gckEVENT Event,
+ IN gctBOOL Wait,
+ OUT gctUINT8 * EventID,
+ IN gceKERNEL_WHERE Source,
+ IN gceCORE_3D_MASK ChipEnable
+ )
+#else
gceSTATUS
gckEVENT_GetEvent(
IN gckEVENT Event,
OUT gctUINT8 * EventID,
IN gceKERNEL_WHERE Source
)
+#endif
{
gctINT i, id;
gceSTATUS status;
gctBOOL acquired = gcvFALSE;
gctINT32 free;
-
-#if gcdGPU_TIMEOUT
- gctUINT32 timer = 0;
+#if gcdMULTI_GPU
+ gctINT j;
#endif
gcmkHEADER_ARG("Event=0x%x Source=%d", Event, Source);
Event->lastID = (gctUINT8) nextID;
/* Save time stamp of event. */
+ Event->queues[id].head = gcdINVALID_EVENT_PTR;
Event->queues[id].stamp = ++(Event->stamp);
Event->queues[id].source = Source;
+#if gcdMULTI_GPU
+ Event->queues[id].chipEnable = ChipEnable;
+
+ if (ChipEnable == gcvCORE_3D_ALL_MASK)
+ {
+ gckOS_AtomSetMask(Event->pendingMask, (1 << id));
+
+ for (j = 0; j < gcdMULTI_GPU; j++)
+ {
+ gckOS_AtomSetMask(Event->pending3DMask[j], (1 << id));
+ }
+ }
+ else
+ {
+ for (j = 0; j < gcdMULTI_GPU; j++)
+ {
+ if (ChipEnable & (1 << j))
+ {
+ gckOS_AtomSetMask(Event->pending3DMask[j], (1 << id));
+ }
+ }
+ }
+#endif
+
gcmkONERROR(gckOS_AtomDecrement(Event->os,
Event->freeAtom,
&free));
/* Delay a while. */
gcmkONERROR(gckOS_Delay(Event->os, 1));
-
-#if gcdGPU_TIMEOUT
- /* Increment the wait timer. */
- timer += 1;
-
- if (timer == Event->kernel->timeOut)
- {
- /* Try to call any outstanding events. */
- gcmkONERROR(gckHARDWARE_Interrupt(Event->kernel->hardware,
- gcvTRUE));
- }
- else if (timer > Event->kernel->timeOut)
- {
- gcmkTRACE_N(
- gcvLEVEL_ERROR,
- gcmSIZEOF(gctCONST_STRING) + gcmSIZEOF(gctINT),
- "%s(%d): no available events\n",
- __FUNCTION__, __LINE__
- );
-
- /* Bail out. */
- gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING);
- }
-#endif
}
OnError:
/* Release the mutex. */
gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->freeEventMutex));
- acquired = gcvFALSE;
/* Success. */
gcmkFOOTER_ARG("*Record=0x%x", gcmOPT_POINTER(Record));
gctBOOL acquired = gcvFALSE;
gcsEVENT_PTR record = gcvNULL;
gcsEVENT_QUEUE_PTR queue;
+ gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
gckKERNEL kernel = Event->kernel;
gcmkHEADER_ARG("Event=0x%x Interface=0x%x",
gcmkASSERT
( (Interface->command == gcvHAL_FREE_NON_PAGED_MEMORY)
|| (Interface->command == gcvHAL_FREE_CONTIGUOUS_MEMORY)
- || (Interface->command == gcvHAL_FREE_VIDEO_MEMORY)
|| (Interface->command == gcvHAL_WRITE_DATA)
|| (Interface->command == gcvHAL_UNLOCK_VIDEO_MEMORY)
|| (Interface->command == gcvHAL_SIGNAL)
|| (Interface->command == gcvHAL_COMMIT_DONE)
|| (Interface->command == gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER)
|| (Interface->command == gcvHAL_SYNC_POINT)
+ || (Interface->command == gcvHAL_DESTROY_MMU)
);
/* Validate the source. */
/* Get process ID. */
gcmkONERROR(gckOS_GetProcessID(&record->processID));
+ gcmkONERROR(__RemoveRecordFromProcessDB(Event, record));
+
+ /* Handle is belonged to current process, it must be released now. */
+ if (FromKernel == gcvFALSE)
+ {
+ status = _ReleaseVideoMemoryHandle(Event->kernel, record, Interface);
+
+ if (gcmIS_ERROR(status))
+ {
+ /* Ingore error because there are other events in the queue. */
+ status = gcvSTATUS_OK;
+ goto OnError;
+ }
+ }
+
#ifdef __QNXNTO__
record->kernel = Event->kernel;
#endif
- gcmkONERROR(__RemoveRecordFromProcessDB(Event, record));
-
/* Acquire the mutex. */
gcmkONERROR(gckOS_AcquireMutex(Event->os, Event->eventListMutex, gcvINFINITE));
acquired = gcvTRUE;
(gctSIZE_T) Interface->u.FreeContiguousMemory.bytes,
gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical)));
break;
+
+ case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
+ buffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)gcmNAME_TO_PTR(Interface->u.FreeVirtualCommandBuffer.physical);
+ if (buffer->userLogical)
+ {
+ gcmkONERROR(gckOS_DestroyUserVirtualMapping(
+ Event->os,
+ buffer->physical,
+ (gctSIZE_T) Interface->u.FreeVirtualCommandBuffer.bytes,
+ gcmUINT64_TO_PTR(Interface->u.FreeVirtualCommandBuffer.logical)));
+ }
+ break;
+
default:
break;
}
-
/* Release the mutex. */
gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
gckEVENT_Unlock(
IN gckEVENT Event,
IN gceKERNEL_WHERE FromWhere,
- IN gcuVIDMEM_NODE_PTR Node,
+ IN gctPOINTER Node,
IN gceSURF_TYPE Type
)
{
return status;
}
-/*******************************************************************************
-**
-** gckEVENT_FreeVideoMemory
-**
-** Schedule an event to free video memory.
-**
-** INPUT:
-**
-** gckEVENT Event
-** Pointer to an gckEVENT object.
-**
-** gcuVIDMEM_NODE_PTR VideoMemory
-** Pointer to a gcuVIDMEM_NODE object to free.
-**
-** gceKERNEL_WHERE FromWhere
-** Place in the pipe where the event needs to be generated.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gckEVENT_FreeVideoMemory(
- IN gckEVENT Event,
- IN gcuVIDMEM_NODE_PTR VideoMemory,
- IN gceKERNEL_WHERE FromWhere
- )
-{
- gceSTATUS status;
- gcsHAL_INTERFACE iface;
-
- gcmkHEADER_ARG("Event=0x%x VideoMemory=0x%x FromWhere=%d",
- Event, VideoMemory, FromWhere);
-
- /* Verify the arguments. */
- gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
- gcmkVERIFY_ARGUMENT(VideoMemory != gcvNULL);
-
- /* Create an event. */
- iface.command = gcvHAL_FREE_VIDEO_MEMORY;
- iface.u.FreeVideoMemory.node = gcmPTR_TO_UINT64(VideoMemory);
-
- /* Append it to the queue. */
- gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
-
- /* Success. */
- gcmkFOOTER_NO();
- return gcvSTATUS_OK;
-
-OnError:
- /* Return the status. */
- gcmkFOOTER();
- return status;
-}
-
/*******************************************************************************
**
** gckEVENT_FreeNonPagedMemory
gcmkFOOTER();
return status;
}
+
+#if gcdPROCESS_ADDRESS_SPACE
+gceSTATUS
+gckEVENT_DestroyMmu(
+ IN gckEVENT Event,
+ IN gckMMU Mmu,
+ IN gceKERNEL_WHERE FromWhere
+ )
+{
+ gceSTATUS status;
+ gcsHAL_INTERFACE iface;
+
+ gcmkHEADER_ARG("Event=0x%x FromWhere=%d", Event, FromWhere);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+
+ iface.command = gcvHAL_DESTROY_MMU;
+ iface.u.DestroyMmu.mmu = gcmPTR_TO_UINT64(Mmu);
+
+ /* Append it to the queue. */
+ gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
/*******************************************************************************
**
** gckEVENT_Submit
**
** Nothing.
*/
+#if gcdMULTI_GPU
+gceSTATUS
+gckEVENT_Submit(
+ IN gckEVENT Event,
+ IN gctBOOL Wait,
+ IN gctBOOL FromPower,
+ IN gceCORE_3D_MASK ChipEnable
+ )
+#else
gceSTATUS
gckEVENT_Submit(
IN gckEVENT Event,
IN gctBOOL Wait,
IN gctBOOL FromPower
)
+#endif
{
gceSTATUS status;
gctUINT8 id = 0xFF;
gckCOMMAND command = gcvNULL;
gctBOOL commitEntered = gcvFALSE;
#if !gcdNULL_DRIVER
- gctSIZE_T bytes;
+ gctUINT32 bytes;
gctPOINTER buffer;
#endif
+#if gcdMULTI_GPU
+ gctSIZE_T chipEnableBytes;
+#endif
+
+#if gcdINTERRUPT_STATISTIC
+ gctINT32 oldValue;
+#endif
+
+#if gcdSECURITY
+ gctPOINTER reservedBuffer;
+#endif
+
+ gctUINT32 flushBytes;
+ gctUINT32 executeBytes;
+ gckHARDWARE hardware;
+
+ gceKERNEL_FLUSH flush = gcvFALSE;
+
gcmkHEADER_ARG("Event=0x%x Wait=%d", Event, Wait);
/* Get gckCOMMAND object. */
command = Event->kernel->command;
+ hardware = Event->kernel->hardware;
+
+ gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
+
+ gckOS_GetTicks(&Event->lastCommitStamp);
/* Are there event queues? */
if (Event->queueHead != gcvNULL)
queue = Event->queueHead;
/* Allocate an event ID. */
+#if gcdMULTI_GPU
+ gcmkONERROR(gckEVENT_GetEvent(Event, Wait, &id, queue->source, ChipEnable));
+#else
gcmkONERROR(gckEVENT_GetEvent(Event, Wait, &id, queue->source));
+#endif
/* Copy event list to event ID queue. */
Event->queues[id].head = queue->head;
gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
acquired = gcvFALSE;
+ /* Determine cache needed to flush. */
+ gcmkVERIFY_OK(_QueryFlush(Event, Event->queues[id].head, &flush));
+
+#if gcdINTERRUPT_STATISTIC
+ gcmkVERIFY_OK(gckOS_AtomIncrement(
+ Event->os,
+ Event->interruptCount,
+ &oldValue
+ ));
+#endif
+
#if gcdNULL_DRIVER
/* Notify immediately on infinite hardware. */
gcmkONERROR(gckEVENT_Interrupt(Event, 1 << id));
- gcmkONERROR(gckEVENT_Notify(Event, 0));
-#else
- /* Get the size of the hardware event. */
- gcmkONERROR(gckHARDWARE_Event(Event->kernel->hardware,
- gcvNULL,
- id,
- Event->queues[id].source,
- &bytes));
+ gcmkONERROR(gckEVENT_Notify(Event, 0));
+#else
+ /* Get the size of the hardware event. */
+ gcmkONERROR(gckHARDWARE_Event(
+ hardware,
+ gcvNULL,
+ id,
+ Event->queues[id].source,
+ &bytes
+ ));
+
+ /* Get the size of flush command. */
+ gcmkONERROR(gckHARDWARE_Flush(
+ hardware,
+ flush,
+ gcvNULL,
+ &flushBytes
+ ));
+
+ bytes += flushBytes;
+
+#if gcdMULTI_GPU
+ gcmkONERROR(gckHARDWARE_ChipEnable(
+ hardware,
+ gcvNULL,
+ 0,
+ &chipEnableBytes
+ ));
+
+ bytes += chipEnableBytes * 2;
+#endif
+
+ /* Total bytes need to execute. */
+ executeBytes = bytes;
+
+ /* Reserve space in the command queue. */
+ gcmkONERROR(gckCOMMAND_Reserve(command, bytes, &buffer, &bytes));
+#if gcdSECURITY
+ reservedBuffer = buffer;
+#endif
+
+#if gcdMULTI_GPU
+ gcmkONERROR(gckHARDWARE_ChipEnable(
+ hardware,
+ buffer,
+ ChipEnable,
+ &chipEnableBytes
+ ));
+
+ buffer = (gctUINT8_PTR)buffer + chipEnableBytes;
+#endif
+
+ /* Set the flush in the command queue. */
+ gcmkONERROR(gckHARDWARE_Flush(
+ hardware,
+ flush,
+ buffer,
+ &flushBytes
+ ));
- /* Reserve space in the command queue. */
- gcmkONERROR(gckCOMMAND_Reserve(command,
- bytes,
- &buffer,
- &bytes));
+ /* Advance to next command. */
+ buffer = (gctUINT8_PTR)buffer + flushBytes;
/* Set the hardware event in the command queue. */
- gcmkONERROR(gckHARDWARE_Event(Event->kernel->hardware,
- buffer,
- id,
- Event->queues[id].source,
- &bytes));
+ gcmkONERROR(gckHARDWARE_Event(
+ hardware,
+ buffer,
+ id,
+ Event->queues[id].source,
+ &bytes
+ ));
+
+ /* Advance to next command. */
+ buffer = (gctUINT8_PTR)buffer + bytes;
+
+#if gcdMULTI_GPU
+ gcmkONERROR(gckHARDWARE_ChipEnable(
+ hardware,
+ buffer,
+ gcvCORE_3D_ALL_MASK,
+ &chipEnableBytes
+ ));
+#endif
+#if gcdSECURITY
+ gckKERNEL_SecurityExecute(
+ Event->kernel,
+ reservedBuffer,
+ executeBytes
+ );
+#else
/* Execute the hardware event. */
- gcmkONERROR(gckCOMMAND_Execute(command, bytes));
+ gcmkONERROR(gckCOMMAND_Execute(command, executeBytes));
+#endif
#endif
}
/* Release the command queue. */
gcmkONERROR(gckCOMMAND_ExitCommit(command, FromPower));
- commitEntered = gcvFALSE;
#if !gcdNULL_DRIVER
gcmkVERIFY_OK(_TryToIdleGPU(Event));
return gcvSTATUS_OK;
OnError:
- if (commitEntered)
- {
- /* Release the command queue mutex. */
- gcmkVERIFY_OK(gckCOMMAND_ExitCommit(command, FromPower));
- }
-
if (acquired)
{
/* Need to unroll the mutex acquire. */
gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
}
+ if (commitEntered)
+ {
+ /* Release the command queue mutex. */
+ gcmkVERIFY_OK(gckCOMMAND_ExitCommit(command, FromPower));
+ }
+
if (id != 0xFF)
{
/* Need to unroll the event allocation. */
**
** Nothing.
*/
+#if gcdMULTI_GPU
+gceSTATUS
+gckEVENT_Commit(
+ IN gckEVENT Event,
+ IN gcsQUEUE_PTR Queue,
+ IN gceCORE_3D_MASK ChipEnable
+ )
+#else
gceSTATUS
gckEVENT_Commit(
IN gckEVENT Event,
IN gcsQUEUE_PTR Queue
)
+#endif
{
gceSTATUS status;
gcsQUEUE_PTR record = gcvNULL, next;
}
/* Submit the event list. */
+#if gcdMULTI_GPU
+ gcmkONERROR(gckEVENT_Submit(Event, gcvTRUE, gcvFALSE, ChipEnable));
+#else
gcmkONERROR(gckEVENT_Submit(Event, gcvTRUE, gcvFALSE));
+#endif
/* Success */
gcmkFOOTER_NO();
gcmkVERIFY_ARGUMENT(Info != gcvNULL);
/* Allocate an event ID. */
+#if gcdMULTI_GPU
+ gcmkONERROR(gckEVENT_GetEvent(Event, gcvTRUE, &id, gcvKERNEL_PIXEL, gcvCORE_3D_ALL_MASK));
+#else
gcmkONERROR(gckEVENT_GetEvent(Event, gcvTRUE, &id, gcvKERNEL_PIXEL));
+#endif
/* Get process ID. */
gcmkONERROR(gckOS_GetProcessID(&processID));
/* Allocate a record. */
gcmkONERROR(gckEVENT_AllocateRecord(Event, gcvTRUE, &tempRecord));
tailRecord->next = tempRecord;
- tailRecord = tempRecord;
/* Initialize the record. */
tempRecord->info.command = gcvHAL_SIGNAL;
tempRecord->processID = processID;
}
- /* Set the event list. */
+ /* Set the event list. */
Event->queues[id].head = headRecord;
/* Start composition. */
gceSTATUS
gckEVENT_Interrupt(
IN gckEVENT Event,
+#if gcdMULTI_GPU
+ IN gctUINT CoreId,
+#endif
IN gctUINT32 Data
)
{
+#if gcdMULTI_GPU
+#if defined(WIN32)
+ gctUINT32 i;
+#endif
+#endif
gcmkHEADER_ARG("Event=0x%x Data=0x%x", Event, Data);
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+ if (Data & 0x20000000)
+ {
+ gckENTRYDATA data;
+ gctUINT32 idle;
+ Data &= ~0x20000000;
+
+#if gcdMULTI_GPU
+ if (Event->kernel->core == gcvCORE_MAJOR)
+#endif
+ {
+ /* Get first entry information. */
+ gcmkVERIFY_OK(
+ gckENTRYQUEUE_Dequeue(&Event->kernel->command->queue, &data));
+
+ /* Make sure FE is idle. */
+ do
+ {
+ gcmkVERIFY_OK(gckOS_ReadRegisterEx(
+ Event->os,
+ Event->kernel->core,
+ 0x4,
+ &idle));
+ }
+ while (idle != 0x7FFFFFFF);
+
+ /* Start Command Parser. */
+ gcmkVERIFY_OK(gckHARDWARE_Execute(
+ Event->kernel->hardware,
+ data->physical,
+ data->bytes
+ ));
+ }
+ }
+
/* Combine current interrupt status with pending flags. */
#if gcdSMP
- gckOS_AtomSetMask(Event->pending, Data);
+#if gcdMULTI_GPU
+ if (Event->kernel->core == gcvCORE_MAJOR)
+ {
+ gckOS_AtomSetMask(Event->pending3D[CoreId], Data);
+ }
+ else
+#endif
+ {
+ gckOS_AtomSetMask(Event->pending, Data);
+ }
#elif defined(__QNXNTO__)
- atomic_set(&Event->pending, Data);
+#if gcdMULTI_GPU
+ if (Event->kernel->core == gcvCORE_MAJOR)
+ {
+ atomic_set(&Event->pending3D[CoreId], Data);
+ }
+ else
+#endif
+ {
+ atomic_set(&Event->pending, Data);
+ }
+#else
+#if gcdMULTI_GPU
+#if defined(WIN32)
+ if (Event->kernel->core == gcvCORE_MAJOR)
+ {
+ for (i = 0; i < gcdMULTI_GPU; i++)
+ {
+ Event->pending3D[i] |= Data;
+ }
+ }
+ else
#else
- Event->pending |= Data;
+ if (Event->kernel->core == gcvCORE_MAJOR)
+ {
+ Event->pending3D[CoreId] |= Data;
+ }
+ else
+#endif
+#endif
+ {
+ Event->pending |= Data;
+ }
+#endif
+
+#if gcdINTERRUPT_STATISTIC
+ {
+ gctINT j = 0;
+ gctINT32 oldValue;
+
+ for (j = 0; j < gcmCOUNTOF(Event->queues); j++)
+ {
+ if ((Data & (1 << j)))
+ {
+ gcmkVERIFY_OK(gckOS_AtomDecrement(Event->os,
+ Event->interruptCount,
+ &oldValue));
+ }
+ }
+ }
#endif
/* Success. */
gcsEVENT_QUEUE * queue;
gctUINT mask = 0;
gctBOOL acquired = gcvFALSE;
- gcuVIDMEM_NODE_PTR node;
gctPOINTER info;
gctSIGNAL signal;
- gctUINT pending;
+ gctUINT pending = 0;
gckKERNEL kernel = Event->kernel;
+#if gcdMULTI_GPU
+ gceCORE core = Event->kernel->core;
+ gctUINT32 busy;
+ gctUINT32 oldValue;
+ gctUINT pendingMask;
+#endif
#if !gcdSMP
gctBOOL suspended = gcvFALSE;
#endif
#if gcdSECURE_USER
gcskSECURE_CACHE_PTR cache;
#endif
+ gckVIDMEM_NODE nodeObject;
+ gcuVIDMEM_NODE_PTR node;
gcmkHEADER_ARG("Event=0x%x IDs=0x%x", Event, IDs);
}
);
+#if gcdMULTI_GPU
+ /* Set busy flag. */
+ gckOS_AtomicExchange(Event->os, &Event->busy, 1, &busy);
+ if (busy)
+ {
+ /* Another thread is already busy - abort. */
+ goto OnSuccess;
+ }
+#endif
+
for (;;)
{
gcsEVENT_PTR record;
+#if gcdMULTI_GPU
+ gctUINT32 pend[gcdMULTI_GPU];
+ gctUINT32 pendMask[gcdMULTI_GPU];
+#endif
+
+ /* Grab the mutex queue. */
+ gcmkONERROR(gckOS_AcquireMutex(Event->os,
+ Event->eventQueueMutex,
+ gcvINFINITE));
+ acquired = gcvTRUE;
#if gcdSMP
- /* Get current interrupts. */
- gckOS_AtomGet(Event->os, Event->pending, (gctINT32_PTR)&pending);
+#if gcdMULTI_GPU
+ if (core == gcvCORE_MAJOR)
+ {
+ /* Get current interrupts. */
+ for (i = 0; i < gcdMULTI_GPU; i++)
+ {
+ gckOS_AtomGet(Event->os, Event->pending3D[i], (gctINT32_PTR)&pend[i]);
+ gckOS_AtomGet(Event->os, Event->pending3DMask[i], (gctINT32_PTR)&pendMask[i]);
+ }
+
+ gckOS_AtomGet(Event->os, Event->pendingMask, (gctINT32_PTR)&pendingMask);
+ }
+ else
+#endif
+ {
+ gckOS_AtomGet(Event->os, Event->pending, (gctINT32_PTR)&pending);
+ }
#else
/* Suspend interrupts. */
gcmkONERROR(gckOS_SuspendInterruptEx(Event->os, Event->kernel->core));
suspended = gcvTRUE;
- /* Get current interrupts. */
- pending = Event->pending;
+#if gcdMULTI_GPU
+ if (core == gcvCORE_MAJOR)
+ {
+ for (i = 0; i < gcdMULTI_GPU; i++)
+ {
+ /* Get current interrupts. */
+ pend[i] = Event->pending3D[i];
+ pendMask[i] = Event->pending3DMask[i];
+ }
+
+ pendingMask = Event->pendingMask;
+ }
+ else
+#endif
+ {
+ pending = Event->pending;
+ }
/* Resume interrupts. */
gcmkONERROR(gckOS_ResumeInterruptEx(Event->os, Event->kernel->core));
suspended = gcvFALSE;
#endif
+#if gcdMULTI_GPU
+ if (core == gcvCORE_MAJOR)
+ {
+ for (i = 0; i < gcdMULTI_GPU; i++)
+ {
+ gctUINT32 bad_pend = (pend[i] & ~pendMask[i]);
+
+ if (bad_pend != 0)
+ {
+ gcmkTRACE_ZONE_N(
+ gcvLEVEL_ERROR, gcvZONE_EVENT,
+ gcmSIZEOF(bad_pend) + gcmSIZEOF(i),
+ "Interrupts 0x%x are not unexpected for Core%d.",
+ bad_pend, i
+ );
+
+ gckOS_AtomClearMask(Event->pending3D[i], bad_pend);
+
+ pend[i] &= pendMask[i];
+ }
+ }
+
+ pending = (pend[0] & pend[1] & pendingMask) /* Check combined events on both GPUs */
+ | (pend[0] & ~pendingMask) /* Check individual events on GPU 0 */
+ | (pend[1] & ~pendingMask); /* Check individual events on GPU 1 */
+ }
+#endif
+
if (pending == 0)
{
+ /* Release the mutex queue. */
+ gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
+ acquired = gcvFALSE;
+
/* No more pending interrupts - done. */
break;
}
if (pending & 0x80000000)
{
- gckOS_Print("!!!!!!!!!!!!! AXI BUS ERROR !!!!!!!!!!!!!\n");
- gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_EVENT, "AXI BUS ERROR");
+ gcmkPRINT("AXI BUS ERROR");
pending &= 0x7FFFFFFF;
}
);
#if gcdSMP
- /* Mark pending interrupts as handled. */
- gckOS_AtomClearMask(Event->pending, pending);
+#if gcdMULTI_GPU
+ if (core == gcvCORE_MAJOR)
+ {
+ /* Mark pending interrupts as handled. */
+ for (i = 0; i < gcdMULTI_GPU; i++)
+ {
+ gckOS_AtomClearMask(Event->pending3D[i], pending);
+ gckOS_AtomClearMask(Event->pending3DMask[i], pending);
+ }
+
+ gckOS_AtomClearMask(Event->pendingMask, pending);
+ }
+ else
+#endif
+ {
+ gckOS_AtomClearMask(Event->pending, pending);
+ }
+
#elif defined(__QNXNTO__)
- /* Mark pending interrupts as handled. */
- atomic_clr((gctUINT32_PTR)&Event->pending, pending);
+#if gcdMULTI_GPU
+ if (core == gcvCORE_MAJOR)
+ {
+ for (i = 0; i < gcdMULTI_GPU; i++)
+ {
+ atomic_clr((gctUINT32_PTR)&Event->pending3D[i], pending);
+ atomic_clr((gctUINT32_PTR)&Event->pending3DMask[i], pending);
+ }
+
+ atomic_clr((gctUINT32_PTR)&Event->pendingMask, pending);
+ }
+ else
+#endif
+ {
+ atomic_clr((gctUINT32_PTR)&Event->pending, pending);
+ }
#else
/* Suspend interrupts. */
gcmkONERROR(gckOS_SuspendInterruptEx(Event->os, Event->kernel->core));
suspended = gcvTRUE;
- /* Mark pending interrupts as handled. */
- Event->pending &= ~pending;
+#if gcdMULTI_GPU
+ if (core == gcvCORE_MAJOR)
+ {
+ for (i = 0; i < gcdMULTI_GPU; i++)
+ {
+ /* Mark pending interrupts as handled. */
+ Event->pending3D[i] &= ~pending;
+ Event->pending3DMask[i] &= ~pending;
+ }
+ }
+ else
+#endif
+ {
+ Event->pending &= ~pending;
+ }
/* Resume interrupts. */
gcmkONERROR(gckOS_ResumeInterruptEx(Event->os, Event->kernel->core));
suspended = gcvFALSE;
#endif
+
+ /* Release the mutex queue. */
+ gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
+ acquired = gcvFALSE;
break;
}
if ((Event->queues[i].head != gcvNULL)
&& (Event->queues[i].stamp < queue->stamp)
&& (Event->queues[i].source <= queue->source)
+#if gcdMULTI_GPU
+ && (Event->queues[i].chipEnable == queue->chipEnable)
+#endif
)
{
gcmkTRACE_N(
}
#if gcdSMP
- /* Mark pending interrupt as handled. */
- gckOS_AtomClearMask(Event->pending, mask);
+#if gcdMULTI_GPU
+ if (core == gcvCORE_MAJOR)
+ {
+ for (i = 0; i < gcdMULTI_GPU; i++)
+ {
+ /* Mark pending interrupt as handled. */
+ gckOS_AtomClearMask(Event->pending3D[i], mask);
+ gckOS_AtomClearMask(Event->pending3DMask[i], mask);
+ }
+
+ gckOS_AtomClearMask(Event->pendingMask, mask);
+ }
+ else
+#endif
+ {
+ gckOS_AtomClearMask(Event->pending, mask);
+ }
+
#elif defined(__QNXNTO__)
- /* Mark pending interrupt as handled. */
- atomic_clr(&Event->pending, mask);
+#if gcdMULTI_GPU
+ if (core == gcvCORE_MAJOR)
+ {
+ for (i = 0; i < gcdMULTI_GPU; i++)
+ {
+ atomic_clr(&Event->pending3D[i], mask);
+ atomic_clr(&Event->pending3DMask[i], mask);
+ }
+
+ atomic_clr(&Event->pendingMask, mask);
+ }
+ else
+#endif
+ {
+ atomic_clr(&Event->pending, mask);
+ }
#else
/* Suspend interrupts. */
gcmkONERROR(gckOS_SuspendInterruptEx(Event->os, Event->kernel->core));
suspended = gcvTRUE;
- /* Mark pending interrupt as handled. */
- Event->pending &= ~mask;
+#if gcdMULTI_GPU
+ if (core == gcvCORE_MAJOR)
+ {
+ for (i = 0; i < gcdMULTI_GPU; i++)
+ {
+ /* Mark pending interrupt as handled. */
+ Event->pending3D[i] &= ~mask;
+ Event->pending3DMask[i] &= ~mask;
+ }
+
+ Event->pendingMask &= ~mask;
+ }
+ else
+#endif
+ {
+ Event->pending &= ~mask;
+ }
/* Resume interrupts. */
gcmkONERROR(gckOS_ResumeInterruptEx(Event->os, Event->kernel->core));
suspended = gcvFALSE;
#endif
- /* Grab the mutex queue. */
- gcmkONERROR(gckOS_AcquireMutex(Event->os,
- Event->eventQueueMutex,
- gcvINFINITE));
- acquired = gcvTRUE;
-
- /* We are in the notify loop. */
- Event->inNotify = gcvTRUE;
-
/* Grab the event head. */
record = queue->head;
gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
Event->kernel,
cache,
- gcmUINT64_TO_PTR(record->record.u.FreeContiguousMemory.logical),
- (gctSIZE_T) record->record.u.FreeContiguousMemory.bytes));
+ gcmUINT64_TO_PTR(event->event.u.FreeContiguousMemory.logical),
+ (gctSIZE_T) event->event.u.FreeContiguousMemory.bytes));
#endif
}
gcmRELEASE_NAME(record->info.u.FreeContiguousMemory.physical);
break;
- case gcvHAL_FREE_VIDEO_MEMORY:
- node = gcmUINT64_TO_PTR(record->info.u.FreeVideoMemory.node);
- gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
- "gcvHAL_FREE_VIDEO_MEMORY: 0x%x",
- node);
-#ifdef __QNXNTO__
-#if gcdUSE_VIDMEM_PER_PID
- /* Check if the VidMem object still exists. */
- if (gckKERNEL_GetVideoMemoryPoolPid(record->kernel,
- gcvPOOL_SYSTEM,
- record->processID,
- gcvNULL) == gcvSTATUS_NOT_FOUND)
- {
- /*printf("Vidmem not found for process:%d\n", queue->processID);*/
- status = gcvSTATUS_OK;
- break;
- }
-#else
- if ((node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
- && (node->VidMem.logical != gcvNULL)
- )
- {
- gcmkERR_BREAK(
- gckKERNEL_UnmapVideoMemory(record->kernel,
- node->VidMem.logical,
- record->processID,
- node->VidMem.bytes));
- node->VidMem.logical = gcvNULL;
- }
-#endif
-#endif
-
- /* Free video memory. */
- status =
- gckVIDMEM_Free(node);
-
- break;
-
case gcvHAL_WRITE_DATA:
#ifndef __QNXNTO__
/* Convert physical into logical address. */
break;
case gcvHAL_UNLOCK_VIDEO_MEMORY:
- node = gcmUINT64_TO_PTR(record->info.u.UnlockVideoMemory.node);
-
gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
"gcvHAL_UNLOCK_VIDEO_MEMORY: 0x%x",
- node);
+ record->info.u.UnlockVideoMemory.node);
+
+ nodeObject = gcmUINT64_TO_PTR(record->info.u.UnlockVideoMemory.node);
+
+ node = nodeObject->node;
/* Save node information before it disappears. */
#if gcdSECURE_USER
+ node = event->event.u.UnlockVideoMemory.node;
if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
{
logical = gcvNULL;
/* Unlock. */
status = gckVIDMEM_Unlock(
Event->kernel,
- node,
+ nodeObject,
record->info.u.UnlockVideoMemory.type,
gcvNULL);
bytes));
}
#endif
+
+#if gcdPROCESS_ADDRESS_SPACE
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Unlock(
+ Event->kernel,
+ nodeObject,
+ record->processID
+ ));
+#endif
+
+ status = gckVIDMEM_NODE_Dereference(Event->kernel, nodeObject);
break;
case gcvHAL_SIGNAL:
}
break;
-#if gcdVIRTUAL_COMMAND_BUFFER
case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
gcmkVERIFY_OK(
gckKERNEL_DestroyVirtualCommandBuffer(Event->kernel,
));
gcmRELEASE_NAME(record->info.u.FreeVirtualCommandBuffer.physical);
break;
-#endif
#if gcdANDROID_NATIVE_FENCE_SYNC
case gcvHAL_SYNC_POINT:
break;
#endif
+#if gcdPROCESS_ADDRESS_SPACE
+ case gcvHAL_DESTROY_MMU:
+ status = gckMMU_Destroy(gcmUINT64_TO_PTR(record->info.u.DestroyMmu.mmu));
+ break;
+#endif
+
case gcvHAL_COMMIT_DONE:
break;
"Handled interrupt 0x%x", mask);
}
+#if gcdMULTI_GPU
+ /* Clear busy flag. */
+ gckOS_AtomicExchange(Event->os, &Event->busy, 0, &oldValue);
+#endif
+
if (IDs == 0)
{
gcmkONERROR(_TryToIdleGPU(Event));
}
- /* We are out the notify loop. */
- Event->inNotify = gcvFALSE;
-
+#if gcdMULTI_GPU
+OnSuccess:
+#endif
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
}
#endif
- /* We are out the notify loop. */
- Event->inNotify = gcvFALSE;
-
/* Return the status. */
gcmkFOOTER();
return status;
IN gctPHYS_ADDR Handle,
IN gctPOINTER Logical,
IN gctSIGNAL Signal,
- IN OUT gctSIZE_T * waitSize
+ IN OUT gctUINT32 * waitSize
)
{
gceSTATUS status;
gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
/* Submit the current event queue. */
+#if gcdMULTI_GPU
+ gcmkONERROR(gckEVENT_Submit(Event, gcvTRUE, gcvFALSE, gcvCORE_3D_ALL_MASK));
+#else
gcmkONERROR(gckEVENT_Submit(Event, gcvTRUE, gcvFALSE));
-
+#endif
+#if gcdMULTI_GPU
+ gcmkONERROR(gckEVENT_GetEvent(Event, gcvTRUE, &id, gcvKERNEL_PIXEL, gcvCORE_3D_ALL_MASK));
+#else
gcmkONERROR(gckEVENT_GetEvent(Event, gcvTRUE, &id, gcvKERNEL_PIXEL));
+#endif
/* Allocate a record. */
gcmkONERROR(gckEVENT_AllocateRecord(Event, gcvTRUE, &record));
Event->os,
ProcessID,
gcvNULL,
- Handle,
+ (gctUINT32)Handle,
Logical,
*waitSize
));
gcmkPRINT(" gcvHAL_FREE_CONTIGUOUS_MEMORY");
break;
- case gcvHAL_FREE_VIDEO_MEMORY:
- gcmkPRINT(" gcvHAL_FREE_VIDEO_MEMORY");
- break;
-
case gcvHAL_WRITE_DATA:
gcmkPRINT(" gcvHAL_WRITE_DATA");
break;
record->info.u.FreeVirtualCommandBuffer.logical);
break;
+ case gcvHAL_SYNC_POINT:
+ gcmkPRINT(" gcvHAL_SYNC_POINT syncPoint=0x%08x",
+ gcmUINT64_TO_PTR(record->info.u.SyncPoint.syncPoint));
+
+ break;
+
+ case gcvHAL_DESTROY_MMU:
+ gcmkPRINT(" gcvHAL_DESTORY_MMU mmu=0x%08x",
+ gcmUINT64_TO_PTR(record->info.u.DestroyMmu.mmu));
+
+ break;
default:
gcmkPRINT(" Illegal Event %d", record->info.command);
break;
gcsEVENT_QUEUE_PTR queue;
gcsEVENT_PTR record = gcvNULL;
gctINT i;
+#if gcdINTERRUPT_STATISTIC
+ gctINT32 pendingInterrupt;
+ gctUINT32 intrAcknowledge;
+#endif
gcmkHEADER_ARG("Event=0x%x", Event);
gcmkPRINT("*** EVENT STATE DUMP ***\n");
gcmkPRINT("**************************\n");
-
gcmkPRINT(" Unsumbitted Event:");
while(queueHead)
{
}
gcmkPRINT(" Untriggered Event:");
- for (i = 0; i < 30; i++)
+ for (i = 0; i < gcmCOUNTOF(Event->queues); i++)
{
queue = &Event->queues[i];
record = queue->head;
}
}
- gcmkFOOTER_NO();
- return gcvSTATUS_OK;
-}
+#if gcdINTERRUPT_STATISTIC
+ gckOS_AtomGet(Event->os, Event->interruptCount, &pendingInterrupt);
+ gcmkPRINT(" Number of Pending Interrupt: %d", pendingInterrupt);
-gceSTATUS gckEVENT_WaitEmpty(gckEVENT Event)
-{
- gctBOOL isEmpty;
+ if (Event->kernel->recovery == 0)
+ {
+ gckOS_ReadRegisterEx(
+ Event->os,
+ Event->kernel->core,
+ 0x10,
+ &intrAcknowledge
+ );
- while (Event->inNotify || (gcmIS_SUCCESS(gckEVENT_IsEmpty(Event, &isEmpty)) && !isEmpty)) ;
+ gcmkPRINT(" INTR_ACKNOWLEDGE=0x%x", intrAcknowledge);
+ }
+#endif
+ gcmkFOOTER_NO();
return gcvSTATUS_OK;
}
+
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
/*******************************************************************************
***** Structures ***************************************************************
*******************************************************************************/
-
-#define gcdIN_USE ((gcskNODE_PTR) ~0)
+#define gcdIN_USE ((gcskNODE_PTR)gcvMAXUINTPTR_T)
typedef struct _gcskNODE * gcskNODE_PTR;
typedef struct _gcskNODE
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#define gcdMMU_TABLE_DUMP 0
-#define gcdUSE_MMU_EXCEPTION 0
+#define gcdUSE_MMU_EXCEPTION 1
/*
gcdMMU_CLEAR_VALUE
# define gcdMMU_CLEAR_VALUE 0x00000ABC
#endif
-/* VIV: Start GPU address for gcvSURF_VERTEX. */
#define gcdVERTEX_START (128 << 10)
typedef struct _gcsMMU_STLB *gcsMMU_STLB_PTR;
else
{
/* Address page table. */
- gctUINT32_PTR pageTable = Mmu->pageTableLogical;
+ gctUINT32_PTR map = Mmu->mapLogical;
/* Dispatch on node type. */
- switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[Index])))
+ switch (gcmENTRY_TYPE(_ReadPageEntry(&map[Index])))
{
case gcvMMU_SINGLE:
/* Set single index. */
- _WritePageEntry(&pageTable[Index], (Next << 8) | gcvMMU_SINGLE);
+ _WritePageEntry(&map[Index], (Next << 8) | gcvMMU_SINGLE);
break;
case gcvMMU_FREE:
/* Set index. */
- _WritePageEntry(&pageTable[Index + 1], Next);
+ _WritePageEntry(&map[Index + 1], Next);
break;
default:
IN gctUINT32 Count
)
{
- gctUINT32_PTR pageTable = Mmu->pageTableLogical;
+ gctUINT32_PTR map = Mmu->mapLogical;
if (Count == 1)
{
/* Initialize a single page node. */
- _WritePageEntry(pageTable + Node, (~((1U<<8)-1)) | gcvMMU_SINGLE);
+ _WritePageEntry(map + Node, (~((1U<<8)-1)) | gcvMMU_SINGLE);
}
else
{
/* Initialize the node. */
- _WritePageEntry(pageTable + Node + 0, (Count << 8) | gcvMMU_FREE);
- _WritePageEntry(pageTable + Node + 1, ~0U);
+ _WritePageEntry(map + Node + 0, (Count << 8) | gcvMMU_FREE);
+ _WritePageEntry(map + Node + 1, ~0U);
}
/* Append the node. */
IN gckMMU Mmu
)
{
- gctUINT32_PTR pageTable = Mmu->pageTableLogical;
+ gctUINT32_PTR map = Mmu->mapLogical;
gceSTATUS status;
gctUINT32 i, previous, start = 0, count = 0;
for (i = 0; i < Mmu->pageTableEntries; ++i)
{
/* Dispatch based on type of page. */
- switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[i])))
+ switch (gcmENTRY_TYPE(_ReadPageEntry(&map[i])))
{
case gcvMMU_USED:
/* Used page, so close any open node. */
}
/* Advance the count. */
- count += _ReadPageEntry(&pageTable[i]) >> 8;
+ count += _ReadPageEntry(&map[i]) >> 8;
/* Advance the index into the page table. */
- i += (_ReadPageEntry(&pageTable[i]) >> 8) - 1;
+ i += (_ReadPageEntry(&map[i]) >> 8) - 1;
break;
default:
| (1 << 0);
}
+#if gcdPROCESS_ADDRESS_SPACE
+gctUINT32
+_AddressToIndex(
+ IN gckMMU Mmu,
+ IN gctUINT32 Address
+ )
+{
+ gctUINT32 mtlbOffset = (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
+ gctUINT32 stlbOffset = (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
+
+ return (mtlbOffset - Mmu->dynamicMappingStart) * gcdMMU_STLB_4K_ENTRY_NUM + stlbOffset;
+}
+
+gctUINT32
+_MtlbOffset(
+ gctUINT32 Address
+ )
+{
+ return (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
+}
+
+gctUINT32
+_StlbOffset(
+ gctUINT32 Address
+ )
+{
+ return (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
+}
+
+static gceSTATUS
+_AllocateStlb(
+ IN gckOS Os,
+ OUT gcsMMU_STLB_PTR *Stlb
+ )
+{
+ gceSTATUS status;
+ gcsMMU_STLB_PTR stlb;
+ gctPOINTER pointer;
+
+ /* Allocate slave TLB record. */
+ gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsMMU_STLB), &pointer));
+ stlb = pointer;
+
+ stlb->size = gcdMMU_STLB_4K_SIZE;
+
+ /* Allocate slave TLB entries. */
+ gcmkONERROR(gckOS_AllocateContiguous(
+ Os,
+ gcvFALSE,
+ &stlb->size,
+ &stlb->physical,
+ (gctPOINTER)&stlb->logical
+ ));
+
+ gcmkONERROR(gckOS_GetPhysicalAddress(Os, stlb->logical, &stlb->physBase));
+
+#if gcdUSE_MMU_EXCEPTION
+ _FillPageTable(stlb->logical, stlb->size / 4, gcdMMU_STLB_EXCEPTION);
+#else
+ gckOS_ZeroMemory(stlb->logical, stlb->size);
+#endif
+
+ *Stlb = stlb;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+gceSTATUS
+_SetupProcessAddressSpace(
+ IN gckMMU Mmu
+ )
+{
+ gceSTATUS status;
+ gctINT numEntries = 0;
+ gctUINT32_PTR map;
+
+ numEntries = gcdPROCESS_ADDRESS_SPACE_SIZE
+ /* Address space mapped by one MTLB entry. */
+ / (1 << gcdMMU_MTLB_SHIFT);
+
+ Mmu->dynamicMappingStart = 0;
+
+ Mmu->pageTableSize = numEntries * 4096;
+
+ Mmu->pageTableEntries = Mmu->pageTableSize / gcmSIZEOF(gctUINT32);
+
+ gcmkONERROR(gckOS_Allocate(Mmu->os,
+ Mmu->pageTableSize,
+ (void **)&Mmu->mapLogical));
+
+ /* Initilization. */
+ map = Mmu->mapLogical;
+ _WritePageEntry(map, (Mmu->pageTableEntries << 8) | gcvMMU_FREE);
+ _WritePageEntry(map + 1, ~0U);
+ Mmu->heapList = 0;
+ Mmu->freeNodes = gcvFALSE;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+#else
static gceSTATUS
_FillFlatMapping(
IN gckMMU Mmu,
gctUINT32 mEnd = end >> gcdMMU_MTLB_SHIFT;
gctUINT32 sStart = (start & gcdMMU_STLB_64K_MASK) >> gcdMMU_STLB_64K_SHIFT;
gctUINT32 sEnd = (end & gcdMMU_STLB_64K_MASK) >> gcdMMU_STLB_64K_SHIFT;
+ gctBOOL ace = gckHARDWARE_IsFeatureAvailable(Mmu->hardware, gcvFEATURE_ACE);
/* Grab the mutex. */
gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
gcsMMU_STLB_PTR stlb;
gctPOINTER pointer = gcvNULL;
gctUINT32 last = (mStart == mEnd) ? sEnd : (gcdMMU_STLB_64K_ENTRY_NUM - 1);
+ gctUINT32 mtlbEntry;
gcmkONERROR(gckOS_Allocate(Mmu->os, sizeof(struct _gcsMMU_STLB), &pointer));
stlb = pointer;
gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
}
- _WritePageEntry(Mmu->mtlbLogical + mStart,
- stlb->physBase
- /* 64KB page size */
- | (1 << 2)
- /* Ignore exception */
- | (0 << 1)
- /* Present */
- | (1 << 0)
- );
+ mtlbEntry = stlb->physBase
+ /* 64KB page size */
+ | (1 << 2)
+ /* Ignore exception */
+ | (0 << 1)
+ /* Present */
+ | (1 << 0);
+
+ if (ace)
+ {
+ mtlbEntry = mtlbEntry
+ /* Secure */
+ | (1 << 4);
+ }
+
+ _WritePageEntry(Mmu->mtlbLogical + mStart, mtlbEntry);
+
#if gcdMMU_TABLE_DUMP
gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
__FUNCTION__, __LINE__,
gctINT i, nodeArraySize = 0;
gctUINT32 physical;
gctINT numEntries = 0;
- gctUINT32_PTR pageTable;
+ gctUINT32_PTR map;
gctBOOL acquired = gcvFALSE;
+ gctUINT32 mtlbEntry;
+ gctBOOL ace = gckHARDWARE_IsFeatureAvailable(Mmu->hardware, gcvFEATURE_ACE);
/* Find all the dynamic address space. */
gcmkONERROR(_FindDynamicSpace(Mmu, &nodeArray, &nodeArraySize));
Mmu->pageTableSize = numEntries * 4096;
- Mmu->pageTableEntries = Mmu->pageTableSize / gcmSIZEOF(gctUINT32);
+ gcmkSAFECASTSIZET(Mmu->pageTableEntries, Mmu->pageTableSize / gcmSIZEOF(gctUINT32));
+
+ gcmkONERROR(gckOS_Allocate(Mmu->os,
+ Mmu->pageTableSize,
+ (void **)&Mmu->mapLogical));
/* Construct Slave TLB. */
gcmkONERROR(gckOS_AllocateContiguous(Mmu->os,
#endif
/* Initilization. */
- pageTable = Mmu->pageTableLogical;
- _WritePageEntry(pageTable, (Mmu->pageTableEntries << 8) | gcvMMU_FREE);
- _WritePageEntry(pageTable + 1, ~0U);
+ map = Mmu->mapLogical;
+ _WritePageEntry(map, (Mmu->pageTableEntries << 8) | gcvMMU_FREE);
+ _WritePageEntry(map + 1, ~0U);
Mmu->heapList = 0;
Mmu->freeNodes = gcvFALSE;
i < (gctINT)Mmu->dynamicMappingStart + numEntries;
i++)
{
- _WritePageEntry(Mmu->mtlbLogical + i,
- physical
- /* 4KB page size */
- | (0 << 2)
- /* Ignore exception */
- | (0 << 1)
- /* Present */
- | (1 << 0)
- );
+ mtlbEntry = physical
+ /* 4KB page size */
+ | (0 << 2)
+ /* Ignore exception */
+ | (0 << 1)
+ /* Present */
+ | (1 << 0);
+
+ if (ace)
+ {
+ mtlbEntry = mtlbEntry
+ /* Secure */
+ | (1 << 4);
+ }
+
+ _WritePageEntry(Mmu->mtlbLogical + i, mtlbEntry);
+
#if gcdMMU_TABLE_DUMP
gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
__FUNCTION__, __LINE__,
return gcvSTATUS_OK;
OnError:
- if (Mmu->pageTableLogical)
+ if (Mmu->mapLogical)
{
- /* Free the page table. */
gcmkVERIFY_OK(
- gckOS_FreeContiguous(Mmu->os,
- Mmu->pageTablePhysical,
- (gctPOINTER) Mmu->pageTableLogical,
- Mmu->pageTableSize));
+ gckOS_Free(Mmu->os, (gctPOINTER) Mmu->mapLogical));
+
+
+ gcmkVERIFY_OK(
+ gckOS_FreeContiguous(Mmu->os,
+ Mmu->pageTablePhysical,
+ (gctPOINTER) Mmu->pageTableLogical,
+ Mmu->pageTableSize));
}
if (acquired)
return status;
}
+#endif
/*******************************************************************************
**
gckHARDWARE hardware;
gceSTATUS status;
gckMMU mmu = gcvNULL;
- gctUINT32_PTR pageTable;
+ gctUINT32_PTR map;
gctPOINTER pointer = gcvNULL;
+#if gcdPROCESS_ADDRESS_SPACE
+ gctUINT32 i;
+ gctUINT32 physical;
+#endif
+ gctUINT32 physBase;
+ gctUINT32 physSize;
+ gctUINT32 gpuAddress;
gcmkHEADER_ARG("Kernel=0x%x MmuSize=%lu", Kernel, MmuSize);
mmu->mtlbLogical = gcvNULL;
mmu->staticSTLB = gcvNULL;
mmu->enabled = gcvFALSE;
-#ifdef __QNXNTO__
- mmu->nodeList = gcvNULL;
- mmu->nodeMutex = gcvNULL;
-#endif
+ mmu->mapLogical = gcvNULL;
/* Create the page table mutex. */
gcmkONERROR(gckOS_CreateMutex(os, &mmu->pageTableMutex));
-#ifdef __QNXNTO__
- /* Create the node list mutex. */
- gcmkONERROR(gckOS_CreateMutex(os, &mmu->nodeMutex));
-#endif
-
if (hardware->mmuVersion == 0)
{
mmu->pageTableSize = MmuSize;
- gcmkONERROR(
- gckOS_AllocateContiguous(os,
- gcvFALSE,
- &mmu->pageTableSize,
- &mmu->pageTablePhysical,
- &pointer));
+ /* Construct address space management table. */
+ gcmkONERROR(gckOS_Allocate(mmu->os,
+ mmu->pageTableSize,
+ &pointer));
+
+ mmu->mapLogical = pointer;
+
+ /* Construct page table read by GPU. */
+ gcmkONERROR(gckOS_AllocateContiguous(mmu->os,
+ gcvFALSE,
+ &mmu->pageTableSize,
+ &mmu->pageTablePhysical,
+ (gctPOINTER)&mmu->pageTableLogical));
- mmu->pageTableLogical = pointer;
/* Compute number of entries in page table. */
- mmu->pageTableEntries = mmu->pageTableSize / sizeof(gctUINT32);
+ gcmkSAFECASTSIZET(mmu->pageTableEntries, mmu->pageTableSize / sizeof(gctUINT32));
/* Mark all pages as free. */
- pageTable = mmu->pageTableLogical;
+ map = mmu->mapLogical;
#if gcdMMU_CLEAR_VALUE
- _FillPageTable(pageTable, mmu->pageTableEntries, gcdMMU_CLEAR_VALUE);
+ _FillPageTable(mmu->pageTableLogical, mmu->pageTableEntries, gcdMMU_CLEAR_VALUE);
#endif
- _WritePageEntry(pageTable, (mmu->pageTableEntries << 8) | gcvMMU_FREE);
- _WritePageEntry(pageTable + 1, ~0U);
+ _WritePageEntry(map, (mmu->pageTableEntries << 8) | gcvMMU_FREE);
+ _WritePageEntry(map + 1, ~0U);
mmu->heapList = 0;
mmu->freeNodes = gcvFALSE;
-
- /* Set page table address. */
- gcmkONERROR(
- gckHARDWARE_SetMMU(hardware, (gctPOINTER) mmu->pageTableLogical));
}
else
{
mmu->mtlbLogical = pointer;
+#if gcdPROCESS_ADDRESS_SPACE
+ _FillPageTable(pointer, mmu->mtlbSize / 4, gcdMMU_MTLB_EXCEPTION);
+
+ /* Allocate a array to store stlbs. */
+ gcmkONERROR(gckOS_Allocate(os, mmu->mtlbSize, &mmu->stlbs));
+
+ gckOS_ZeroMemory(mmu->stlbs, mmu->mtlbSize);
+
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ gcmkONERROR(gckOS_AtomConstruct(os, &mmu->pageTableDirty[i]));
+ }
+
+ _SetupProcessAddressSpace(mmu);
+
+ /* Map kernel command buffer in MMU. */
+ for (i = 0; i < gcdCOMMAND_QUEUES; i++)
+ {
+ gcmkONERROR(gckOS_GetPhysicalAddress(
+ mmu->os,
+ Kernel->command->queues[i].logical,
+ &physical
+ ));
+
+ gcmkONERROR(gckMMU_FlatMapping(mmu, physical));
+ }
+#else
/* Invalid all the entries. */
gcmkONERROR(
gckOS_ZeroMemory(pointer, mmu->mtlbSize));
+
+ gcmkONERROR(
+ gckOS_QueryOption(mmu->os, "physBase", &physBase));
+
+ gcmkONERROR(
+ gckOS_QueryOption(mmu->os, "physSize", &physSize));
+
+ gcmkONERROR(
+ gckOS_CPUPhysicalToGPUPhysical(mmu->os, physBase, &gpuAddress));
+
+ /* Setup [physBase - physSize) flat mapping. */
+ gcmkONERROR(_FillFlatMapping(
+ mmu,
+ gpuAddress,
+ physSize
+ ));
+
+ gcmkONERROR(_SetupDynamicSpace(mmu));
+#endif
}
/* Return the gckMMU object pointer. */
/* Roll back. */
if (mmu != gcvNULL)
{
- if (mmu->pageTableLogical != gcvNULL)
+ if (mmu->mapLogical != gcvNULL)
{
- /* Free the page table. */
+ gcmkVERIFY_OK(
+ gckOS_Free(os, (gctPOINTER) mmu->mapLogical));
+
+
gcmkVERIFY_OK(
gckOS_FreeContiguous(os,
mmu->pageTablePhysical,
(gctPOINTER) mmu->pageTableLogical,
mmu->pageTableSize));
-
}
if (mmu->mtlbLogical != gcvNULL)
gckOS_DeleteMutex(os, mmu->pageTableMutex));
}
-#ifdef __QNXNTO__
- if (mmu->nodeMutex != gcvNULL)
- {
- /* Delete the mutex. */
- gcmkVERIFY_OK(
- gckOS_DeleteMutex(os, mmu->nodeMutex));
- }
-#endif
-
/* Mark the gckMMU object as unknown. */
mmu->object.type = gcvOBJ_UNKNOWN;
IN gckMMU Mmu
)
{
-#ifdef __QNXNTO__
- gcuVIDMEM_NODE_PTR node, next;
+#if gcdPROCESS_ADDRESS_SPACE
+ gctUINT32 i;
#endif
-
gcmkHEADER_ARG("Mmu=0x%x", Mmu);
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
-#ifdef __QNXNTO__
- /* Free all associated virtual memory. */
- for (node = Mmu->nodeList; node != gcvNULL; node = next)
- {
- next = node->Virtual.next;
- gcmkVERIFY_OK(gckVIDMEM_Free(node));
- }
-#endif
-
while (Mmu->staticSTLB != gcvNULL)
{
gcsMMU_STLB_PTR pre = Mmu->staticSTLB;
Mmu->mtlbSize));
}
- /* Free the page table. */
- gcmkVERIFY_OK(
- gckOS_FreeContiguous(Mmu->os,
- Mmu->pageTablePhysical,
- (gctPOINTER) Mmu->pageTableLogical,
- Mmu->pageTableSize));
+ /* Free address space management table. */
+ if (Mmu->mapLogical != gcvNULL)
+ {
+ gcmkVERIFY_OK(
+ gckOS_Free(Mmu->os, (gctPOINTER) Mmu->mapLogical));
+ }
-#ifdef __QNXNTO__
- /* Delete the node list mutex. */
- gcmkVERIFY_OK(gckOS_DeleteMutex(Mmu->os, Mmu->nodeMutex));
-#endif
+ if (Mmu->pageTableLogical != gcvNULL)
+ {
+ /* Free page table. */
+ gcmkVERIFY_OK(
+ gckOS_FreeContiguous(Mmu->os,
+ Mmu->pageTablePhysical,
+ (gctPOINTER) Mmu->pageTableLogical,
+ Mmu->pageTableSize));
+ }
/* Delete the page table mutex. */
gcmkVERIFY_OK(gckOS_DeleteMutex(Mmu->os, Mmu->pageTableMutex));
+#if gcdPROCESS_ADDRESS_SPACE
+ for (i = 0; i < Mmu->mtlbSize / 4; i++)
+ {
+ struct _gcsMMU_STLB *stlb = ((struct _gcsMMU_STLB **)Mmu->stlbs)[i];
+
+ if (stlb)
+ {
+ gcmkVERIFY_OK(gckOS_FreeContiguous(
+ Mmu->os,
+ stlb->physical,
+ stlb->logical,
+ stlb->size));
+
+ gcmkOS_SAFE_FREE(Mmu->os, stlb);
+ }
+ }
+
+ gcmkOS_SAFE_FREE(Mmu->os, Mmu->stlbs);
+#endif
+
/* Mark the gckMMU object as unknown. */
Mmu->object.type = gcvOBJ_UNKNOWN;
{
gceSTATUS status;
gctUINT32 index = Index;
- gctUINT32_PTR map = Mmu->pageTableLogical;
+ gctUINT32_PTR map = Mmu->mapLogical;
gcmkHEADER();
gcmkONERROR(_Construct(Kernel, MmuSize, &sharedPageTable->mmu));
}
- else if (Kernel->hardware->mmuVersion == 0)
- {
- /* Set page table address. */
- gcmkONERROR(
- gckHARDWARE_SetMMU(Kernel->hardware, (gctPOINTER) sharedPageTable->mmu->pageTableLogical));
- }
*Mmu = sharedPageTable->mmu;
)
{
#if gcdSHARED_PAGETABLE
+ gckOS os = Mmu->os;
+
sharedPageTable->reference--;
if (sharedPageTable->reference == 0)
gcmkVERIFY_OK(_Destroy(Mmu));
}
- gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, sharedPageTable));
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, sharedPageTable));
}
return gcvSTATUS_OK;
gceSTATUS status;
gctBOOL mutex = gcvFALSE;
gctUINT32 index = 0, previous = ~0U, left;
- gctUINT32_PTR pageTable;
+ gctUINT32_PTR map;
gctBOOL gotIt;
gctUINT32 address;
+ gctUINT32 pageCount;
gcmkHEADER_ARG("Mmu=0x%x PageCount=%lu", Mmu, PageCount);
if (PageCount > Mmu->pageTableEntries)
{
- gcmkPRINT("[galcore]: %s(%d): Run out of free page entry.",
- __FUNCTION__, __LINE__);
-
/* Not enough pages avaiable. */
gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
}
+ gcmkSAFECASTSIZET(pageCount, PageCount);
+
/* Grab the mutex. */
gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
mutex = gcvTRUE;
/* Cast pointer to page table. */
- for (pageTable = Mmu->pageTableLogical, gotIt = gcvFALSE; !gotIt;)
+ for (map = Mmu->mapLogical, gotIt = gcvFALSE; !gotIt;)
{
index = Mmu->heapList;
gcmkONERROR(_AdjustIndex(
Mmu,
index,
- PageCount,
+ pageCount,
gcdVERTEX_START / gcmSIZEOF(gctUINT32),
&index
));
for (; !gotIt && (index < Mmu->pageTableEntries);)
{
/* Check the node type. */
- switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[index])))
+ switch (gcmENTRY_TYPE(_ReadPageEntry(&map[index])))
{
case gcvMMU_SINGLE:
/* Single odes are valid if we only need 1 page. */
- if (PageCount == 1)
+ if (pageCount == 1)
{
gotIt = gcvTRUE;
}
{
/* Move to next node. */
previous = index;
- index = _ReadPageEntry(&pageTable[index]) >> 8;
+ index = _ReadPageEntry(&map[index]) >> 8;
}
break;
case gcvMMU_FREE:
/* Test if the node has enough space. */
- if (PageCount <= (_ReadPageEntry(&pageTable[index]) >> 8))
+ if (pageCount <= (_ReadPageEntry(&map[index]) >> 8))
{
gotIt = gcvTRUE;
}
{
/* Move to next node. */
previous = index;
- index = _ReadPageEntry(&pageTable[index + 1]);
+ index = _ReadPageEntry(&map[index + 1]);
}
break;
}
else
{
- gcmkPRINT("[galcore]: %s(%d): Run out of free page entry.",
- __FUNCTION__, __LINE__);
-
/* Out of resources. */
gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
}
}
}
- switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[index])))
+ switch (gcmENTRY_TYPE(_ReadPageEntry(&map[index])))
{
case gcvMMU_SINGLE:
/* Unlink single node from free list. */
gcmkONERROR(
- _Link(Mmu, previous, _ReadPageEntry(&pageTable[index]) >> 8));
+ _Link(Mmu, previous, _ReadPageEntry(&map[index]) >> 8));
break;
case gcvMMU_FREE:
/* Check how many pages will be left. */
- left = (_ReadPageEntry(&pageTable[index]) >> 8) - PageCount;
+ left = (_ReadPageEntry(&map[index]) >> 8) - pageCount;
switch (left)
{
case 0:
/* The entire node is consumed, just unlink it. */
gcmkONERROR(
- _Link(Mmu, previous, _ReadPageEntry(&pageTable[index + 1])));
+ _Link(Mmu, previous, _ReadPageEntry(&map[index + 1])));
break;
case 1:
/* One page will remain. Convert the node to a single node and
** advance the index. */
- _WritePageEntry(&pageTable[index], (_ReadPageEntry(&pageTable[index + 1]) << 8) | gcvMMU_SINGLE);
+ _WritePageEntry(&map[index], (_ReadPageEntry(&map[index + 1]) << 8) | gcvMMU_SINGLE);
index ++;
break;
default:
/* Enough pages remain for a new node. However, we will just adjust
** the size of the current node and advance the index. */
- _WritePageEntry(&pageTable[index], (left << 8) | gcvMMU_FREE);
+ _WritePageEntry(&map[index], (left << 8) | gcvMMU_FREE);
index += left;
break;
}
}
/* Mark node as used. */
- gcmkONERROR(_FillPageTable(&pageTable[index], PageCount, gcvMMU_USED));
+ gcmkONERROR(_FillPageTable(&map[index], pageCount, gcvMMU_USED));
/* Return pointer to page table. */
- *PageTable = &pageTable[index];
+ *PageTable = &Mmu->pageTableLogical[index];
/* Build virtual address. */
if (Mmu->hardware->mmuVersion == 0)
IN gctSIZE_T PageCount
)
{
- gctUINT32_PTR pageTable;
+ gctUINT32_PTR node;
gceSTATUS status;
gctBOOL acquired = gcvFALSE;
+ gctUINT32 pageCount;
gcmkHEADER_ARG("Mmu=0x%x PageTable=0x%x PageCount=%lu",
Mmu, PageTable, PageCount);
gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
gcmkVERIFY_ARGUMENT(PageCount > 0);
- /* Convert the pointer. */
- pageTable = (gctUINT32_PTR) PageTable;
+ gcmkSAFECASTSIZET(pageCount, PageCount);
+
+ /* Get the node by index. */
+ node = Mmu->mapLogical + ((gctUINT32_PTR)PageTable - Mmu->pageTableLogical);
gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
acquired = gcvTRUE;
#if gcdMMU_CLEAR_VALUE
if (Mmu->hardware->mmuVersion == 0)
{
- _FillPageTable(pageTable, PageCount, gcdMMU_CLEAR_VALUE);
+ _FillPageTable(PageTable, pageCount, gcdMMU_CLEAR_VALUE);
}
#endif
if (PageCount == 1)
{
- /* Single page node. */
- _WritePageEntry(pageTable,
- (~((1U<<8)-1)) | gcvMMU_SINGLE
+ /* Single page node. */
+ _WritePageEntry(node, (~((1U<<8)-1)) | gcvMMU_SINGLE);
#if gcdUSE_MMU_EXCEPTION
- /* Enable exception */
- | 1 << 1
+ /* Enable exception */
+ _WritePageEntry(PageTable, (1 << 1));
#endif
- );
}
else
{
/* Mark the node as free. */
- _WritePageEntry(pageTable,
- (PageCount << 8) | gcvMMU_FREE
-#if gcdUSE_MMU_EXCEPTION
- /* Enable exception */
- | 1 << 1
-#endif
- );
- _WritePageEntry(pageTable + 1, ~0U);
+ _WritePageEntry(node, (pageCount << 8) | gcvMMU_FREE);
+ _WritePageEntry(node + 1, ~0U);
#if gcdUSE_MMU_EXCEPTION
/* Enable exception */
- gcmkVERIFY_OK(_FillPageTable(pageTable + 2, PageCount - 2, 1 << 1));
+ gcmkVERIFY_OK(_FillPageTable(PageTable, pageCount, 1 << 1));
#endif
}
)
{
return gckMMU_AllocatePagesEx(
- Mmu, PageCount, gcvSURF_UNKNOWN, PageTable, Address);
+ Mmu, PageCount, gcvSURF_TYPE_UNKNOWN, PageTable, Address);
}
gceSTATUS
#endif
}
-gceSTATUS
-gckMMU_Enable(
- IN gckMMU Mmu,
- IN gctUINT32 PhysBaseAddr,
- IN gctUINT32 PhysSize
- )
-{
- gceSTATUS status;
-#if gcdSHARED_PAGETABLE
- gckHARDWARE hardware;
- gctINT i;
-#endif
-
- gcmkHEADER_ARG("Mmu=0x%x", Mmu);
-
- /* Verify the arguments. */
- gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
-
-#if gcdSHARED_PAGETABLE
- if (Mmu->enabled)
- {
- gcmkFOOTER_ARG("Status=%d", gcvSTATUS_SKIP);
- return gcvSTATUS_SKIP;
- }
-#endif
-
- if (Mmu->hardware->mmuVersion == 0)
- {
- /* Success. */
- gcmkFOOTER_ARG("Status=%d", gcvSTATUS_SKIP);
- return gcvSTATUS_SKIP;
- }
- else
- {
- if (PhysSize != 0)
- {
- gcmkONERROR(_FillFlatMapping(
- Mmu,
- PhysBaseAddr,
- PhysSize
- ));
- }
-
- gcmkONERROR(_SetupDynamicSpace(Mmu));
-
-#if gcdSHARED_PAGETABLE
- for(i = 0; i < gcdMAX_GPU_COUNT; i++)
- {
- hardware = sharedPageTable->hardwares[i];
- if (hardware != gcvNULL)
- {
- gcmkONERROR(
- gckHARDWARE_SetMMUv2(
- hardware,
- gcvTRUE,
- Mmu->mtlbLogical,
- gcvMMU_MODE_4K,
- (gctUINT8_PTR)Mmu->mtlbLogical + gcdMMU_MTLB_SIZE,
- gcvFALSE
- ));
- }
- }
-#else
- gcmkONERROR(
- gckHARDWARE_SetMMUv2(
- Mmu->hardware,
- gcvTRUE,
- Mmu->mtlbLogical,
- gcvMMU_MODE_4K,
- (gctUINT8_PTR)Mmu->mtlbLogical + gcdMMU_MTLB_SIZE,
- gcvFALSE
- ));
-#endif
-
- Mmu->enabled = gcvTRUE;
-
- /* Success. */
- gcmkFOOTER_NO();
- return gcvSTATUS_OK;
- }
-
-OnError:
- /* Return the status. */
- gcmkFOOTER();
- return status;
-}
-
gceSTATUS
gckMMU_SetPage(
IN gckMMU Mmu,
gctUINT32 offset = (gctUINT32)PageEntry - (gctUINT32)Mmu->pageTableLogical;
#endif
- gctUINT32 data;
gcmkHEADER_ARG("Mmu=0x%x", Mmu);
/* Verify the arguments. */
if (Mmu->hardware->mmuVersion == 0)
{
- data = PageAddress;
+ _WritePageEntry(PageEntry, PageAddress);
}
else
{
- data = _SetPage(PageAddress);
+ _WritePageEntry(PageEntry, _SetPage(PageAddress));
}
- _WritePageEntry(PageEntry, data);
-
#if gcdMIRROR_PAGETABLE
for (i = 0; i < (gctINT)mirrorPageTable->reference; i++)
{
}
#endif
+
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
}
-#ifdef __QNXNTO__
+#if gcdPROCESS_ADDRESS_SPACE
gceSTATUS
-gckMMU_InsertNode(
+gckMMU_GetPageEntry(
IN gckMMU Mmu,
- IN gcuVIDMEM_NODE_PTR Node)
+ IN gctUINT32 Address,
+ IN gctUINT32_PTR *PageTable
+ )
{
gceSTATUS status;
- gctBOOL mutex = gcvFALSE;
+ struct _gcsMMU_STLB *stlb;
+ struct _gcsMMU_STLB **stlbs = Mmu->stlbs;
+ gctUINT32 offset = _MtlbOffset(Address);
+ gctUINT32 mtlbEntry;
+ gctBOOL ace = gckHARDWARE_IsFeatureAvailable(Mmu->hardware, gcvFEATURE_ACE);
- gcmkHEADER_ARG("Mmu=0x%x Node=0x%x", Mmu, Node);
+ gcmkHEADER_ARG("Mmu=0x%x", Mmu);
+ /* Verify the arguments. */
gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
+ gcmkVERIFY_ARGUMENT((Address & 0xFFF) == 0);
- gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->nodeMutex, gcvINFINITE));
- mutex = gcvTRUE;
+ stlb = stlbs[offset];
- Node->Virtual.next = Mmu->nodeList;
- Mmu->nodeList = Node;
+ if (stlb == gcvNULL)
+ {
+ gcmkONERROR(_AllocateStlb(Mmu->os, &stlb));
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
+ mtlbEntry = stlb->physBase
+ | gcdMMU_MTLB_4K_PAGE
+ | gcdMMU_MTLB_PRESENT
+ ;
- gcmkFOOTER();
+ if (ace)
+ {
+ mtlbEntry = mtlbEntry
+ /* Secure */
+ | (1 << 4);
+ }
+
+ /* Insert Slave TLB address to Master TLB entry.*/
+ _WritePageEntry(Mmu->mtlbLogical + offset, mtlbEntry);
+
+ /* Record stlb. */
+ stlbs[offset] = stlb;
+ }
+
+ *PageTable = &stlb->logical[_StlbOffset(Address)];
+
+ /* Success. */
+ gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
- if (mutex)
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+_CheckMap(
+ IN gckMMU Mmu
+ )
+{
+ gceSTATUS status;
+ gctUINT32_PTR map = Mmu->mapLogical;
+ gctUINT32 index;
+
+ for (index = Mmu->heapList; index < Mmu->pageTableEntries;)
{
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
+ /* Check the node type. */
+ switch (gcmENTRY_TYPE(_ReadPageEntry(&map[index])))
+ {
+ case gcvMMU_SINGLE:
+ /* Move to next node. */
+ index = _ReadPageEntry(&map[index]) >> 8;
+ break;
+
+ case gcvMMU_FREE:
+ /* Move to next node. */
+ index = _ReadPageEntry(&map[index + 1]);
+ break;
+
+ default:
+ gcmkFATAL("MMU table correcupted at index [%u] = %x!", index, map[index]);
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
}
- gcmkFOOTER();
+ return gcvSTATUS_OK;
+
+OnError:
return status;
}
gceSTATUS
-gckMMU_RemoveNode(
+gckMMU_FlatMapping(
IN gckMMU Mmu,
- IN gcuVIDMEM_NODE_PTR Node)
+ IN gctUINT32 Physical
+ )
{
gceSTATUS status;
- gctBOOL mutex = gcvFALSE;
- gcuVIDMEM_NODE_PTR *iter;
+ gctUINT32 index = _AddressToIndex(Mmu, Physical);
+ gctUINT32 i;
+ gctBOOL gotIt = gcvFALSE;
+ gctUINT32_PTR map = Mmu->mapLogical;
+ gctUINT32 previous = ~0U;
+ gctUINT32_PTR pageTable;
- gcmkHEADER_ARG("Mmu=0x%x Node=0x%x", Mmu, Node);
+ gckMMU_GetPageEntry(Mmu, Physical, &pageTable);
- gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
+ _WritePageEntry(pageTable, _SetPage(Physical));
- gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->nodeMutex, gcvINFINITE));
- mutex = gcvTRUE;
-
- for (iter = &Mmu->nodeList; *iter; iter = &(*iter)->Virtual.next)
+ if (map)
{
- if (*iter == Node)
+ /* Find node which contains index. */
+ for (i = 0; !gotIt && (i < Mmu->pageTableEntries);)
+ {
+ gctUINT32 numPages;
+
+ switch (gcmENTRY_TYPE(_ReadPageEntry(&map[i])))
+ {
+ case gcvMMU_SINGLE:
+ if (i == index)
+ {
+ gotIt = gcvTRUE;
+ }
+ else
+ {
+ previous = i;
+ i = _ReadPageEntry(&map[i]) >> 8;
+ }
+ break;
+
+ case gcvMMU_FREE:
+ numPages = _ReadPageEntry(&map[i]) >> 8;
+ if (index >= i && index < i + numPages)
+ {
+ gotIt = gcvTRUE;
+ }
+ else
+ {
+ previous = i;
+ i = _ReadPageEntry(&map[i + 1]);
+ }
+ break;
+
+ default:
+ gcmkFATAL("MMU table correcupted at index %u!", index);
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+ }
+
+ switch (gcmENTRY_TYPE(_ReadPageEntry(&map[i])))
{
- *iter = Node->Virtual.next;
+ case gcvMMU_SINGLE:
+ /* Unlink single node from free list. */
+ gcmkONERROR(
+ _Link(Mmu, previous, _ReadPageEntry(&map[i]) >> 8));
+ break;
+
+ case gcvMMU_FREE:
+ /* Split the node. */
+ {
+ gctUINT32 start;
+ gctUINT32 next = _ReadPageEntry(&map[i+1]);
+ gctUINT32 total = _ReadPageEntry(&map[i]) >> 8;
+ gctUINT32 countLeft = index - i;
+ gctUINT32 countRight = total - countLeft - 1;
+
+ if (countLeft)
+ {
+ start = i;
+ _AddFree(Mmu, previous, start, countLeft);
+ previous = start;
+ }
+
+ if (countRight)
+ {
+ start = index + 1;
+ _AddFree(Mmu, previous, start, countRight);
+ previous = start;
+ }
+
+ _Link(Mmu, previous, next);
+ }
break;
}
}
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
-
- gcmkFOOTER();
return gcvSTATUS_OK;
OnError:
- if (mutex)
- {
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
- }
- gcmkFOOTER();
+ /* Roll back. */
return status;
}
+
+
gceSTATUS
-gckMMU_FreeHandleMemory(
- IN gckKERNEL Kernel,
+gckMMU_FreePagesEx(
IN gckMMU Mmu,
- IN gctUINT32 Pid
+ IN gctUINT32 Address,
+ IN gctSIZE_T PageCount
)
{
+ gctUINT32_PTR node;
gceSTATUS status;
- gctBOOL acquired = gcvFALSE;
- gcuVIDMEM_NODE_PTR curr, next;
- gcmkHEADER_ARG("Kernel=0x%x, Mmu=0x%x Pid=%u", Kernel, Mmu, Pid);
+#if gcdUSE_MMU_EXCEPTION
+ gctUINT32 i;
+ struct _gcsMMU_STLB *stlb;
+ struct _gcsMMU_STLB **stlbs = Mmu->stlbs;
+#endif
+
+ gcmkHEADER_ARG("Mmu=0x%x Address=0x%x PageCount=%lu",
+ Mmu, Address, PageCount);
- gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ /* Verify the arguments. */
gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
+ gcmkVERIFY_ARGUMENT(PageCount > 0);
- gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->nodeMutex, gcvINFINITE));
- acquired = gcvTRUE;
+ /* Get the node by index. */
+ node = Mmu->mapLogical + _AddressToIndex(Mmu, Address);
- for (curr = Mmu->nodeList; curr != gcvNULL; curr = next)
+ gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
+
+ if (PageCount == 1)
{
- next = curr->Virtual.next;
+ /* Single page node. */
+ _WritePageEntry(node, (~((1U<<8)-1)) | gcvMMU_SINGLE);
+ }
+ else
+ {
+ /* Mark the node as free. */
+ _WritePageEntry(node, (PageCount << 8) | gcvMMU_FREE);
+ _WritePageEntry(node + 1, ~0U);
+ }
- if (curr->Virtual.processID == Pid)
- {
- while (curr->Virtual.unlockPendings[Kernel->core] == 0 && curr->Virtual.lockeds[Kernel->core] > 0)
- {
- gcmkONERROR(gckVIDMEM_Unlock(Kernel, curr, gcvSURF_TYPE_UNKNOWN, gcvNULL));
- }
+ /* We have free nodes. */
+ Mmu->freeNodes = gcvTRUE;
- gcmkVERIFY_OK(gckVIDMEM_Free(curr));
- }
+#if gcdUSE_MMU_EXCEPTION
+ for (i = 0; i < PageCount; i++)
+ {
+ /* Get */
+ stlb = stlbs[_MtlbOffset(Address)];
+
+ /* Enable exception */
+ stlb->logical[_StlbOffset(Address)] = gcdMMU_STLB_EXCEPTION;
}
+#endif
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
- gcmkFOOTER();
+
+ /* Success. */
+ gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
- if (acquired)
- {
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
- }
-
gcmkFOOTER();
return status;
}
gceSTATUS
gckMMU_Flush(
- IN gckMMU Mmu
+ IN gckMMU Mmu,
+ IN gceSURF_TYPE Type
)
{
gckHARDWARE hardware;
-#if gcdSHARED_PAGETABLE
+ gctUINT32 mask;
gctINT i;
+
+ if (Type == gcvSURF_VERTEX || Type == gcvSURF_INDEX)
+ {
+ mask = gcvPAGE_TABLE_DIRTY_BIT_FE;
+ }
+ else
+ {
+ mask = gcvPAGE_TABLE_DIRTY_BIT_OTHER;
+ }
+
+#if gcdPROCESS_ADDRESS_SPACE
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ gcmkVERIFY_OK(
+ gckOS_AtomSetMask(Mmu->pageTableDirty[i], mask));
+ }
+#else
+#if gcdSHARED_PAGETABLE
for (i = 0; i < gcdMAX_GPU_COUNT; i++)
{
-#if gcdENABLE_VG
- if (i == gcvCORE_VG)
- {
- continue;
- }
-#endif
hardware = sharedPageTable->hardwares[i];
if (hardware)
{
- /* Notify cores who use this page table. */
- gcmkVERIFY_OK(
- gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1));
+ gcmkVERIFY_OK(gckOS_AtomSetMask(hardware->pageTableDirty, mask));
}
}
#elif gcdMIRROR_PAGETABLE
- gctINT i;
- for (i = 0; i < mirrorPageTable->reference; i++)
+ for (i = 0; i < (gctINT)mirrorPageTable->reference; i++)
{
hardware = mirrorPageTable->hardwares[i];
/* Notify cores who use this page table. */
gcmkVERIFY_OK(
- gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1));
+ gckOS_AtomSetMask(hardware->pageTableDirty, mask));
}
#else
hardware = Mmu->hardware;
gcmkVERIFY_OK(
- gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1));
+ gckOS_AtomSetMask(hardware->pageTableDirty, mask));
+#endif
#endif
return gcvSTATUS_OK;
IN gctUINT32 Address
)
{
+#if gcdPROCESS_ADDRESS_SPACE
+ gcsMMU_STLB_PTR *stlbs = Mmu->stlbs;
+ gcsMMU_STLB_PTR stlbDesc = stlbs[_MtlbOffset(Address)];
+#else
gctUINT32_PTR pageTable;
gctUINT32 index;
gctUINT32 mtlb, stlb;
+#endif
gcmkHEADER_ARG("Mmu=0x%08X Address=0x%08X", Mmu, Address);
gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
gcmkASSERT(Mmu->hardware->mmuVersion > 0);
+#if gcdPROCESS_ADDRESS_SPACE
+ if (stlbDesc)
+ {
+ gcmkPRINT(" STLB entry = 0x%08X",
+ _ReadPageEntry(&stlbDesc->logical[_StlbOffset(Address)]));
+ }
+ else
+ {
+ gcmkPRINT(" MTLB entry is empty.");
+ }
+#else
mtlb = (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
- stlb = (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
- if (Address >= 0x80000000)
+ if (mtlb >= Mmu->dynamicMappingStart)
{
+ stlb = (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
+
pageTable = Mmu->pageTableLogical;
index = (mtlb - Mmu->dynamicMappingStart)
gcmkPRINT(" Page table entry = 0x%08X", _ReadPageEntry(pageTable + index));
}
+ else
+ {
+ gcsMMU_STLB_PTR stlbObj = Mmu->staticSTLB;
+ gctUINT32 entry = Mmu->mtlbLogical[mtlb];
+
+ stlb = (Address & gcdMMU_STLB_64K_MASK) >> gcdMMU_STLB_64K_SHIFT;
+
+ entry &= 0xFFFFFFF0;
+
+ while (stlbObj)
+ {
+
+ if (entry == stlbObj->physBase)
+ {
+ gcmkPRINT(" Page table entry = 0x%08X", stlbObj->logical[stlb]);
+ break;
+ }
+
+ stlbObj = stlbObj->next;
+ }
+ }
+#endif
gcmkFOOTER_NO();
return gcvSTATUS_OK;
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
*/
gceSTATUS gckVGMMU_Construct(
IN gckVGKERNEL Kernel,
- IN gctSIZE_T MmuSize,
+ IN gctUINT32 MmuSize,
OUT gckVGMMU * Mmu
)
{
}
/* Allocate the page table. */
- mmu->pageTableSize = MmuSize;
+ mmu->pageTableSize = (gctUINT32)MmuSize;
status = gckOS_AllocateContiguous(os,
gcvFALSE,
&mmu->pageTableSize,
}
/* Compute number of entries in page table. */
- mmu->entryCount = mmu->pageTableSize / sizeof(gctUINT32);
+ mmu->entryCount = (gctUINT32)mmu->pageTableSize / sizeof(gctUINT32);
mmu->entry = 0;
/* Mark the entire page table as available. */
}
/* Compute the tail for this allocation. */
- tail = Mmu->entryCount - PageCount;
+ tail = Mmu->entryCount - (gctUINT32)PageCount;
/* Walk all entries until we find enough slots. */
for (index = Mmu->entry; index <= tail;)
if (status >= 0)
{
/* Update current entry into page table. */
- Mmu->entry = index + PageCount;
+ Mmu->entry = index + (gctUINT32)PageCount;
/* Return pointer to page table. */
*PageTable = (gctUINT32 *) Mmu->pageTableLogical + index;
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
--- /dev/null
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2014 by Vivante Corp.
+*
+* 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.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_precomp.h"
+
+
+
+
+#define _GC_OBJ_ZONE gcvZONE_KERNEL
+
+#if gcdSECURITY
+
+/*
+** Open a security service channel.
+*/
+gceSTATUS
+gckKERNEL_SecurityOpen(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 GPU,
+ OUT gctUINT32 *Channel
+ )
+{
+ gceSTATUS status;
+
+ gcmkONERROR(gckOS_OpenSecurityChannel(Kernel->os, Kernel->core, Channel));
+ gcmkONERROR(gckOS_InitSecurityChannel(*Channel));
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+/*
+** Close a security service channel
+*/
+gceSTATUS
+gckKERNEL_SecurityClose(
+ IN gctUINT32 Channel
+ )
+{
+ return gcvSTATUS_OK;
+}
+
+/*
+** Security service interface.
+*/
+gceSTATUS
+gckKERNEL_SecurityCallService(
+ IN gctUINT32 Channel,
+ IN OUT gcsTA_INTERFACE * Interface
+)
+{
+ gceSTATUS status;
+ gcmkHEADER();
+
+ gcmkVERIFY_ARGUMENT(Interface != gcvNULL);
+
+ gckOS_CallSecurityService(Channel, Interface);
+
+ status = Interface->result;
+
+ gcmkONERROR(status);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_SecurityStartCommand(
+ IN gckKERNEL Kernel
+ )
+{
+ gceSTATUS status;
+ gcsTA_INTERFACE iface;
+
+ gcmkHEADER();
+
+ iface.command = KERNEL_START_COMMAND;
+ iface.u.StartCommand.gpu = Kernel->core;
+
+ gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_SecurityAllocateSecurityMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Bytes,
+ OUT gctUINT32 * Handle
+ )
+{
+ gceSTATUS status;
+ gcsTA_INTERFACE iface;
+
+ gcmkHEADER();
+
+ iface.command = KERNEL_ALLOCATE_SECRUE_MEMORY;
+ iface.u.AllocateSecurityMemory.bytes = Bytes;
+
+ gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface));
+
+ *Handle = iface.u.AllocateSecurityMemory.memory_handle;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_SecurityExecute(
+ IN gckKERNEL Kernel,
+ IN gctPOINTER Buffer,
+ IN gctUINT32 Bytes
+ )
+{
+ gceSTATUS status;
+ gcsTA_INTERFACE iface;
+
+ gcmkHEADER();
+
+ iface.command = KERNEL_EXECUTE;
+ iface.u.Execute.command_buffer = (gctUINT32 *)Buffer;
+ iface.u.Execute.gpu = Kernel->core;
+ iface.u.Execute.command_buffer_length = Bytes;
+
+#if defined(LINUX)
+ gcmkONERROR(gckOS_GetPhysicalAddress(Kernel->os, Buffer,
+ (gctUINT32 *)&iface.u.Execute.command_buffer));
+#endif
+
+ gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface));
+
+ /* Update queue tail pointer. */
+ gcmkONERROR(gckHARDWARE_UpdateQueueTail(
+ Kernel->hardware, 0, 0
+ ));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_SecurityMapMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 *PhysicalArray,
+ IN gctUINT32 PageCount,
+ OUT gctUINT32 * GPUAddress
+ )
+{
+ gceSTATUS status;
+ gcsTA_INTERFACE iface;
+
+ gcmkHEADER();
+
+ iface.command = KERNEL_MAP_MEMORY;
+
+#if defined(LINUX)
+ gcmkONERROR(gckOS_GetPhysicalAddress(Kernel->os, PhysicalArray,
+ (gctUINT32 *)&iface.u.MapMemory.physicals));
+#endif
+
+ iface.u.MapMemory.pageCount = PageCount;
+
+ gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface));
+
+ *GPUAddress = iface.u.MapMemory.gpuAddress;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckKERNEL_SecurityUnmapMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 GPUAddress,
+ IN gctUINT32 PageCount
+ )
+{
+ gceSTATUS status;
+ gcsTA_INTERFACE iface;
+
+ gcmkHEADER();
+
+ iface.command = KERNEL_UNMAP_MEMORY;
+
+ iface.u.UnmapMemory.gpuAddress = GPUAddress;
+ iface.u.UnmapMemory.pageCount = PageCount;
+
+ gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+#endif
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#if gcdENABLE_VG
-#define ENABLE_VG_TRY_VIRTUAL_MEMORY 0
-
#define _GC_OBJ_ZONE gcvZONE_VG
/******************************************************************************\
** Allocated node.
*/
gceSTATUS
-gckKERNEL_AllocateLinearMemory(
+gckVGKERNEL_AllocateLinearMemory(
IN gckKERNEL Kernel,
IN OUT gcePOOL * Pool,
IN gctSIZE_T Bytes,
- IN gctSIZE_T Alignment,
+ IN gctUINT32 Alignment,
IN gceSURF_TYPE Type,
OUT gcuVIDMEM_NODE_PTR * Node
)
if (status == gcvSTATUS_OK)
{
- if(*Pool == gcvPOOL_SYSTEM)
- Type |= gcvSURF_VG;
/* Allocate memory. */
- status = gckVIDMEM_AllocateLinear(videoMemory,
+ status = gckVIDMEM_AllocateLinear(Kernel,
+ videoMemory,
Bytes,
Alignment,
Type,
+ (*Pool == gcvPOOL_SYSTEM),
Node);
if (status == gcvSTATUS_OK)
else if (pool == gcvPOOL_SYSTEM)
{
/* Advance to virtual memory. */
-#if ENABLE_VG_TRY_VIRTUAL_MEMORY
pool = gcvPOOL_VIRTUAL;
-#else
- /*VG non-contiguous memory support is not ready yet, disable it temporary*/
- status = gcvSTATUS_OUT_OF_MEMORY;
- break;
-#endif
}
else
{
/* Out of pools. */
- status = gcvSTATUS_OUT_OF_MEMORY;
break;
}
}
{
gceSTATUS status;
gcsHAL_INTERFACE * kernelInterface = Interface;
- gcuVIDMEM_NODE_PTR node;
gctUINT32 processID;
gckKERNEL kernel = Kernel;
gctPOINTER info = gcvNULL;
case gcvHAL_ALLOCATE_NON_PAGED_MEMORY:
bytes = (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes;
/* Allocate non-paged memory. */
- gcmkERR_BREAK(gckOS_AllocateContiguous(
+ gcmkERR_BREAK(gckOS_AllocateNonPagedMemory(
Kernel->os,
gcvTRUE,
&bytes,
break;
case gcvHAL_ALLOCATE_VIDEO_MEMORY:
- {
- gctSIZE_T bytes;
- gctUINT32 bitsPerPixel;
- gctUINT32 bits;
-
- /* Align width and height to tiles. */
- gcmkERR_BREAK(gckVGHARDWARE_AlignToTile(
- Kernel->vg->hardware,
- kernelInterface->u.AllocateVideoMemory.type,
- &kernelInterface->u.AllocateVideoMemory.width,
- &kernelInterface->u.AllocateVideoMemory.height
- ));
-
- /* Convert format into bytes per pixel and bytes per tile. */
- gcmkERR_BREAK(gckVGHARDWARE_ConvertFormat(
- Kernel->vg->hardware,
- kernelInterface->u.AllocateVideoMemory.format,
- &bitsPerPixel,
- gcvNULL
- ));
-
- /* Compute number of bits for the allocation. */
- bits
- = kernelInterface->u.AllocateVideoMemory.width
- * kernelInterface->u.AllocateVideoMemory.height
- * kernelInterface->u.AllocateVideoMemory.depth
- * bitsPerPixel;
-
- /* Compute number of bytes for the allocation. */
- bytes = gcmALIGN(bits, 8) / 8;
-
- /* Allocate memory. */
- gcmkERR_BREAK(gckKERNEL_AllocateLinearMemory(
- Kernel,
- &kernelInterface->u.AllocateVideoMemory.pool,
- bytes,
- 64,
- kernelInterface->u.AllocateVideoMemory.type,
- &node
- ));
-
- kernelInterface->u.AllocateVideoMemory.node = gcmPTR_TO_UINT64(node);
- }
+ gcmkERR_BREAK(gcvSTATUS_NOT_SUPPORTED);
break;
case gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY:
/* Allocate memory. */
gcmkERR_BREAK(gckKERNEL_AllocateLinearMemory(
- Kernel,
+ Kernel, processID,
&kernelInterface->u.AllocateLinearVideoMemory.pool,
kernelInterface->u.AllocateLinearVideoMemory.bytes,
kernelInterface->u.AllocateLinearVideoMemory.alignment,
kernelInterface->u.AllocateLinearVideoMemory.type,
- &node
+ kernelInterface->u.AllocateLinearVideoMemory.flag,
+ &kernelInterface->u.AllocateLinearVideoMemory.node
));
- gcmkERR_BREAK(gckKERNEL_AddProcessDB(Kernel,
- processID, gcvDB_VIDEO_MEMORY,
- node,
- gcvNULL,
- kernelInterface->u.AllocateLinearVideoMemory.bytes
- ));
-
- kernelInterface->u.AllocateLinearVideoMemory.node = gcmPTR_TO_UINT64(node);
break;
- case gcvHAL_FREE_VIDEO_MEMORY:
- node = gcmUINT64_TO_PTR(Interface->u.FreeVideoMemory.node);
-#ifdef __QNXNTO__
- /* Unmap the video memory */
-
- if ((node->VidMem.memory->object.type == gcvOBJ_VIDMEM) &&
- (node->VidMem.logical != gcvNULL))
- {
- gckKERNEL_UnmapVideoMemory(Kernel,
- node->VidMem.logical,
- processID,
- node->VidMem.bytes);
- node->VidMem.logical = gcvNULL;
- }
-#endif /* __QNXNTO__ */
-
+ case gcvHAL_RELEASE_VIDEO_MEMORY:
/* Free video memory. */
- gcmkERR_BREAK(gckVIDMEM_Free(
- node
- ));
-
- gcmkERR_BREAK(gckKERNEL_RemoveProcessDB(
- Kernel,
- processID, gcvDB_VIDEO_MEMORY,
- node
+ gcmkERR_BREAK(gckKERNEL_ReleaseVideoMemory(
+ Kernel, processID,
+ (gctUINT32)kernelInterface->u.ReleaseVideoMemory.node
));
break;
));
kernelInterface->u.MapUserMemory.info = gcmPTR_TO_NAME(info);
+
+ /* Clear temp storage. */
+ info = gcvNULL;
break;
case gcvHAL_UNMAP_USER_MEMORY:
gcmNAME_TO_PTR(kernelInterface->u.UnmapUserMemory.info),
kernelInterface->u.UnmapUserMemory.address
));
+
gcmRELEASE_NAME(kernelInterface->u.UnmapUserMemory.info);
break;
- case gcvHAL_LOCK_VIDEO_MEMORY:
- node = gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node);
-
- /* Lock video memory. */
- gcmkERR_BREAK(
- gckVIDMEM_Lock(Kernel,
- node,
- gcvFALSE,
- &Interface->u.LockVideoMemory.address));
- if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
- {
- /* Map video memory address into user space. */
-#ifdef __QNXNTO__
- if (node->VidMem.logical == gcvNULL)
- {
- gcmkONERROR(
- gckKERNEL_MapVideoMemory(Kernel,
- FromUser,
- Interface->u.LockVideoMemory.address,
- processID,
- node->VidMem.bytes,
- &node->VidMem.logical));
- }
-
- Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->VidMem.logical);
-#else
- gcmkERR_BREAK(
- gckKERNEL_MapVideoMemoryEx(Kernel,
- gcvCORE_VG,
- FromUser,
- Interface->u.LockVideoMemory.address,
- &logical));
- Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(logical);
-#endif
- }
- else
- {
- Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->Virtual.logical);
-
- /* Success. */
- status = gcvSTATUS_OK;
- }
-
-#if gcdSECURE_USER
- /* Return logical address as physical address. */
- Interface->u.LockVideoMemory.address =
- (gctUINT32)(Interface->u.LockVideoMemory.memory);
-#endif
- gcmkERR_BREAK(
- gckKERNEL_AddProcessDB(Kernel,
- processID, gcvDB_VIDEO_MEMORY_LOCKED,
- node,
- gcvNULL,
- 0));
+ case gcvHAL_LOCK_VIDEO_MEMORY:
+ gcmkONERROR(gckKERNEL_LockVideoMemory(Kernel, gcvCORE_VG, processID, FromUser, Interface));
break;
case gcvHAL_UNLOCK_VIDEO_MEMORY:
- /* Unlock video memory. */
- node = gcmUINT64_TO_PTR(Interface->u.UnlockVideoMemory.node);
-
-#if gcdSECURE_USER
- /* Save node information before it disappears. */
- if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
- {
- logical = gcvNULL;
- bytes = 0;
- }
- else
- {
- logical = node->Virtual.logical;
- bytes = node->Virtual.bytes;
- }
-#endif
-
- /* Unlock video memory. */
- gcmkERR_BREAK(
- gckVIDMEM_Unlock(Kernel,
- node,
- Interface->u.UnlockVideoMemory.type,
- &Interface->u.UnlockVideoMemory.asynchroneous));
-
-#if gcdSECURE_USER
- /* Flush the translation cache for virtual surfaces. */
- if (logical != gcvNULL)
- {
- gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(Kernel,
- cache,
- logical,
- bytes));
- }
-#endif
-
- if (Interface->u.UnlockVideoMemory.asynchroneous == gcvFALSE)
- {
- /* There isn't a event to unlock this node, remove record now */
- gcmkERR_BREAK(
- gckKERNEL_RemoveProcessDB(Kernel,
- processID, gcvDB_VIDEO_MEMORY_LOCKED,
- node));
- }
-
+ gcmkONERROR(gckKERNEL_UnlockVideoMemory(Kernel, processID, Interface));
break;
+
case gcvHAL_USER_SIGNAL:
#if !USE_NEW_LINUX_SIGNAL
/* Dispatch depends on the user signal subcommands. */
break;
case gcvUSER_SIGNAL_DESTROY:
+ gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
+ Kernel,
+ processID, gcvDB_SIGNAL,
+ gcmINT2PTR(Interface->u.UserSignal.id)));
+
/* Destroy the signal. */
gcmkERR_BREAK(
gckOS_DestroyUserSignal(Kernel->os,
Interface->u.UserSignal.id));
- gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
- Kernel,
- processID, gcvDB_SIGNAL,
- gcmINT2PTR(Interface->u.UserSignal.id)));
break;
case gcvUSER_SIGNAL_SIGNAL:
gckOS_GetBaseAddress(Kernel->os,
&kernelInterface->u.GetBaseAddress.baseAddress));
break;
+ case gcvHAL_IMPORT_VIDEO_MEMORY:
+ gcmkONERROR(gckVIDMEM_NODE_Import(Kernel,
+ Interface->u.ImportVideoMemory.name,
+ &Interface->u.ImportVideoMemory.handle));
+ gcmkONERROR(gckKERNEL_AddProcessDB(Kernel,
+ processID, gcvDB_VIDEO_MEMORY,
+ gcmINT2PTR(Interface->u.ImportVideoMemory.handle),
+ gcvNULL,
+ 0));
+ break;
+
+ case gcvHAL_NAME_VIDEO_MEMORY:
+ gcmkONERROR(gckVIDMEM_NODE_Name(Kernel,
+ Interface->u.NameVideoMemory.handle,
+ &Interface->u.NameVideoMemory.name));
+ break;
+
+ case gcvHAL_DATABASE:
+ gcmkONERROR(gckKERNEL_QueryDatabase(Kernel, processID, Interface));
+ break;
+ case gcvHAL_SHBUF:
+ {
+ gctSHBUF shBuf;
+ gctPOINTER uData;
+ gctUINT32 bytes;
+
+ switch (Interface->u.ShBuf.command)
+ {
+ case gcvSHBUF_CREATE:
+ bytes = Interface->u.ShBuf.bytes;
+
+ /* Create. */
+ gcmkONERROR(gckKERNEL_CreateShBuffer(Kernel, bytes, &shBuf));
+
+ Interface->u.ShBuf.id = gcmPTR_TO_UINT64(shBuf);
+
+ gcmkVERIFY_OK(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID,
+ gcvDB_SHBUF,
+ shBuf,
+ gcvNULL,
+ 0));
+ break;
+
+ case gcvSHBUF_DESTROY:
+ shBuf = gcmUINT64_TO_PTR(Interface->u.ShBuf.id);
+
+ /* Check db first to avoid illegal destroy in the process. */
+ gcmkONERROR(
+ gckKERNEL_RemoveProcessDB(Kernel,
+ processID,
+ gcvDB_SHBUF,
+ shBuf));
+
+ gcmkONERROR(gckKERNEL_DestroyShBuffer(Kernel, shBuf));
+ break;
+
+ case gcvSHBUF_MAP:
+ shBuf = gcmUINT64_TO_PTR(Interface->u.ShBuf.id);
+
+ /* Map for current process access. */
+ gcmkONERROR(gckKERNEL_MapShBuffer(Kernel, shBuf));
+
+ gcmkVERIFY_OK(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID,
+ gcvDB_SHBUF,
+ shBuf,
+ gcvNULL,
+ 0));
+ break;
+
+ case gcvSHBUF_WRITE:
+ shBuf = gcmUINT64_TO_PTR(Interface->u.ShBuf.id);
+ uData = gcmUINT64_TO_PTR(Interface->u.ShBuf.data);
+ bytes = Interface->u.ShBuf.bytes;
+
+ /* Write. */
+ gcmkONERROR(
+ gckKERNEL_WriteShBuffer(Kernel, shBuf, uData, bytes));
+ break;
+
+ case gcvSHBUF_READ:
+ shBuf = gcmUINT64_TO_PTR(Interface->u.ShBuf.id);
+ uData = gcmUINT64_TO_PTR(Interface->u.ShBuf.data);
+ bytes = Interface->u.ShBuf.bytes;
+
+ /* Read. */
+ gcmkONERROR(
+ gckKERNEL_ReadShBuffer(Kernel,
+ shBuf,
+ uData,
+ bytes,
+ &bytes));
+
+ /* Return copied size. */
+ Interface->u.ShBuf.bytes = bytes;
+ break;
+
+ default:
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ break;
+ }
+ }
+ break;
default:
/* Invalid command. */
status = gcvSTATUS_INVALID_ARGUMENT;
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
node->VidMem.pool = Node->VidMem.pool;
node->VidMem.physical = Node->VidMem.physical;
#ifdef __QNXNTO__
-#if gcdUSE_VIDMEM_PER_PID
- gcmkASSERT(Node->VidMem.physical != 0);
- gcmkASSERT(Node->VidMem.logical != gcvNULL);
- node->VidMem.processID = Node->VidMem.processID;
- node->VidMem.physical = Node->VidMem.physical + Bytes;
- node->VidMem.logical = Node->VidMem.logical + Bytes;
-#else
node->VidMem.processID = 0;
node->VidMem.logical = gcvNULL;
-#endif
#endif
/* Insert node behind specified node. */
/* Save pointer to next node. */
node = Node->VidMem.next;
-#if gcdUSE_VIDMEM_PER_PID
- /* Check if the nodes are adjacent physically. */
- if ( ((Node->VidMem.physical + Node->VidMem.bytes) != node->VidMem.physical) ||
- ((Node->VidMem.logical + Node->VidMem.bytes) != node->VidMem.logical) )
- {
- /* Can't merge. */
- return gcvSTATUS_OK;
- }
-#else
/* This is a good time to make sure the heap is not corrupted. */
if (Node->VidMem.offset + Node->VidMem.bytes != node->VidMem.offset)
Node->VidMem.offset + Node->VidMem.bytes == node->VidMem.offset);
return gcvSTATUS_HEAP_CORRUPTED;
}
-#endif
/* Adjust byte count. */
Node->VidMem.bytes += node->VidMem.bytes;
gceSTATUS
gckVIDMEM_ConstructVirtual(
IN gckKERNEL Kernel,
- IN gctBOOL Contiguous,
+ IN gctUINT32 Flag,
IN gctSIZE_T Bytes,
OUT gcuVIDMEM_NODE_PTR * Node
)
gctPOINTER pointer = gcvNULL;
gctINT i;
- gcmkHEADER_ARG("Kernel=0x%x Contiguous=%d Bytes=%lu", Kernel, Contiguous, Bytes);
+ gcmkHEADER_ARG("Kernel=0x%x Flag=%x Bytes=%lu", Kernel, Flag, Bytes);
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
/* Initialize gcuVIDMEM_NODE union for virtual memory. */
node->Virtual.kernel = Kernel;
- node->Virtual.contiguous = Contiguous;
+ node->Virtual.contiguous = Flag & gcvALLOC_FLAG_CONTIGUOUS;
node->Virtual.logical = gcvNULL;
+#if gcdENABLE_VG
+ node->Virtual.kernelVirtual = gcvNULL;
+#endif
for (i = 0; i < gcdMAX_GPU_COUNT; i++)
{
node->Virtual.lockKernels[i] = gcvNULL;
}
- node->Virtual.mutex = gcvNULL;
-
gcmkONERROR(gckOS_GetProcessID(&node->Virtual.processID));
-#ifdef __QNXNTO__
- node->Virtual.next = gcvNULL;
- node->Virtual.freePending = gcvFALSE;
- for (i = 0; i < gcdMAX_GPU_COUNT; i++)
- {
- node->Virtual.unlockPendings[i] = gcvFALSE;
- }
-#endif
-
- node->Virtual.freed = gcvFALSE;
-
- gcmkONERROR(gckOS_ZeroMemory(&node->Virtual.sharedInfo, gcmSIZEOF(gcsVIDMEM_NODE_SHARED_INFO)));
-
- /* Create the mutex. */
- gcmkONERROR(
- gckOS_CreateMutex(os, &node->Virtual.mutex));
-
/* Allocate the virtual memory. */
gcmkONERROR(
gckOS_AllocatePagedMemoryEx(os,
- node->Virtual.contiguous,
+ Flag,
node->Virtual.bytes = Bytes,
+ &node->Virtual.gid,
&node->Virtual.physical));
-#ifdef __QNXNTO__
- /* Register. */
-#if gcdENABLE_VG
- if (Kernel->core != gcvCORE_VG)
-#endif
- {
- gckMMU_InsertNode(Kernel->mmu, node);
- }
-#endif
-
/* Return pointer to the gcuVIDMEM_NODE union. */
*Node = node;
/* Roll back. */
if (node != gcvNULL)
{
- if (node->Virtual.mutex != gcvNULL)
- {
- /* Destroy the mutex. */
- gcmkVERIFY_OK(gckOS_DeleteMutex(os, node->Virtual.mutex));
- }
-
/* Free the structure. */
gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, node));
}
)
{
gckOS os;
- gctINT i;
gcmkHEADER_ARG("Node=0x%x", Node);
os = Node->Virtual.kernel->os;
gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
-#ifdef __QNXNTO__
- /* Unregister. */
-#if gcdENABLE_VG
- if (Node->Virtual.kernel->core != gcvCORE_VG)
-#endif
- {
- gcmkVERIFY_OK(
- gckMMU_RemoveNode(Node->Virtual.kernel->mmu, Node));
- }
-#endif
-
- /* Delete the mutex. */
- gcmkVERIFY_OK(gckOS_DeleteMutex(os, Node->Virtual.mutex));
-
- for (i = 0; i < gcdMAX_GPU_COUNT; i++)
- {
- if (Node->Virtual.pageTables[i] != gcvNULL)
- {
-#if gcdENABLE_VG
- if (i == gcvCORE_VG)
- {
- /* Free the pages. */
- gcmkVERIFY_OK(gckVGMMU_FreePages(Node->Virtual.lockKernels[i]->vg->mmu,
- Node->Virtual.pageTables[i],
- Node->Virtual.pageCount));
- }
- else
-#endif
- {
- /* Free the pages. */
- gcmkVERIFY_OK(gckMMU_FreePages(Node->Virtual.lockKernels[i]->mmu,
- Node->Virtual.pageTables[i],
- Node->Virtual.pageCount));
- }
- }
- }
-
/* Delete the gcuVIDMEM_NODE union. */
gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, Node));
gcuVIDMEM_NODE_PTR node;
gctINT i, banks = 0;
gctPOINTER pointer = gcvNULL;
+ gctUINT32 heapBytes;
+ gctUINT32 bankSize;
gcmkHEADER_ARG("Os=0x%x BaseAddress=%08x Bytes=%lu Threshold=%lu "
"BankSize=%lu",
gcmkVERIFY_ARGUMENT(Bytes > 0);
gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
+ gcmkSAFECASTSIZET(heapBytes, Bytes);
+ gcmkSAFECASTSIZET(bankSize, BankSize);
+
/* Allocate the gckVIDMEM object. */
gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(struct _gckVIDMEM), &pointer));
/* Set video memory heap information. */
memory->baseAddress = BaseAddress;
- memory->bytes = Bytes;
- memory->freeBytes = Bytes;
+ memory->bytes = heapBytes;
+ memory->freeBytes = heapBytes;
memory->threshold = Threshold;
memory->mutex = gcvNULL;
-#if gcdUSE_VIDMEM_PER_PID
- gcmkONERROR(gckOS_GetProcessID(&memory->pid));
-#endif
BaseAddress = 0;
/* Walk all possible banks. */
for (i = 0; i < gcmCOUNTOF(memory->sentinel); ++i)
{
- gctSIZE_T bytes;
+ gctUINT32 bytes;
if (BankSize == 0)
{
/* Use all bytes for the first bank. */
- bytes = Bytes;
+ bytes = heapBytes;
}
else
{
/* Compute number of bytes for this bank. */
- bytes = gcmALIGN(BaseAddress + 1, BankSize) - BaseAddress;
+ bytes = gcmALIGN(BaseAddress + 1, bankSize) - BaseAddress;
- if (bytes > Bytes)
+ if (bytes > heapBytes)
{
/* Make sure we don't exceed the total number of bytes. */
- bytes = Bytes;
+ bytes = heapBytes;
}
}
node->VidMem.locked = 0;
-#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
- node->VidMem.kernelVirtual = gcvNULL;
-#endif
-
- gcmkONERROR(gckOS_ZeroMemory(&node->VidMem.sharedInfo, gcmSIZEOF(gcsVIDMEM_NODE_SHARED_INFO)));
-
#ifdef __QNXNTO__
-#if gcdUSE_VIDMEM_PER_PID
- node->VidMem.processID = memory->pid;
- node->VidMem.physical = memory->baseAddress + BaseAddress;
- gcmkONERROR(gckOS_GetLogicalAddressProcess(Os,
- node->VidMem.processID,
- node->VidMem.physical,
- &node->VidMem.logical));
-#else
node->VidMem.processID = 0;
node->VidMem.logical = gcvNULL;
#endif
+
+#if gcdENABLE_VG
+ node->VidMem.kernelVirtual = gcvNULL;
#endif
/* Initialize the linked list of nodes. */
/* Adjust address for next bank. */
BaseAddress += bytes;
- Bytes -= bytes;
+ heapBytes -= bytes;
banks ++;
}
return gcvSTATUS_OK;
}
-/*******************************************************************************
-**
-** gckVIDMEM_Allocate
-**
-** Allocate rectangular memory from the gckVIDMEM object.
-**
-** INPUT:
-**
-** gckVIDMEM Memory
-** Pointer to an gckVIDMEM object.
-**
-** gctUINT Width
-** Width of rectangle to allocate. Make sure the width is properly
-** aligned.
-**
-** gctUINT Height
-** Height of rectangle to allocate. Make sure the height is properly
-** aligned.
-**
-** gctUINT Depth
-** Depth of rectangle to allocate. This equals to the number of
-** rectangles to allocate contiguously (i.e., for cubic maps and volume
-** textures).
-**
-** gctUINT BytesPerPixel
-** Number of bytes per pixel.
-**
-** gctUINT32 Alignment
-** Byte alignment for allocation.
-**
-** gceSURF_TYPE Type
-** Type of surface to allocate (use by bank optimization).
-**
-** OUTPUT:
-**
-** gcuVIDMEM_NODE_PTR * Node
-** Pointer to a variable that will hold the allocated memory node.
-*/
-gceSTATUS
-gckVIDMEM_Allocate(
- IN gckVIDMEM Memory,
- IN gctUINT Width,
- IN gctUINT Height,
- IN gctUINT Depth,
- IN gctUINT BytesPerPixel,
- IN gctUINT32 Alignment,
- IN gceSURF_TYPE Type,
- OUT gcuVIDMEM_NODE_PTR * Node
- )
-{
- gctSIZE_T bytes;
- gceSTATUS status;
-
- gcmkHEADER_ARG("Memory=0x%x Width=%u Height=%u Depth=%u BytesPerPixel=%u "
- "Alignment=%u Type=%d",
- Memory, Width, Height, Depth, BytesPerPixel, Alignment,
- Type);
-
- /* Verify the arguments. */
- gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM);
- gcmkVERIFY_ARGUMENT(Width > 0);
- gcmkVERIFY_ARGUMENT(Height > 0);
- gcmkVERIFY_ARGUMENT(Depth > 0);
- gcmkVERIFY_ARGUMENT(BytesPerPixel > 0);
- gcmkVERIFY_ARGUMENT(Node != gcvNULL);
-
- /* Compute linear size. */
- bytes = Width * Height * Depth * BytesPerPixel;
-
- /* Allocate through linear function. */
- gcmkONERROR(
- gckVIDMEM_AllocateLinear(Memory, bytes, Alignment, Type, Node));
-
- /* Success. */
- gcmkFOOTER_ARG("*Node=0x%x", *Node);
- return gcvSTATUS_OK;
-
-OnError:
- /* Return the status. */
- gcmkFOOTER();
- return status;
-}
-
#if gcdENABLE_BANK_ALIGNMENT
#if !gcdBANK_BIT_START
*/
static gceSTATUS
_GetSurfaceBankAlignment(
+ IN gckKERNEL Kernel,
IN gceSURF_TYPE Type,
IN gctUINT32 BaseAddress,
OUT gctUINT32_PTR AlignmentOffset
0 :
((1 << (gcdBANK_BIT_END + 1)) + (2 << gcdBANK_BIT_START)) - (BaseAddress & byteMask);
- /* Add a channel offset at the channel bit. */
- *AlignmentOffset += (1 << gcdBANK_CHANNEL_BIT);
+ /* Minimum 256 byte alignment needed for fast_msaa. */
+ if ((gcdBANK_CHANNEL_BIT > 7) ||
+ ((gckHARDWARE_IsFeatureAvailable(Kernel->hardware, gcvFEATURE_FAST_MSAA) != gcvSTATUS_TRUE) &&
+ (gckHARDWARE_IsFeatureAvailable(Kernel->hardware, gcvFEATURE_SMALL_MSAA) != gcvSTATUS_TRUE)))
+ {
+ /* Add a channel offset at the channel bit. */
+ *AlignmentOffset += (1 << gcdBANK_CHANNEL_BIT);
+ }
break;
default:
static gcuVIDMEM_NODE_PTR
_FindNode(
+ IN gckKERNEL Kernel,
IN gckVIDMEM Memory,
IN gctINT Bank,
IN gctSIZE_T Bytes,
node->VidMem.bytes != 0;
node = node->VidMem.nextFree)
{
+ if (node->VidMem.bytes < Bytes)
+ {
+ continue;
+ }
+
gcmkONERROR(_GetSurfaceBankAlignment(
+ Kernel,
Type,
node->VidMem.memory->baseAddress + node->VidMem.offset,
&bankAlignment));
node->VidMem.bytes != 0;
node = node->VidMem.nextFree)
{
+ gctUINT offset;
- gctINT modulo = gckMATH_ModuloInt(node->VidMem.offset, *Alignment);
+ gctINT modulo;
+
+ gcmkSAFECASTSIZET(offset, node->VidMem.offset);
+
+ modulo = gckMATH_ModuloInt(offset, *Alignment);
/* Compute number of bytes to skip for alignment. */
alignment = (*Alignment == 0) ? 0 : (*Alignment - modulo);
** gceSURF_TYPE Type
** Type of surface to allocate (use by bank optimization).
**
+** gctBOOL Specified
+** If user must use this pool, it should set Specified to gcvTRUE,
+** otherwise allocator may reserve some memory for other usage, such
+** as small block size allocation request.
+**
** OUTPUT:
**
** gcuVIDMEM_NODE_PTR * Node
*/
gceSTATUS
gckVIDMEM_AllocateLinear(
+ IN gckKERNEL Kernel,
IN gckVIDMEM Memory,
IN gctSIZE_T Bytes,
IN gctUINT32 Alignment,
IN gceSURF_TYPE Type,
+ IN gctBOOL Specified,
OUT gcuVIDMEM_NODE_PTR * Node
)
{
gctUINT32 alignment;
gctINT bank, i;
gctBOOL acquired = gcvFALSE;
-#if gcdSMALL_BLOCK_SIZE
- gctBOOL force_allocate = (Type == gcvSURF_TILE_STATUS) || (Type & gcvSURF_VG);
-#endif
gcmkHEADER_ARG("Memory=0x%x Bytes=%lu Alignment=%u Type=%d",
Memory, Bytes, Alignment, Type);
- Type &= ~gcvSURF_VG;
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM);
gcmkVERIFY_ARGUMENT(Bytes > 0);
gcmkONERROR(gckOS_AcquireMutex(Memory->os, Memory->mutex, gcvINFINITE));
acquired = gcvTRUE;
-#if !gcdUSE_VIDMEM_PER_PID
if (Bytes > Memory->freeBytes)
{
status = gcvSTATUS_OUT_OF_MEMORY;
goto OnError;
}
-#endif
#if gcdSMALL_BLOCK_SIZE
- if ((!force_allocate) && (Memory->freeBytes < (Memory->bytes/gcdRATIO_FOR_SMALL_MEMORY))
+ if ((Memory->freeBytes < (Memory->bytes/gcdRATIO_FOR_SMALL_MEMORY))
&& (Bytes >= gcdSMALL_BLOCK_SIZE)
+ && (Specified == gcvFALSE)
)
{
/* The left memory is for small memory.*/
bank = Memory->mapping[Type];
alignment = Alignment;
-#if gcdUSE_VIDMEM_PER_PID
- if (Bytes <= Memory->freeBytes)
- {
-#endif
/* Find a free node in the default bank. */
- node = _FindNode(Memory, bank, Bytes, Type, &alignment);
+ node = _FindNode(Kernel, Memory, bank, Bytes, Type, &alignment);
/* Out of memory? */
if (node == gcvNULL)
for (i = bank - 1; i >= 0; --i)
{
/* Find a free node inside the current bank. */
- node = _FindNode(Memory, i, Bytes, Type, &alignment);
+ node = _FindNode(Kernel, Memory, i, Bytes, Type, &alignment);
if (node != gcvNULL)
{
break;
}
/* Find a free node inside the current bank. */
- node = _FindNode(Memory, i, Bytes, Type, &alignment);
+ node = _FindNode(Kernel, Memory, i, Bytes, Type, &alignment);
if (node != gcvNULL)
{
break;
}
}
}
-#if gcdUSE_VIDMEM_PER_PID
- }
-#endif
if (node == gcvNULL)
{
/* Out of memory. */
-#if gcdUSE_VIDMEM_PER_PID
- /* Allocate more memory from shared pool. */
- gctSIZE_T bytes;
- gctPHYS_ADDR physical_temp;
- gctUINT32 physical;
- gctPOINTER logical;
-
- bytes = gcmALIGN(Bytes, gcdUSE_VIDMEM_PER_PID_SIZE);
-
- gcmkONERROR(gckOS_AllocateContiguous(Memory->os,
- gcvTRUE,
- &bytes,
- &physical_temp,
- &logical));
-
- /* physical address is returned as 0 for user space. workaround. */
- if (physical_temp == gcvNULL)
- {
- gcmkONERROR(gckOS_GetPhysicalAddress(Memory->os, logical, &physical));
- }
-
- /* Allocate one gcuVIDMEM_NODE union. */
- gcmkONERROR(
- gckOS_Allocate(Memory->os,
- gcmSIZEOF(gcuVIDMEM_NODE),
- (gctPOINTER *) &node));
-
- /* Initialize gcuVIDMEM_NODE union. */
- node->VidMem.memory = Memory;
-
- node->VidMem.offset = 0;
- node->VidMem.bytes = bytes;
- node->VidMem.alignment = 0;
- node->VidMem.physical = physical;
- node->VidMem.pool = gcvPOOL_UNKNOWN;
-
- node->VidMem.locked = 0;
-
-#ifdef __QNXNTO__
- gcmkONERROR(gckOS_GetProcessID(&node->VidMem.processID));
- node->VidMem.logical = logical;
- gcmkASSERT(logical != gcvNULL);
-#endif
-
- /* Insert node behind sentinel node. */
- node->VidMem.next = Memory->sentinel[bank].VidMem.next;
- node->VidMem.prev = &Memory->sentinel[bank];
- Memory->sentinel[bank].VidMem.next = node->VidMem.next->VidMem.prev = node;
-
- /* Insert free node behind sentinel node. */
- node->VidMem.nextFree = Memory->sentinel[bank].VidMem.nextFree;
- node->VidMem.prevFree = &Memory->sentinel[bank];
- Memory->sentinel[bank].VidMem.nextFree = node->VidMem.nextFree->VidMem.prevFree = node;
-
- Memory->freeBytes += bytes;
-#else
status = gcvSTATUS_OUT_OF_MEMORY;
goto OnError;
-#endif
}
/* Do we have an alignment? */
node->VidMem.alignment = alignment;
node->VidMem.memory = Memory;
#ifdef __QNXNTO__
-#if !gcdUSE_VIDMEM_PER_PID
node->VidMem.logical = gcvNULL;
gcmkONERROR(gckOS_GetProcessID(&node->VidMem.processID));
-#else
- gcmkASSERT(node->VidMem.logical != gcvNULL);
-#endif
#endif
/* Adjust the number of free bytes. */
Memory->freeBytes -= node->VidMem.bytes;
- node->VidMem.freePending = gcvFALSE;
-
-#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
+#if gcdENABLE_VG
node->VidMem.kernelVirtual = gcvNULL;
#endif
**
** INPUT:
**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
** gcuVIDMEM_NODE_PTR Node
** Pointer to a gcuVIDMEM_NODE object.
**
*/
gceSTATUS
gckVIDMEM_Free(
+ IN gckKERNEL Kernel,
IN gcuVIDMEM_NODE_PTR Node
)
{
gckVIDMEM memory = gcvNULL;
gcuVIDMEM_NODE_PTR node;
gctBOOL mutexAcquired = gcvFALSE;
- gckOS os = gcvNULL;
- gctBOOL acquired = gcvFALSE;
- gctINT32 i, totalLocked;
gcmkHEADER_ARG("Node=0x%x", Node);
if (Node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
{
- if (Node->VidMem.locked > 0)
- {
- /* Client still has a lock, defer free op 'till when lock reaches 0. */
- Node->VidMem.freePending = gcvTRUE;
-
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
- "Node 0x%x is locked (%d)... deferring free.",
- Node, Node->VidMem.locked);
-
- gcmkFOOTER_NO();
- return gcvSTATUS_OK;
- }
-
/* Extract pointer to gckVIDMEM object owning the node. */
memory = Node->VidMem.memory;
mutexAcquired = gcvTRUE;
#ifdef __QNXNTO__
-#if !gcdUSE_VIDMEM_PER_PID
+ /* Unmap the video memory. */
+ if (Node->VidMem.logical != gcvNULL)
+ {
+ gckKERNEL_UnmapVideoMemory(
+ Kernel,
+ Node->VidMem.logical,
+ Node->VidMem.processID,
+ Node->VidMem.bytes);
+ Node->VidMem.logical = gcvNULL;
+ }
+
/* Reset. */
Node->VidMem.processID = 0;
- Node->VidMem.logical = gcvNULL;
-#endif
/* Don't try to re-free an already freed node. */
if ((Node->VidMem.nextFree == gcvNULL)
)
#endif
{
-#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
+#if gcdENABLE_VG
if (Node->VidMem.kernelVirtual)
{
gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
/* Verify the gckKERNEL object pointer. */
gcmkVERIFY_OBJECT(kernel, gcvOBJ_KERNEL);
- /* Get the gckOS object pointer. */
- os = kernel->os;
- gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
-
- /* Grab the mutex. */
- gcmkONERROR(
- gckOS_AcquireMutex(os, Node->Virtual.mutex, gcvINFINITE));
-
- acquired = gcvTRUE;
-
- for (i = 0, totalLocked = 0; i < gcdMAX_GPU_COUNT; i++)
- {
- totalLocked += Node->Virtual.lockeds[i];
- }
-
- if (totalLocked > 0)
+#if gcdENABLE_VG
+ if (Node->Virtual.kernelVirtual)
{
- gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_VIDMEM,
- "gckVIDMEM_Free: Virtual node 0x%x is locked (%d)",
- Node, totalLocked);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+ "%s(%d) Unmap %x from kernel space.",
+ __FUNCTION__, __LINE__,
+ Node->Virtual.kernelVirtual);
- /* Set Flag */
- Node->Virtual.freed = gcvTRUE;
+ gcmkVERIFY_OK(
+ gckOS_UnmapPhysical(kernel->os,
+ Node->Virtual.kernelVirtual,
+ Node->Virtual.bytes));
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
+ Node->Virtual.kernelVirtual = gcvNULL;
}
- else
- {
- /* Free the virtual memory. */
- gcmkVERIFY_OK(gckOS_FreePagedMemory(kernel->os,
- Node->Virtual.physical,
- Node->Virtual.bytes));
+#endif
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
+ /* Free the virtual memory. */
+ gcmkVERIFY_OK(gckOS_FreePagedMemory(kernel->os,
+ Node->Virtual.physical,
+ Node->Virtual.bytes));
- /* Destroy the gcuVIDMEM_NODE union. */
- gcmkVERIFY_OK(gckVIDMEM_DestroyVirtual(Node));
- }
+ /* Destroy the gcuVIDMEM_NODE union. */
+ gcmkVERIFY_OK(gckVIDMEM_DestroyVirtual(Node));
/* Success. */
gcmkFOOTER_NO();
));
}
- if (acquired)
- {
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
- }
-
/* Return the status. */
gcmkFOOTER();
return status;
}
-
-#ifdef __QNXNTO__
+#if !gcdPROCESS_ADDRESS_SPACE
/*******************************************************************************
**
-** gcoVIDMEM_FreeHandleMemory
+** _NeedVirtualMapping
**
-** Free all allocated video memory nodes for a handle.
+** Whether setup GPU page table for video node.
**
** INPUT:
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
**
-** gcoVIDMEM Memory
-** Pointer to an gcoVIDMEM object..
+** gcuVIDMEM_NODE_PTR Node
+** Pointer to a gcuVIDMEM_NODE union.
**
-** OUTPUT:
+** gceCORE Core
+** Id of current GPU.
**
-** Nothing.
+** OUTPUT:
+** gctBOOL * NeedMapping
+** A pointer hold the result whether Node should be mapping.
*/
-gceSTATUS
-gckVIDMEM_FreeHandleMemory(
+static gceSTATUS
+_NeedVirtualMapping(
IN gckKERNEL Kernel,
- IN gckVIDMEM Memory,
- IN gctUINT32 Pid
- )
+ IN gceCORE Core,
+ IN gcuVIDMEM_NODE_PTR Node,
+ OUT gctBOOL * NeedMapping
+)
{
gceSTATUS status;
- gctBOOL mutex = gcvFALSE;
- gcuVIDMEM_NODE_PTR node;
- gctINT i;
- gctUINT32 nodeCount = 0, byteCount = 0;
- gctBOOL again;
-
- gcmkHEADER_ARG("Kernel=0x%x, Memory=0x%x Pid=0x%u", Kernel, Memory, Pid);
+ gctUINT32 phys;
+ gctUINT32 end;
+ gcePOOL pool;
+ gctUINT32 offset;
+ gctUINT32 baseAddress;
+ gctUINT32 bytes;
- gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
- gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM);
+ gcmkHEADER_ARG("Node=0x%X", Node);
- gcmkONERROR(gckOS_AcquireMutex(Memory->os, Memory->mutex, gcvINFINITE));
- mutex = gcvTRUE;
+ /* Verify the arguments. */
+ gcmkVERIFY_ARGUMENT(Kernel != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Node != gcvNULL);
+ gcmkVERIFY_ARGUMENT(NeedMapping != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Core < gcdMAX_GPU_COUNT);
- /* Walk all sentinels. */
- for (i = 0; i < gcmCOUNTOF(Memory->sentinel); ++i)
+ if (Node->Virtual.contiguous)
{
- /* Bail out of the heap if it is not used. */
- if (Memory->sentinel[i].VidMem.next == gcvNULL)
+#if gcdENABLE_VG
+ if (Core == gcvCORE_VG)
{
- break;
+ *NeedMapping = gcvFALSE;
}
-
- do
+ else
+#endif
{
- again = gcvFALSE;
+ /* Convert logical address into a physical address. */
+ gcmkONERROR(gckOS_UserLogicalToPhysical(
+ Kernel->os, Node->Virtual.logical, &phys
+ ));
- /* Walk all the nodes until we reach the sentinel. */
- for (node = Memory->sentinel[i].VidMem.next;
- node->VidMem.bytes != 0;
- node = node->VidMem.next)
- {
- /* Free the node if it was allocated by Handle. */
- if (node->VidMem.processID == Pid)
- {
- /* Unlock video memory. */
- while (node->VidMem.locked > 0)
- {
- gckVIDMEM_Unlock(Kernel, node, gcvSURF_TYPE_UNKNOWN, gcvNULL);
- }
+ gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress));
- nodeCount++;
- byteCount += node->VidMem.bytes;
+ gcmkASSERT(phys >= baseAddress);
- /* Free video memory. */
- gcmkVERIFY_OK(gckVIDMEM_Free(node));
+ /* Subtract baseAddress to get a GPU address used for programming. */
+ phys -= baseAddress;
- /*
- * Freeing may cause a merge which will invalidate our iteration.
- * Don't be clever, just restart.
- */
- again = gcvTRUE;
+ /* If part of region is belong to gcvPOOL_VIRTUAL,
+ ** whole region has to be mapped. */
+ gcmkSAFECASTSIZET(bytes, Node->Virtual.bytes);
+ end = phys + bytes - 1;
- break;
- }
-#if gcdUSE_VIDMEM_PER_PID
- else
- {
- gcmkASSERT(node->VidMem.processID == Pid);
- }
-#endif
- }
+ gcmkONERROR(gckHARDWARE_SplitMemory(
+ Kernel->hardware, end, &pool, &offset
+ ));
+
+ *NeedMapping = (pool == gcvPOOL_VIRTUAL);
}
- while (again);
+ }
+ else
+ {
+ *NeedMapping = gcvTRUE;
}
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
- gcmkFOOTER();
+ gcmkFOOTER_ARG("*NeedMapping=%d", *NeedMapping);
return gcvSTATUS_OK;
OnError:
- if (mutex)
- {
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
- }
-
gcmkFOOTER();
return status;
}
#endif
-/*******************************************************************************
-**
-** _NeedVirtualMapping
-**
-** Whether setup GPU page table for video node.
-**
-** INPUT:
-** gckKERNEL Kernel
-** Pointer to an gckKERNEL object.
-**
-** gcuVIDMEM_NODE_PTR Node
-** Pointer to a gcuVIDMEM_NODE union.
-**
-** gceCORE Core
-** Id of current GPU.
-**
-** OUTPUT:
-** gctBOOL * NeedMapping
-** A pointer hold the result whether Node should be mapping.
-*/
-static gceSTATUS
-_NeedVirtualMapping(
- IN gckKERNEL Kernel,
- IN gceCORE Core,
- IN gcuVIDMEM_NODE_PTR Node,
- OUT gctBOOL * NeedMapping
-)
+#if gcdPROCESS_ADDRESS_SPACE
+gcsGPU_MAP_PTR
+_FindGPUMap(
+ IN gcsGPU_MAP_PTR Head,
+ IN gctINT ProcessID
+ )
{
- gceSTATUS status;
- gctUINT32 phys;
- gctUINT32 end;
- gcePOOL pool;
- gctUINT32 offset;
- gctUINT32 baseAddress;
-
- gcmkHEADER_ARG("Node=0x%X", Node);
-
- /* Verify the arguments. */
- gcmkVERIFY_ARGUMENT(Kernel != gcvNULL);
- gcmkVERIFY_ARGUMENT(Node != gcvNULL);
- gcmkVERIFY_ARGUMENT(NeedMapping != gcvNULL);
- gcmkVERIFY_ARGUMENT(Core < gcdMAX_GPU_COUNT);
+ gcsGPU_MAP_PTR map = Head;
- if (Node->Virtual.contiguous)
+ while (map)
{
-#if gcdENABLE_VG
- if (Core == gcvCORE_VG)
+ if (map->pid == ProcessID)
{
- *NeedMapping = gcvFALSE;
+ return map;
}
- else
-#endif
- {
- /* Convert logical address into a physical address. */
- gcmkONERROR(
- gckOS_GetPhysicalAddress(Kernel->os, Node->Virtual.logical, &phys));
- gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress));
+ map = map->next;
+ }
- gcmkASSERT(phys >= baseAddress);
+ return gcvNULL;
+}
- /* Subtract baseAddress to get a GPU address used for programming. */
- phys -= baseAddress;
+gcsGPU_MAP_PTR
+_CreateGPUMap(
+ IN gckOS Os,
+ IN gcsGPU_MAP_PTR *Head,
+ IN gcsGPU_MAP_PTR *Tail,
+ IN gctINT ProcessID
+ )
+{
+ gcsGPU_MAP_PTR gpuMap;
+ gctPOINTER pointer = gcvNULL;
- /* If part of region is belong to gcvPOOL_VIRTUAL,
- ** whole region has to be mapped. */
- end = phys + Node->Virtual.bytes - 1;
+ gckOS_Allocate(Os, sizeof(gcsGPU_MAP), &pointer);
- gcmkONERROR(gckHARDWARE_SplitMemory(
- Kernel->hardware, end, &pool, &offset
- ));
+ if (pointer == gcvNULL)
+ {
+ return gcvNULL;
+ }
- *NeedMapping = (pool == gcvPOOL_VIRTUAL);
- }
+ gpuMap = pointer;
+
+ gckOS_ZeroMemory(pointer, sizeof(gcsGPU_MAP));
+
+ gpuMap->pid = ProcessID;
+
+ if (!*Head)
+ {
+ *Head = *Tail = gpuMap;
}
else
{
- *NeedMapping = gcvTRUE;
+ gpuMap->prev = *Tail;
+ (*Tail)->next = gpuMap;
+ *Tail = gpuMap;
}
- gcmkFOOTER_ARG("*NeedMapping=%d", *NeedMapping);
- return gcvSTATUS_OK;
+ return gpuMap;
+}
-OnError:
- gcmkFOOTER();
- return status;
+void
+_DestroyGPUMap(
+ IN gckOS Os,
+ IN gcsGPU_MAP_PTR *Head,
+ IN gcsGPU_MAP_PTR *Tail,
+ IN gcsGPU_MAP_PTR gpuMap
+ )
+{
+
+ if (gpuMap == *Head)
+ {
+ if ((*Head = gpuMap->next) == gcvNULL)
+ {
+ *Tail = gcvNULL;
+ }
+ }
+ else
+ {
+ gpuMap->prev->next = gpuMap->next;
+ if (gpuMap == *Tail)
+ {
+ *Tail = gpuMap->prev;
+ }
+ else
+ {
+ gpuMap->next->prev = gpuMap->prev;
+ }
+ }
+
+ gcmkOS_SAFE_FREE(Os, gpuMap);
}
+#endif
/*******************************************************************************
**
**
** gctUINT32 * Address
** Pointer to a variable that will hold the hardware specific address.
+**
+** gctUINT32 * PhysicalAddress
+** Pointer to a variable that will hold the bus address of a contiguous
+** video node.
*/
gceSTATUS
gckVIDMEM_Lock(
IN gckKERNEL Kernel,
- IN gcuVIDMEM_NODE_PTR Node,
+ IN gckVIDMEM_NODE Node,
IN gctBOOL Cacheable,
- OUT gctUINT32 * Address
+ OUT gctUINT32 * Address,
+ OUT gctUINT32 * Gid,
+ OUT gctUINT64 * PhysicalAddress
)
{
gceSTATUS status;
gctBOOL acquired = gcvFALSE;
gctBOOL locked = gcvFALSE;
gckOS os = gcvNULL;
- gctBOOL needMapping;
+#if !gcdPROCESS_ADDRESS_SPACE
+ gctBOOL needMapping = gcvFALSE;
+#endif
gctUINT32 baseAddress;
+ gctUINT32 physicalAddress;
+ gcuVIDMEM_NODE_PTR node = Node->node;
gcmkHEADER_ARG("Node=0x%x", Node);
/* Verify the arguments. */
gcmkVERIFY_ARGUMENT(Address != gcvNULL);
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
- if ((Node == gcvNULL)
- || (Node->VidMem.memory == gcvNULL)
+ /* Extract the gckOS object pointer. */
+ os = Kernel->os;
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+ if ((node == gcvNULL)
+ || (node->VidMem.memory == gcvNULL)
)
{
/* Invalid object. */
gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
}
+ /* Grab the mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(os, Node->mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
/**************************** Video Memory ********************************/
- if (Node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
{
+ gctUINT32 offset;
+
if (Cacheable == gcvTRUE)
{
gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
}
/* Increment the lock count. */
- Node->VidMem.locked ++;
+ node->VidMem.locked ++;
/* Return the physical address of the node. */
-#if !gcdUSE_VIDMEM_PER_PID
- *Address = Node->VidMem.memory->baseAddress
- + Node->VidMem.offset
- + Node->VidMem.alignment;
-#else
- *Address = Node->VidMem.physical;
-#endif
+ gcmkSAFECASTSIZET(offset, node->VidMem.offset);
+
+ *Address = node->VidMem.memory->baseAddress
+ + offset
+ + node->VidMem.alignment;
+
+ physicalAddress = *Address;
/* Get hardware specific address. */
#if gcdENABLE_VG
}
}
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
+ Kernel->os,
+ *Address,
+ Address
+ ));
+
gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
"Locked node 0x%x (%d) @ 0x%08X",
- Node,
- Node->VidMem.locked,
+ node,
+ node->VidMem.locked,
*Address);
}
else
{
- /* Verify the gckKERNEL object pointer. */
- gcmkVERIFY_OBJECT(Node->Virtual.kernel, gcvOBJ_KERNEL);
-
- /* Extract the gckOS object pointer. */
- os = Node->Virtual.kernel->os;
- gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
- /* Grab the mutex. */
- gcmkONERROR(gckOS_AcquireMutex(os, Node->Virtual.mutex, gcvINFINITE));
- acquired = gcvTRUE;
+ *Gid = node->Virtual.gid;
#if gcdPAGED_MEMORY_CACHEABLE
/* Force video memory cacheable. */
gcmkONERROR(
gckOS_LockPages(os,
- Node->Virtual.physical,
- Node->Virtual.bytes,
+ node->Virtual.physical,
+ node->Virtual.bytes,
Cacheable,
- &Node->Virtual.logical,
- &Node->Virtual.pageCount));
+ &node->Virtual.logical,
+ &node->Virtual.pageCount));
- /* Increment the lock count. */
- if (Node->Virtual.lockeds[Kernel->core] ++ == 0)
- {
- /* Is this node pending for a final unlock? */
-#ifdef __QNXNTO__
- if (!Node->Virtual.contiguous && Node->Virtual.unlockPendings[Kernel->core])
- {
- /* Make sure we have a page table. */
- gcmkASSERT(Node->Virtual.pageTables[Kernel->core] != gcvNULL);
-
- /* Remove pending unlock. */
- Node->Virtual.unlockPendings[Kernel->core] = gcvFALSE;
- }
-
- /* First lock - create a page table. */
- gcmkASSERT(Node->Virtual.pageTables[Kernel->core] == gcvNULL);
+ gcmkONERROR(gckOS_GetPhysicalAddress(
+ os,
+ node->Virtual.logical,
+ &physicalAddress
+ ));
- /* Make sure we mark our node as not flushed. */
- Node->Virtual.unlockPendings[Kernel->core] = gcvFALSE;
+#if gcdENABLE_VG
+ node->Virtual.physicalAddress = physicalAddress;
#endif
+#if !gcdPROCESS_ADDRESS_SPACE
+ /* Increment the lock count. */
+ if (node->Virtual.lockeds[Kernel->core] ++ == 0)
+ {
locked = gcvTRUE;
- gcmkONERROR(_NeedVirtualMapping(Kernel, Kernel->core, Node, &needMapping));
+ gcmkONERROR(_NeedVirtualMapping(Kernel, Kernel->core, node, &needMapping));
if (needMapping == gcvFALSE)
{
#if gcdENABLE_VG
if (Kernel->vg != gcvNULL)
{
- gcmkONERROR(gckVGHARDWARE_ConvertLogical(Kernel->vg->hardware,
- Node->Virtual.logical,
- &Node->Virtual.addresses[Kernel->core]));
+ gcmkONERROR(gckVGHARDWARE_ConvertLogical(
+ Kernel->vg->hardware,
+ node->Virtual.logical,
+ gcvTRUE,
+ &node->Virtual.addresses[Kernel->core]));
}
else
#endif
{
- gcmkONERROR(gckHARDWARE_ConvertLogical(Kernel->hardware,
- Node->Virtual.logical,
- &Node->Virtual.addresses[Kernel->core]));
+ gcmkONERROR(gckHARDWARE_ConvertLogical(
+ Kernel->hardware,
+ node->Virtual.logical,
+ gcvTRUE,
+ &node->Virtual.addresses[Kernel->core]));
}
}
else
{
+#if gcdSECURITY
+ gctPHYS_ADDR physicalArrayPhysical;
+ gctPOINTER physicalArrayLogical;
+
+ gcmkONERROR(gckOS_AllocatePageArray(
+ os,
+ node->Virtual.physical,
+ node->Virtual.pageCount,
+ &physicalArrayLogical,
+ &physicalArrayPhysical
+ ));
+
+ gcmkONERROR(gckKERNEL_SecurityMapMemory(
+ Kernel,
+ physicalArrayLogical,
+ node->Virtual.pageCount,
+ &node->Virtual.addresses[Kernel->core]
+ ));
+
+ gcmkONERROR(gckOS_FreeNonPagedMemory(
+ os,
+ 1,
+ physicalArrayPhysical,
+ physicalArrayLogical
+ ));
+#else
#if gcdENABLE_VG
if (Kernel->vg != gcvNULL)
{
/* Allocate pages inside the MMU. */
gcmkONERROR(
gckVGMMU_AllocatePages(Kernel->vg->mmu,
- Node->Virtual.pageCount,
- &Node->Virtual.pageTables[Kernel->core],
- &Node->Virtual.addresses[Kernel->core]));
+ node->Virtual.pageCount,
+ &node->Virtual.pageTables[Kernel->core],
+ &node->Virtual.addresses[Kernel->core]));
}
else
#endif
/* Allocate pages inside the MMU. */
gcmkONERROR(
gckMMU_AllocatePagesEx(Kernel->mmu,
- Node->Virtual.pageCount,
- Node->Virtual.type,
- &Node->Virtual.pageTables[Kernel->core],
- &Node->Virtual.addresses[Kernel->core]));
+ node->Virtual.pageCount,
+ node->Virtual.type,
+ &node->Virtual.pageTables[Kernel->core],
+ &node->Virtual.addresses[Kernel->core]));
}
- Node->Virtual.lockKernels[Kernel->core] = Kernel;
+ node->Virtual.lockKernels[Kernel->core] = Kernel;
/* Map the pages. */
-#ifdef __QNXNTO__
- gcmkONERROR(
- gckOS_MapPagesEx(os,
- Kernel->core,
- Node->Virtual.physical,
- Node->Virtual.logical,
- Node->Virtual.pageCount,
- Node->Virtual.pageTables[Kernel->core]));
-#else
gcmkONERROR(
gckOS_MapPagesEx(os,
Kernel->core,
- Node->Virtual.physical,
- Node->Virtual.pageCount,
- Node->Virtual.pageTables[Kernel->core]));
-#endif
+ node->Virtual.physical,
+ node->Virtual.pageCount,
+ node->Virtual.addresses[Kernel->core],
+ node->Virtual.pageTables[Kernel->core]));
#if gcdENABLE_VG
if (Kernel->core == gcvCORE_VG)
else
#endif
{
- gcmkONERROR(gckMMU_Flush(Kernel->mmu));
+ gcmkONERROR(gckMMU_Flush(Kernel->mmu, node->Virtual.type));
}
+#endif
}
gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
"Mapped virtual node 0x%x to 0x%08X",
- Node,
- Node->Virtual.addresses[Kernel->core]);
+ node,
+ node->Virtual.addresses[Kernel->core]);
}
/* Return hardware address. */
- *Address = Node->Virtual.addresses[Kernel->core];
-
- /* Release the mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
+ *Address = node->Virtual.addresses[Kernel->core];
+#endif
}
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mutex));
+
+ *PhysicalAddress = (gctUINT64)physicalAddress;
+
/* Success. */
gcmkFOOTER_ARG("*Address=%08x", *Address);
return gcvSTATUS_OK;
OnError:
if (locked)
{
- if (Node->Virtual.pageTables[Kernel->core] != gcvNULL)
+ if (node->Virtual.pageTables[Kernel->core] != gcvNULL)
{
#if gcdENABLE_VG
if (Kernel->vg != gcvNULL)
/* Free the pages from the MMU. */
gcmkVERIFY_OK(
gckVGMMU_FreePages(Kernel->vg->mmu,
- Node->Virtual.pageTables[Kernel->core],
- Node->Virtual.pageCount));
+ node->Virtual.pageTables[Kernel->core],
+ node->Virtual.pageCount));
}
else
#endif
/* Free the pages from the MMU. */
gcmkVERIFY_OK(
gckMMU_FreePages(Kernel->mmu,
- Node->Virtual.pageTables[Kernel->core],
- Node->Virtual.pageCount));
+ node->Virtual.pageTables[Kernel->core],
+ node->Virtual.pageCount));
}
- Node->Virtual.pageTables[Kernel->core] = gcvNULL;
- Node->Virtual.lockKernels[Kernel->core] = gcvNULL;
+ node->Virtual.pageTables[Kernel->core] = gcvNULL;
+ node->Virtual.lockKernels[Kernel->core] = gcvNULL;
}
/* Unlock the pages. */
gcmkVERIFY_OK(
gckOS_UnlockPages(os,
- Node->Virtual.physical,
- Node->Virtual.bytes,
- Node->Virtual.logical
+ node->Virtual.physical,
+ node->Virtual.bytes,
+ node->Virtual.logical
));
- Node->Virtual.lockeds[Kernel->core]--;
+ node->Virtual.lockeds[Kernel->core]--;
}
if (acquired)
{
/* Release the mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mutex));
}
/* Return the status. */
gceSTATUS
gckVIDMEM_Unlock(
IN gckKERNEL Kernel,
- IN gcuVIDMEM_NODE_PTR Node,
+ IN gckVIDMEM_NODE Node,
IN gceSURF_TYPE Type,
IN OUT gctBOOL * Asynchroneous
)
{
gceSTATUS status;
- gckHARDWARE hardware;
- gctPOINTER buffer;
- gctSIZE_T requested, bufferSize;
- gckCOMMAND command = gcvNULL;
- gceKERNEL_FLUSH flush;
gckOS os = gcvNULL;
gctBOOL acquired = gcvFALSE;
- gctBOOL commitEntered = gcvFALSE;
- gctINT32 i, totalLocked;
+ gcuVIDMEM_NODE_PTR node = Node->node;
gcmkHEADER_ARG("Node=0x%x Type=%d *Asynchroneous=%d",
Node, Type, gcmOPT_VALUE(Asynchroneous));
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+
+ /* Get the gckOS object pointer. */
+ os = Kernel->os;
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
/* Verify the arguments. */
- if ((Node == gcvNULL)
- || (Node->VidMem.memory == gcvNULL)
+ if ((node == gcvNULL)
+ || (node->VidMem.memory == gcvNULL)
)
{
/* Invalid object. */
gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
}
+ /* Grab the mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(os, Node->mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
/**************************** Video Memory ********************************/
- if (Node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
{
- if (Node->VidMem.locked <= 0)
+ if (node->VidMem.locked <= 0)
{
/* The surface was not locked. */
status = gcvSTATUS_MEMORY_UNLOCKED;
goto OnError;
}
- /* Decrement the lock count. */
- Node->VidMem.locked --;
-
if (Asynchroneous != gcvNULL)
{
- /* No need for any events. */
- *Asynchroneous = gcvFALSE;
+ /* Schedule an event to sync with GPU. */
+ *Asynchroneous = gcvTRUE;
+ }
+ else
+ {
+ /* Decrement the lock count. */
+ node->VidMem.locked --;
}
gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
"Unlocked node 0x%x (%d)",
- Node,
- Node->VidMem.locked);
-
-#ifdef __QNXNTO__
- /* Unmap the video memory */
- if ((Node->VidMem.locked == 0) && (Node->VidMem.logical != gcvNULL))
- {
- if (Kernel->core == gcvCORE_VG)
- {
- gckKERNEL_UnmapVideoMemory(Kernel,
- Node->VidMem.logical,
- Node->VidMem.processID,
- Node->VidMem.bytes);
- Node->VidMem.logical = gcvNULL;
- }
- }
-#endif /* __QNXNTO__ */
-
- if (Node->VidMem.freePending && (Node->VidMem.locked == 0))
- {
- /* Client has unlocked node previously attempted to be freed by compositor. Free now. */
- Node->VidMem.freePending = gcvFALSE;
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
- "Deferred-freeing Node 0x%x.",
- Node);
- gcmkONERROR(gckVIDMEM_Free(Node));
- }
+ node,
+ node->VidMem.locked);
}
/*************************** Virtual Memory *******************************/
else
{
- /* Verify the gckHARDWARE object pointer. */
- hardware = Kernel->hardware;
- gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
-
- /* Verify the gckCOMMAND object pointer. */
- command = Kernel->command;
- gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
-
- /* Get the gckOS object pointer. */
- os = Kernel->os;
- gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
-
- /* Grab the mutex. */
- gcmkONERROR(
- gckOS_AcquireMutex(os, Node->Virtual.mutex, gcvINFINITE));
- acquired = gcvTRUE;
if (Asynchroneous == gcvNULL)
{
- if (Node->Virtual.lockeds[Kernel->core] == 0)
+#if !gcdPROCESS_ADDRESS_SPACE
+ if (node->Virtual.lockeds[Kernel->core] == 0)
{
status = gcvSTATUS_MEMORY_UNLOCKED;
goto OnError;
}
/* Decrement lock count. */
- -- Node->Virtual.lockeds[Kernel->core];
+ -- node->Virtual.lockeds[Kernel->core];
/* See if we can unlock the resources. */
- if (Node->Virtual.lockeds[Kernel->core] == 0)
+ if (node->Virtual.lockeds[Kernel->core] == 0)
{
+#if gcdSECURITY
+ if (node->Virtual.addresses[Kernel->core] > 0x80000000)
+ {
+ gcmkONERROR(gckKERNEL_SecurityUnmapMemory(
+ Kernel,
+ node->Virtual.addresses[Kernel->core],
+ node->Virtual.pageCount
+ ));
+ }
+#else
/* Free the page table. */
- if (Node->Virtual.pageTables[Kernel->core] != gcvNULL)
+ if (node->Virtual.pageTables[Kernel->core] != gcvNULL)
{
#if gcdENABLE_VG
if (Kernel->vg != gcvNULL)
{
gcmkONERROR(
gckVGMMU_FreePages(Kernel->vg->mmu,
- Node->Virtual.pageTables[Kernel->core],
- Node->Virtual.pageCount));
+ node->Virtual.pageTables[Kernel->core],
+ node->Virtual.pageCount));
}
else
#endif
{
gcmkONERROR(
gckMMU_FreePages(Kernel->mmu,
- Node->Virtual.pageTables[Kernel->core],
- Node->Virtual.pageCount));
+ node->Virtual.pageTables[Kernel->core],
+ node->Virtual.pageCount));
}
- /* Mark page table as freed. */
- Node->Virtual.pageTables[Kernel->core] = gcvNULL;
- Node->Virtual.lockKernels[Kernel->core] = gcvNULL;
- }
-
-#ifdef __QNXNTO__
- /* Mark node as unlocked. */
- Node->Virtual.unlockPendings[Kernel->core] = gcvFALSE;
-#endif
- }
-
- for (i = 0, totalLocked = 0; i < gcdMAX_GPU_COUNT; i++)
- {
- totalLocked += Node->Virtual.lockeds[i];
- }
-
- if (totalLocked == 0)
- {
- /* Owner have already freed this node
- ** and we are the last one to unlock, do
- ** real free */
- if (Node->Virtual.freed)
- {
- /* Free the virtual memory. */
- gcmkVERIFY_OK(gckOS_FreePagedMemory(Kernel->os,
- Node->Virtual.physical,
- Node->Virtual.bytes));
-
- /* Release mutex before node is destroyed */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
- acquired = gcvFALSE;
-
- /* Destroy the gcuVIDMEM_NODE union. */
- gcmkVERIFY_OK(gckVIDMEM_DestroyVirtual(Node));
+ gcmkONERROR(gckOS_UnmapPages(
+ Kernel->os,
+ node->Virtual.pageCount,
+ node->Virtual.addresses[Kernel->core]
+ ));
- /* Node has been destroyed, so we should not touch it any more */
- gcmkFOOTER();
- return gcvSTATUS_OK;
+ /* Mark page table as freed. */
+ node->Virtual.pageTables[Kernel->core] = gcvNULL;
+ node->Virtual.lockKernels[Kernel->core] = gcvNULL;
}
+#endif
}
gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
"Unmapped virtual node 0x%x from 0x%08X",
- Node, Node->Virtual.addresses[Kernel->core]);
+ node, node->Virtual.addresses[Kernel->core]);
+#endif
}
else
{
- /* If we need to unlock a node from virtual memory we have to be
- ** very carefull. If the node is still inside the caches we
- ** might get a bus error later if the cache line needs to be
- ** replaced. So - we have to flush the caches before we do
- ** anything. */
-
- /* gckCommand_EnterCommit() can't be called in interrupt handler because
- ** of a dead lock situation:
- ** process call Command_Commit(), and acquire Command->mutexQueue in
- ** gckCOMMAND_EnterCommit(). Then it will wait for a signal which depends
- ** on interrupt handler to generate, if interrupt handler enter
- ** gckCommand_EnterCommit(), process will never get the signal. */
-
- /* So, flush cache when we still in process context, and then ask caller to
- ** schedule a event. */
-
gcmkONERROR(
gckOS_UnlockPages(os,
- Node->Virtual.physical,
- Node->Virtual.bytes,
- Node->Virtual.logical));
-
- if (!Node->Virtual.contiguous
- && (Node->Virtual.lockeds[Kernel->core] == 1)
-#if gcdENABLE_VG
- && (Kernel->vg == gcvNULL)
-#endif
- )
- {
- if (Type == gcvSURF_BITMAP)
- {
- /* Flush 2D cache. */
- flush = gcvFLUSH_2D;
- }
- else if (Type == gcvSURF_RENDER_TARGET)
- {
- /* Flush color cache. */
- flush = gcvFLUSH_COLOR;
- }
- else if (Type == gcvSURF_DEPTH)
- {
- /* Flush depth cache. */
- flush = gcvFLUSH_DEPTH;
- }
- else
- {
- /* No flush required. */
- flush = (gceKERNEL_FLUSH) 0;
- }
- if(hardware)
- {
- gcmkONERROR(
- gckHARDWARE_Flush(hardware, flush, gcvNULL, &requested));
+ node->Virtual.physical,
+ node->Virtual.bytes,
+ node->Virtual.logical));
- if (requested != 0)
- {
- /* Acquire the command queue. */
- gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvFALSE));
- commitEntered = gcvTRUE;
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+ "Scheduled unlock for virtual node 0x%x",
+ node);
- gcmkONERROR(gckCOMMAND_Reserve(
- command, requested, &buffer, &bufferSize
- ));
+ /* Schedule the surface to be unlocked. */
+ *Asynchroneous = gcvTRUE;
+ }
+ }
- gcmkONERROR(gckHARDWARE_Flush(
- hardware, flush, buffer, &bufferSize
- ));
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mutex));
+ acquired = gcvFALSE;
- /* Mark node as pending. */
-#ifdef __QNXNTO__
- Node->Virtual.unlockPendings[Kernel->core] = gcvTRUE;
-#endif
+ /* Success. */
+ gcmkFOOTER_ARG("*Asynchroneous=%d", gcmOPT_VALUE(Asynchroneous));
+ return gcvSTATUS_OK;
- gcmkONERROR(gckCOMMAND_Execute(command, requested));
+OnError:
+ if (acquired)
+ {
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mutex));
+ }
- /* Release the command queue. */
- gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvFALSE));
- commitEntered = gcvFALSE;
- }
- }
- else
- {
- gckOS_Print("Hardware already is freed.\n");
- }
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+#if gcdPROCESS_ADDRESS_SPACE
+gceSTATUS
+gckVIDMEM_Node_Lock(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node,
+ OUT gctUINT32 *Address
+ )
+{
+ gceSTATUS status;
+ gckOS os;
+ gcuVIDMEM_NODE_PTR node = Node->node;
+ gcsGPU_MAP_PTR gpuMap;
+ gctPHYS_ADDR physical = gcvNULL;
+ gctUINT32 phys = gcvINVALID_ADDRESS;
+ gctUINT32 processID;
+ gcsLOCK_INFO_PTR lockInfo;
+ gctUINT32 pageCount;
+ gckMMU mmu;
+ gctUINT32 i;
+ gctUINT32_PTR pageTableEntry;
+ gctUINT32 offset = 0;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Node = %x", Node);
+
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Node != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Address != gcvNULL);
+
+ os = Kernel->os;
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+ gcmkONERROR(gckOS_GetProcessID(&processID));
+
+ gcmkONERROR(gckKERNEL_GetProcessMMU(Kernel, &mmu));
+
+ gcmkONERROR(gckOS_AcquireMutex(os, Node->mapMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Get map information for current process. */
+ gpuMap = _FindGPUMap(Node->mapHead, processID);
+
+ if (gpuMap == gcvNULL)
+ {
+ gpuMap = _CreateGPUMap(os, &Node->mapHead, &Node->mapTail, processID);
+
+ if (gpuMap == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+ }
+
+ lockInfo = &gpuMap->lockInfo;
+
+ if (lockInfo->lockeds[Kernel->core] ++ == 0)
+ {
+ /* Get necessary information. */
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ phys = node->VidMem.memory->baseAddress
+ + node->VidMem.offset
+ + node->VidMem.alignment;
+
+ /* GPU page table use 4K page. */
+ pageCount = ((phys + node->VidMem.bytes + 4096 - 1) >> 12)
+ - (phys >> 12);
+
+ offset = phys & 0xFFF;
+ }
+ else
+ {
+ pageCount = node->Virtual.pageCount;
+ physical = node->Virtual.physical;
+ }
+
+ /* Allocate pages inside the MMU. */
+ gcmkONERROR(gckMMU_AllocatePages(
+ mmu,
+ pageCount,
+ &lockInfo->pageTables[Kernel->core],
+ &lockInfo->GPUAddresses[Kernel->core]));
+
+ /* Record MMU from which pages are allocated. */
+ lockInfo->lockMmus[Kernel->core] = mmu;
+
+ pageTableEntry = lockInfo->pageTables[Kernel->core];
+
+ /* Fill page table entries. */
+ if (phys != gcvINVALID_ADDRESS)
+ {
+ gctUINT32 address = lockInfo->GPUAddresses[Kernel->core];
+ for (i = 0; i < pageCount; i++)
+ {
+ gckMMU_GetPageEntry(mmu, address, &pageTableEntry);
+ gckMMU_SetPage(mmu, phys & 0xFFFFF000, pageTableEntry);
+ phys += 4096;
+ address += 4096;
+ pageTableEntry += 1;
}
+ }
+ else
+ {
+ gctUINT32 address = lockInfo->GPUAddresses[Kernel->core];
+ gcmkASSERT(physical != gcvNULL);
+ gcmkONERROR(gckOS_MapPagesEx(os,
+ Kernel->core,
+ physical,
+ pageCount,
+ address,
+ pageTableEntry));
+ }
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
- "Scheduled unlock for virtual node 0x%x",
- Node);
+ gcmkONERROR(gckMMU_Flush(mmu));
+ }
- /* Schedule the surface to be unlocked. */
- *Asynchroneous = gcvTRUE;
+ *Address = lockInfo->GPUAddresses[Kernel->core] + offset;
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mapMutex));
+ acquired = gcvFALSE;
+
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mapMutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_Unlock(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node,
+ IN gctUINT32 ProcessID
+ )
+{
+ gceSTATUS status;
+ gcsGPU_MAP_PTR gpuMap;
+ gcsLOCK_INFO_PTR lockInfo;
+ gckMMU mmu;
+ gcuVIDMEM_NODE_PTR node;
+ gctUINT32 pageCount;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Kernel=0x%08X, Node = %x, ProcessID=%d",
+ Kernel, Node, ProcessID);
+
+ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ gcmkVERIFY_ARGUMENT(Node != gcvNULL);
+
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Node->mapMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Get map information for current process. */
+ gpuMap = _FindGPUMap(Node->mapHead, ProcessID);
+
+ if (gpuMap == gcvNULL)
+ {
+ /* No mapping for this process. */
+ gcmkONERROR(gcvSTATUS_INVALID_DATA);
+ }
+
+ lockInfo = &gpuMap->lockInfo;
+
+ if (--lockInfo->lockeds[Kernel->core] == 0)
+ {
+ node = Node->node;
+
+ /* Get necessary information. */
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ gctUINT32 phys = node->VidMem.memory->baseAddress
+ + node->VidMem.offset
+ + node->VidMem.alignment;
+
+ /* GPU page table use 4K page. */
+ pageCount = ((phys + node->VidMem.bytes + 4096 - 1) >> 12)
+ - (phys >> 12);
+ }
+ else
+ {
+ pageCount = node->Virtual.pageCount;
}
- /* Release the mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
+ /* Get MMU which allocates pages. */
+ mmu = lockInfo->lockMmus[Kernel->core];
+
+ /* Free virtual spaces in page table. */
+ gcmkVERIFY_OK(gckMMU_FreePagesEx(
+ mmu,
+ lockInfo->GPUAddresses[Kernel->core],
+ pageCount
+ ));
- acquired = gcvFALSE;
+ _DestroyGPUMap(Kernel->os, &Node->mapHead, &Node->mapTail, gpuMap);
}
- /* Success. */
- gcmkFOOTER_ARG("*Asynchroneous=%d", gcmOPT_VALUE(Asynchroneous));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Node->mapMutex));
+ acquired = gcvFALSE;
+
+ gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
- if (commitEntered)
+ if (acquired)
{
- /* Release the command queue mutex. */
- gcmkVERIFY_OK(gckCOMMAND_ExitCommit(command, gcvFALSE));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Node->mapMutex));
}
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
+/*******************************************************************************
+**
+** gckVIDMEM_HANDLE_Allocate
+**
+** Allocate a handle for a gckVIDMEM_NODE object.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gckVIDMEM_NODE Node
+** Pointer to a gckVIDMEM_NODE object.
+**
+** OUTPUT:
+**
+** gctUINT32 * Handle
+** Pointer to a variable receiving a handle represent this
+** gckVIDMEM_NODE in userspace.
+*/
+static gceSTATUS
+gckVIDMEM_HANDLE_Allocate(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node,
+ OUT gctUINT32 * Handle
+ )
+{
+ gceSTATUS status;
+ gctUINT32 processID = 0;
+ gctPOINTER pointer = gcvNULL;
+ gctPOINTER handleDatabase = gcvNULL;
+ gctPOINTER mutex = gcvNULL;
+ gctUINT32 handle = 0;
+ gckVIDMEM_HANDLE handleObject = gcvNULL;
+ gckOS os = Kernel->os;
+
+ gcmkHEADER_ARG("Kernel=0x%X, Node=0x%X", Kernel, Node);
+
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+ /* Allocate a gckVIDMEM_HANDLE object. */
+ gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsVIDMEM_HANDLE), &pointer));
+
+ gcmkVERIFY_OK(gckOS_ZeroMemory(pointer, gcmSIZEOF(gcsVIDMEM_HANDLE)));
+
+ handleObject = pointer;
+
+ gcmkONERROR(gckOS_AtomConstruct(os, &handleObject->reference));
+
+ /* Set default reference count to 1. */
+ gckOS_AtomSet(os, handleObject->reference, 1);
+
+ gcmkVERIFY_OK(gckOS_GetProcessID(&processID));
+
+ gcmkONERROR(
+ gckKERNEL_FindHandleDatbase(Kernel,
+ processID,
+ &handleDatabase,
+ &mutex));
+
+ /* Allocate a handle for this object. */
+ gcmkONERROR(
+ gckKERNEL_AllocateIntegerId(handleDatabase, handleObject, &handle));
+
+ handleObject->node = Node;
+ handleObject->handle = handle;
+
+ *Handle = handle;
+
+ gcmkFOOTER_ARG("*Handle=%d", *Handle);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (handleObject != gcvNULL)
+ {
+ if (handleObject->reference != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(os, handleObject->reference));
+ }
+
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, handleObject));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+gckVIDMEM_NODE_Reference(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node
+ )
+{
+ gctINT32 oldValue;
+ gcmkHEADER_ARG("Kernel=0x%X Node=0x%X", Kernel, Node);
+
+ gckOS_AtomIncrement(Kernel->os, Node->reference, &oldValue);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckVIDMEM_HANDLE_Reference(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 Handle
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_HANDLE handleObject = gcvNULL;
+ gctPOINTER database = gcvNULL;
+ gctPOINTER mutex = gcvNULL;
+ gctINT32 oldValue = 0;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Handle=%d PrcoessID=%d", Handle, ProcessID);
+
+ gcmkONERROR(
+ gckKERNEL_FindHandleDatbase(Kernel, ProcessID, &database, &mutex));
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Translate handle to gckVIDMEM_HANDLE object. */
+ gcmkONERROR(
+ gckKERNEL_QueryIntegerId(database, Handle, (gctPOINTER *)&handleObject));
+
+ /* Increase the reference count. */
+ gckOS_AtomIncrement(Kernel->os, handleObject->reference, &oldValue);
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ acquired = gcvFALSE;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
if (acquired)
{
- /* Release the mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckVIDMEM_HANDLE_Dereference(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 Handle
+ )
+{
+ gceSTATUS status;
+ gctPOINTER handleDatabase = gcvNULL;
+ gctPOINTER mutex = gcvNULL;
+ gctINT32 oldValue = 0;
+ gckVIDMEM_HANDLE handleObject = gcvNULL;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Handle=%d PrcoessID=%d", Handle, ProcessID);
+
+ gcmkONERROR(
+ gckKERNEL_FindHandleDatbase(Kernel,
+ ProcessID,
+ &handleDatabase,
+ &mutex));
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Translate handle to gckVIDMEM_HANDLE. */
+ gcmkONERROR(
+ gckKERNEL_QueryIntegerId(handleDatabase, Handle, (gctPOINTER *)&handleObject));
+
+ gckOS_AtomDecrement(Kernel->os, handleObject->reference, &oldValue);
+
+ if (oldValue == 1)
+ {
+ /* Remove handle from database if this is the last reference. */
+ gcmkVERIFY_OK(gckKERNEL_FreeIntegerId(handleDatabase, Handle));
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ acquired = gcvFALSE;
+
+ if (oldValue == 1)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, handleObject->reference));
+ gcmkOS_SAFE_FREE(Kernel->os, handleObject);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckVIDMEM_HANDLE_LookupAndReference(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ OUT gckVIDMEM_NODE * Node
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_HANDLE handleObject = gcvNULL;
+ gckVIDMEM_NODE node = gcvNULL;
+ gctPOINTER database = gcvNULL;
+ gctPOINTER mutex = gcvNULL;
+ gctUINT32 processID = 0;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Kernel=0x%X Handle=%d", Kernel, Handle);
+
+ gckOS_GetProcessID(&processID);
+
+ gcmkONERROR(
+ gckKERNEL_FindHandleDatbase(Kernel, processID, &database, &mutex));
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Translate handle to gckVIDMEM_HANDLE object. */
+ gcmkONERROR(
+ gckKERNEL_QueryIntegerId(database, Handle, (gctPOINTER *)&handleObject));
+
+ /* Get gckVIDMEM_NODE object. */
+ node = handleObject->node;
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ acquired = gcvFALSE;
+
+ /* Reference this gckVIDMEM_NODE object. */
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Reference(Kernel, node));
+
+ /* Return result. */
+ *Node = node;
+
+ gcmkFOOTER_ARG("*Node=%d", *Node);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckVIDMEM_HANDLE_Lookup(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 Handle,
+ OUT gckVIDMEM_NODE * Node
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_HANDLE handleObject = gcvNULL;
+ gckVIDMEM_NODE node = gcvNULL;
+ gctPOINTER database = gcvNULL;
+ gctPOINTER mutex = gcvNULL;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Kernel=0x%X ProcessID=%d Handle=%d",
+ Kernel, ProcessID, Handle);
+
+ gcmkONERROR(
+ gckKERNEL_FindHandleDatbase(Kernel, ProcessID, &database, &mutex));
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ gcmkONERROR(
+ gckKERNEL_QueryIntegerId(database, Handle, (gctPOINTER *)&handleObject));
+
+ node = handleObject->node;
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ acquired = gcvFALSE;
+
+ *Node = node;
+
+ gcmkFOOTER_ARG("*Node=%d", *Node);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
}
- /* Return the status. */
gcmkFOOTER();
return status;
}
+
+/*******************************************************************************
+**
+** gckVIDMEM_NODE_Allocate
+**
+** Allocate a gckVIDMEM_NODE object.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gcuVIDMEM_NODE_PTR Node
+** Pointer to a gcuVIDMEM_NODE union.
+**
+** OUTPUT:
+**
+** gctUINT32 * Handle
+** Pointer to a variable receiving a handle represent this
+** gckVIDMEM_NODE in userspace.
+*/
+gceSTATUS
+gckVIDMEM_NODE_Allocate(
+ IN gckKERNEL Kernel,
+ IN gcuVIDMEM_NODE_PTR VideoNode,
+ IN gceSURF_TYPE Type,
+ IN gcePOOL Pool,
+ IN gctUINT32 * Handle
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE node = gcvNULL;
+ gctPOINTER pointer = gcvNULL;
+ gctUINT32 handle = 0;
+ gckOS os = Kernel->os;
+
+ gcmkHEADER_ARG("Kernel=0x%X VideoNode=0x%X", Kernel, VideoNode);
+
+ /* Construct a node. */
+ gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsVIDMEM_NODE), &pointer));
+
+ gcmkVERIFY_OK(gckOS_ZeroMemory(pointer, gcmSIZEOF(gcsVIDMEM_NODE)));
+
+ node = pointer;
+
+ node->node = VideoNode;
+ node->type = Type;
+ node->pool = Pool;
+
+#if gcdPROCESS_ADDRESS_SPACE
+ gcmkONERROR(gckOS_CreateMutex(os, &node->mapMutex));
+#endif
+
+ gcmkONERROR(gckOS_AtomConstruct(os, &node->reference));
+
+ gcmkONERROR(gckOS_CreateMutex(os, &node->mutex));
+
+ /* Reference is 1 by default . */
+ gckVIDMEM_NODE_Reference(Kernel, node);
+
+ /* Create a handle to represent this node. */
+ gcmkONERROR(gckVIDMEM_HANDLE_Allocate(Kernel, node, &handle));
+
+ *Handle = handle;
+
+ gcmkFOOTER_ARG("*Handle=%d", *Handle);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (node != gcvNULL)
+ {
+#if gcdPROCESS_ADDRESS_SPACE
+ if (node->mapMutex != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_DeleteMutex(os, node->mapMutex));
+ }
+#endif
+
+ if (node->mutex)
+ {
+ gcmkVERIFY_OK(gckOS_DeleteMutex(os, node->mutex));
+ }
+
+ if (node->reference != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(os, node->reference));
+ }
+
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, node));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_Dereference(
+ IN gckKERNEL Kernel,
+ IN gckVIDMEM_NODE Node
+ )
+{
+ gctINT32 oldValue = 0;
+ gctPOINTER database = Kernel->db->nameDatabase;
+ gctPOINTER mutex = Kernel->db->nameDatabaseMutex;
+
+ gcmkHEADER_ARG("Kernel=0x%X Node=0x%X", Kernel, Node);
+
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE));
+
+ gcmkVERIFY_OK(gckOS_AtomDecrement(Kernel->os, Node->reference, &oldValue));
+
+ if (oldValue == 1 && Node->name)
+ {
+ /* Free name if exists. */
+ gcmkVERIFY_OK(gckKERNEL_FreeIntegerId(database, Node->name));
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+
+ if (oldValue == 1)
+ {
+ /* Free gcuVIDMEM_NODE. */
+ gcmkVERIFY_OK(gckVIDMEM_Free(Kernel, Node->node));
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Node->reference));
+#if gcdPROCESS_ADDRESS_SPACE
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Node->mapMutex));
+#endif
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Node->mutex));
+ gcmkOS_SAFE_FREE(Kernel->os, Node);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckVIDMEM_NODE_Name
+**
+** Naming a gckVIDMEM_NODE object.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctUINT32 Handle
+** Handle to a gckVIDMEM_NODE object.
+**
+** OUTPUT:
+**
+** gctUINT32 * Name
+** Pointer to a variable receiving a name which can be pass to another
+** process.
+*/
+gceSTATUS
+gckVIDMEM_NODE_Name(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ IN gctUINT32 * Name
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE node = gcvNULL;
+ gctUINT32 name = 0;
+ gctUINT32 processID = 0;
+ gctPOINTER database = Kernel->db->nameDatabase;
+ gctPOINTER mutex = Kernel->db->nameDatabaseMutex;
+ gctBOOL acquired = gcvFALSE;
+ gctBOOL referenced = gcvFALSE;
+ gcmkHEADER_ARG("Kernel=0x%X Handle=%d", Kernel, Handle);
+
+ gcmkONERROR(gckOS_GetProcessID(&processID));
+
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ gcmkONERROR(gckVIDMEM_HANDLE_LookupAndReference(Kernel, Handle, &node));
+ referenced = gcvTRUE;
+
+ if (node->name == 0)
+ {
+ /* Name this node. */
+ gcmkONERROR(gckKERNEL_AllocateIntegerId(database, node, &name));
+ node->name = name;
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ acquired = gcvFALSE;
+
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, node));
+
+ if(node)
+ {
+ *Name = node->name;
+ }
+
+ gcmkFOOTER_ARG("*Name=%d", *Name);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (referenced)
+ {
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, node));
+ }
+
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckVIDMEM_NODE_Import
+**
+** Import a gckVIDMEM_NODE object.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctUINT32 Name
+** Name of a gckVIDMEM_NODE object.
+**
+** OUTPUT:
+**
+** gctUINT32 * Handle
+** Pointer to a variable receiving a handle represent this
+** gckVIDMEM_NODE in userspace.
+*/
+gceSTATUS
+gckVIDMEM_NODE_Import(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Name,
+ IN gctUINT32 * Handle
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE node = gcvNULL;
+ gctPOINTER database = Kernel->db->nameDatabase;
+ gctPOINTER mutex = Kernel->db->nameDatabaseMutex;
+ gctBOOL acquired = gcvFALSE;
+ gctBOOL referenced = gcvFALSE;
+
+ gcmkHEADER_ARG("Kernel=0x%X Name=%d", Kernel, Name);
+
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ /* Lookup in database to get the node. */
+ gcmkONERROR(gckKERNEL_QueryIntegerId(database, Name, (gctPOINTER *)&node));
+
+ /* Reference the node. */
+ gcmkONERROR(gckVIDMEM_NODE_Reference(Kernel, node));
+ referenced = gcvTRUE;
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ acquired = gcvFALSE;
+
+ /* Allocate a handle for current process. */
+ gcmkONERROR(gckVIDMEM_HANDLE_Allocate(Kernel, node, Handle));
+
+ gcmkFOOTER_ARG("*Handle=%d", *Handle);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (referenced)
+ {
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, node));
+ }
+
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+
+typedef struct _gcsVIDMEM_NODE_FDPRIVATE
+{
+ gcsFDPRIVATE base;
+ gckKERNEL kernel;
+ gckVIDMEM_NODE node;
+}
+gcsVIDMEM_NODE_FDPRIVATE;
+
+
+static gctINT
+_ReleaseFdPrivate(
+ gcsFDPRIVATE_PTR FdPrivate
+ )
+{
+ /* Cast private info. */
+ gcsVIDMEM_NODE_FDPRIVATE * private = (gcsVIDMEM_NODE_FDPRIVATE *) FdPrivate;
+
+ gckVIDMEM_NODE_Dereference(private->kernel, private->node);
+ gckOS_Free(private->kernel->os, private);
+
+ return 0;
+}
+
+/*******************************************************************************
+**
+** gckVIDMEM_NODE_GetFd
+**
+** Attach a gckVIDMEM_NODE object to a native fd.
+**
+** INPUT:
+**
+** gckKERNEL Kernel
+** Pointer to an gckKERNEL object.
+**
+** gctUINT32 Handle
+** Handle to a gckVIDMEM_NODE object.
+**
+** OUTPUT:
+**
+** gctUINT32 * Fd
+** Pointer to a variable receiving a native fd from os.
+*/
+gceSTATUS
+gckVIDMEM_NODE_GetFd(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 Handle,
+ OUT gctINT * Fd
+ )
+{
+ gceSTATUS status;
+ gckVIDMEM_NODE node = gcvNULL;
+ gctBOOL referenced = gcvFALSE;
+ gcsVIDMEM_NODE_FDPRIVATE * fdPrivate = gcvNULL;
+ gcmkHEADER_ARG("Kernel=0x%X Handle=%d", Kernel, Handle);
+
+ /* Query and reference handle. */
+ gcmkONERROR(gckVIDMEM_HANDLE_LookupAndReference(Kernel, Handle, &node));
+ referenced = gcvTRUE;
+
+ /* Allocate memory for private info. */
+ gcmkONERROR(gckOS_Allocate(
+ Kernel->os,
+ gcmSIZEOF(gcsVIDMEM_NODE_FDPRIVATE),
+ (gctPOINTER *)&fdPrivate
+ ));
+
+ fdPrivate->base.release = _ReleaseFdPrivate;
+ fdPrivate->kernel = Kernel;
+ fdPrivate->node = node;
+
+ /* Allocated fd owns a reference. */
+ gcmkONERROR(gckOS_GetFd("vidmem", &fdPrivate->base, Fd));
+
+ gcmkFOOTER_ARG("*Fd=%d", *Fd);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (referenced)
+ {
+ gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, node));
+ }
+
+ if (fdPrivate)
+ {
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, fdPrivate));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#include "gc_hal_base.h"
#include "gc_hal_profiler.h"
#include "gc_hal_driver.h"
-#ifndef VIVANTE_NO_3D
+#if gcdENABLE_3D
#include "gc_hal_statistics.h"
#endif
+#if gcdSECURITY
+#include "gc_hal_security_interface.h"
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
******************************* Alignment Macros *******************************
\******************************************************************************/
+/* Alignment with a non-power of two value. */
+#define gcmALIGN_NP2(n, align) \
+( \
+ ((n) + (align) - 1) - (((n) + (align) - 1) % (align)) \
+)
+
+/* Alignment with a power of two value. */
#define gcmALIGN(n, align) \
( \
((n) + ((align) - 1)) & ~((align) - 1) \
#define gcmRELEASE_NAME(na) \
gckKERNEL_DeleteName(kernel, gcmALL_TO_UINT32(na))
-#ifdef __LP64__
-
#define gcmALL_TO_UINT32(t) \
( \
(gctUINT32) (gctUINTPTR_T) (t)\
)
-#define gcmPTR_TO_UINT64(p) \
-( \
- (gctUINT64) (p)\
-)
-
-#define gcmUINT64_TO_PTR(u) \
-( \
- (gctPOINTER) (u)\
-)
-
-#else /* 32 bit */
-
-#define gcmALL_TO_UINT32(t) \
-( \
- (gctUINT32) (t)\
-)
-
#define gcmPTR_TO_UINT64(p) \
( \
(gctUINT64) (gctUINTPTR_T) (p)\
(gctPOINTER) (gctUINTPTR_T) (u)\
)
-#endif
-
#define gcmUINT64_TO_TYPE(u, t) \
( \
(t) (gctUINTPTR_T) (u)\
gcvOBJ_VERTEX = gcmCC('V','R','T','X'),
gcvOBJ_VIDMEM = gcmCC('V','M','E','M'),
gcvOBJ_VG = gcmCC('V','G',' ',' '),
+ gcvOBJ_BUFOBJ = gcmCC('B','U','F','O'),
+ gcvOBJ_UNIFORM_BLOCK = gcmCC('U','B','L','K'),
+ gcvOBJ_CL = gcmCC('C','L',' ',' '),
}
gceOBJECT_TYPE;
{
gcvCORE_MAJOR = 0x0,
gcvCORE_2D = 0x1,
- gcvCORE_VG = 0x2
+ gcvCORE_VG = 0x2,
+#if gcdMULTI_GPU_AFFINITY
+ gcvCORE_OCL = 0x3,
+#endif
}
gceCORE;
+#if gcdMULTI_GPU_AFFINITY
+#define gcdMAX_GPU_COUNT 4
+#else
#define gcdMAX_GPU_COUNT 3
+#endif
+
+#define gcdMAX_SURF_LAYER 4
+
+#define gcdMAX_DRAW_BUFFERS 4
/*******************************************************************************
**
gceSTATUS
gckOS_AllocatePagedMemoryEx(
IN gckOS Os,
- IN gctBOOL Contiguous,
+ IN gctUINT32 Flag,
IN gctSIZE_T Bytes,
+ OUT gctUINT32 * Gid,
OUT gctPHYS_ADDR * Physical
);
gckOS_MapPages(
IN gckOS Os,
IN gctPHYS_ADDR Physical,
-#ifdef __QNXNTO__
- IN gctPOINTER Logical,
-#endif
IN gctSIZE_T PageCount,
IN gctPOINTER PageTable
);
IN gckOS Os,
IN gceCORE Core,
IN gctPHYS_ADDR Physical,
-#ifdef __QNXNTO__
- IN gctPOINTER Logical,
-#endif
IN gctSIZE_T PageCount,
+ IN gctUINT32 Address,
IN gctPOINTER PageTable
);
+gceSTATUS
+gckOS_UnmapPages(
+ IN gckOS Os,
+ IN gctSIZE_T PageCount,
+ IN gctUINT32 Address
+ );
+
/* Unlock pages. */
gceSTATUS
gckOS_UnlockPages(
OUT gctUINT32 * Address
);
+/* Get the physical address of a corresponding user logical address. */
+gceSTATUS
+gckOS_UserLogicalToPhysical(
+ IN gckOS Os,
+ IN gctPOINTER Logical,
+ OUT gctUINT32 * Address
+ );
+
/* Get the physical address of a corresponding logical address. */
gceSTATUS
gckOS_GetPhysicalAddressProcess(
IN gctSIZE_T Bytes
);
+/* Get real physical address from descriptor. */
+gceSTATUS
+gckOS_PhysicalToPhysicalAddress(
+ IN gckOS Os,
+ IN gctPOINTER Physical,
+ OUT gctUINT32 * PhysicalAddress
+ );
+
/* Read data from a hardware register. */
gceSTATUS
gckOS_ReadRegister(
IN gctUINT32 Data
);
+#if gcdMULTI_GPU
+gceSTATUS
+gckOS_ReadRegisterByCoreId(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctUINT32 CoreId,
+ IN gctUINT32 Address,
+ OUT gctUINT32 * Data
+ );
+
+gceSTATUS
+gckOS_WriteRegisterByCoreId(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctUINT32 CoreId,
+ IN gctUINT32 Address,
+ IN gctUINT32 Data
+ );
+#endif
+
/* Write data to a 32-bit memory location. */
gceSTATUS
gckOS_WriteMemory(
OUT gctPOINTER * OldValue
);
-#if gcdSMP
gceSTATUS
gckOS_AtomSetMask(
IN gctPOINTER Atom,
IN gctPOINTER Atom,
IN gctUINT32 Mask
);
-#endif
gceSTATUS
gckOS_DumpCallStack(
OUT gctUINT8_PTR String
);
-
-
/*******************************************************************************
**
** gckOS_AtomConstruct
IN gctSIZE_T Size
);
-#ifdef __QNXNTO__
-/* Map user physical address. */
-gceSTATUS
-gckOS_MapUserPhysical(
- IN gckOS Os,
- IN gctPHYS_ADDR Phys,
- OUT gctPOINTER * KernelPointer
- );
-#endif
-
gceSTATUS
gckOS_SuspendInterrupt(
IN gckOS Os
OUT gctUINT32_PTR ThreadID
);
+#if gcdSECURITY
+gceSTATUS
+gckOS_OpenSecurityChannel(
+ IN gckOS Os,
+ IN gceCORE Core,
+ OUT gctUINT32 *Channel
+ );
+
+gceSTATUS
+gckOS_CloseSecurityChannel(
+ IN gctUINT32 Channel
+ );
+
+gceSTATUS
+gckOS_CallSecurityService(
+ IN gctUINT32 Channel,
+ IN gcsTA_INTERFACE * Interface
+ );
+
+gceSTATUS
+gckOS_InitSecurityChannel(
+ OUT gctUINT32 Channel
+ );
+
+gceSTATUS
+gckOS_AllocatePageArray(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T PageCount,
+ OUT gctPOINTER * PageArrayLogical,
+ OUT gctPHYS_ADDR * PageArrayPhysical
+ );
+#endif
+
/******************************************************************************\
********************************** Signal Object *********************************
\******************************************************************************/
gckOS Os,
gctUINT32 ProcessID,
gctPHYS_ADDR Handle,
- gctPOINTER Physical,
+ gctUINT32 Physical,
gctPOINTER Logical,
gctSIZE_T Bytes
);
gckOS Os,
gctUINT32 ProcessID,
gctPHYS_ADDR Handle,
- gctPOINTER Physical,
+ gctUINT32 Physical,
gctPOINTER Logical,
gctSIZE_T Bytes
);
gckOS Os,
gctUINT32 ProcessID,
gctPHYS_ADDR Handle,
- gctPOINTER Physical,
+ gctUINT32 Physical,
gctPOINTER Logical,
gctSIZE_T Bytes
);
+gceSTATUS
+gckOS_CPUPhysicalToGPUPhysical(
+ IN gckOS Os,
+ IN gctUINT32 CPUPhysical,
+ IN gctUINT32_PTR GPUPhysical
+ );
+
+gceSTATUS
+gckOS_GPUPhysicalToCPUPhysical(
+ IN gckOS Os,
+ IN gctUINT32 GPUPhysical,
+ IN gctUINT32_PTR CPUPhysical
+ );
+
+gceSTATUS
+gckOS_QueryOption(
+ IN gckOS Os,
+ IN gctCONST_STRING Option,
+ OUT gctUINT32 * Value
+ );
+
/******************************************************************************\
** Debug Support
*/
/* AXI bus error. */
gcvBROADCAST_AXI_BUS_ERROR,
+
+ /* Out of memory. */
+ gcvBROADCAST_OUT_OF_MEMORY,
}
gceBROADCAST;
** INPUT:
**
** gckOS Os
-** Pointer to a gckOS object.ß
+** Pointer to a gckOS object.
**
-** gckCORE Core
+** gceCORE Core
** GPU whose power is set.
**
** gctBOOL Clock
IN gckVIDMEM Memory
);
-/* Allocate rectangular memory. */
-gceSTATUS
-gckVIDMEM_Allocate(
- IN gckVIDMEM Memory,
- IN gctUINT Width,
- IN gctUINT Height,
- IN gctUINT Depth,
- IN gctUINT BytesPerPixel,
- IN gctUINT32 Alignment,
- IN gceSURF_TYPE Type,
- OUT gcuVIDMEM_NODE_PTR * Node
- );
-
/* Allocate linear memory. */
gceSTATUS
gckVIDMEM_AllocateLinear(
+ IN gckKERNEL Kernel,
IN gckVIDMEM Memory,
IN gctSIZE_T Bytes,
IN gctUINT32 Alignment,
IN gceSURF_TYPE Type,
+ IN gctBOOL Specified,
OUT gcuVIDMEM_NODE_PTR * Node
);
/* Free memory. */
gceSTATUS
gckVIDMEM_Free(
+ IN gckKERNEL Kernel,
IN gcuVIDMEM_NODE_PTR Node
);
gceSTATUS
gckVIDMEM_Lock(
IN gckKERNEL Kernel,
- IN gcuVIDMEM_NODE_PTR Node,
+ IN gckVIDMEM_NODE Node,
IN gctBOOL Cacheable,
- OUT gctUINT32 * Address
+ OUT gctUINT32 * Address,
+ OUT gctUINT32 * Gid,
+ OUT gctUINT64 * PhysicalAddress
);
/* Unlock memory. */
gceSTATUS
gckVIDMEM_Unlock(
IN gckKERNEL Kernel,
- IN gcuVIDMEM_NODE_PTR Node,
+ IN gckVIDMEM_NODE Node,
IN gceSURF_TYPE Type,
IN OUT gctBOOL * Asynchroneous
);
gceSTATUS
gckVIDMEM_ConstructVirtual(
IN gckKERNEL Kernel,
- IN gctBOOL Contiguous,
+ IN gctUINT32 Flag,
IN gctSIZE_T Bytes,
OUT gcuVIDMEM_NODE_PTR * Node
);
gcvFLUSH_DEPTH = 0x02,
gcvFLUSH_TEXTURE = 0x04,
gcvFLUSH_2D = 0x08,
+#if gcdMULTI_GPU
+ gcvFLUSH_L2 = 0x10,
+#endif
+ gcvFLUSH_TILE_STATUS = 0x20,
gcvFLUSH_ALL = gcvFLUSH_COLOR
| gcvFLUSH_DEPTH
| gcvFLUSH_TEXTURE
- | gcvFLUSH_2D,
+ | gcvFLUSH_2D
+#if gcdMULTI_GPU
+ | gcvFLUSH_L2
+#endif
+ | gcvFLUSH_TILE_STATUS
}
gceKERNEL_FLUSH;
IN OUT struct _gcsHAL_INTERFACE * Interface
);
+/* Query Database requirements. */
+gceSTATUS
+ gckKERNEL_QueryDatabase(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN OUT gcsHAL_INTERFACE * Interface
+ );
+
/* Query the video memory. */
gceSTATUS
gckKERNEL_QueryVideoMemory(
OUT gckVIDMEM * VideoMemory
);
-#if gcdUSE_VIDMEM_PER_PID
gceSTATUS
-gckKERNEL_GetVideoMemoryPoolPid(
+gckKERNEL_AllocateLinearMemory(
IN gckKERNEL Kernel,
- IN gcePOOL Pool,
- IN gctUINT32 Pid,
- OUT gckVIDMEM * VideoMemory
+ IN gctUINT32 ProcessID,
+ IN OUT gcePOOL * Pool,
+ IN gctSIZE_T Bytes,
+ IN gctUINT32 Alignment,
+ IN gceSURF_TYPE Type,
+ IN gctUINT32 Flag,
+ OUT gctUINT32 * Node
);
gceSTATUS
-gckKERNEL_CreateVideoMemoryPoolPid(
+gckKERNEL_ReleaseVideoMemory(
IN gckKERNEL Kernel,
- IN gcePOOL Pool,
- IN gctUINT32 Pid,
- OUT gckVIDMEM * VideoMemory
+ IN gctUINT32 ProcessID,
+ IN gctUINT32 Handle
);
gceSTATUS
-gckKERNEL_RemoveVideoMemoryPoolPid(
+gckKERNEL_LockVideoMemory(
IN gckKERNEL Kernel,
- IN gckVIDMEM VideoMemory
+ IN gceCORE Core,
+ IN gctUINT32 ProcessID,
+ IN gctBOOL FromUser,
+ IN OUT gcsHAL_INTERFACE * Interface
+ );
+
+gceSTATUS
+gckKERNEL_UnlockVideoMemory(
+ IN gckKERNEL Kernel,
+ IN gctUINT32 ProcessID,
+ IN OUT gcsHAL_INTERFACE * Interface
);
-#endif
/* Map video memory. */
gceSTATUS
gceSTATUS
gckKERNEL_Notify(
IN gckKERNEL Kernel,
+#if gcdMULTI_GPU
+ IN gctUINT CoreId,
+#endif
IN gceNOTIFY Notifcation,
IN gctBOOL Data
);
gceSTATUS
gckHARDWARE_QueryCommandBuffer(
IN gckHARDWARE Hardware,
- OUT gctSIZE_T * Alignment,
- OUT gctSIZE_T * ReservedHead,
- OUT gctSIZE_T * ReservedTail
+ OUT gctUINT32 * Alignment,
+ OUT gctUINT32 * ReservedHead,
+ OUT gctUINT32 * ReservedTail
);
/* Add a WAIT/LINK pair in the command queue. */
IN gckHARDWARE Hardware,
IN gctPOINTER Logical,
IN gctUINT32 Offset,
- IN OUT gctSIZE_T * Bytes,
+ IN OUT gctUINT32 * Bytes,
OUT gctUINT32 * WaitOffset,
- OUT gctSIZE_T * WaitBytes
+ OUT gctUINT32 * WaitBytes
);
/* Kickstart the command processor. */
gceSTATUS
gckHARDWARE_Execute(
IN gckHARDWARE Hardware,
- IN gctPOINTER Logical,
-#ifdef __QNXNTO__
- IN gctPOINTER Physical,
- IN gctBOOL PhysicalAddresses,
-#endif
+ IN gctUINT32 Address,
IN gctSIZE_T Bytes
);
gckHARDWARE_End(
IN gckHARDWARE Hardware,
IN gctPOINTER Logical,
- IN OUT gctSIZE_T * Bytes
+ IN OUT gctUINT32 * Bytes
);
-/* Add a NOP command in the command queue. */
+#if gcdMULTI_GPU
gceSTATUS
-gckHARDWARE_Nop(
+gckHARDWARE_ChipEnable(
IN gckHARDWARE Hardware,
IN gctPOINTER Logical,
+ IN gceCORE_3D_MASK ChipEnable,
IN OUT gctSIZE_T * Bytes
);
+#endif
-/* Add a WAIT command in the command queue. */
+/* Add a NOP command in the command queue. */
gceSTATUS
-gckHARDWARE_Wait(
+gckHARDWARE_Nop(
IN gckHARDWARE Hardware,
IN gctPOINTER Logical,
- IN gctUINT32 Count,
IN OUT gctSIZE_T * Bytes
);
IN gckHARDWARE Hardware,
IN gctPOINTER Logical,
IN gcePIPE_SELECT Pipe,
- IN OUT gctSIZE_T * Bytes
+ IN OUT gctUINT32 * Bytes
);
/* Add a LINK command in the command queue. */
gckHARDWARE_Link(
IN gckHARDWARE Hardware,
IN gctPOINTER Logical,
- IN gctPOINTER FetchAddress,
- IN gctSIZE_T FetchSize,
- IN OUT gctSIZE_T * Bytes
+ IN gctUINT32 FetchAddress,
+ IN gctUINT32 FetchSize,
+ IN OUT gctUINT32 * Bytes
);
/* Add an EVENT command in the command queue. */
IN gctPOINTER Logical,
IN gctUINT8 Event,
IN gceKERNEL_WHERE FromWhere,
- IN OUT gctSIZE_T * Bytes
+ IN OUT gctUINT32 * Bytes
);
/* Query the available memory. */
OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
);
-/* Query the shader support. */
+/* Query the shader uniforms support. */
gceSTATUS
gckHARDWARE_QueryShaderCaps(
IN gckHARDWARE Hardware,
OUT gctUINT * VertexUniforms,
OUT gctUINT * FragmentUniforms,
- OUT gctUINT * Varyings
+ OUT gctBOOL * UnifiedUnforms
);
/* Split a harwdare specific address into API stuff. */
gckHARDWARE_ConvertLogical(
IN gckHARDWARE Hardware,
IN gctPOINTER Logical,
+ IN gctBOOL InUserSpace,
OUT gctUINT32 * Address
);
-#ifdef __QNXNTO__
-/* Convert physical address to hardware specific address. */
-gceSTATUS
-gckHARDWARE_ConvertPhysical(
- IN gckHARDWARE Hardware,
- IN gctPHYS_ADDR Physical,
- OUT gctUINT32 * Address
- );
-#endif
-
/* Interrupt manager. */
gceSTATUS
gckHARDWARE_Interrupt(
IN gckHARDWARE Hardware,
+#if gcdMULTI_GPU
+ IN gctUINT CoreId,
+#endif
IN gctBOOL InterruptValid
);
IN gctBOOL FromPower
);
+#if gcdPROCESS_ADDRESS_SPACE
+/* Configure mmu configuration. */
+gceSTATUS
+gckHARDWARE_ConfigMMU(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctPOINTER MtlbLogical,
+ IN gctUINT32 Offset,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctSIZE_T * WaitLinkOffset,
+ OUT gctSIZE_T * WaitLinkBytes
+ );
+#endif
+
/* Get idle register. */
gceSTATUS
gckHARDWARE_GetIdle(
IN gckHARDWARE Hardware,
IN gceKERNEL_FLUSH Flush,
IN gctPOINTER Logical,
- IN OUT gctSIZE_T * Bytes
+ IN OUT gctUINT32 * Bytes
);
/* Enable/disable fast clear. */
IN gctBOOL PowerManagement
);
+gceSTATUS
+gckHARDWARE_SetPowerManagementLock(
+ IN gckHARDWARE Hardware,
+ IN gctBOOL Lock
+ );
+
gceSTATUS
gckHARDWARE_SetGpuProfiler(
IN gckHARDWARE Hardware,
IN gctUINT * MinFscaleValue,
IN gctUINT * MaxFscaleValue
);
+
+gceSTATUS
+gckHARDWARE_SetMinFscaleValue(
+ IN gckHARDWARE Hardware,
+ IN gctUINT MinFscaleValue
+ );
#endif
#if gcdPOWEROFF_TIMEOUT
IN gctUINT32 Frequency
);
+gceSTATUS
+gckHARDWARE_PrepareFunctions(
+ gckHARDWARE Hardware
+ );
+
+gceSTATUS
+gckHARDWARE_SetMMUStates(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER MtlbAddress,
+ IN gceMMU_MODE Mode,
+ IN gctPOINTER SafeAddress,
+ IN gctPOINTER Logical,
+ IN OUT gctUINT32 * Bytes
+ );
+
#if !gcdENABLE_VG
/******************************************************************************\
***************************** gckINTERRUPT Object ******************************
);
/* Reserve the next available hardware event. */
+#if gcdMULTI_GPU
+gceSTATUS
+gckEVENT_GetEvent(
+ IN gckEVENT Event,
+ IN gctBOOL Wait,
+ OUT gctUINT8 * EventID,
+ IN gceKERNEL_WHERE Source,
+ IN gceCORE_3D_MASK ChipEnable
+ );
+#else
gceSTATUS
gckEVENT_GetEvent(
IN gckEVENT Event,
OUT gctUINT8 * EventID,
IN gceKERNEL_WHERE Source
);
+#endif
/* Add a new event to the list of events. */
gceSTATUS
gckEVENT_Unlock(
IN gckEVENT Event,
IN gceKERNEL_WHERE FromWhere,
- IN gcuVIDMEM_NODE_PTR Node,
+ IN gctPOINTER Node,
IN gceSURF_TYPE Type
);
IN gceKERNEL_WHERE FromWhere
);
-#if gcdVIRTUAL_COMMAND_BUFFER
/* Schedule a FreeVirtualCommandBuffer event. */
gceSTATUS
gckEVENT_DestroyVirtualCommandBuffer(
IN gctPOINTER Logical,
IN gceKERNEL_WHERE FromWhere
);
-#endif
+#if gcdMULTI_GPU
+gceSTATUS
+gckEVENT_Submit(
+ IN gckEVENT Event,
+ IN gctBOOL Wait,
+ IN gctBOOL FromPower,
+ IN gceCORE_3D_MASK ChipEnable
+ );
+#else
gceSTATUS
gckEVENT_Submit(
IN gckEVENT Event,
IN gctBOOL Wait,
IN gctBOOL FromPower
);
+#endif
-/* Commit an event queue. */
+#if gcdMULTI_GPU
+gceSTATUS
+gckEVENT_Commit(
+ IN gckEVENT Event,
+ IN gcsQUEUE_PTR Queue,
+ IN gceCORE_3D_MASK ChipEnable
+ );
+#else
gceSTATUS
gckEVENT_Commit(
IN gckEVENT Event,
IN gcsQUEUE_PTR Queue
);
+#endif
/* Schedule a composition event. */
gceSTATUS
gceSTATUS
gckEVENT_Interrupt(
IN gckEVENT Event,
+#if gcdMULTI_GPU
+ IN gctUINT CoreId,
+#endif
IN gctUINT32 IDs
);
IN gctBOOL FromRecovery
);
+#if gcdMULTI_GPU
/* Commit a buffer to the command queue. */
gceSTATUS
+gckCOMMAND_Commit(
+ IN gckCOMMAND Command,
+ IN gckCONTEXT Context,
+ IN gcoCMDBUF CommandBuffer,
+ IN gcsSTATE_DELTA_PTR StateDelta,
+ IN gcsQUEUE_PTR EventQueue,
+ IN gctUINT32 ProcessID,
+ IN gceCORE_3D_MASK ChipEnable
+ );
+#else
+gceSTATUS
gckCOMMAND_Commit(
IN gckCOMMAND Command,
IN gckCONTEXT Context,
IN gcsQUEUE_PTR EventQueue,
IN gctUINT32 ProcessID
);
+#endif
/* Reserve space in the command buffer. */
gceSTATUS
gckCOMMAND_Reserve(
IN gckCOMMAND Command,
- IN gctSIZE_T RequestedBytes,
+ IN gctUINT32 RequestedBytes,
OUT gctPOINTER * Buffer,
- OUT gctSIZE_T * BufferSize
+ OUT gctUINT32 * BufferSize
);
/* Execute reserved space in the command buffer. */
gceSTATUS
gckCOMMAND_Execute(
IN gckCOMMAND Command,
- IN gctSIZE_T RequstedBytes
+ IN gctUINT32 RequstedBytes
);
/* Stall the command queue. */
+#if gcdMULTI_GPU
+gceSTATUS
+gckCOMMAND_Stall(
+ IN gckCOMMAND Command,
+ IN gctBOOL FromPower,
+ IN gceCORE_3D_MASK ChipEnable
+ );
+#else
gceSTATUS
gckCOMMAND_Stall(
IN gckCOMMAND Command,
IN gctBOOL FromPower
);
+#endif
/* Attach user process. */
gceSTATUS
IN gckCONTEXT Context
);
-#if gcdVIRTUAL_COMMAND_BUFFER
+/* Dump command buffer being executed by GPU. */
gceSTATUS
gckCOMMAND_DumpExecutingBuffer(
IN gckCOMMAND Command
);
-#endif
+
+/* Whether a kernel command buffer address. */
+gceSTATUS
+gckCOMMAND_AddressInKernelCommandBuffer(
+ IN gckCOMMAND Command,
+ IN gctUINT32 Address,
+ OUT gctBOOL *In
+ );
/******************************************************************************\
********************************* gckMMU Object ********************************
IN gckMMU Mmu
);
-/* Enable the MMU. */
-gceSTATUS
-gckMMU_Enable(
- IN gckMMU Mmu,
- IN gctUINT32 PhysBaseAddr,
- IN gctUINT32 PhysSize
- );
-
/* Allocate pages inside the MMU. */
gceSTATUS
gckMMU_AllocatePages(
IN gctUINT32 *PageEntry
);
-#ifdef __QNXNTO__
-gceSTATUS
-gckMMU_InsertNode(
- IN gckMMU Mmu,
- IN gcuVIDMEM_NODE_PTR Node);
-
-gceSTATUS
-gckMMU_RemoveNode(
- IN gckMMU Mmu,
- IN gcuVIDMEM_NODE_PTR Node);
-#endif
-
-#ifdef __QNXNTO__
-gceSTATUS
-gckMMU_FreeHandleMemory(
- IN gckKERNEL Kernel,
- IN gckMMU Mmu,
- IN gctUINT32 Pid
- );
-#endif
-
gceSTATUS
gckMMU_Flush(
- IN gckMMU Mmu
+ IN gckMMU Mmu,
+ IN gceSURF_TYPE Type
);
gceSTATUS
gceSTATUS
gckHARDWARE_QueryProfileRegisters(
IN gckHARDWARE Hardware,
- IN gctBOOL Clear,
+ IN gctBOOL Reset,
OUT gcsPROFILER_COUNTERS * Counters
);
#endif
gceSTATUS
gckHARDWARE_QueryContextProfile(
IN gckHARDWARE Hardware,
- IN gctBOOL Clear,
+ IN gctBOOL Reset,
IN gckCONTEXT Context,
OUT gcsPROFILER_COUNTERS * Counters
);
);
#endif
+#if VIVANTE_PROFILER_NEW
+gceSTATUS
+gckHARDWARE_InitProfiler(
+ IN gckHARDWARE Hardware
+ );
+#endif
+
gceSTATUS
gckOS_SignalQueryHardware(
IN gckOS Os,
gckHARDWARE Hardware
);
+gceSTATUS
+gckOS_DetectProcessByName(
+ IN gctCONST_POINTER Name
+ );
+
+void
+gckOS_DumpParam(
+ void
+ );
+
#ifdef __cplusplus
}
#endif
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
*
*****************************************************************************/
-
#ifndef __gc_hal_base_h_
#define __gc_hal_base_h_
#include "gc_hal_enum.h"
#include "gc_hal_types.h"
-
#include "gc_hal_dump.h"
#ifdef __cplusplus
typedef struct _gcoHAL * gcoHAL;
typedef struct _gcoOS * gcoOS;
typedef struct _gco2D * gco2D;
+typedef struct gcsATOM * gcsATOM_PTR;
-#ifndef VIVANTE_NO_3D
+#if gcdENABLE_3D
typedef struct _gco3D * gco3D;
+typedef struct _gcoCL * gcoCL;
+typedef struct _gcsFAST_FLUSH * gcsFAST_FLUSH_PTR;
#endif
typedef struct _gcoSURF * gcoSURF;
typedef struct _gcoDUMP * gcoDUMP;
typedef struct _gcoHARDWARE * gcoHARDWARE;
typedef union _gcuVIDMEM_NODE * gcuVIDMEM_NODE_PTR;
-
-typedef struct gcsATOM * gcsATOM_PTR;
+typedef struct _gcsVIDMEM_NODE * gckVIDMEM_NODE;
#if gcdENABLE_VG
typedef struct _gcoVG * gcoVG;
-typedef struct _gcsCOMPLETION_SIGNAL * gcsCOMPLETION_SIGNAL_PTR;
-typedef struct _gcsCONTEXT_MAP * gcsCONTEXT_MAP_PTR;
+typedef struct _gcsCOMPLETION_SIGNAL * gcsCOMPLETION_SIGNAL_PTR;
+typedef struct _gcsCONTEXT_MAP * gcsCONTEXT_MAP_PTR;
#else
typedef void * gcoVG;
#endif
#if gcdSYNC
typedef struct _gcoFENCE * gcoFENCE;
-typedef struct _gcsSYNC_CONTEXT * gcsSYNC_CONTEXT_PTR;
+typedef struct _gcsSYNC_CONTEXT * gcsSYNC_CONTEXT_PTR;
#endif
+#if defined(ANDROID)
typedef struct _gcoOS_SymbolsList gcoOS_SymbolsList;
+#endif
/******************************************************************************\
******************************* Process local storage *************************
\******************************************************************************/
+
typedef struct _gcsPLS * gcsPLS_PTR;
+#if gcdENABLE_3D
+/******************************************************************************
+**
+** Patch defines which should be moved to dedicate file later
+**
+** !!! ALWAYS ADD new ID in the TAIL, otherwise will break exising TRACE FILE
+*******************************************************************************/
+typedef enum _gcePATCH_ID
+{
+ gcvPATCH_NOTINIT = -1,
+ gcvPATCH_INVALID = 0,
+
+#if gcdDEBUG_OPTION
+ gcvPATCH_DEBUG,
+#endif
+
+ gcvPATCH_GTFES30,
+ gcvPATCH_CTGL11,
+ gcvPATCH_CTGL20,
+ gcvPATCH_GLBM11,
+ gcvPATCH_GLBM21,
+ gcvPATCH_GLBM25,
+ gcvPATCH_GLBM27,
+ gcvPATCH_GLBMGUI,
+ gcvPATCH_GFXBENCH,
+ gcvPATCH_ANTUTU, /* Antutu 3.x */
+ gcvPATCH_ANTUTU4X, /* Antutu 4.x */
+ gcvPATCH_QUADRANT,
+ gcvPATCH_GPUBENCH,
+ gcvPATCH_DUOKAN,
+ gcvPATCH_GLOFTSXHM,
+ gcvPATCH_XRUNNER,
+ gcvPATCH_BUSPARKING3D,
+ gcvPATCH_SIEGECRAFT,
+ gcvPATCH_PREMIUM,
+ gcvPATCH_RACEILLEGAL,
+ gcvPATCH_MEGARUN,
+ gcvPATCH_BMGUI,
+ gcvPATCH_NENAMARK,
+ gcvPATCH_NENAMARK2,
+ gcvPATCH_FISHNOODLE,
+ gcvPATCH_MM06,
+ gcvPATCH_MM07,
+ gcvPATCH_BM21,
+ gcvPATCH_SMARTBENCH,
+ gcvPATCH_JPCT,
+ gcvPATCH_NEOCORE,
+ gcvPATCH_RTESTVA,
+ gcvPATCH_NBA2013,
+ gcvPATCH_BARDTALE,
+ gcvPATCH_F18,
+ gcvPATCH_CARPARK,
+ gcvPATCH_CARCHALLENGE,
+ gcvPATCH_HEROESCALL,
+ gcvPATCH_GLOFTF3HM,
+ gcvPATCH_CRAZYRACING,
+ gcvPATCH_FIREFOX,
+ gcvPATCH_CHROME,
+ gcvPATCH_MONOPOLY,
+ gcvPATCH_SNOWCOLD,
+ gcvPATCH_BM3,
+ gcvPATCH_BASEMARKX,
+ gcvPATCH_DEQP,
+ gcvPATCH_SF4,
+ gcePATCH_MGOHEAVEN2,
+ gcePATCH_SILIBILI,
+ gcePATCH_ELEMENTSDEF,
+ gcePATCH_GLOFTKRHM,
+ gcvPATCH_OCLCTS,
+ gcvPATCH_A8HP,
+ gcvPATCH_A8CN,
+ gcvPATCH_WISTONESG,
+ gcvPATCH_SPEEDRACE,
+ gcvPATCH_FSBHAWAIIF,
+ gcvPATCH_AIRNAVY,
+ gcvPATCH_F18NEW,
+ gcvPATCH_CKZOMBIES2,
+ gcvPATCH_EADGKEEPER,
+ gcvPATCH_BASEMARK2V2,
+ gcvPATCH_RIPTIDEGP2,
+ gcvPATCH_OESCTS,
+ gcvPATCH_GANGSTAR,
+ gcvPATCH_WHRKYZIXOVAN,
+ gcvPATCH_NAMESGAS,
+ gcvPATCH_AFTERBURNER,
+ gcvPATCH_UIMARK,
+ gcvPATCH_FM_OES_PLAYER,
+ gcvPATCH_SUMSUNG_BENCH,
+ gcvPATCH_ROCKSTAR_MAXPAYNE,
+ gcvPATCH_TITANPACKING,
+ gcvPATCH_BASEMARKOSIICN,
+ gcvPATCH_FRUITNINJA,
+#if defined(ANDROID)
+ gcePATCH_ANDROID_CTS_MEDIA_PRESENTATIONTIME,
+#endif
+ gcvPATCH_ANDROID_COMPOSITOR,
+ gcvPATCH_CTS_TEXTUREVIEW,
+ gcvPATCH_WATER2_CHUKONG,
+
+ gcvPATCH_COUNT
+} gcePATCH_ID;
+#endif /* gcdENABLE_3D */
+
typedef void (* gctPLS_DESTRUCTOR) (
gcsPLS_PTR
);
gctPOINTER eglSurfaceInfo;
gceSURF_FORMAT eglConfigFormat;
+ /* PLS reference count */
+ gcsATOM_PTR reference;
+
/* PorcessID of the constrcutor process */
gctUINT32 processID;
-#if gcdFORCE_GAL_LOAD_TWICE
+
/* ThreadID of the constrcutor process. */
gctSIZE_T threadID;
/* Flag for calling module destructor. */
gctBOOL exiting;
-#endif
- /* Reference count for destructor. */
- gcsATOM_PTR reference;
- gctBOOL bKFS;
-#if gcdUSE_NPOT_PATCH
gctBOOL bNeedSupportNP2Texture;
-#endif
- /* Destructor for eglDisplayInfo. */
gctPLS_DESTRUCTOR destructor;
+ /* Mutex to guard PLS access. currently it's for EGL.
+ ** We can use this mutex for every PLS access.
+ */
+ gctPOINTER accessLock;
+#if gcdENABLE_3D
+ /* Global patchID to overwrite the detection */
+ gcePATCH_ID patchID;
+#endif
}
gcsPLS;
extern gcsPLS gcPLS;
+#if gcdENABLE_3D
+#define gcPLS_INITIALIZER \
+{ \
+ gcvNULL, /* gcoOS object. */ \
+ gcvNULL, /* gcoHAL object. */ \
+ 0, /* internalSize */ \
+ gcvNULL, /* internalPhysical */ \
+ gcvNULL, /* internalLogical */ \
+ 0, /* externalSize */ \
+ gcvNULL, /* externalPhysical */ \
+ gcvNULL, /* externalLogical */ \
+ 0, /* contiguousSize */ \
+ gcvNULL, /* contiguousPhysical */ \
+ gcvNULL, /* contiguousLogical */ \
+ gcvNULL, /* eglDisplayInfo */ \
+ gcvNULL, /* eglSurfaceInfo */ \
+ gcvSURF_A8R8G8B8,/* eglConfigFormat */ \
+ gcvNULL, /* reference */ \
+ 0, /* processID */ \
+ 0, /* threadID */ \
+ gcvFALSE, /* exiting */ \
+ gcvFALSE, /* Special flag for NP2 texture. */ \
+ gcvNULL, /* destructor */ \
+ gcvNULL, /* accessLock */ \
+ gcvPATCH_NOTINIT,/* global patchID */ \
+}
+#else
+#define gcPLS_INITIALIZER \
+{ \
+ gcvNULL, /* gcoOS object. */ \
+ gcvNULL, /* gcoHAL object. */ \
+ 0, /* internalSize */ \
+ gcvNULL, /* internalPhysical */ \
+ gcvNULL, /* internalLogical */ \
+ 0, /* externalSize */ \
+ gcvNULL, /* externalPhysical */ \
+ gcvNULL, /* externalLogical */ \
+ 0, /* contiguousSize */ \
+ gcvNULL, /* contiguousPhysical */ \
+ gcvNULL, /* contiguousLogical */ \
+ gcvNULL, /* eglDisplayInfo */ \
+ gcvNULL, /* eglSurfaceInfo */ \
+ gcvSURF_A8R8G8B8,/* eglConfigFormat */ \
+ gcvNULL, /* reference */ \
+ 0, /* processID */ \
+ 0, /* threadID */ \
+ gcvFALSE, /* exiting */ \
+ gcvFALSE, /* Special flag for NP2 texture. */ \
+ gcvNULL, /* destructor */ \
+ gcvNULL, /* accessLock */ \
+}
+#endif
+
/******************************************************************************\
******************************* Thread local storage *************************
\******************************************************************************/
typedef struct _gcsTLS
{
gceHARDWARE_TYPE currentType;
- gcoHARDWARE hardware;
+
+ /* Current 3D hardwre of this thread */
+ gcoHARDWARE currentHardware;
+
+ /* Default 3D hardware of this thread */
+ gcoHARDWARE defaultHardware;
+
/* Only for separated 3D and 2D */
gcoHARDWARE hardware2D;
#if gcdENABLE_VG
gcoVGHARDWARE vg;
gcoVG engineVG;
#endif /* gcdENABLE_VG */
+#if gcdENABLE_3D
+ gco3D engine3D;
+#endif
+#if gcdENABLE_2D
+ gco2D engine2D;
+#endif
+
+ /*thread data */
gctPOINTER context;
+ /* ES(including es1 and es2) client driver context which is current state */
+ gctPOINTER esClientCtx;
gctTLS_DESTRUCTOR destructor;
- gctBOOL ProcessExiting;
-#ifndef VIVANTE_NO_3D
- gco3D engine3D;
-#endif
-#if gcdSYNC
- gctBOOL fenceEnable;
-#endif
- gco2D engine2D;
gctBOOL copied;
-#if gcdFORCE_GAL_LOAD_TWICE
/* libGAL.so handle */
gctHANDLE handle;
-#endif
+
+ /* If true, do not releas 2d engine and hardware in hal layer */
+ gctBOOL release2DUpper;
}
gcsTLS;
gcvPOOL_VIRTUAL,
gcvPOOL_USER,
gcvPOOL_CONTIGUOUS,
- gcvPOOL_DEFAULT_FORCE_CONTIGUOUS,
- gcvPOOL_DEFAULT_FORCE_CONTIGUOUS_CACHEABLE,
gcvPOOL_NUMBER_OF_POOLS
}
gcePOOL;
-#ifndef VIVANTE_NO_3D
+#if gcdENABLE_3D
/* Blending functions. */
typedef enum _gceBLEND_FUNCTION
{
}
gceBLEND_MODE;
-/* API flags. */
-typedef enum _gceAPI
-{
- gcvAPI_D3D = 0x1,
- gcvAPI_OPENGL = 0x2,
- gcvAPI_OPENVG = 0x3,
- gcvAPI_OPENCL = 0x4,
-}
-gceAPI;
-
/* Depth modes. */
typedef enum _gceDEPTH_MODE
{
gcvDEPTH_W,
}
gceDEPTH_MODE;
-#endif /* VIVANTE_NO_3D */
+#endif /* gcdENABLE_3D */
+
+#if (gcdENABLE_3D || gcdENABLE_VG)
+/* API flags. */
+typedef enum _gceAPI
+{
+ gcvAPI_D3D = 1,
+ gcvAPI_OPENGL_ES11,
+ gcvAPI_OPENGL_ES20,
+ gcvAPI_OPENGL_ES30,
+ gcvAPI_OPENGL,
+ gcvAPI_OPENVG,
+ gcvAPI_OPENCL,
+}
+gceAPI;
+#endif
+
typedef enum _gceWHERE
{
}
gceSignalHandlerType;
-
-#if gcdENABLE_VG
/* gcsHAL_Limits*/
typedef struct _gcsHAL_LIMITS
{
gctUINT32 *chipFeatures;
/* target caps */
- gctUINT32 maxWidth;
- gctUINT32 maxHeight;
- gctUINT32 multiTargetCount;
- gctUINT32 maxSamples;
+ gctUINT32 maxWidth;
+ gctUINT32 maxHeight;
+ gctUINT32 multiTargetCount;
+ gctUINT32 maxSamples;
}gcsHAL_LIMITS;
-#endif
/******************************************************************************\
*********** Generic Memory Allocation Optimization Using Containers ************
/* Construct a new gcoHAL object. */
gceSTATUS
-gcoHAL_Construct(
+gcoHAL_ConstructEx(
IN gctPOINTER Context,
IN gcoOS Os,
OUT gcoHAL * Hal
/* Destroy an gcoHAL object. */
gceSTATUS
+gcoHAL_DestroyEx(
+ IN gcoHAL Hal
+ );
+
+/* Empty function for compatibility. */
+gceSTATUS
+gcoHAL_Construct(
+ IN gctPOINTER Context,
+ IN gcoOS Os,
+ OUT gcoHAL * Hal
+ );
+
+/* Empty function for compatibility. */
+gceSTATUS
gcoHAL_Destroy(
IN gcoHAL Hal
);
+/* Get HAL options */
+gceSTATUS
+gcoHAL_GetOption(
+ IN gcoHAL Hal,
+ IN gceOPTION Option
+ );
+
+gceSTATUS
+gcoHAL_FrameInfoOps(
+ IN gcoHAL Hal,
+ IN gceFRAMEINFO FrameInfo,
+ IN gceFRAMEINFO_OP Op,
+ IN OUT gctUINT * Val
+ );
+
+
+gceSTATUS
+gcoHAL_GetHardware(
+ IN gcoHAL Hal,
+ OUT gcoHARDWARE* Hw
+ );
+
+#if gcdENABLE_2D
/* Get pointer to gco2D object. */
gceSTATUS
gcoHAL_Get2DEngine(
IN gcoHAL Hal,
OUT gco2D * Engine
);
+#endif
+
+#if gcdENABLE_3D
+gceSTATUS
+gcoHAL_GetSpecialHintData(
+ IN gcoHAL Hal,
+ OUT gctINT * Hint
+ );
+/*
+** Deprecated(Don't use it), keep it here for external library(libgcu.so)
+*/
+gceSTATUS
+gcoHAL_Get3DEngine(
+ IN gcoHAL Hal,
+ OUT gco3D * Engine
+ );
+#endif /* gcdEANBLE_3D */
+
+
+gceSTATUS
+gcoHAL_GetProductName(
+ IN gcoHAL Hal,
+ OUT gctSTRING *ProductName
+ );
gceSTATUS
gcoHAL_SetFscaleValue(
gctBOOL enable
);
-#ifndef VIVANTE_NO_3D
-/* Get pointer to gco3D object. */
gceSTATUS
-gcoHAL_Get3DEngine(
- IN gcoHAL Hal,
- OUT gco3D * Engine
+gcoHAL_NameVideoMemory(
+ IN gctUINT32 Handle,
+ OUT gctUINT32 * Name
);
gceSTATUS
-gcoHAL_Query3DEngine(
- IN gcoHAL Hal,
- OUT gco3D * Engine
+gcoHAL_ImportVideoMemory(
+ IN gctUINT32 Name,
+ OUT gctUINT32 * Handle
);
gceSTATUS
-gcoHAL_Set3DEngine(
- IN gcoHAL Hal,
- IN gco3D Engine
+gcoHAL_GetVideoMemoryFd(
+ IN gctUINT32 Handle,
+ OUT gctINT * Fd
);
+/* Verify whether the specified feature is available in hardware. */
gceSTATUS
-gcoHAL_Get3DHardware(
+gcoHAL_IsFeatureAvailable(
IN gcoHAL Hal,
- OUT gcoHARDWARE * Hardware
+ IN gceFEATURE Feature
);
gceSTATUS
-gcoHAL_Set3DHardware(
+gcoHAL_IsSwwaNeeded(
IN gcoHAL Hal,
- IN gcoHARDWARE Hardware
+ IN gceSWWA Swwa
);
-
-#endif /* VIVANTE_NO_3D */
-
-/* Verify whether the specified feature is available in hardware. */
gceSTATUS
-gcoHAL_IsFeatureAvailable(
+gcoHAL_IsFeatureAvailable1(
IN gcoHAL Hal,
IN gceFEATURE Feature
);
OUT gctUINT32* ChipMinorFeatures
);
+gctINT32
+gcoOS_EndRecordAllocation(void);
+void
+gcoOS_RecordAllocation(void);
+void
+gcoOS_AddRecordAllocation(gctSIZE_T Size);
+
/* Query the amount of video memory. */
gceSTATUS
gcoHAL_QueryVideoMemory(
IN gctPOINTER Logical
);
+/* Allocate video memory. */
+gceSTATUS
+gcoOS_AllocateVideoMemory(
+ IN gcoOS Os,
+ IN gctBOOL InUserSpace,
+ IN gctBOOL InCacheable,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctUINT32 * Physical,
+ OUT gctPOINTER * Logical,
+ OUT gctPOINTER * Handle
+ );
+
+/* Free video memory. */
+gceSTATUS
+gcoOS_FreeVideoMemory(
+ IN gcoOS Os,
+ IN gctPOINTER Handle
+ );
+
+/* Lock video memory. */
+gceSTATUS
+gcoOS_LockVideoMemory(
+ IN gcoOS Os,
+ IN gctPOINTER Handle,
+ IN gctBOOL InUserSpace,
+ IN gctBOOL InCacheable,
+ OUT gctUINT32 * Physical,
+ OUT gctPOINTER * Logical
+ );
+
/* Map user memory. */
gceSTATUS
gcoHAL_MapUserMemory(
IN gctBOOL Stall
);
+#if gcdENABLE_3D
+/* Sencd fence command. */
+gceSTATUS
+gcoHAL_SendFence(
+ IN gcoHAL Hal
+ );
+#endif /* gcdENABLE_3D */
+
/* Query the tile capabilities. */
gceSTATUS
gcoHAL_QueryTiled(
OUT gcoDUMP * Dump
);
-/* Call the kernel HAL layer. */
+#if gcdENABLE_3D
gceSTATUS
-gcoHAL_Call(
- IN gcoHAL Hal,
- IN OUT gcsHAL_INTERFACE_PTR Interface
+gcoHAL_SetPatchID(
+ IN gcoHAL Hal,
+ IN gcePATCH_ID PatchID
);
+/* Get Patch ID based on process name */
gceSTATUS
gcoHAL_GetPatchID(
IN gcoHAL Hal,
OUT gcePATCH_ID * PatchID
);
+gceSTATUS
+gcoHAL_SetGlobalPatchID(
+ IN gcoHAL Hal,
+ IN gcePATCH_ID PatchID
+ );
+#endif /* gcdENABLE_3D */
+/* Call the kernel HAL layer. */
+gceSTATUS
+gcoHAL_Call(
+ IN gcoHAL Hal,
+ IN OUT gcsHAL_INTERFACE_PTR Interface
+ );
+
/* Schedule an event. */
gceSTATUS
gcoHAL_ScheduleEvent(
);
gceSTATUS
-gcoHAL_QuerySeparated3D2D(
- IN gcoHAL Hal
+gcoHAL_Query3DCoreCount(
+ IN gcoHAL Hal,
+ OUT gctUINT32 *Count
);
gceSTATUS
-gcoHAL_QuerySpecialHint(
- IN gceSPECIAL_HINT Hint
+gcoHAL_QuerySeparated2D(
+ IN gcoHAL Hal
);
gceSTATUS
-gcoHAL_SetSpecialHintData(
- IN gcoHARDWARE Hardware
+gcoHAL_Is3DAvailable(
+ IN gcoHAL Hal
);
/* Get pointer to gcoVG object. */
OUT gcoVG * Engine
);
-#if gcdENABLE_VG
gceSTATUS
gcoHAL_QueryChipLimits(
IN gcoHAL Hal,
IN gctINT32 Chip,
+ IN gctINT32 Mask,
OUT gcsHAL_LIMITS *Limits);
gceSTATUS
gcoHAL_QueryChipFeature(
IN gcoHAL Hal,
IN gctINT32 Chip,
+ IN gctINT32 Mask,
IN gceFEATURE Feature);
+/*----------------------------------------------------------------------------*/
+/*----- Shared Buffer --------------------------------------------------------*/
+
+/* Create shared buffer. */
+gceSTATUS
+gcoHAL_CreateShBuffer(
+ IN gctUINT32 Size,
+ OUT gctSHBUF * ShBuf
+ );
+
+/* Destroy shared buffer. */
+gceSTATUS
+gcoHAL_DestroyShBuffer(
+ IN gctSHBUF ShBuf
+ );
+
+/* Map shared buffer to current process. */
+gceSTATUS
+gcoHAL_MapShBuffer(
+ IN gctSHBUF ShBuf
+ );
+
+/* Write user data to shared buffer. */
+gceSTATUS
+gcoHAL_WriteShBuffer(
+ IN gctSHBUF ShBuf,
+ IN gctCONST_POINTER Data,
+ IN gctUINT32 ByteCount
+ );
+
+/* Read user data from shared buffer. */
+gceSTATUS
+gcoHAL_ReadShBuffer(
+ IN gctSHBUF ShBuf,
+ IN gctPOINTER Data,
+ IN gctUINT32 BytesCount,
+ OUT gctUINT32 * BytesRead
+ );
+
+/* Config power management to be enabled or disabled. */
+gceSTATUS
+gcoHAL_ConfigPowerManagement(
+ IN gctBOOL Enable
+ );
+
+#if gcdENABLE_3D || gcdENABLE_VG
+/* Query the target capabilities. */
+gceSTATUS
+gcoHAL_QueryTargetCaps(
+ IN gcoHAL Hal,
+ OUT gctUINT * MaxWidth,
+ OUT gctUINT * MaxHeight,
+ OUT gctUINT * MultiTargetCount,
+ OUT gctUINT * MaxSamples
+ );
#endif
+
/******************************************************************************\
********************************** gcoOS Object *********************************
\******************************************************************************/
+/* Lock PLS access */
+gceSTATUS
+gcoOS_LockPLS(
+ void
+ );
+
+/* Unlock PLS access */
+gceSTATUS
+gcoOS_UnLockPLS(
+ void
+ );
/* Get PLS value for given key */
gctPOINTER
/* Destroy the objects associated with the current thread. */
void
gcoOS_FreeThreadData(
- IN gctBOOL ProcessExiting
+ void
);
-/* Construct a new gcoOS object. */
+/* Empty function for compatibility. */
gceSTATUS
gcoOS_Construct(
IN gctPOINTER Context,
OUT gcoOS * Os
);
-/* Destroy an gcoOS object. */
+/* Empty function for compatibility. */
gceSTATUS
gcoOS_Destroy(
IN gcoOS Os
IN gctPOINTER Memory
);
+/* Allocate memory. */
+gceSTATUS
+gcoOS_AllocateSharedMemory(
+ IN gcoOS Os,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Memory
+ );
+
+/* Free memory. */
+gceSTATUS
+gcoOS_FreeSharedMemory(
+ IN gcoOS Os,
+ IN gctPOINTER Memory
+ );
+
/* Allocate memory. */
gceSTATUS
gcoOS_AllocateMemory(
IN gctSIZE_T Bytes
);
-/* Allocate video memory. */
-gceSTATUS
-gcoOS_AllocateVideoMemory(
- IN gcoOS Os,
- IN gctBOOL InUserSpace,
- IN gctBOOL InCacheable,
- IN OUT gctSIZE_T * Bytes,
- OUT gctUINT32 * Physical,
- OUT gctPOINTER * Logical,
- OUT gctPOINTER * Handle
- );
-
-/* Free video memory. */
-gceSTATUS
-gcoOS_FreeVideoMemory(
- IN gcoOS Os,
- IN gctPOINTER Handle
- );
-
-gceSTATUS
-gcoSURF_GetBankOffsetBytes(
- IN gcoSURF Surfce,
- IN gceSURF_TYPE Type,
- IN gctUINT32 Stride,
- IN gctUINT32_PTR Bytes
- );
-
/* Map user memory. */
gceSTATUS
gcoOS_MapUserMemory(
);
#define gcmOS_SAFE_FREE(os, mem) \
- gcoOS_Free(os, mem); \
- mem = gcvNULL
+ gcoOS_Free(os, mem); \
+ mem = gcvNULL
+
+#define gcmOS_SAFE_FREE_SHARED_MEMORY(os, mem) \
+ gcoOS_FreeSharedMemory(os, mem); \
+ mem = gcvNULL
#define gcmkOS_SAFE_FREE(os, mem) \
gckOS_Free(os, mem); \
- mem = gcvNULL
+ mem = gcvNULL
typedef enum _gceFILE_MODE
{
gceSTATUS
gcoOS_GetCwd(
IN gcoOS Os,
- IN gctINT SizeInBytes,
+ IN gctINT SizeInBytes,
OUT gctSTRING Buffer
);
);
/* Convert hex string to integer. */
-gceSTATUS
-gcoOS_HexStrToInt(
- IN gctCONST_STRING String,
- OUT gctINT * Int
- );
+gceSTATUS gcoOS_HexStrToInt(
+ IN gctCONST_STRING String,
+ OUT gctINT * Int
+ );
/* Convert hex string to float. */
gceSTATUS
gcoOS_HexStrToFloat(
- IN gctCONST_STRING String,
- OUT gctFLOAT * Float
- );
+ IN gctCONST_STRING String,
+ OUT gctFLOAT * Float
+ );
/* Convert string to integer. */
gceSTATUS
);
#endif
-gctBOOL
-gcoOS_IsNeededSupportNP2Texture(
- IN gctCHAR* ProcName
- );
-
/* Query the video memory. */
gceSTATUS
gcoOS_QueryVideoMemory(
IN gcsATOM_PTR Atom
);
+/* Get the 32-bit value protected by an atom. */
+gceSTATUS
+gcoOS_AtomGet(
+ IN gcoOS Os,
+ IN gcsATOM_PTR Atom,
+ OUT gctINT32_PTR Value
+ );
+
+/* Set the 32-bit value protected by an atom. */
+gceSTATUS
+gcoOS_AtomSet(
+ IN gcoOS Os,
+ IN gcsATOM_PTR Atom,
+ IN gctINT32 Value
+ );
+
/* Increment an atom. */
gceSTATUS
gcoOS_AtomIncrement(
gceSTATUS
gcoOS_CacheClean(
IN gcoOS Os,
- IN gctUINT64 Node,
+ IN gctUINT32 Node,
IN gctPOINTER Logical,
IN gctSIZE_T Bytes
);
gceSTATUS
gcoOS_CacheFlush(
IN gcoOS Os,
- IN gctUINT64 Node,
+ IN gctUINT32 Node,
IN gctPOINTER Logical,
IN gctSIZE_T Bytes
);
gceSTATUS
gcoOS_CacheInvalidate(
IN gcoOS Os,
- IN gctUINT64 Node,
+ IN gctUINT32 Node,
IN gctPOINTER Logical,
IN gctSIZE_T Bytes
);
IN gctPOINTER Logical
);
+gceSTATUS
+gcoOS_CPUPhysicalToGPUPhysical(
+ IN gctUINT32 CPUPhysical,
+ OUT gctUINT32_PTR GPUPhysical
+ );
/*----------------------------------------------------------------------------*/
/*----- Profile --------------------------------------------------------------*/
# define gcmPROFILE_QUERY(start, ticks) do { } while (gcvFALSE)
# define gcmPROFILE_ONLY(x) do { } while (gcvFALSE)
# define gcmPROFILE_ELSE(x) x
-# define gcmPROFILE_DECLARE_ONLY(x) do { } while (gcvFALSE)
+# define gcmPROFILE_DECLARE_ONLY(x) do { } while (gcvFALSE)
# define gcmPROFILE_DECLARE_ELSE(x) x
#endif
IN gctUINT8 X
);
+gctUINT32
+gcoMATH_Float16ToFloat(
+ IN gctUINT16 In
+ );
+
+gctUINT16
+gcoMATH_FloatToFloat16(
+ IN gctUINT32 In
+ );
+
+gctUINT32
+gcoMATH_Float11ToFloat(
+ IN gctUINT32 In
+ );
+
+gctUINT16
+gcoMATH_FloatToFloat11(
+ IN gctUINT32 In
+ );
+
+gctUINT32
+gcoMATH_Float10ToFloat(
+ IN gctUINT32 In
+ );
+
+gctUINT16
+gcoMATH_FloatToFloat10(
+ IN gctUINT32 In
+ );
+
+gctUINT32
+gcoMATH_Float14ToFloat(
+ IN gctUINT16 In
+ );
+
/******************************************************************************\
**************************** Coordinate Structures *****************************
\******************************************************************************/
} gcsPIXEL;
-
/******************************************************************************\
********************************* gcoSURF Object ********************************
\******************************************************************************/
gcvFORMAT_CLASS_LUMINANCE,
gcvFORMAT_CLASS_BUMP,
gcvFORMAT_CLASS_DEPTH,
+ gcvFORMAT_CLASS_ASTC,
+ gcvFORMAT_CLASS_OTHER
}
gceFORMAT_CLASS;
+/* Color format data type */
+typedef enum _gceFORMAT_DATATYPE
+{
+ gcvFORMAT_DATATYPE_UNSIGNED_NORMALIZED,
+ gcvFORMAT_DATATYPE_SIGNED_NORMALIZED,
+ gcvFORMAT_DATATYPE_UNSIGNED_INTEGER,
+ gcvFORMAT_DATATYPE_SIGNED_INTEGER,
+ gcvFORMAT_DATATYPE_FLOAT16,
+ gcvFORMAT_DATATYPE_FLOAT32,
+ gcvFORMAT_DATATYPE_FLOAT_E5B9G9R9,
+ gcvFORMAT_DATATYPE_FLOAT_B10G11R11F,
+ gcvFORMAT_DATATYPE_INDEX,
+ gcvFORMAT_DATATYPE_SRGB,
+ gcvFORMAT_DATATYPE_FLOAT32_UINT,
+}
+gceFORMAT_DATATYPE;
+
/* Special enums for width field in gcsFORMAT_COMPONENT. */
typedef enum _gceCOMPONENT_CONTROL
{
}
gcsFORMAT_CLASS_TYPE_DEPTH;
+typedef union _gcuPIXEL_FORMAT_CLASS
+{
+ gcsFORMAT_CLASS_TYPE_BUMP bump;
+ gcsFORMAT_CLASS_TYPE_RGBA rgba;
+ gcsFORMAT_CLASS_TYPE_YUV yuv;
+ gcsFORMAT_CLASS_TYPE_LUMINANCE lum;
+ gcsFORMAT_CLASS_TYPE_INDEX index;
+ gcsFORMAT_CLASS_TYPE_DEPTH depth;
+}
+gcuPIXEL_FORMAT_CLASS;
+
/* Format parameters. */
typedef struct _gcsSURF_FORMAT_INFO
{
+ /* Name of the format */
+ gctCONST_STRING formatName;
+
/* Format code and class. */
gceSURF_FORMAT format;
gceFORMAT_CLASS fmtClass;
+ /* Format data type */
+ gceFORMAT_DATATYPE fmtDataType;
+
/* The size of one pixel in bits. */
gctUINT8 bitsPerPixel;
- /* Component swizzle. */
- gceSURF_SWIZZLE swizzle;
+ /* Pixel block dimensions. */
+ gctUINT blockWidth;
+ gctUINT blockHeight;
+
+ /* Pixel block size in bits. */
+ gctUINT blockSize;
+
+ /* Some formats are larger than what the GPU can support. */
+ /* These formats are read in the number of layers specified. */
+ gctUINT8 layers;
+
+ /* The format is faked and software will interpret it differently
+ ** with HW. Most of them can't be blendable(PE) or filterable(TX).
+ */
+ gctBOOL fakedFormat;
/* Some formats have two neighbour pixels interleaved together. */
/* To describe such format, set the flag to 1 and add another */
/* like this one describing the odd pixel format. */
- gctUINT8 interleaved;
+ gctBOOL interleaved;
+
+ /* sRGB format. */
+ gctBOOL sRGB;
/* Format components. */
- union
- {
- gcsFORMAT_CLASS_TYPE_BUMP bump;
- gcsFORMAT_CLASS_TYPE_RGBA rgba;
- gcsFORMAT_CLASS_TYPE_YUV yuv;
- gcsFORMAT_CLASS_TYPE_LUMINANCE lum;
- gcsFORMAT_CLASS_TYPE_INDEX index;
- gcsFORMAT_CLASS_TYPE_DEPTH depth;
- } u;
+ gcuPIXEL_FORMAT_CLASS u;
+
+ /* Format components. */
+ gcuPIXEL_FORMAT_CLASS uOdd;
+
+ /* Render format. */
+ gceSURF_FORMAT closestRenderFormat;
+ /*gctCLOSEST_FORMAT dynamicClosestRenderFormat;*/
+ gctUINT renderFormat;
+ const gceTEXTURE_SWIZZLE * pixelSwizzle;
+
+ /* Texture format. */
+ gceSURF_FORMAT closestTXFormat;
+ gctUINT txFormat;
+ const gceTEXTURE_SWIZZLE * txSwizzle;
+ gctBOOL txIntFilter;
}
gcsSURF_FORMAT_INFO;
}
gcsSURF_FRAMEBUFFER;
-typedef struct _gcsVIDMEM_NODE_SHARED_INFO
-{
- gctBOOL tileStatusDisabled;
- gcsPOINT SrcOrigin;
- gcsPOINT DestOrigin;
- gcsSIZE RectSize;
- gctUINT32 clearValue;
-}
-gcsVIDMEM_NODE_SHARED_INFO;
-
/* Generic pixel component descriptors. */
extern gcsFORMAT_COMPONENT gcvPIXEL_COMP_XXX8;
extern gcsFORMAT_COMPONENT gcvPIXEL_COMP_XX8X;
IN gctUINT32 Physical
);
+/* Wrapp surface with known logical/GPU address */
+gceSTATUS
+gcoSURF_WrapSurface(
+ IN gcoSURF Surface,
+ IN gctUINT Alignment,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Physical
+ );
+
+
/* Query vid mem node info. */
gceSTATUS
gcoSURF_QueryVidMemNode(
IN gcoSURF Surface,
- OUT gctUINT64 * Node,
+ OUT gctUINT32 * Node,
OUT gcePOOL * Pool,
- OUT gctUINT_PTR Bytes
+ OUT gctSIZE_T_PTR Bytes
);
/* Set the color type of the surface. */
OUT gceSURF_COLOR_TYPE *ColorType
);
-/* Set the surface ration angle. */
+/* Set the color space of the surface. */
gceSTATUS
-gcoSURF_SetRotation(
+gcoSURF_SetColorSpace(
IN gcoSURF Surface,
- IN gceSURF_ROTATION Rotation
+ IN gceSURF_COLOR_SPACE ColorSpace
);
+/* Get the color space of the surface. */
gceSTATUS
-gcoSURF_SetPreRotation(
+gcoSURF_GetColorSpace(
IN gcoSURF Surface,
- IN gceSURF_ROTATION Rotation
+ OUT gceSURF_COLOR_SPACE *ColorSpace
);
+
+/* Set the surface ration angle. */
gceSTATUS
-gcoSURF_GetPreRotation(
+gcoSURF_SetRotation(
IN gcoSURF Surface,
- IN gceSURF_ROTATION *Rotation
+ IN gceSURF_ROTATION Rotation
);
gceSTATUS
IN gcoSURF Surface
);
-#ifndef VIVANTE_NO_3D
+#if gcdENABLE_3D
/* Verify and return the state of the tile status mechanism. */
gceSTATUS
gcoSURF_IsTileStatusSupported(
IN gcoSURF Surface
);
-/* Process tile status for the specified surface. */
+/* Verify if surface has tile status enabled. */
+gceSTATUS
+gcoSURF_IsTileStatusEnabled(
+ IN gcoSURF Surface
+ );
+
+/* Verify if surface is compressed. */
gceSTATUS
-gcoSURF_SetTileStatus(
+gcoSURF_IsCompressed(
IN gcoSURF Surface
);
-/* Enable tile status for the specified surface. */
+/* Enable tile status for the specified surface on zero slot. */
gceSTATUS
gcoSURF_EnableTileStatus(
IN gcoSURF Surface
);
+/* Enable tile status for the specified surface on specified slot. */
+gceSTATUS
+gcoSURF_EnableTileStatusEx(
+ IN gcoSURF Surface,
+ IN gctUINT RtIndex
+ );
+
/* Disable tile status for the specified surface. */
gceSTATUS
gcoSURF_DisableTileStatus(
IN gctBOOL Decompress
);
+/* Flush tile status cache for the specified surface. */
gceSTATUS
-gcoSURF_AlignResolveRect(
- IN gcoSURF Surf,
- IN gcsPOINT_PTR RectOrigin,
- IN gcsPOINT_PTR RectSize,
- OUT gcsPOINT_PTR AlignedOrigin,
- OUT gcsPOINT_PTR AlignedSize
+gcoSURF_FlushTileStatus(
+ IN gcoSURF Surface,
+ IN gctBOOL Decompress
);
-#endif /* VIVANTE_NO_3D */
+#endif /* gcdENABLE_3D */
/* Get surface size. */
gceSTATUS
OUT gctUINT * YAlignment
);
+gceSTATUS
+gcoSURF_AlignResolveRect(
+ IN gcoSURF Surf,
+ IN gcsPOINT_PTR RectOrigin,
+ IN gcsPOINT_PTR RectSize,
+ OUT gcsPOINT_PTR AlignedOrigin,
+ OUT gcsPOINT_PTR AlignedSize
+ );
+
/* Get surface type and format. */
gceSTATUS
gcoSURF_GetFormat(
IN gcoSURF Surface,
- OUT gceSURF_TYPE * Type,
+ OUT OPTIONAL gceSURF_TYPE * Type,
+ OUT OPTIONAL gceSURF_FORMAT * Format
+ );
+
+/* Get surface information */
+gceSTATUS
+gcoSURF_GetFormatInfo(
+ IN gcoSURF Surface,
+ OUT gcsSURF_FORMAT_INFO_PTR * formatInfo
+ );
+
+/* Get Surface pack format */
+gceSTATUS
+gcoSURF_GetPackedFormat(
+ IN gcoSURF Surface,
OUT gceSURF_FORMAT * Format
);
OUT gceTILING * Tiling
);
+/* Get flip bitmap offset bytes. */
+gceSTATUS
+gcoSURF_GetFlipBitmapOffset(
+ IN gcoSURF Surface,
+ OUT gctUINT_PTR FlipBitmapOffset
+ );
+
+/* Get bottom buffer offset bytes. */
+gceSTATUS
+gcoSURF_GetBottomBufferOffset(
+ IN gcoSURF Surface,
+ OUT gctUINT_PTR BottomBufferOffset
+ );
+
/* Lock the surface. */
gceSTATUS
gcoSURF_Lock(
IN gctPOINTER Memory
);
-/* Return pixel format parameters. */
+/*. Query surface flags.*/
+gceSTATUS
+gcoSURF_QueryFlags(
+ IN gcoSURF Surface,
+ IN gceSURF_FLAG Flag
+ );
+
+/* Return pixel format parameters; Info is required to be a pointer to an
+ * array of at least two items because some formats have up to two records
+ * of description. */
gceSTATUS
gcoSURF_QueryFormat(
IN gceSURF_FORMAT Format,
IN gcoSURF Surface
);
-/* Check if surface needs a filler. */
-gceSTATUS gcoSURF_NeedFiller(IN gcoSURF Surface);
-
/* Fill surface with a value. */
gceSTATUS
gcoSURF_Fill(
OUT gcoSURF * Surface
);
+/* Set surface flags.*/
+gceSTATUS
+gcoSURF_SetFlags(
+ IN gcoSURF Surface,
+ IN gceSURF_FLAG Flag,
+ IN gctBOOL Value
+ );
+
/* Set the underlying buffer for the surface wrapper. */
gceSTATUS
gcoSURF_SetBuffer(
gceSTATUS
gcoSURF_SetOffset(
IN gcoSURF Surface,
- IN gctUINT Offset
- );
-
-gceSTATUS
-gcoSURF_GetOffset(
- IN gcoSURF Surface,
- OUT gctUINT *Offset
+ IN gctSIZE_T Offset
);
gceSTATUS
IN gceCACHEOPERATION Operation
);
+/* Lock and unlock surface node */
+gceSTATUS
+gcoSURF_LockNode(
+ IN gcsSURF_NODE_PTR Node,
+ OUT gctUINT32 * Address,
+ OUT gctPOINTER * Memory
+ );
+
+gceSTATUS
+gcoSURF_UnLockNode(
+ IN gcsSURF_NODE_PTR Node,
+ IN gceSURF_TYPE Type
+ );
+
+/* Perform CPU cache operation on surface node */
+gceSTATUS
+gcoSURF_NODE_CPUCacheOperation(
+ IN gcsSURF_NODE_PTR Node,
+ IN gceSURF_TYPE Type,
+ IN gctSIZE_T Offset,
+ IN gctSIZE_T Length,
+ IN gceCACHEOPERATION Operation
+ );
+
/* Perform CPU cache operation on surface */
gceSTATUS
gcoSURF_CPUCacheOperation(
gceSTATUS
-gcoSURF_SetLinearResolveAddress(
+gcoSURF_Swap(
+ IN gcoSURF Surface1,
+ IN gcoSURF Surface2
+ );
+
+gceSTATUS
+gcoSURF_ResetSurWH(
IN gcoSURF Surface,
- IN gctUINT32 Address,
- IN gctPOINTER Memory
+ IN gctUINT oriw,
+ IN gctUINT orih,
+ IN gctUINT alignw,
+ IN gctUINT alignh,
+ IN gceSURF_FORMAT fmt
+);
+
+/* Update surface timestamp. */
+gceSTATUS
+gcoSURF_UpdateTimeStamp(
+ IN gcoSURF Surface
);
- gceSTATUS
- gcoSURF_Swap(IN gcoSURF Surface1, IN gcoSURF Surface2);
+/* Query surface current timestamp. */
+gceSTATUS
+gcoSURF_QueryTimeStamp(
+ IN gcoSURF Surface,
+ OUT gctUINT64 * TimeStamp
+ );
+
+/*
+ * Allocate shared buffer for this surface, so that
+ * surface states can be shared across processes.
+ */
+gceSTATUS
+gcoSURF_AllocShBuffer(
+ IN gcoSURF Surface,
+ OUT gctSHBUF * ShBuf
+ );
+
+/* Bind shared buffer to this surface */
+gceSTATUS
+gcoSURF_BindShBuffer(
+ IN gcoSURF Surface,
+ IN gctSHBUF ShBuf
+ );
+
+/* Push surface shared states to shared buffer. */
+gceSTATUS
+gcoSURF_PushSharedInfo(
+ IN gcoSURF Surface
+ );
+
+/* Pop shared states from shared buffer. */
+gceSTATUS
+gcoSURF_PopSharedInfo(
+ IN gcoSURF Surface
+ );
+
+#if (gcdENABLE_3D || gcdENABLE_VG)
+/* Copy surface. */
+gceSTATUS
+gcoSURF_Copy(
+ IN gcoSURF Surface,
+ IN gcoSURF Source
+ );
+
+/* Set number of samples for a gcoSURF object. */
+gceSTATUS
+gcoSURF_SetSamples(
+ IN gcoSURF Surface,
+ IN gctUINT Samples
+ );
+
+/* Get the number of samples per pixel. */
+gceSTATUS
+gcoSURF_GetSamples(
+ IN gcoSURF Surface,
+ OUT gctUINT_PTR Samples
+ );
+#endif
/******************************************************************************\
********************************* gcoDUMP Object ********************************
gctFILE
gcoOS_ReplaceDebugFile(
IN gctFILE fp
- );
+ );
+
+void
+gcoOS_SysTraceBegin(
+ IN gctCONST_STRING FuncName
+ );
+
+void
+gcoOS_SysTraceEnd(
+ IN void);
/*******************************************************************************
**
#if gcmIS_DEBUG(gcdDEBUG_FATAL)
# define gcmFATAL gcoOS_DebugFatal
# define gcmkFATAL gckOS_DebugFatal
-#elif gcdHAS_ELLIPSES
+#elif gcdHAS_ELLIPSIS
# define gcmFATAL(...)
# define gcmkFATAL(...)
#else
# define gcmTRACE gcoOS_DebugTrace
# define gcmkTRACE gckOS_DebugTrace
# define gcmkTRACE_N gckOS_DebugTraceN
-#elif gcdHAS_ELLIPSES
+#elif gcdHAS_ELLIPSIS
# define gcmTRACE(...)
# define gcmkTRACE(...)
# define gcmkTRACE_N(...)
#define gcvZONE_IMAGE (1 << 19)
#define gcvZONE_UTILITY (1 << 20)
#define gcvZONE_PARAMETERS (1 << 21)
+#define gcvZONE_BUFOBJ (1 << 22)
+#define gcvZONE_SHADER (1 << 23)
+#define gcvZONE_STREAM_OUT (1 << 24)
/* API definitions. */
#define gcvZONE_API_HAL (1 << 28)
#define gcvZONE_API_VG11 (5 << 28)
#define gcvZONE_API_GL (6 << 28)
#define gcvZONE_API_DFB (7 << 28)
-#define gcvZONE_API_GDI (8 << 28)
-#define gcvZONE_API_D3D (9 << 28)
-#define gcvZONE_API_ES30 (10 << 28)
+#define gcvZONE_API_GDI ((gctUINT32)8 << 28)
+#define gcvZONE_API_D3D ((gctUINT32)9 << 28)
+#define gcvZONE_API_ES30 ((gctUINT32)10 << 28)
#define gcmZONE_GET_API(zone) ((zone) >> 28)
# define gcmTRACE_ZONE gcoOS_DebugTraceZone
# define gcmkTRACE_ZONE gckOS_DebugTraceZone
# define gcmkTRACE_ZONE_N gckOS_DebugTraceZoneN
-#elif gcdHAS_ELLIPSES
+#elif gcdHAS_ELLIPSIS
# define gcmTRACE_ZONE(...)
# define gcmkTRACE_ZONE(...)
# define gcmkTRACE_ZONE_N(...)
** ... Optional arguments for text.
*/
#if gcmIS_DEBUG(gcdDEBUG_STACK)
- void
- gcoOS_StackPush(
- IN gctCONST_STRING Function,
- IN gctINT Line,
- IN gctCONST_STRING Text,
- ...
- );
- void
- gcoOS_StackPop(
- IN gctCONST_STRING Function
- );
- void
- gcoOS_StackDump(
- void
- );
+ void gcoOS_StackPush(IN gctINT8_PTR Identity, IN gctCONST_STRING Function, IN gctINT Line, IN gctCONST_STRING Text, ...);
+ void gcoOS_StackPop(IN gctINT8_PTR Identity, IN gctCONST_STRING Function);
+ void gcoOS_StackDump(void);
+ void gcoOS_StackRemove(IN gctHANDLE Thread);
+
# define gcmSTACK_PUSH gcoOS_StackPush
# define gcmSTACK_POP gcoOS_StackPop
# define gcmSTACK_DUMP gcoOS_StackDump
-#elif gcdHAS_ELLIPSES
+# define gcmSTACK_REMOVE gcoOS_StackRemove
+#elif gcdHAS_ELLIPSIS
# define gcmSTACK_PUSH(...) do { } while (0)
-# define gcmSTACK_POP(Function) do { } while (0)
+# define gcmSTACK_POP(...) do { } while (0)
# define gcmSTACK_DUMP() do { } while (0)
+# define gcmSTACK_REMOVE(...) do { } while (0)
#else
gcmINLINE static void
__dummy_stack_push(
{
}
# define gcmSTACK_PUSH __dummy_stack_push
-# define gcmSTACK_POP(Function) do { } while (0)
+# define gcmSTACK_POP(a,b) do { } while (0)
# define gcmSTACK_DUMP() do { } while (0)
+# define gcmSTACK_REMOVE(a) do { } while (0)
+#endif
+
+/******************************************************************************\
+******************************** Binary Trace **********************************
+\******************************************************************************/
+typedef struct _gcsBINARY_TRACE_MESSAGE * gcsBINARY_TRACE_MESSAGE_PTR;
+typedef struct _gcsBINARY_TRACE_MESSAGE
+{
+ gctUINT32 signature;
+ gctUINT32 pid;
+ gctUINT32 tid;
+ gctUINT32 line;
+ gctUINT32 numArguments;
+ gctUINT8 payload;
+}
+gcsBINARY_TRACE_MESSAGE;
+
+#define gcdBINARY_TRACE_MESSAGE_SIZE 240
+
+#if gcdBINARY_TRACE
+ void
+ gcoOS_BinaryTrace(
+ IN gctCONST_STRING Function,
+ IN gctINT Line,
+ IN gctCONST_STRING Text OPTIONAL,
+ ...
+ );
+
+ void
+ gckOS_BinaryTrace(
+ IN gctCONST_STRING Function,
+ IN gctINT Line,
+ IN gctCONST_STRING Text OPTIONAL,
+ ...
+ );
+
+# define gcmBINARY_TRACE gcoOS_BinaryTrace
+# define gcmkBINARY_TRACE gckOS_BinaryTrace
+#elif gcdHAS_ELLIPSIS
+# define gcmBINARY_TRACE(Function, Line, Text, ...)
+# define gcmkBINARY_TRACE(Function, Line, Text, ...)
+#else
+ gcmINLINE static void
+ __dummy_binary_trace(
+ IN gctCONST_STRING Function,
+ IN gctINT Line,
+ IN gctCONST_STRING Text,
+ )
+ {
+ }
+
+# define gcmBINARY_TRACE __dummy_binary_trace
+# define gcmkBINARY_TRACE __dummy_binary_trace
#endif
/******************************************************************************\
#define gcdHEADER_LEVEL gcvLEVEL_VERBOSE
+#ifndef gcdEMPTY_HEADER_FOOTER
+#define gcdEMPTY_HEADER_FOOTER 0
+#endif
#if gcdENABLE_PROFILING
void
);
#define gcmHEADER() \
+ gctINT8 __user__ = 1; \
static gctBOOL __profile__initialized__ = gcvFALSE; \
- gcmSTACK_PUSH(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
+ gcmSTACK_PUSH(&__user__, __FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
gcoOS_ProfileDB(__FUNCTION__, &__profile__initialized__)
#define gcmHEADER_ARG(...) \
+ gctINT8 __user__ = 1; \
static gctBOOL __profile__initialized__ = gcvFALSE; \
- gcmSTACK_PUSH(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \
+ gcmSTACK_PUSH(&__user__, __FUNCTION__, __LINE__, Text, __VA_ARGS__); \
gcoOS_ProfileDB(__FUNCTION__, &__profile__initialized__)
#define gcmFOOTER() \
- gcmSTACK_POP(__FUNCTION__); \
+ gcmSTACK_POP(&__user__, __FUNCTION__); \
gcoOS_ProfileDB(__FUNCTION__, gcvNULL)
#define gcmFOOTER_NO() \
- gcmSTACK_POP(__FUNCTION__); \
+ gcmSTACK_POP(&__user__, __FUNCTION__); \
gcoOS_ProfileDB(__FUNCTION__, gcvNULL)
#define gcmFOOTER_ARG(...) \
- gcmSTACK_POP(__FUNCTION__); \
+ gcmSTACK_POP(&__user__, __FUNCTION__); \
gcoOS_ProfileDB(__FUNCTION__, gcvNULL)
#define gcmFOOTER_KILL() \
- gcmSTACK_POP(__FUNCTION__); \
+ gcmSTACK_POP(&__user__, __FUNCTION__); \
gcoOS_ProfileDB(gcvNULL, gcvNULL)
#else /* gcdENABLE_PROFILING */
-#if gcdHAS_ELLIPSES
+#ifdef gcdFSL_REL_BUILD
+#define gcmHEADER()
+#elif gcdEMPTY_HEADER_FOOTER
+# define gcmHEADER()
+#elif gcdHAS_ELLIPSIS
#define gcmHEADER() \
gctINT8 __user__ = 1; \
gctINT8_PTR __user_ptr__ = &__user__; \
- gcmSTACK_PUSH(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
+ gcmSTACK_PUSH(__user_ptr__, __FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
+ gcmBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
"++%s(%d)", __FUNCTION__, __LINE__)
#else
# define gcmHEADER __dummy_header
#endif
-#if gcdHAS_ELLIPSES
+#ifdef gcdFSL_REL_BUILD
+#define gcmHEADER_ARG(Text, ...)
+#elif gcdHAS_ELLIPSIS
+#if gcdEMPTY_HEADER_FOOTER
+# define gcmHEADER_ARG(Text, ...)
+#else
# define gcmHEADER_ARG(Text, ...) \
gctINT8 __user__ = 1; \
gctINT8_PTR __user_ptr__ = &__user__; \
- gcmSTACK_PUSH(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \
+ gcmSTACK_PUSH(__user_ptr__, __FUNCTION__, __LINE__, Text, __VA_ARGS__); \
+ gcmBINARY_TRACE(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \
gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
"++%s(%d): " Text, __FUNCTION__, __LINE__, __VA_ARGS__)
+#endif
#else
gcmINLINE static void
__dummy_header_arg(
# define gcmHEADER_ARG __dummy_header_arg
#endif
-#if gcdHAS_ELLIPSES
+#ifdef gcdFSL_REL_BUILD
+# define gcmFOOTER()
+#elif gcdEMPTY_HEADER_FOOTER
+# define gcmFOOTER()
+#elif gcdHAS_ELLIPSIS
# define gcmFOOTER() \
- gcmSTACK_POP(__FUNCTION__); \
- gcmPROFILE_ONLY(gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
- "--%s(%d) [%llu,%llu]: status=%d(%s)", \
- __FUNCTION__, __LINE__, \
- __ticks__, __total__, \
- status, gcoOS_DebugStatus2Name(status))); \
- gcmPROFILE_ELSE(gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
- "--%s(%d): status=%d(%s)", \
- __FUNCTION__, __LINE__, \
- status, gcoOS_DebugStatus2Name(status))); \
+ gcmSTACK_POP(__user_ptr__, __FUNCTION__); \
+ gcmBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
+ gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
+ "--%s(%d): status=%d(%s)", \
+ __FUNCTION__, __LINE__, \
+ status, gcoOS_DebugStatus2Name(status)); \
*__user_ptr__ -= 1
#else
gcmINLINE static void
# define gcmFOOTER __dummy_footer
#endif
-#if gcdHAS_ELLIPSES
+#ifdef gcdFSL_REL_BUILD
+#define gcmFOOTER_NO()
+#elif gcdEMPTY_HEADER_FOOTER
+# define gcmFOOTER_NO()
+#elif gcdHAS_ELLIPSIS
#define gcmFOOTER_NO() \
- gcmSTACK_POP(__FUNCTION__); \
+ gcmSTACK_POP(__user_ptr__, __FUNCTION__); \
+ gcmBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
"--%s(%d)", __FUNCTION__, __LINE__); \
*__user_ptr__ -= 1
# define gcmFOOTER_NO __dummy_footer_no
#endif
-#if gcdHAS_ELLIPSES
+#ifdef gcdFSL_REL_BUILD
+#define gcmFOOTER_KILL()
+#elif gcdEMPTY_HEADER_FOOTER
+# define gcmFOOTER_KILL()
+#elif gcdHAS_ELLIPSIS
#define gcmFOOTER_KILL() \
- gcmSTACK_POP(__FUNCTION__); \
+ gcmSTACK_POP(__user_ptr__, __FUNCTION__); \
+ gcmBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
"--%s(%d)", __FUNCTION__, __LINE__); \
*__user_ptr__ -= 1
# define gcmFOOTER_KILL __dummy_footer_kill
#endif
-#if gcdHAS_ELLIPSES
+#ifdef gcdFSL_REL_BUILD
+# define gcmFOOTER_ARG(Text, ...)
+#elif gcdHAS_ELLIPSIS
+#if gcdEMPTY_HEADER_FOOTER
+# define gcmFOOTER_ARG(Text, ...)
+#else
# define gcmFOOTER_ARG(Text, ...) \
- gcmSTACK_POP(__FUNCTION__); \
+ gcmSTACK_POP(__user_ptr__, __FUNCTION__); \
+ gcmBINARY_TRACE(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \
gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
"--%s(%d): " Text, __FUNCTION__, __LINE__, __VA_ARGS__); \
*__user_ptr__ -= 1
+#endif
#else
gcmINLINE static void
__dummy_footer_arg(
#endif /* gcdENABLE_PROFILING */
-#if gcdHAS_ELLIPSES
+#ifdef gcdFSL_REL_BUILD
+#define gcmkHEADER()
+#elif gcdHAS_ELLIPSIS
#define gcmkHEADER() \
gctINT8 __kernel__ = 1; \
gctINT8_PTR __kernel_ptr__ = &__kernel__; \
+ gcmkBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
"++%s(%d)", __FUNCTION__, __LINE__)
#else
# define gcmkHEADER __dummy_kheader
#endif
-#if gcdHAS_ELLIPSES
+#ifdef gcdFSL_REL_BUILD
+# define gcmkHEADER_ARG(Text, ...)
+#elif gcdHAS_ELLIPSIS
# define gcmkHEADER_ARG(Text, ...) \
gctINT8 __kernel__ = 1; \
gctINT8_PTR __kernel_ptr__ = &__kernel__; \
+ gcmkBINARY_TRACE(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \
gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
"++%s(%d): " Text, __FUNCTION__, __LINE__, __VA_ARGS__)
#else
# define gcmkHEADER_ARG __dummy_kheader_arg
#endif
-#if gcdHAS_ELLIPSES
+#ifdef gcdFSL_REL_BUILD
+#define gcmkFOOTER()
+#elif gcdHAS_ELLIPSIS
#define gcmkFOOTER() \
+ gcmkBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, status); \
gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
"--%s(%d): status=%d(%s)", \
__FUNCTION__, __LINE__, status, gckOS_DebugStatus2Name(status)); \
# define gcmkFOOTER __dummy_kfooter
#endif
-#if gcdHAS_ELLIPSES
+#ifdef gcdFSL_REL_BUILD
+#define gcmkFOOTER_NO()
+#elif gcdHAS_ELLIPSIS
#define gcmkFOOTER_NO() \
+ gcmkBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
"--%s(%d)", __FUNCTION__, __LINE__); \
*__kernel_ptr__ -= 1
# define gcmkFOOTER_NO __dummy_kfooter_no
#endif
-#if gcdHAS_ELLIPSES
+#ifdef gcdFSL_REL_BUILD
+# define gcmkFOOTER_ARG(Text, ...)
+#elif gcdHAS_ELLIPSIS
# define gcmkFOOTER_ARG(Text, ...) \
+ gcmkBINARY_TRACE(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \
gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
"--%s(%d): " Text, \
__FUNCTION__, __LINE__, __VA_ARGS__); \
void
);
# define gcmDUMP_FRAMERATE gcfDumpFrameRate
-#elif gcdHAS_ELLIPSES
+#elif gcdHAS_ELLIPSIS
# define gcmDUMP_FRAMERATE(...)
#else
gcmINLINE static void
...
);
# define gcmDUMP gcfDump
-#elif gcdHAS_ELLIPSES
+#elif gcdHAS_ELLIPSIS
# define gcmDUMP(...)
#else
gcmINLINE static void
IN gctSIZE_T Bytes
);
# define gcmDUMP_DATA gcfDumpData
-#elif gcdHAS_ELLIPSES
+#elif gcdHAS_ELLIPSIS
# define gcmDUMP_DATA(...)
#else
gcmINLINE static void
IN gctSIZE_T Bytes
);
# define gcmDUMP_BUFFER gcfDumpBuffer
-#elif gcdHAS_ELLIPSES
+#elif gcdHAS_ELLIPSIS
# define gcmDUMP_BUFFER(...)
#else
gcmINLINE static void
gceSTATUS gcfDumpApi(IN gctCONST_STRING String, ...);
#if gcdDUMP_API
# define gcmDUMP_API gcfDumpApi
-#elif gcdHAS_ELLIPSES
+#elif gcdHAS_ELLIPSIS
# define gcmDUMP_API(...)
#else
gcmINLINE static void
gceSTATUS gcfDumpArray(IN gctCONST_POINTER Data, IN gctUINT32 Size);
#if gcdDUMP_API
# define gcmDUMP_API_ARRAY gcfDumpArray
-#elif gcdHAS_ELLIPSES
+#elif gcdHAS_ELLIPSIS
# define gcmDUMP_API_ARRAY(...)
#else
gcmINLINE static void
gceSTATUS gcfDumpArrayToken(IN gctCONST_POINTER Data, IN gctUINT32 Termination);
#if gcdDUMP_API
# define gcmDUMP_API_ARRAY_TOKEN gcfDumpArrayToken
-#elif gcdHAS_ELLIPSES
+#elif gcdHAS_ELLIPSIS
# define gcmDUMP_API_ARRAY_TOKEN(...)
#else
gcmINLINE static void
gceSTATUS gcfDumpApiData(IN gctCONST_POINTER Data, IN gctSIZE_T Size);
#if gcdDUMP_API
# define gcmDUMP_API_DATA gcfDumpApiData
-#elif gcdHAS_ELLIPSES
+#elif gcdHAS_ELLIPSIS
# define gcmDUMP_API_DATA(...)
#else
gcmINLINE static void
# define gcmDUMP_API_DATA __dummy_dump_api_data
#endif
+/*******************************************************************************
+** gcmDUMP_2D_COMMAND
+**
+** Print the 2D command buffer.
+**
+** ARGUMENTS:
+**
+** gctUINT32_PTR Pointer to the command buffer.
+** gctUINT32 Command buffer size.
+*/
+gceSTATUS gcfDump2DCommand(IN gctUINT32_PTR Command, IN gctUINT32 Size);
+#if gcdDUMP_2D
+# define gcmDUMP_2D_COMMAND gcfDump2DCommand
+#elif gcdHAS_ELLIPSIS
+# define gcmDUMP_2D_COMMAND(...)
+#else
+ gcmINLINE static void
+ __dummy_dump_2d_command(
+ IN gctUINT32_PTR Command,
+ IN gctUINT32 Size
+ )
+ {
+ }
+# define gcmDUMP_2D_COMMAND __dummy_dump_2d_command
+#endif
+
+/*******************************************************************************
+** gcmDUMP_2D_SURFACE
+**
+** Print the 2D surface memory.
+**
+** ARGUMENTS:
+**
+** gctBOOL Src.
+** gctUINT32 Address.
+*/
+gceSTATUS gcfDump2DSurface(IN gctBOOL Src, IN gctUINT32 Address);
+#if gcdDUMP_2D
+# define gcmDUMP_2D_SURFACE gcfDump2DSurface
+#elif gcdHAS_ELLIPSIS
+# define gcmDUMP_2D_SURFACE(...)
+#else
+ gcmINLINE static void
+ __dummy_dump_2d_surface(
+ IN gctBOOL Src,
+ IN gctUINT32 Address
+ )
+ {
+ }
+# define gcmDUMP_2D_SURFACE __dummy_dump_2d_surface
+#endif
+
+/*******************************************************************************
+** gcmDUMP_ADD_MEMORY_INFO
+**
+** Record the memory info.
+**
+** ARGUMENTS:
+**
+** gctUINT32 Address.
+** gctSIZE_T Size.
+*/
+gceSTATUS gcfAddMemoryInfo(IN gctUINT32 GPUAddress, IN gctPOINTER Logical, IN gctUINT32 Physical, IN gctUINT32 Size);
+#if gcdDUMP_2D
+# define gcmDUMP_ADD_MEMORY_INFO gcfAddMemoryInfo
+#elif gcdHAS_ELLIPSIS
+# define gcmDUMP_ADD_MEMORY_INFO(...)
+#else
+ gcmINLINE static void
+ __dummy_dump_add_memory_info(
+ IN gctUINT32 GPUAddress,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Physical,
+ IN gctUINT32 Size
+ )
+ {
+ }
+# define gcmDUMP_ADD_MEMORY_INFO __dummy_dump_add_memory_info
+#endif
+
+/*******************************************************************************
+** gcmDUMP_DEL_MEMORY_INFO
+**
+** Record the memory info.
+**
+** ARGUMENTS:
+**
+** gctUINT32 Address.
+*/
+gceSTATUS gcfDelMemoryInfo(IN gctUINT32 Address);
+#if gcdDUMP_2D
+# define gcmDUMP_DEL_MEMORY_INFO gcfDelMemoryInfo
+#elif gcdHAS_ELLIPSIS
+# define gcmDUMP_DEL_MEMORY_INFO(...)
+#else
+ gcmINLINE static void
+ __dummy_dump_del_memory_info(
+ IN gctUINT32 Address
+ )
+ {
+ }
+# define gcmDUMP_DEL_MEMORY_INFO __dummy_dump_del_memory_info
+#endif
+
+#if gcdDUMP_2D
+extern gctPOINTER dumpMemInfoListMutex;
+extern gctBOOL dump2DFlag;
+#endif
+
/*******************************************************************************
**
** gcmTRACE_RELEASE
#define gcmONERROR(func) _gcmONERROR(gcm, func)
#define gcmkONERROR(func) _gcmkONERROR(gcmk, func)
+/*******************************************************************************
+**
+** gcmkSAFECASTSIZET
+**
+** Check wether value of a gctSIZE_T varible beyond the capability
+** of 32bits GPU hardware.
+**
+** ASSUMPTIONS:
+**
+**
+**
+** ARGUMENTS:
+**
+** x A gctUINT32 variable
+** y A gctSIZE_T variable
+*/
+#define gcmkSAFECASTSIZET(x, y) \
+ do \
+ { \
+ gctUINT32 tmp = (gctUINT32)(y); \
+ if (gcmSIZEOF(gctSIZE_T) > gcmSIZEOF(gctUINT32)) \
+ { \
+ gcmkASSERT(tmp <= gcvMAXUINT32); \
+ } \
+ (x) = tmp; \
+ } \
+ while (gcvFALSE)
+
+#define gcmSAFECASTSIZET(x, y) \
+ do \
+ { \
+ gctUINT32 tmp = (gctUINT32)(y); \
+ if (gcmSIZEOF(gctSIZE_T) > gcmSIZEOF(gctUINT32)) \
+ { \
+ gcmASSERT(tmp <= gcvMAXUINT32); \
+ } \
+ (x) = tmp; \
+ } \
+ while (gcvFALSE)
+
/*******************************************************************************
**
** gcmVERIFY_LOCK
void
);
+#if defined(ANDROID)
struct _gcoOS_SymbolsList
{
+#if gcdENABLE_3D
gcePATCH_ID patchId;
+#endif
const char * symList[10];
};
+#endif
-#if gcdHAS_ELLIPSES
+#if gcdHAS_ELLIPSIS
#define gcmUSER_DEBUG_MSG(level, ...) \
do \
{ \
#define gcmUSER_DEBUG_WARNING_MSG
#endif
+/*******************************************************************************
+**
+** A set of macros to aid state loading.
+**
+** ARGUMENTS:
+**
+** CommandBuffer Pointer to a gcoCMDBUF object.
+** StateDelta Pointer to a gcsSTATE_DELTA state delta structure.
+** Memory Destination memory pointer of gctUINT32_PTR type.
+** PartOfContext Whether or not the state is a part of the context.
+** FixedPoint Whether or not the state is of the fixed point format.
+** Count Number of consecutive states to be loaded.
+** Address State address.
+** Data Data to be set to the state.
+*/
+
+/*----------------------------------------------------------------------------*/
+
+#if gcmIS_DEBUG(gcdDEBUG_CODE)
+
+# define gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count) \
+ CommandBuffer->lastLoadStatePtr = gcmPTR_TO_UINT64(Memory); \
+ CommandBuffer->lastLoadStateAddress = Address; \
+ CommandBuffer->lastLoadStateCount = Count
+
+# define gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address) \
+ gcmASSERT( \
+ (gctUINT) (Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastLoadStatePtr, gctUINT32_PTR) - 1) \
+ == \
+ (gctUINT) (Address - CommandBuffer->lastLoadStateAddress) \
+ ); \
+ \
+ gcmASSERT(CommandBuffer->lastLoadStateCount > 0); \
+ \
+ CommandBuffer->lastLoadStateCount -= 1
+
+# define gcmVERIFYLOADSTATEDONE(CommandBuffer) \
+ gcmASSERT(CommandBuffer->lastLoadStateCount == 0);
+
+# define gcmDEFINELOADSTATEBASE() \
+ gctUINT32_PTR LoadStateBase;
+
+# define gcmSETLOADSTATEBASE(CommandBuffer, OutSide) \
+ if (OutSide) \
+ {\
+ LoadStateBase = (gctUINT32_PTR)*OutSide; \
+ }\
+ else\
+ {\
+ LoadStateBase = (gctUINT_PTR)CommandBuffer->buffer;\
+ }
+
+
+# define gcmVERIFYLOADSTATEALIGNED(CommandBuffer, Memory) \
+ gcmASSERT(((Memory - LoadStateBase) & 1) == 0);
+
+# define gcmUNSETLOADSTATEBASE() \
+ LoadStateBase = LoadStateBase;
+
+#else
+
+# define gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count)
+# define gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address)
+# define gcmVERIFYLOADSTATEDONE(CommandBuffer)
+
+# define gcmDEFINELOADSTATEBASE()
+# define gcmSETLOADSTATEBASE(CommandBuffer, OutSide)
+# define gcmVERIFYLOADSTATEALIGNED(CommandBuffer, Memory)
+# define gcmUNSETLOADSTATEBASE()
+
+#endif
+
+#if gcdSECURE_USER
+
+# define gcmDEFINESECUREUSER() \
+ gctUINT __secure_user_offset__; \
+ gctUINT32_PTR __secure_user_hintArray__;
+
+# define gcmBEGINSECUREUSER() \
+ __secure_user_offset__ = reserve->lastOffset; \
+ \
+ __secure_user_hintArray__ = gcmUINT64_TO_PTR(reserve->hintArrayTail)
+
+# define gcmENDSECUREUSER() \
+ reserve->hintArrayTail = gcmPTR_TO_UINT64(__secure_user_hintArray__)
+
+# define gcmSKIPSECUREUSER() \
+ __secure_user_offset__ += gcmSIZEOF(gctUINT32)
+
+# define gcmUPDATESECUREUSER() \
+ *__secure_user_hintArray__ = __secure_user_offset__; \
+ \
+ __secure_user_offset__ += gcmSIZEOF(gctUINT32); \
+ __secure_user_hintArray__ += 1
+
+#else
+
+# define gcmDEFINESECUREUSER()
+# define gcmBEGINSECUREUSER()
+# define gcmENDSECUREUSER()
+# define gcmSKIPSECUREUSER()
+# define gcmUPDATESECUREUSER()
+
+#endif
+
+/*----------------------------------------------------------------------------*/
+
+#if gcdDUMP
+# define gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, Data) \
+ if (FixedPoint) \
+ { \
+ gcmDUMP(gcvNULL, "#[state.x 0x%04X 0x%08X]", \
+ Address, Data \
+ ); \
+ } \
+ else \
+ { \
+ gcmDUMP(gcvNULL, "#[state 0x%04X 0x%08X]", \
+ Address, Data \
+ ); \
+ }
+#else
+# define gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, Data)
+#endif
+
+#define gcmDEFINESTATEBUFFER(CommandBuffer, StateDelta, Memory, ReserveSize) \
+ gcmDEFINESECUREUSER() \
+ gctSIZE_T ReserveSize; \
+ gcoCMDBUF CommandBuffer; \
+ gctUINT32_PTR Memory; \
+ gcsSTATE_DELTA_PTR StateDelta
+
+#define gcmBEGINSTATEBUFFER(Hardware, CommandBuffer, StateDelta, Memory, ReserveSize) \
+{ \
+ gcmONERROR(gcoBUFFER_Reserve( \
+ Hardware->buffer, ReserveSize, gcvTRUE, gcvCOMMAND_3D, &CommandBuffer \
+ )); \
+ \
+ Memory = (gctUINT32_PTR) gcmUINT64_TO_PTR(CommandBuffer->lastReserve); \
+ \
+ StateDelta = Hardware->delta; \
+ \
+ gcmBEGINSECUREUSER(); \
+}
+
+#define gcmENDSTATEBUFFER(Hardware, CommandBuffer, Memory, ReserveSize) \
+{ \
+ gcmENDSECUREUSER(); \
+ \
+ gcmASSERT( \
+ gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT8_PTR) + ReserveSize \
+ == \
+ (gctUINT8_PTR) Memory \
+ ); \
+}
+
+/*----------------------------------------------------------------------------*/
+
+#define gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, Count) \
+{ \
+ gcmASSERT(((Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT32_PTR)) & 1) == 0); \
+ gcmASSERT((gctUINT32)Count <= 1024); \
+ \
+ gcmVERIFYLOADSTATEDONE(CommandBuffer); \
+ \
+ gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count); \
+ \
+ *Memory++ \
+ = gcmSETFIELDVALUE(0, AQ_COMMAND_LOAD_STATE_COMMAND, OPCODE, LOAD_STATE) \
+ | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, FLOAT, FixedPoint) \
+ | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, COUNT, Count) \
+ | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, ADDRESS, Address); \
+ \
+ gcmSKIPSECUREUSER(); \
+}
+
+#define gcmENDSTATEBATCH(CommandBuffer, Memory) \
+{ \
+ gcmVERIFYLOADSTATEDONE(CommandBuffer); \
+ \
+ gcmASSERT(((Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT32_PTR)) & 1) == 0); \
+}
+
+/*----------------------------------------------------------------------------*/
+
+#define gcmSETSTATEDATA(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data) \
+{ \
+ gctUINT32 __temp_data32__; \
+ \
+ gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \
+ \
+ gcmSAFECASTSIZET(__temp_data32__, Data); \
+ \
+ *Memory++ = __temp_data32__; \
+ \
+ gcoHARDWARE_UpdateDelta( \
+ StateDelta, Address, 0, __temp_data32__ \
+ ); \
+ \
+ gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
+ \
+ gcmUPDATESECUREUSER(); \
+}
+
+#define gcmSETSTATEDATAWITHMASK(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data) \
+{ \
+ gctUINT32 __temp_data32__; \
+ \
+ gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \
+ \
+ __temp_data32__ = Data; \
+ \
+ *Memory++ = __temp_data32__; \
+ \
+ gcoHARDWARE_UpdateDelta( \
+ StateDelta, Address, Mask, __temp_data32__ \
+ ); \
+ \
+ gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
+ \
+ gcmUPDATESECUREUSER(); \
+}
+
+
+#define gcmSETCTRLSTATE(StateDelta, CommandBuffer, Memory, Address, Data) \
+{ \
+ gctUINT32 __temp_data32__; \
+ \
+ gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \
+ \
+ __temp_data32__ = Data; \
+ \
+ *Memory++ = __temp_data32__; \
+ \
+ gcmDUMPSTATEDATA(StateDelta, gcvFALSE, Address, __temp_data32__); \
+ \
+ gcmSKIPSECUREUSER(); \
+}
+
+#define gcmSETFILLER(CommandBuffer, Memory) \
+{ \
+ gcmVERIFYLOADSTATEDONE(CommandBuffer); \
+ \
+ Memory += 1; \
+ \
+ gcmSKIPSECUREUSER(); \
+}
+
+/*----------------------------------------------------------------------------*/
+
+#define gcmSETSINGLESTATE(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data) \
+{ \
+ gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \
+ gcmSETSTATEDATA(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data); \
+ gcmENDSTATEBATCH(CommandBuffer, Memory); \
+}
+
+#define gcmSETSINGLESTATEWITHMASK(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data) \
+{ \
+ gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \
+ gcmSETSTATEDATAWITHMASK(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data); \
+ gcmENDSTATEBATCH(CommandBuffer, Memory); \
+}
+
+
+#define gcmSETSINGLECTRLSTATE(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data) \
+{ \
+ gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \
+ gcmSETCTRLSTATE(StateDelta, CommandBuffer, Memory, Address, Data); \
+ gcmENDSTATEBATCH(CommandBuffer, Memory); \
+}
+
+
+
+#define gcmSETSEMASTALLPIPE(StateDelta, CommandBuffer, Memory, Data) \
+{ \
+ gcmSETSINGLESTATE(StateDelta, CommandBuffer, Memory, gcvFALSE, AQSemaphoreRegAddrs, Data); \
+ \
+ *Memory++ = gcmSETFIELDVALUE(0, STALL_COMMAND, OPCODE, STALL); \
+ \
+ *Memory++ = Data; \
+ \
+ gcmDUMP(gcvNULL, "#[stall 0x%08X 0x%08X]", \
+ gcmSETFIELDVALUE(0, AQ_SEMAPHORE, SOURCE, FRONT_END), \
+ gcmSETFIELDVALUE(0, AQ_SEMAPHORE, DESTINATION, PIXEL_ENGINE)); \
+ \
+ gcmSKIPSECUREUSER(); \
+}
+
+/*******************************************************************************
+**
+** gcmSETSTARTDECOMMAND
+**
+** Form a START_DE command.
+**
+** ARGUMENTS:
+**
+** Memory Destination memory pointer of gctUINT32_PTR type.
+** Count Number of the rectangles.
+*/
+
+#define gcmSETSTARTDECOMMAND(Memory, Count) \
+{ \
+ *Memory++ \
+ = gcmSETFIELDVALUE(0, AQ_COMMAND_START_DE_COMMAND, OPCODE, START_DE) \
+ | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, COUNT, Count) \
+ | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, DATA_COUNT, 0); \
+ \
+ *Memory++ = 0xDEADDEED; \
+}
+
+/*****************************************
+** Temp command buffer macro
+*/
+#define gcmDEFINESTATEBUFFER_NEW(CommandBuffer, StateDelta, Memory) \
+ gcmDEFINESECUREUSER() \
+ gcmDEFINELOADSTATEBASE() \
+ gcsTEMPCMDBUF CommandBuffer = gcvNULL; \
+ gctUINT32_PTR Memory; \
+ gcsSTATE_DELTA_PTR StateDelta
+
+
+#define gcmBEGINSTATEBUFFER_NEW(Hardware, CommandBuffer, StateDelta, Memory, OutSide) \
+{ \
+ if (OutSide) \
+ {\
+ Memory = (gctUINT32_PTR)*OutSide; \
+ }\
+ else \
+ {\
+ gcmONERROR(gcoBUFFER_StartTEMPCMDBUF( \
+ Hardware->buffer, &CommandBuffer \
+ ));\
+ \
+ Memory = (gctUINT32_PTR)(CommandBuffer->buffer); \
+ \
+ }\
+ StateDelta = Hardware->delta; \
+ \
+ gcmBEGINSECUREUSER(); \
+ gcmSETLOADSTATEBASE(CommandBuffer,OutSide);\
+}
+
+#define gcmENDSTATEBUFFER_NEW(Hardware, CommandBuffer, Memory, OutSide) \
+{ \
+ gcmENDSECUREUSER(); \
+ \
+ if (OutSide) \
+ {\
+ *OutSide = Memory; \
+ }\
+ else \
+ {\
+ CommandBuffer->currentByteSize = (gctUINT32)((gctUINT8_PTR)Memory - \
+ (gctUINT8_PTR)CommandBuffer->buffer); \
+ \
+ gcmONERROR(gcoBUFFER_EndTEMPCMDBUF(Hardware->buffer));\
+ }\
+ gcmUNSETLOADSTATEBASE()\
+}
+
+/*----------------------------------------------------------------------------*/
+
+#define gcmBEGINSTATEBATCH_NEW(CommandBuffer, Memory, FixedPoint, Address, Count) \
+{ \
+ gcmVERIFYLOADSTATEALIGNED(CommandBuffer,Memory);\
+ gcmASSERT((gctUINT32)Count <= 1024); \
+ \
+ *Memory++ \
+ = gcmSETFIELDVALUE(0, AQ_COMMAND_LOAD_STATE_COMMAND, OPCODE, LOAD_STATE) \
+ | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, FLOAT, FixedPoint) \
+ | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, COUNT, Count) \
+ | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, ADDRESS, Address); \
+ \
+ gcmSKIPSECUREUSER(); \
+}
+
+#define gcmENDSTATEBATCH_NEW(CommandBuffer, Memory) \
+ gcmVERIFYLOADSTATEALIGNED(CommandBuffer,Memory);
+
+/*----------------------------------------------------------------------------*/
+
+#define gcmSETSTATEDATA_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data) \
+{ \
+ gctUINT32 __temp_data32__; \
+ \
+ __temp_data32__ = Data; \
+ \
+ *Memory++ = __temp_data32__; \
+ \
+ gcoHARDWARE_UpdateDelta( \
+ StateDelta, Address, 0, __temp_data32__ \
+ ); \
+ \
+ gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
+ \
+ gcmUPDATESECUREUSER(); \
+}
+
+#define gcmSETSTATEDATAWITHMASK_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data) \
+{ \
+ gctUINT32 __temp_data32__; \
+ \
+ __temp_data32__ = Data; \
+ \
+ *Memory++ = __temp_data32__; \
+ \
+ gcoHARDWARE_UpdateDelta( \
+ StateDelta, Address, Mask, __temp_data32__ \
+ ); \
+ \
+ gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
+ \
+ gcmUPDATESECUREUSER(); \
+}
+
+
+#define gcmSETCTRLSTATE_NEW(StateDelta, CommandBuffer, Memory, Address, Data) \
+{ \
+ gctUINT32 __temp_data32__; \
+ \
+ __temp_data32__ = Data; \
+ \
+ *Memory++ = __temp_data32__; \
+ \
+ gcmDUMPSTATEDATA(StateDelta, gcvFALSE, Address, __temp_data32__); \
+ \
+ gcmSKIPSECUREUSER(); \
+}
+
+#define gcmSETFILLER_NEW(CommandBuffer, Memory) \
+{ \
+ Memory += 1; \
+ \
+ gcmSKIPSECUREUSER(); \
+}
+
+/*----------------------------------------------------------------------------*/
+
+#define gcmSETSINGLESTATE_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data) \
+{ \
+ gcmBEGINSTATEBATCH_NEW(CommandBuffer, Memory, FixedPoint, Address, 1); \
+ gcmSETSTATEDATA_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data); \
+ gcmENDSTATEBATCH_NEW(CommandBuffer, Memory); \
+}
+
+#define gcmSETSINGLESTATEWITHMASK_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data) \
+{ \
+ gcmBEGINSTATEBATCH_NEW(CommandBuffer, Memory, FixedPoint, Address, 1); \
+ gcmSETSTATEDATAWITHMASK_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data); \
+ gcmENDSTATEBATCH_NEW(CommandBuffer, Memory); \
+}
+
+
+#define gcmSETSINGLECTRLSTATE_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data) \
+{ \
+ gcmBEGINSTATEBATCH_NEW(CommandBuffer, Memory, FixedPoint, Address, 1); \
+ gcmSETCTRLSTATE_NEW(StateDelta, CommandBuffer, Memory, Address, Data); \
+ gcmENDSTATEBATCH_NEW(CommandBuffer, Memory); \
+}
+
+
+
+#define gcmSETSEMASTALLPIPE_NEW(StateDelta, CommandBuffer, Memory, Data) \
+{ \
+ gcmSETSINGLESTATE_NEW(StateDelta, CommandBuffer, Memory, gcvFALSE, AQSemaphoreRegAddrs, Data); \
+ \
+ *Memory++ = gcmSETFIELDVALUE(0, STALL_COMMAND, OPCODE, STALL); \
+ \
+ *Memory++ = Data; \
+ \
+ gcmDUMP(gcvNULL, "#[stall 0x%08X 0x%08X]", \
+ gcmSETFIELDVALUE(0, AQ_SEMAPHORE, SOURCE, FRONT_END), \
+ gcmSETFIELDVALUE(0, AQ_SEMAPHORE, DESTINATION, PIXEL_ENGINE)); \
+ \
+ gcmSKIPSECUREUSER(); \
+}
+
+#define gcmSETSTARTDECOMMAND_NEW(CommandBuffer, Memory, Count) \
+{ \
+ *Memory++ \
+ = gcmSETFIELDVALUE(0, AQ_COMMAND_START_DE_COMMAND, OPCODE, START_DE) \
+ | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, COUNT, Count) \
+ | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, DATA_COUNT, 0); \
+ \
+ *Memory++ = 0xDEADDEED; \
+ \
+}
+
+#define gcmSETSTATEDATA_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data) \
+{ \
+ gctUINT32 __temp_data32__; \
+ \
+ __temp_data32__ = Data; \
+ \
+ *Memory++ = __temp_data32__; \
+ \
+ gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
+ \
+ gcmUPDATESECUREUSER(); \
+}
+
+#define gcmSETSTATEDATAWITHMASK_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data) \
+{ \
+ gctUINT32 __temp_data32__; \
+ \
+ __temp_data32__ = Data; \
+ \
+ *Memory++ = __temp_data32__; \
+ \
+ gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
+ \
+ gcmUPDATESECUREUSER(); \
+}
+
+#define gcmSETSINGLESTATE_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data) \
+{ \
+ gcmBEGINSTATEBATCH_NEW(CommandBuffer, Memory, FixedPoint, Address, 1); \
+ gcmSETSTATEDATA_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data); \
+ gcmENDSTATEBATCH_NEW(CommandBuffer, Memory); \
+}
+
+#define gcmSETSINGLESTATEWITHMASK_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data) \
+{ \
+ gcmBEGINSTATEBATCH_NEW(CommandBuffer, Memory, FixedPoint, Address, 1); \
+ gcmSETSTATEDATAWITHMASK_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data); \
+ gcmENDSTATEBATCH_NEW(CommandBuffer, Memory); \
+}
+
+#define gcmSETSTATEDATA_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data) \
+{ \
+ gctUINT32 __temp_data32__; \
+ \
+ gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \
+ \
+ gcmSAFECASTSIZET(__temp_data32__, Data); \
+ \
+ *Memory++ = __temp_data32__; \
+ \
+ gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
+ \
+ gcmUPDATESECUREUSER(); \
+}
+
+#define gcmSETSTATEDATAWITHMASK_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data) \
+{ \
+ gctUINT32 __temp_data32__; \
+ \
+ gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \
+ \
+ __temp_data32__ = Data; \
+ \
+ *Memory++ = __temp_data32__; \
+ \
+ gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
+ \
+ gcmUPDATESECUREUSER(); \
+}
+
+#define gcmSETSINGLESTATE_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data) \
+{ \
+ gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \
+ gcmSETSTATEDATA_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Data); \
+ gcmENDSTATEBATCH(CommandBuffer, Memory); \
+}
+
+#define gcmSETSINGLESTATEWITHMASK_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data) \
+{ \
+ gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \
+ gcmSETSTATEDATAWITHMASK_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
+ Address, Mask, Data); \
+ gcmENDSTATEBATCH(CommandBuffer, Memory); \
+}
+
+#define gcmDEFINESTATEBUFFER_NEW_FAST(CommandBuffer, Memory) \
+ gcmDEFINESECUREUSER() \
+ gcmDEFINELOADSTATEBASE() \
+ gcsTEMPCMDBUF CommandBuffer = gcvNULL; \
+ gctUINT32_PTR Memory;
+
+#define gcmDEFINESTATEBUFFER_FAST(CommandBuffer, Memory, ReserveSize) \
+ gcmDEFINESECUREUSER() \
+ gctSIZE_T ReserveSize; \
+ gcoCMDBUF CommandBuffer; \
+ gctUINT32_PTR Memory;
+
+#define gcmBEGINSTATEBUFFER_FAST(Hardware, CommandBuffer, Memory, ReserveSize) \
+{ \
+ gcmONERROR(gcoBUFFER_Reserve( \
+ Hardware->buffer, ReserveSize, gcvTRUE, &CommandBuffer \
+ )); \
+ \
+ Memory = (gctUINT32_PTR) gcmUINT64_TO_PTR(CommandBuffer->lastReserve); \
+ \
+ gcmBEGINSECUREUSER(); \
+}
+
+#define gcmBEGINSTATEBUFFER_NEW_FAST(Hardware, CommandBuffer, Memory, OutSide) \
+{ \
+ if (OutSide) \
+ {\
+ Memory = (gctUINT32_PTR)*OutSide; \
+ }\
+ else \
+ {\
+ gcmONERROR(gcoBUFFER_StartTEMPCMDBUF( \
+ Hardware->buffer, &CommandBuffer \
+ ));\
+ \
+ Memory = (gctUINT32_PTR)(CommandBuffer->buffer); \
+ \
+ }\
+ \
+ gcmBEGINSECUREUSER(); \
+ gcmSETLOADSTATEBASE(CommandBuffer,OutSide);\
+}
+/*******************************************************************************
+**
+** gcmCONFIGUREUNIFORMS
+**
+** Configure uniforms according to chip and numConstants.
+*/
+#if !gcdENABLE_UNIFIED_CONSTANT
+#define gcmCONFIGUREUNIFORMS(ChipModel, ChipRevision, NumConstants, \
+ UnifiedConst, VsConstBase, PsConstBase, VsConstMax, PsConstMax, ConstMax) \
+{ \
+ if (ChipModel == gcv2000 && ChipRevision == 0x5118) \
+ { \
+ UnifiedConst = gcvFALSE; \
+ VsConstBase = AQVertexShaderConstRegAddrs; \
+ PsConstBase = AQPixelShaderConstRegAddrs; \
+ VsConstMax = 256; \
+ PsConstMax = 64; \
+ ConstMax = 320; \
+ } \
+ else if (NumConstants == 320) \
+ { \
+ UnifiedConst = gcvFALSE; \
+ VsConstBase = AQVertexShaderConstRegAddrs; \
+ PsConstBase = AQPixelShaderConstRegAddrs; \
+ VsConstMax = 256; \
+ PsConstMax = 64; \
+ ConstMax = 320; \
+ } \
+ /* All GC1000 series chips can only support 64 uniforms for ps on non-unified const mode. */ \
+ else if (NumConstants > 256 && ChipModel == gcv1000) \
+ { \
+ UnifiedConst = gcvFALSE; \
+ VsConstBase = AQVertexShaderConstRegAddrs; \
+ PsConstBase = AQPixelShaderConstRegAddrs; \
+ VsConstMax = 256; \
+ PsConstMax = 64; \
+ ConstMax = 320; \
+ } \
+ else if (NumConstants > 256) \
+ { \
+ UnifiedConst = gcvFALSE; \
+ VsConstBase = AQVertexShaderConstRegAddrs; \
+ PsConstBase = AQPixelShaderConstRegAddrs; \
+ VsConstMax = 256; \
+ PsConstMax = 256; \
+ ConstMax = 512; \
+ } \
+ else if (NumConstants == 256) \
+ { \
+ UnifiedConst = gcvFALSE; \
+ VsConstBase = AQVertexShaderConstRegAddrs; \
+ PsConstBase = AQPixelShaderConstRegAddrs; \
+ VsConstMax = 256; \
+ PsConstMax = 256; \
+ ConstMax = 512; \
+ } \
+ else \
+ { \
+ UnifiedConst = gcvFALSE; \
+ VsConstBase = AQVertexShaderConstRegAddrs; \
+ PsConstBase = AQPixelShaderConstRegAddrs; \
+ VsConstMax = 168; \
+ PsConstMax = 64; \
+ ConstMax = 232; \
+ } \
+}
+#else
+#define gcmCONFIGUREUNIFORMS(ChipModel, ChipRevision, NumConstants, \
+ UnifiedConst, VsConstBase, PsConstBase, VsConstMax, PsConstMax, ConstMax) \
+{ \
+ if (NumConstants > 256) \
+ { \
+ UnifiedConst = gcvTRUE; \
+ VsConstBase = gcregSHUniformsRegAddrs; \
+ PsConstBase = gcregSHUniformsRegAddrs; \
+ ConstMax = NumConstants; \
+ VsConstMax = 256; \
+ PsConstMax = ConstMax - VsConstMax; \
+ } \
+ else if (NumConstants == 256) \
+ { \
+ if (ChipModel == gcv2000 && ChipRevision == 0x5118) \
+ { \
+ UnifiedConst = gcvFALSE; \
+ VsConstBase = AQVertexShaderConstRegAddrs; \
+ PsConstBase = AQPixelShaderConstRegAddrs; \
+ VsConstMax = 256; \
+ PsConstMax = 64; \
+ ConstMax = 320; \
+ } \
+ else \
+ { \
+ UnifiedConst = gcvFALSE; \
+ VsConstBase = AQVertexShaderConstRegAddrs; \
+ PsConstBase = AQPixelShaderConstRegAddrs; \
+ VsConstMax = 256; \
+ PsConstMax = 256; \
+ ConstMax = 512; \
+ } \
+ } \
+ else \
+ { \
+ UnifiedConst = gcvFALSE; \
+ VsConstBase = AQVertexShaderConstRegAddrs; \
+ PsConstBase = AQPixelShaderConstRegAddrs; \
+ VsConstMax = 168; \
+ PsConstMax = 64; \
+ ConstMax = 232; \
+ } \
+}
+#endif
+
#ifdef __cplusplus
}
#endif
+++ /dev/null
-/****************************************************************************
-*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
-*
-* 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.
-*
-*****************************************************************************/
-
-/*
-** Include file the defines the front- and back-end compilers, as well as the
-** objects they use.
-*/
-
-#ifndef __gc_hal_compiler_h_
-#define __gc_hal_compiler_h_
-
-#ifndef VIVANTE_NO_3D
-#include "gc_hal_types.h"
-#include "gc_hal_engine.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef GC_ENABLE_LOADTIME_OPT
-#define GC_ENABLE_LOADTIME_OPT 1
-#endif
-
-#define TEMP_OPT_CONSTANT_TEXLD_COORD 0
-
-#define TEMP_SHADER_PATCH 1
-
-#define TEMP_INLINE_ALL_EXPANSION 1
-/******************************* IR VERSION ******************/
-#define gcdSL_IR_VERSION gcmCC('\0','\0','\0','\1')
-
-/******************************************************************************\
-|******************************* SHADER LANGUAGE ******************************|
-\******************************************************************************/
-
- /* allocator/deallocator function pointer */
-typedef gceSTATUS (*gctAllocatorFunc)(
- IN gctSIZE_T Bytes,
- OUT gctPOINTER * Memory
- );
-
-typedef gceSTATUS (*gctDeallocatorFunc)(
- IN gctPOINTER Memory
- );
-
-typedef gctBOOL (*compareFunc) (
- IN void * data,
- IN void * key
- );
-
-typedef struct _gcsListNode gcsListNode;
-struct _gcsListNode
-{
- gcsListNode * next;
- void * data;
-};
-
-typedef struct _gcsAllocator
-{
- gctAllocatorFunc allocate;
- gctDeallocatorFunc deallocate;
-} gcsAllocator;
-
-/* simple map structure */
-typedef struct _SimpleMap SimpleMap;
-struct _SimpleMap
-{
- gctUINT32 key;
- gctUINT32 val;
- SimpleMap *next;
- gcsAllocator *allocator;
-
-};
-
-/* SimpleMap Operations */
-/* return -1 if not found, otherwise return the mapped value */
-gctUINT32
-gcSimpleMap_Find(
- IN SimpleMap *Map,
- IN gctUINT32 Key
- );
-
-gceSTATUS
-gcSimpleMap_Destory(
- IN SimpleMap * Map,
- IN gcsAllocator * Allocator
- );
-
-/* Add a pair <Key, Val> to the Map head, the user should be aware that the
- * map pointer is always changed when adding a new node :
- *
- * gcSimpleMap_AddNode(&theMap, key, val, allocator);
- *
- */
-gceSTATUS
-gcSimpleMap_AddNode(
- IN SimpleMap ** Map,
- IN gctUINT32 Key,
- IN gctUINT32 Val,
- IN gcsAllocator * Allocator
- );
-
-/* gcsList data structure and related operations */
-typedef struct _gcsList
-{
- gcsListNode *head;
- gcsListNode *tail;
- gctINT count;
- gcsAllocator *allocator;
-} gcsList;
-
-/* List operations */
-void
-gcList_Init(
- IN gcsList *list,
- IN gcsAllocator *allocator
- );
-
-gceSTATUS
-gcList_CreateNode(
- IN void * Data,
- IN gctAllocatorFunc Allocator,
- OUT gcsListNode ** ListNode
- );
-
-gceSTATUS
-gcList_Clean(
- IN gcsList * List,
- IN gctBOOL FreeData
- );
-
-gcsListNode *
-gcList_FindNode(
- IN gcsList * List,
- IN void * Key,
- IN compareFunc compare
- );
-
-gceSTATUS
-gcList_AddNode(
- IN gcsList * List,
- IN void * Data
- );
-
-gceSTATUS
-gcList_RemoveNode(
- IN gcsList * List,
- IN gcsListNode * Node
- );
-
-/* link list structure for code list */
-typedef gcsList gcsCodeList;
-typedef gcsCodeList * gctCodeList;
-typedef gcsListNode gcsCodeListNode;
-
-/* Possible shader language opcodes. */
-typedef enum _gcSL_OPCODE
-{
- gcSL_NOP, /* 0x00 */
- gcSL_MOV, /* 0x01 */
- gcSL_SAT, /* 0x02 */
- gcSL_DP3, /* 0x03 */
- gcSL_DP4, /* 0x04 */
- gcSL_ABS, /* 0x05 */
- gcSL_JMP, /* 0x06 */
- gcSL_ADD, /* 0x07 */
- gcSL_MUL, /* 0x08 */
- gcSL_RCP, /* 0x09 */
- gcSL_SUB, /* 0x0A */
- gcSL_KILL, /* 0x0B */
- gcSL_TEXLD, /* 0x0C */
- gcSL_CALL, /* 0x0D */
- gcSL_RET, /* 0x0E */
- gcSL_NORM, /* 0x0F */
- gcSL_MAX, /* 0x10 */
- gcSL_MIN, /* 0x11 */
- gcSL_POW, /* 0x12 */
- gcSL_RSQ, /* 0x13 */
- gcSL_LOG, /* 0x14 */
- gcSL_FRAC, /* 0x15 */
- gcSL_FLOOR, /* 0x16 */
- gcSL_CEIL, /* 0x17 */
- gcSL_CROSS, /* 0x18 */
- gcSL_TEXLDP, /* 0x19 */
- gcSL_TEXBIAS, /* 0x1A */
- gcSL_TEXGRAD, /* 0x1B */
- gcSL_TEXLOD, /* 0x1C */
- gcSL_SIN, /* 0x1D */
- gcSL_COS, /* 0x1E */
- gcSL_TAN, /* 0x1F */
- gcSL_EXP, /* 0x20 */
- gcSL_SIGN, /* 0x21 */
- gcSL_STEP, /* 0x22 */
- gcSL_SQRT, /* 0x23 */
- gcSL_ACOS, /* 0x24 */
- gcSL_ASIN, /* 0x25 */
- gcSL_ATAN, /* 0x26 */
- gcSL_SET, /* 0x27 */
- gcSL_DSX, /* 0x28 */
- gcSL_DSY, /* 0x29 */
- gcSL_FWIDTH, /* 0x2A */
- gcSL_DIV, /* 0x2B */
- gcSL_MOD, /* 0x2C */
- gcSL_AND_BITWISE, /* 0x2D */
- gcSL_OR_BITWISE, /* 0x2E */
- gcSL_XOR_BITWISE, /* 0x2F */
- gcSL_NOT_BITWISE, /* 0x30 */
- gcSL_LSHIFT, /* 0x31 */
- gcSL_RSHIFT, /* 0x32 */
- gcSL_ROTATE, /* 0x33 */
- gcSL_BITSEL, /* 0x34 */
- gcSL_LEADZERO, /* 0x35 */
- gcSL_LOAD, /* 0x36 */
- gcSL_STORE, /* 0x37 */
- gcSL_BARRIER, /* 0x38 */
- gcSL_STORE1, /* 0x39 */
- gcSL_ATOMADD, /* 0x3A */
- gcSL_ATOMSUB, /* 0x3B */
- gcSL_ATOMXCHG, /* 0x3C */
- gcSL_ATOMCMPXCHG, /* 0x3D */
- gcSL_ATOMMIN, /* 0x3E */
- gcSL_ATOMMAX, /* 0x3F */
- gcSL_ATOMOR, /* 0x40 */
- gcSL_ATOMAND, /* 0x41 */
- gcSL_ATOMXOR, /* 0x42 */
- /*gcSL_UNUSED, 0x43 */
- /*gcSL_UNUSED, 0x44 */
- /*gcSL_UNUSED, 0x45 */
- /*gcSL_UNUSED, 0x46 */
- /*gcSL_UNUSED, 0x47 */
- /*gcSL_UNUSED, 0x48 */
- /*gcSL_UNUSED, 0x49 */
- /*gcSL_UNUSED, 0x4A */
- /*gcSL_UNUSED, 0x4B */
- /*gcSL_UNUSED, 0x4C */
- /*gcSL_UNUSED, 0x4D */
- /*gcSL_UNUSED, 0x4E */
- /*gcSL_UNUSED, 0x4F */
- /*gcSL_UNUSED, 0x50 */
- /*gcSL_UNUSED, 0x51 */
- /*gcSL_UNUSED, 0x52 */
- gcSL_ADDLO = 0x53, /* 0x53 */ /* Float only. */
- gcSL_MULLO, /* 0x54 */ /* Float only. */
- gcSL_CONV, /* 0x55 */
- gcSL_GETEXP, /* 0x56 */
- gcSL_GETMANT, /* 0x57 */
- gcSL_MULHI, /* 0x58 */ /* Integer only. */
- gcSL_CMP, /* 0x59 */
- gcSL_I2F, /* 0x5A */
- gcSL_F2I, /* 0x5B */
- gcSL_ADDSAT, /* 0x5C */ /* Integer only. */
- gcSL_SUBSAT, /* 0x5D */ /* Integer only. */
- gcSL_MULSAT, /* 0x5E */ /* Integer only. */
- gcSL_DP2, /* 0x5F */
- gcSL_MAXOPCODE
-}
-gcSL_OPCODE;
-
-typedef enum _gcSL_FORMAT
-{
- gcSL_FLOAT = 0, /* 0 */
- gcSL_INTEGER = 1, /* 1 */
- gcSL_INT32 = 1, /* 1 */
- gcSL_BOOLEAN = 2, /* 2 */
- gcSL_UINT32 = 3, /* 3 */
- gcSL_INT8, /* 4 */
- gcSL_UINT8, /* 5 */
- gcSL_INT16, /* 6 */
- gcSL_UINT16, /* 7 */
- gcSL_INT64, /* 8 */ /* Reserved for future enhancement. */
- gcSL_UINT64, /* 9 */ /* Reserved for future enhancement. */
- gcSL_INT128, /* 10 */ /* Reserved for future enhancement. */
- gcSL_UINT128, /* 11 */ /* Reserved for future enhancement. */
- gcSL_FLOAT16, /* 12 */
- gcSL_FLOAT64, /* 13 */ /* Reserved for future enhancement. */
- gcSL_FLOAT128, /* 14 */ /* Reserved for future enhancement. */
-}
-gcSL_FORMAT;
-
-/* Destination write enable bits. */
-typedef enum _gcSL_ENABLE
-{
- gcSL_ENABLE_NONE = 0x0, /* none is enabled, error/uninitialized state */
- gcSL_ENABLE_X = 0x1,
- gcSL_ENABLE_Y = 0x2,
- gcSL_ENABLE_Z = 0x4,
- gcSL_ENABLE_W = 0x8,
- /* Combinations. */
- gcSL_ENABLE_XY = gcSL_ENABLE_X | gcSL_ENABLE_Y,
- gcSL_ENABLE_XYZ = gcSL_ENABLE_X | gcSL_ENABLE_Y | gcSL_ENABLE_Z,
- gcSL_ENABLE_XYZW = gcSL_ENABLE_X | gcSL_ENABLE_Y | gcSL_ENABLE_Z | gcSL_ENABLE_W,
- gcSL_ENABLE_XYW = gcSL_ENABLE_X | gcSL_ENABLE_Y | gcSL_ENABLE_W,
- gcSL_ENABLE_XZ = gcSL_ENABLE_X | gcSL_ENABLE_Z,
- gcSL_ENABLE_XZW = gcSL_ENABLE_X | gcSL_ENABLE_Z | gcSL_ENABLE_W,
- gcSL_ENABLE_XW = gcSL_ENABLE_X | gcSL_ENABLE_W,
- gcSL_ENABLE_YZ = gcSL_ENABLE_Y | gcSL_ENABLE_Z,
- gcSL_ENABLE_YZW = gcSL_ENABLE_Y | gcSL_ENABLE_Z | gcSL_ENABLE_W,
- gcSL_ENABLE_YW = gcSL_ENABLE_Y | gcSL_ENABLE_W,
- gcSL_ENABLE_ZW = gcSL_ENABLE_Z | gcSL_ENABLE_W,
-}
-gcSL_ENABLE;
-
-/* Possible indices. */
-typedef enum _gcSL_INDEXED
-{
- gcSL_NOT_INDEXED, /* 0 */
- gcSL_INDEXED_X, /* 1 */
- gcSL_INDEXED_Y, /* 2 */
- gcSL_INDEXED_Z, /* 3 */
- gcSL_INDEXED_W, /* 4 */
-}
-gcSL_INDEXED;
-
-/* Opcode conditions. */
-typedef enum _gcSL_CONDITION
-{
- gcSL_ALWAYS, /* 0x0 */
- gcSL_NOT_EQUAL, /* 0x1 */
- gcSL_LESS_OR_EQUAL, /* 0x2 */
- gcSL_LESS, /* 0x3 */
- gcSL_EQUAL, /* 0x4 */
- gcSL_GREATER, /* 0x5 */
- gcSL_GREATER_OR_EQUAL, /* 0x6 */
- gcSL_AND, /* 0x7 */
- gcSL_OR, /* 0x8 */
- gcSL_XOR, /* 0x9 */
- gcSL_NOT_ZERO, /* 0xA */
-}
-gcSL_CONDITION;
-
-/* Possible source operand types. */
-typedef enum _gcSL_TYPE
-{
- gcSL_NONE, /* 0x0 */
- gcSL_TEMP, /* 0x1 */
- gcSL_ATTRIBUTE, /* 0x2 */
- gcSL_UNIFORM, /* 0x3 */
- gcSL_SAMPLER, /* 0x4 */
- gcSL_CONSTANT, /* 0x5 */
- gcSL_OUTPUT, /* 0x6 */
- gcSL_PHYSICAL, /* 0x7 */
-}
-gcSL_TYPE;
-
-/* Swizzle generator macro. */
-#define gcmSWIZZLE(Component1, Component2, Component3, Component4) \
-( \
- (gcSL_SWIZZLE_ ## Component1 << 0) | \
- (gcSL_SWIZZLE_ ## Component2 << 2) | \
- (gcSL_SWIZZLE_ ## Component3 << 4) | \
- (gcSL_SWIZZLE_ ## Component4 << 6) \
-)
-
-#define gcmExtractSwizzle(Swizzle, Index) \
- ((gcSL_SWIZZLE) ((((Swizzle) >> (Index * 2)) & 0x3)))
-
-#define gcmComposeSwizzle(SwizzleX, SwizzleY, SwizzleZ, SwizzleW) \
-( \
- ((SwizzleX) << 0) | \
- ((SwizzleY) << 2) | \
- ((SwizzleZ) << 4) | \
- ((SwizzleW) << 6) \
-)
-
-/* Possible swizzle values. */
-typedef enum _gcSL_SWIZZLE
-{
- gcSL_SWIZZLE_X, /* 0x0 */
- gcSL_SWIZZLE_Y, /* 0x1 */
- gcSL_SWIZZLE_Z, /* 0x2 */
- gcSL_SWIZZLE_W, /* 0x3 */
- /* Combinations. */
- gcSL_SWIZZLE_XXXX = gcmSWIZZLE(X, X, X, X),
- gcSL_SWIZZLE_YYYY = gcmSWIZZLE(Y, Y, Y, Y),
- gcSL_SWIZZLE_ZZZZ = gcmSWIZZLE(Z, Z, Z, Z),
- gcSL_SWIZZLE_WWWW = gcmSWIZZLE(W, W, W, W),
- gcSL_SWIZZLE_XYYY = gcmSWIZZLE(X, Y, Y, Y),
- gcSL_SWIZZLE_XZZZ = gcmSWIZZLE(X, Z, Z, Z),
- gcSL_SWIZZLE_XWWW = gcmSWIZZLE(X, W, W, W),
- gcSL_SWIZZLE_YZZZ = gcmSWIZZLE(Y, Z, Z, Z),
- gcSL_SWIZZLE_YWWW = gcmSWIZZLE(Y, W, W, W),
- gcSL_SWIZZLE_ZWWW = gcmSWIZZLE(Z, W, W, W),
- gcSL_SWIZZLE_XYZZ = gcmSWIZZLE(X, Y, Z, Z),
- gcSL_SWIZZLE_XYWW = gcmSWIZZLE(X, Y, W, W),
- gcSL_SWIZZLE_XZWW = gcmSWIZZLE(X, Z, W, W),
- gcSL_SWIZZLE_YZWW = gcmSWIZZLE(Y, Z, W, W),
- gcSL_SWIZZLE_XXYZ = gcmSWIZZLE(X, X, Y, Z),
- gcSL_SWIZZLE_XYZW = gcmSWIZZLE(X, Y, Z, W),
- gcSL_SWIZZLE_XYXY = gcmSWIZZLE(X, Y, X, Y),
- gcSL_SWIZZLE_YYZZ = gcmSWIZZLE(Y, Y, Z, Z),
- gcSL_SWIZZLE_YYWW = gcmSWIZZLE(Y, Y, W, W),
- gcSL_SWIZZLE_ZZZW = gcmSWIZZLE(Z, Z, Z, W),
- gcSL_SWIZZLE_XZZW = gcmSWIZZLE(X, Z, Z, W),
- gcSL_SWIZZLE_YYZW = gcmSWIZZLE(Y, Y, Z, W),
-
- gcSL_SWIZZLE_INVALID = 0x7FFFFFFF
-}
-gcSL_SWIZZLE;
-
-typedef enum _gcSL_COMPONENT
-{
- gcSL_COMPONENT_X, /* 0x0 */
- gcSL_COMPONENT_Y, /* 0x1 */
- gcSL_COMPONENT_Z, /* 0x2 */
- gcSL_COMPONENT_W, /* 0x3 */
- gcSL_COMPONENT_COUNT /* 0x4 */
-} gcSL_COMPONENT;
-
-#define gcmIsComponentEnabled(Enable, Component) (((Enable) & (1 << (Component))) != 0)
-
-/******************************************************************************\
-|*********************************** SHADERS **********************************|
-\******************************************************************************/
-
-/* Shader types. */
-typedef enum _gcSHADER_KIND {
- gcSHADER_TYPE_UNKNOWN = 0,
- gcSHADER_TYPE_VERTEX,
- gcSHADER_TYPE_FRAGMENT,
- gcSHADER_TYPE_CL,
- gcSHADER_TYPE_PRECOMPILED,
- gcSHADER_KIND_COUNT
-} gcSHADER_KIND;
-
-typedef enum _gcGL_DRIVER_VERSION {
- gcGL_DRIVER_ES11, /* OpenGL ES 1.1 */
- gcGL_DRIVER_ES20, /* OpenGL ES 2.0 */
- gcGL_DRIVER_ES30 /* OpenGL ES 3.0 */
-} gcGL_DRIVER_VERSION;
-
-/* gcSHADER objects. */
-typedef struct _gcSHADER * gcSHADER;
-typedef struct _gcATTRIBUTE * gcATTRIBUTE;
-typedef struct _gcUNIFORM * gcUNIFORM;
-typedef struct _gcOUTPUT * gcOUTPUT;
-typedef struct _gcsFUNCTION * gcFUNCTION;
-typedef struct _gcsKERNEL_FUNCTION * gcKERNEL_FUNCTION;
-typedef struct _gcsHINT * gcsHINT_PTR;
-typedef struct _gcSHADER_PROFILER * gcSHADER_PROFILER;
-typedef struct _gcVARIABLE * gcVARIABLE;
-
-struct _gcsHINT
-{
- /* Numbr of data transfers for Vertex Shader output. */
- gctUINT32 vsOutputCount;
-
- /* Flag whether the VS has point size or not. */
- gctBOOL vsHasPointSize;
-
-#if gcdUSE_WCLIP_PATCH
- /* Flag whether the VS gl_position.z depends on gl_position.w
- it's a hint for wclipping */
- gctBOOL vsPositionZDependsOnW;
-#endif
-
- gctBOOL clipW;
-
- /* Flag whether or not the shader has a KILL instruction. */
- gctBOOL hasKill;
-
- /* Element count. */
- gctUINT32 elementCount;
-
- /* Component count. */
- gctUINT32 componentCount;
-
- /* Number of data transfers for Fragment Shader input. */
- gctUINT32 fsInputCount;
-
- /* Maximum number of temporary registers used in FS. */
- gctUINT32 fsMaxTemp;
-
- /* Maximum number of temporary registers used in VS. */
- gctUINT32 vsMaxTemp;
-
- /* Balance minimum. */
- gctUINT32 balanceMin;
-
- /* Balance maximum. */
- gctUINT32 balanceMax;
-
- /* Auto-shift balancing. */
- gctBOOL autoShift;
-
- /* Flag whether the PS outputs the depth value or not. */
- gctBOOL psHasFragDepthOut;
-
- /* Flag whether the ThreadWalker is in PS. */
- gctBOOL threadWalkerInPS;
-
- /* HW reg number for position of VS */
- gctUINT32 hwRegNoOfSIVPos;
-
-#if gcdALPHA_KILL_IN_SHADER
- /* States to set when alpha kill is enabled. */
- gctUINT32 killStateAddress;
- gctUINT32 alphaKillStateValue;
- gctUINT32 colorKillStateValue;
-
- /* Shader instructiuon. */
- gctUINT32 killInstructionAddress;
- gctUINT32 alphaKillInstruction[3];
- gctUINT32 colorKillInstruction[3];
-#endif
-
-#if TEMP_SHADER_PATCH
- gctUINT32 pachedShaderIdentifier;
-#endif
-};
-
-#if TEMP_SHADER_PATCH
-#define INVALID_SHADER_IDENTIFIER 0xFFFFFFFF
-#endif
-
-/* gcSHADER_TYPE enumeration. */
-typedef enum _gcSHADER_TYPE
-{
- gcSHADER_FLOAT_X1 = 0, /* 0x00 */
- gcSHADER_FLOAT_X2, /* 0x01 */
- gcSHADER_FLOAT_X3, /* 0x02 */
- gcSHADER_FLOAT_X4, /* 0x03 */
- gcSHADER_FLOAT_2X2, /* 0x04 */
- gcSHADER_FLOAT_3X3, /* 0x05 */
- gcSHADER_FLOAT_4X4, /* 0x06 */
- gcSHADER_BOOLEAN_X1, /* 0x07 */
- gcSHADER_BOOLEAN_X2, /* 0x08 */
- gcSHADER_BOOLEAN_X3, /* 0x09 */
- gcSHADER_BOOLEAN_X4, /* 0x0A */
- gcSHADER_INTEGER_X1, /* 0x0B */
- gcSHADER_INTEGER_X2, /* 0x0C */
- gcSHADER_INTEGER_X3, /* 0x0D */
- gcSHADER_INTEGER_X4, /* 0x0E */
- gcSHADER_SAMPLER_1D, /* 0x0F */
- gcSHADER_SAMPLER_2D, /* 0x10 */
- gcSHADER_SAMPLER_3D, /* 0x11 */
- gcSHADER_SAMPLER_CUBIC, /* 0x12 */
- gcSHADER_FIXED_X1, /* 0x13 */
- gcSHADER_FIXED_X2, /* 0x14 */
- gcSHADER_FIXED_X3, /* 0x15 */
- gcSHADER_FIXED_X4, /* 0x16 */
- gcSHADER_IMAGE_2D, /* 0x17 */ /* For OCL. */
- gcSHADER_IMAGE_3D, /* 0x18 */ /* For OCL. */
- gcSHADER_SAMPLER, /* 0x19 */ /* For OCL. */
- gcSHADER_FLOAT_2X3, /* 0x1A */
- gcSHADER_FLOAT_2X4, /* 0x1B */
- gcSHADER_FLOAT_3X2, /* 0x1C */
- gcSHADER_FLOAT_3X4, /* 0x1D */
- gcSHADER_FLOAT_4X2, /* 0x1E */
- gcSHADER_FLOAT_4X3, /* 0x1F */
- gcSHADER_ISAMPLER_2D, /* 0x20 */
- gcSHADER_ISAMPLER_3D, /* 0x21 */
- gcSHADER_ISAMPLER_CUBIC, /* 0x22 */
- gcSHADER_USAMPLER_2D, /* 0x23 */
- gcSHADER_USAMPLER_3D, /* 0x24 */
- gcSHADER_USAMPLER_CUBIC, /* 0x25 */
- gcSHADER_SAMPLER_EXTERNAL_OES, /* 0x26 */
-
- gcSHADER_UINT_X1, /* 0x27 */
- gcSHADER_UINT_X2, /* 0x28 */
- gcSHADER_UINT_X3, /* 0x29 */
- gcSHADER_UINT_X4, /* 0x2A */
-
- gcSHADER_UNKONWN_TYPE, /* do not add type after this */
- gcSHADER_TYPE_COUNT /* must to change gcvShaderTypeInfo at the
- * same time if you add any new type! */}
-gcSHADER_TYPE;
-
-typedef enum _gcSHADER_TYPE_KIND
-{
- gceTK_UNKOWN,
- gceTK_FLOAT,
- gceTK_INT,
- gceTK_UINT,
- gceTK_BOOL,
- gceTK_FIXED,
- gceTK_SAMPLER,
- gceTK_IMAGE,
- gceTK_OTHER
-} gcSHADER_TYPE_KIND;
-
-typedef struct _gcSHADER_TYPEINFO
-{
- gcSHADER_TYPE type; /* e.g. gcSHADER_FLOAT_2X4 */
- gctINT components; /* e.g. 4 components */
- gctINT rows; /* e.g. 2 rows */
- gcSHADER_TYPE componentType; /* e.g. gcSHADER_FLOAT_X4 */
- gcSHADER_TYPE_KIND kind; /* e.g. gceTK_FLOAT */
- gctCONST_STRING name; /* e.g. "FLOAT_2X4" */
-} gcSHADER_TYPEINFO;
-
-extern gcSHADER_TYPEINFO gcvShaderTypeInfo[];
-
-#define gcmType_Comonents(Type) (gcvShaderTypeInfo[Type].components)
-#define gcmType_Rows(Type) (gcvShaderTypeInfo[Type].rows)
-#define gcmType_ComonentType(Type) (gcvShaderTypeInfo[Type].componentType)
-#define gcmType_Kind(Type) (gcvShaderTypeInfo[Type].kind)
-#define gcmType_Name(Type) (gcvShaderTypeInfo[Type].name)
-
-#define gcmType_isMatrix(type) (gcmType_Rows(type) > 1)
-
-typedef enum _gcSHADER_VAR_CATEGORY
-{
- gcSHADER_VAR_CATEGORY_NORMAL = 0, /* primitive type and its array */
- gcSHADER_VAR_CATEGORY_STRUCT = 1 /* structure */
-}
-gcSHADER_VAR_CATEGORY;
-
-typedef enum _gceTYPE_QUALIFIER
-{
- gcvTYPE_QUALIFIER_NONE = 0x0, /* unqualified */
- gcvTYPE_QUALIFIER_VOLATILE = 0x1, /* volatile */
-}gceTYPE_QUALIFIER;
-
-typedef gctUINT16 gctTYPE_QUALIFIER;
-
-#if GC_ENABLE_LOADTIME_OPT
-typedef struct _gcSHADER_TYPE_INFO
-{
- gcSHADER_TYPE type; /* eg. gcSHADER_FLOAT_2X3 is the type */
- gctCONST_STRING name; /* the name of the type: "gcSHADER_FLOAT_2X3" */
- gcSHADER_TYPE baseType; /* its base type is gcSHADER_FLOAT_2 */
- gctINT components; /* it has 2 components */
- gctINT rows; /* and 3 rows */
- gctINT size; /* the size in byte */
-} gcSHADER_TYPE_INFO;
-
-extern gcSHADER_TYPE_INFO shader_type_info[];
-
-enum gceLTCDumpOption {
- gceLTC_DUMP_UNIFORM = 0x0001,
- gceLTC_DUMP_EVALUATION = 0x0002,
- gceLTC_DUMP_EXPESSION = 0x0004,
- gceLTC_DUMP_COLLECTING = 0x0008,
-};
-
-gctBOOL gcDumpOption(gctINT Opt);
-
-#endif /* GC_ENABLE_LOADTIME_OPT */
-
-#define IS_MATRIX_TYPE(type) \
- (((type >= gcSHADER_FLOAT_2X2) && (type <= gcSHADER_FLOAT_4X4)) || \
- ((type >= gcSHADER_FLOAT_2X3) && (type <= gcSHADER_FLOAT_4X3)))
-
-/* gcSHADER_PRECISION enumeration. */
-typedef enum _gcSHADER_PRECISION
-{
- gcSHADER_PRECISION_DEFAULT, /* 0x00 */
- gcSHADER_PRECISION_HIGH, /* 0x01 */
- gcSHADER_PRECISION_MEDIUM, /* 0x02 */
- gcSHADER_PRECISION_LOW, /* 0x03 */
-}
-gcSHADER_PRECISION;
-
-/* Shader flags. */
-typedef enum _gceSHADER_FLAGS
-{
- gcvSHADER_NO_OPTIMIZATION = 0x00,
- gcvSHADER_DEAD_CODE = 0x01,
- gcvSHADER_RESOURCE_USAGE = 0x02,
- gcvSHADER_OPTIMIZER = 0x04,
- gcvSHADER_USE_GL_Z = 0x08,
- /*
- The GC family of GPU cores model GC860 and under require the Z
- to be from 0 <= z <= w.
- However, OpenGL specifies the Z to be from -w <= z <= w. So we
- have to a conversion here:
-
- z = (z + w) / 2.
-
- So here we append two instructions to the vertex shader.
- */
- gcvSHADER_USE_GL_POSITION = 0x10,
- gcvSHADER_USE_GL_FACE = 0x20,
- gcvSHADER_USE_GL_POINT_COORD = 0x40,
- gcvSHADER_LOADTIME_OPTIMIZER = 0x80,
-#if gcdALPHA_KILL_IN_SHADER
- gcvSHADER_USE_ALPHA_KILL = 0x100,
-#endif
-
-#if gcdPRE_ROTATION && (ANDROID_SDK_VERSION >= 14)
- gcvSHADER_VS_PRE_ROTATION = 0x200,
-#endif
-
-#if TEMP_INLINE_ALL_EXPANSION
- gcvSHADER_INLINE_ALL_EXPANSION = 0x400,
-#endif
-}
-gceSHADER_FLAGS;
-
-gceSTATUS
-gcSHADER_CheckClipW(
- IN gctCONST_STRING VertexSource,
- IN gctCONST_STRING FragmentSource,
- OUT gctBOOL * clipW);
-
-/*******************************************************************************
-** gcSHADER_GetUniformVectorCount
-**
-** Get the number of vectors used by uniforms for this shader.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** OUTPUT:
-**
-** gctSIZE_T * Count
-** Pointer to a variable receiving the number of vectors.
-*/
-gceSTATUS
-gcSHADER_GetUniformVectorCount(
- IN gcSHADER Shader,
- OUT gctSIZE_T * Count
- );
-
-/*******************************************************************************
-** gcOptimizer Data Structures
-*******************************************************************************/
-typedef enum _gceSHADER_OPTIMIZATION
-{
- /* No optimization. */
- gcvOPTIMIZATION_NONE,
-
- /* Flow graph construction. */
- gcvOPTIMIZATION_CONSTRUCTION = 1 << 0,
-
- /* Dead code elimination. */
- gcvOPTIMIZATION_DEAD_CODE = 1 << 1,
-
- /* Redundant move instruction elimination. */
- gcvOPTIMIZATION_REDUNDANT_MOVE = 1 << 2,
-
- /* Inline expansion. */
- gcvOPTIMIZATION_INLINE_EXPANSION = 1 << 3,
-
- /* Constant propagation. */
- gcvOPTIMIZATION_CONSTANT_PROPAGATION = 1 << 4,
-
- /* Redundant bounds/checking elimination. */
- gcvOPTIMIZATION_REDUNDANT_CHECKING = 1 << 5,
-
- /* Loop invariant movement. */
- gcvOPTIMIZATION_LOOP_INVARIANT = 1 << 6,
-
- /* Induction variable removal. */
- gcvOPTIMIZATION_INDUCTION_VARIABLE = 1 << 7,
-
- /* Common subexpression elimination. */
- gcvOPTIMIZATION_COMMON_SUBEXPRESSION = 1 << 8,
-
- /* Control flow/banch optimization. */
- gcvOPTIMIZATION_CONTROL_FLOW = 1 << 9,
-
- /* Vector component operation merge. */
- gcvOPTIMIZATION_VECTOR_INSTRUCTION_MERGE = 1 << 10,
-
- /* Algebra simplificaton. */
- gcvOPTIMIZATION_ALGEBRAIC_SIMPLIFICATION = 1 << 11,
-
- /* Pattern matching and replacing. */
- gcvOPTIMIZATION_PATTERN_MATCHING = 1 << 12,
-
- /* Interprocedural constant propagation. */
- gcvOPTIMIZATION_IP_CONSTANT_PROPAGATION = 1 << 13,
-
- /* Interprecedural register optimization. */
- gcvOPTIMIZATION_IP_REGISTRATION = 1 << 14,
-
- /* Optimization option number. */
- gcvOPTIMIZATION_OPTION_NUMBER = 1 << 15,
-
- /* Loadtime constant. */
- gcvOPTIMIZATION_LOADTIME_CONSTANT = 1 << 16,
-
- /* MAD instruction optimization. */
- gcvOPTIMIZATION_MAD_INSTRUCTION = 1 << 17,
-
- /* Special optimization for LOAD SW workaround. */
- gcvOPTIMIZATION_LOAD_SW_WORKAROUND = 1 << 18,
-
- /* move code into conditional block if possile */
- gcvOPTIMIZATION_CONDITIONALIZE = 1 << 19,
-
- /* expriemental: power optimization mode
- 1. add extra dummy texld to tune performance
- 2. insert NOP after high power instrucitons
- 3. split high power vec3/vec4 instruciton to vec2/vec1 operation
- 4. ...
- */
- gcvOPTIMIZATION_POWER_OPTIMIZATION = 1 << 20,
-
- /* optimize varying packing */
- gcvOPTIMIZATION_VARYINGPACKING = 1 << 22,
-
-#if TEMP_INLINE_ALL_EXPANSION
- gcvOPTIMIZATION_INLINE_ALL_EXPANSION = 1 << 23,
-#endif
-
- /* Full optimization. */
- /* Note that gcvOPTIMIZATION_LOAD_SW_WORKAROUND is off. */
- gcvOPTIMIZATION_FULL = 0x7FFFFFFF &
- ~gcvOPTIMIZATION_LOAD_SW_WORKAROUND &
- ~gcvOPTIMIZATION_INLINE_ALL_EXPANSION &
- ~gcvOPTIMIZATION_POWER_OPTIMIZATION,
-
- /* Optimization Unit Test flag. */
- gcvOPTIMIZATION_UNIT_TEST = 1 << 31
-}
-gceSHADER_OPTIMIZATION;
-
-typedef enum _gceOPTIMIZATION_VaryingPaking
-{
- gcvOPTIMIZATION_VARYINGPACKING_NONE = 0,
- gcvOPTIMIZATION_VARYINGPACKING_NOSPLIT,
- gcvOPTIMIZATION_VARYINGPACKING_SPLIT
-} gceOPTIMIZATION_VaryingPaking;
-
-typedef struct _gcOPTIMIZER_OPTION
-{
- gceSHADER_OPTIMIZATION optFlags;
-
- /* debug & dump options:
-
- VC_OPTION=-DUMP:SRC:OPT|:OPTV|:CG|:CGV:|ALL|ALLV
-
- SRC: dump shader source code
- OPT: dump incoming and final IR
- OPTV: dump result IR in each optimization phase
- CG: dump generated machine code
- CGV: dump BE tree and optimization detail
-
- ALL = SRC|OPT|CG
- ALLV = SRC|OPT|OPTV|CG|CGV
- */
- gctBOOL dumpShaderSource; /* dump shader source code */
- gctBOOL dumpOptimizer; /* dump incoming and final IR */
- gctBOOL dumpOptimizerVerbose; /* dump result IR in each optimization phase */
- gctBOOL dumpBEGenertedCode; /* dump generated machine code */
- gctBOOL dumpBEVerbose; /* dump BE tree and optimization detail */
- gctBOOL dumpBEFinalIR; /* dump BE final IR */
-
- /* Code generation */
-
- /* Varying Packing:
-
- VC_OPTION=-PACKVARYING:[0-2]|:T[-]m[,n]|:LshaderIdx,min,max
-
- 0: turn off varying packing
- 1: pack varyings, donot split any varying
- 2: pack varyings, may split to make fully packed output
-
- Tm: only packing shader pair which vertex shader id is m
- Tm,n: only packing shader pair which vertex shader id
- is in range of [m, n]
- T-m: do not packing shader pair which vertex shader id is m
- T-m,n: do not packing shader pair which vertex shader id
- is in range of [m, n]
-
- LshaderIdx,min,max : set load balance (min, max) for shaderIdx
- if shaderIdx is -1, all shaders are impacted
- newMin = origMin * (min/100.);
- newMax = origMax * (max/100.);
- */
- gceOPTIMIZATION_VaryingPaking packVarying;
- gctINT _triageStart;
- gctINT _triageEnd;
- gctINT _loadBalanceShaderIdx;
- gctINT _loadBalanceMin;
- gctINT _loadBalanceMax;
-
- /* Do not generate immdeiate
-
- VC_OPTION=-NOIMM
-
- Force generate immediate even the machine model don't support it,
- for testing purpose only
-
- VC_OPTION=-FORCEIMM
- */
- gctBOOL noImmediate;
- gctBOOL forceImmediate;
-
- /* Power reduction mode options */
- gctBOOL needPowerOptimization;
-
- /* Patch TEXLD instruction by adding dummy texld
- (can be used to tune GPU power usage):
- for every TEXLD we seen, add n dummy TEXLD
-
- it can be enabled by environment variable:
-
- VC_OPTION=-PATCH_TEXLD:M:N
-
- (for each M texld, add N dummy texld)
- */
- gctINT patchEveryTEXLDs;
- gctINT patchDummyTEXLDs;
-
- /* Insert NOP after high power consumption instructions
-
- VC_OPTION="-INSERTNOP:MUL:MULLO:DP3:DP4:SEENTEXLD"
- */
- gctBOOL insertNOP;
- gctBOOL insertNOPAfterMUL;
- gctBOOL insertNOPAfterMULLO;
- gctBOOL insertNOPAfterDP3;
- gctBOOL insertNOPAfterDP4;
- gctBOOL insertNOPOnlyWhenTexldSeen;
-
- /* split MAD to MUL and ADD:
-
- VC_OPTION=-SPLITMAD
- */
- gctBOOL splitMAD;
-
- /* Convert vect3/vec4 operations to multiple vec2/vec1 operations
-
- VC_OPTION=-SPLITVEC:MUL:MULLO:DP3:DP4
- */
- gctBOOL splitVec;
- gctBOOL splitVec4MUL;
- gctBOOL splitVec4MULLO;
- gctBOOL splitVec4DP3;
- gctBOOL splitVec4DP4;
-
- /* turn/off features:
-
- VC_OPTION=-F:n,[0|1]
- Note: n must be decimal number
- */
- gctUINT featureBits;
-
- /* inline level (default 2 at O1):
-
- VC_OPTION=-INLINELEVEL:[0-3]
- 0: no inline
- 1: only inline the function only called once or small function
- 2: inline functions be called less than 5 times or medium size function
- 3: inline everything possible
- */
- gctUINT inlineLevel;
-} gcOPTIMIZER_OPTION;
-
-extern gcOPTIMIZER_OPTION theOptimizerOption;
-#define gcmGetOptimizerOption() gcGetOptimizerOption()
-
-#define gcmOPT_DUMP_SHADER_SRC() \
- (gcmGetOptimizerOption()->dumpShaderSource != 0)
-#define gcmOPT_DUMP_OPTIMIZER() \
- (gcmGetOptimizerOption()->dumpOptimizer != 0 || \
- gcmOPT_DUMP_OPTIMIZER_VERBOSE() )
-#define gcmOPT_DUMP_OPTIMIZER_VERBOSE() \
- (gcmGetOptimizerOption()->dumpOptimizerVerbose != 0)
-#define gcmOPT_DUMP_CODEGEN() \
- (gcmGetOptimizerOption()->dumpBEGenertedCode != 0 || \
- gcmOPT_DUMP_CODEGEN_VERBOSE() )
-#define gcmOPT_DUMP_CODEGEN_VERBOSE() \
- (gcmGetOptimizerOption()->dumpBEVerbose != 0)
-#define gcmOPT_DUMP_FINAL_IR() \
- (gcmGetOptimizerOption()->dumpBEFinalIR != 0)
-
-#define gcmOPT_SET_DUMP_SHADER_SRC(v) \
- gcmGetOptimizerOption()->dumpShaderSource = (v)
-
-#define gcmOPT_PATCH_TEXLD() (gcmGetOptimizerOption()->patchDummyTEXLDs != 0)
-#define gcmOPT_INSERT_NOP() (gcmGetOptimizerOption()->insertNOP == gcvTRUE)
-#define gcmOPT_SPLITMAD() (gcmGetOptimizerOption()->splitMAD == gcvTRUE)
-#define gcmOPT_SPLITVEC() (gcmGetOptimizerOption()->splitVec == gcvTRUE)
-
-#define gcmOPT_NOIMMEDIATE() (gcmGetOptimizerOption()->noImmediate == gcvTRUE)
-#define gcmOPT_FORCEIMMEDIATE() (gcmGetOptimizerOption()->forceImmediate == gcvTRUE)
-
-#define gcmOPT_PACKVARYING() (gcmGetOptimizerOption()->packVarying)
-#define gcmOPT_PACKVARYING_triageStart() (gcmGetOptimizerOption()->_triageStart)
-#define gcmOPT_PACKVARYING_triageEnd() (gcmGetOptimizerOption()->_triageEnd)
-
-#define gcmOPT_INLINELEVEL() (gcmGetOptimizerOption()->inlineLevel)
-
-/* Setters */
-#define gcmOPT_SetPatchTexld(m,n) (gcmGetOptimizerOption()->patchEveryTEXLDs = (m),\
- gcmGetOptimizerOption()->patchDummyTEXLDs = (n))
-#define gcmOPT_SetSplitVecMUL() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \
- gcmGetOptimizerOption()->splitVec4MUL = gcvTRUE)
-#define gcmOPT_SetSplitVecMULLO() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \
- gcmGetOptimizerOption()->splitVec4MULLO = gcvTRUE)
-#define gcmOPT_SetSplitVecDP3() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \
- gcmGetOptimizerOption()->splitVec4DP3 = gcvTRUE)
-#define gcmOPT_SetSplitVecDP4() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \
- gcmGetOptimizerOption()->splitVec4DP4 = gcvTRUE)
-
-#define gcmOPT_SetPackVarying(v) (gcmGetOptimizerOption()->packVarying = v)
-
-#define FB_LIVERANGE_FIX1 0x0001
-
-
-#define PredefinedDummySamplerId 8
-
-/* Function argument qualifier */
-typedef enum _gceINPUT_OUTPUT
-{
- gcvFUNCTION_INPUT,
- gcvFUNCTION_OUTPUT,
- gcvFUNCTION_INOUT
-}
-gceINPUT_OUTPUT;
-
-/* Kernel function property flags. */
-typedef enum _gcePROPERTY_FLAGS
-{
- gcvPROPERTY_REQD_WORK_GRP_SIZE = 0x01
-}
-gceKERNEL_FUNCTION_PROPERTY_FLAGS;
-
-/* Uniform flags. */
-typedef enum _gceUNIFORM_FLAGS
-{
- gcvUNIFORM_KERNEL_ARG = 0x01,
- gcvUNIFORM_KERNEL_ARG_LOCAL = 0x02,
- gcvUNIFORM_KERNEL_ARG_SAMPLER = 0x04,
- gcvUNIFORM_LOCAL_ADDRESS_SPACE = 0x08,
- gcvUNIFORM_PRIVATE_ADDRESS_SPACE = 0x10,
- gcvUNIFORM_CONSTANT_ADDRESS_SPACE = 0x20,
- gcvUNIFORM_GLOBAL_SIZE = 0x40,
- gcvUNIFORM_LOCAL_SIZE = 0x80,
- gcvUNIFORM_NUM_GROUPS = 0x100,
- gcvUNIFORM_GLOBAL_OFFSET = 0x200,
- gcvUNIFORM_WORK_DIM = 0x400,
- gcvUNIFORM_KERNEL_ARG_CONSTANT = 0x800,
- gcvUNIFORM_KERNEL_ARG_LOCAL_MEM_SIZE = 0x1000,
- gcvUNIFORM_KERNEL_ARG_PRIVATE = 0x2000,
- gcvUNIFORM_LOADTIME_CONSTANT = 0x4000,
- gcvUNIFORM_IS_ARRAY = 0x8000,
-}
-gceUNIFORM_FLAGS;
-
-#define gcdUNIFORM_KERNEL_ARG_MASK (gcvUNIFORM_KERNEL_ARG | \
- gcvUNIFORM_KERNEL_ARG_LOCAL | \
- gcvUNIFORM_KERNEL_ARG_SAMPLER | \
- gcvUNIFORM_KERNEL_ARG_PRIVATE | \
- gcvUNIFORM_KERNEL_ARG_CONSTANT)
-
-typedef enum _gceVARIABLE_UPDATE_FLAGS
-{
- gcvVARIABLE_UPDATE_NOUPDATE = 0,
- gcvVARIABLE_UPDATE_TEMPREG,
- gcvVARIABLE_UPDATE_TYPE_QUALIFIER,
-}gceVARIABLE_UPDATE_FLAGS;
-
-typedef struct _gcMACHINE_INST
-{
- gctUINT state0;
- gctUINT state1;
- gctUINT state2;
- gctUINT state3;
-}gcMACHINE_INST, *gcMACHINE_INST_PTR;
-
-typedef struct _gcMACHINECODE
-{
- gcMACHINE_INST_PTR pCode; /* machine code */
- gctUINT instCount; /* 128-bit count */
- gctUINT maxConstRegNo;
- gctUINT maxTempRegNo;
- gctUINT endPCOfMainRoutine;
-}gcMACHINECODE, *gcMACHINECODE_PTR;
-
-typedef enum NP2_ADDRESS_MODE
-{
- NP2_ADDRESS_MODE_CLAMP = 0,
- NP2_ADDRESS_MODE_REPEAT = 1,
- NP2_ADDRESS_MODE_MIRROR = 2
-}NP2_ADDRESS_MODE;
-
-typedef struct _gcNPOT_PATCH_PARAM
-{
- gctINT samplerSlot;
- NP2_ADDRESS_MODE addressMode[3];
- gctINT texDimension; /* 2 or 3 */
-}gcNPOT_PATCH_PARAM, *gcNPOT_PATCH_PARAM_PTR;
-
-typedef struct _gcZBIAS_PATCH_PARAM
-{
- /* Driver uses this to program uniform that designating zbias */
- gctINT uniformAddr;
- gctINT channel;
-}gcZBIAS_PATCH_PARAM, *gcZBIAS_PATCH_PARAM_PTR;
-
-void
-gcGetOptionFromEnv(
- IN OUT gcOPTIMIZER_OPTION * Option
- );
-
-void
-gcSetOptimizerOption(
- IN gceSHADER_FLAGS Flags
- );
-
-gcOPTIMIZER_OPTION *
-gcGetOptimizerOption();
-
-/*******************************************************************************
-** gcSHADER_SetCompilerVersion
-**
-** Set the compiler version of a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to gcSHADER object
-**
-** gctINT *Version
-** Pointer to a two word version
-*/
-gceSTATUS
-gcSHADER_SetCompilerVersion(
- IN gcSHADER Shader,
- IN gctUINT32 *Version
- );
-
-/*******************************************************************************
-** gcSHADER_GetCompilerVersion
-**
-** Get the compiler version of a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** OUTPUT:
-**
-** gctUINT32_PTR *CompilerVersion.
-** Pointer to holder of returned compilerVersion pointer
-*/
-gceSTATUS
-gcSHADER_GetCompilerVersion(
- IN gcSHADER Shader,
- OUT gctUINT32_PTR *CompilerVersion
- );
-
-/*******************************************************************************
-** gcSHADER_GetType
-**
-** Get the gcSHADER object's type.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** OUTPUT:
-**
-** gctINT *Type.
-** Pointer to return shader type.
-*/
-gceSTATUS
-gcSHADER_GetType(
- IN gcSHADER Shader,
- OUT gctINT *Type
- );
-
-gctUINT
-gcSHADER_NextId();
-/*******************************************************************************
-** gcSHADER_Construct
-********************************************************************************
-**
-** Construct a new gcSHADER object.
-**
-** INPUT:
-**
-** gcoOS Hal
-** Pointer to an gcoHAL object.
-**
-** gctINT ShaderType
-** Type of gcSHADER object to cerate. 'ShaderType' can be one of the
-** following:
-**
-** gcSHADER_TYPE_VERTEX Vertex shader.
-** gcSHADER_TYPE_FRAGMENT Fragment shader.
-**
-** OUTPUT:
-**
-** gcSHADER * Shader
-** Pointer to a variable receiving the gcSHADER object pointer.
-*/
-gceSTATUS
-gcSHADER_Construct(
- IN gcoHAL Hal,
- IN gctINT ShaderType,
- OUT gcSHADER * Shader
- );
-
-/*******************************************************************************
-** gcSHADER_Destroy
-********************************************************************************
-**
-** Destroy a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_Destroy(
- IN gcSHADER Shader
- );
-
-/*******************************************************************************
-** gcSHADER_Copy
-********************************************************************************
-**
-** Copy a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gcSHADER Source
-** Pointer to a gcSHADER object that will be copied.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_Copy(
- IN gcSHADER Shader,
- IN gcSHADER Source
- );
-
-/*******************************************************************************
-** gcSHADER_LoadHeader
-**
-** Load a gcSHADER object from a binary buffer. The binary buffer is layed out
-** as follows:
-** // Six word header
-** // Signature, must be 'S','H','D','R'.
-** gctINT8 signature[4];
-** gctUINT32 binFileVersion;
-** gctUINT32 compilerVersion[2];
-** gctUINT32 gcSLVersion;
-** gctUINT32 binarySize;
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-** Shader type will be returned if type in shader object is not gcSHADER_TYPE_PRECOMPILED
-**
-** gctPOINTER Buffer
-** Pointer to a binary buffer containing the shader data to load.
-**
-** gctSIZE_T BufferSize
-** Number of bytes inside the binary buffer pointed to by 'Buffer'.
-**
-** OUTPUT:
-** nothing
-**
-*/
-gceSTATUS
-gcSHADER_LoadHeader(
- IN gcSHADER Shader,
- IN gctPOINTER Buffer,
- IN gctSIZE_T BufferSize,
- OUT gctUINT32 * ShaderVersion
- );
-
-/*******************************************************************************
-** gcSHADER_LoadKernel
-**
-** Load a kernel function given by name into gcSHADER object
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctSTRING KernelName
-** Pointer to a kernel function name
-**
-** OUTPUT:
-** nothing
-**
-*/
-gceSTATUS
-gcSHADER_LoadKernel(
- IN gcSHADER Shader,
- IN gctSTRING KernelName
- );
-
-/*******************************************************************************
-** gcSHADER_Load
-********************************************************************************
-**
-** Load a gcSHADER object from a binary buffer.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctPOINTER Buffer
-** Pointer to a binary buffer containg the shader data to load.
-**
-** gctSIZE_T BufferSize
-** Number of bytes inside the binary buffer pointed to by 'Buffer'.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_Load(
- IN gcSHADER Shader,
- IN gctPOINTER Buffer,
- IN gctSIZE_T BufferSize
- );
-
-/*******************************************************************************
-** gcSHADER_Save
-********************************************************************************
-**
-** Save a gcSHADER object to a binary buffer.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctPOINTER Buffer
-** Pointer to a binary buffer to be used as storage for the gcSHADER
-** object. If 'Buffer' is gcvNULL, the gcSHADER object will not be saved,
-** but the number of bytes required to hold the binary output for the
-** gcSHADER object will be returned.
-**
-** gctSIZE_T * BufferSize
-** Pointer to a variable holding the number of bytes allocated in
-** 'Buffer'. Only valid if 'Buffer' is not gcvNULL.
-**
-** OUTPUT:
-**
-** gctSIZE_T * BufferSize
-** Pointer to a variable receiving the number of bytes required to hold
-** the binary form of the gcSHADER object.
-*/
-gceSTATUS
-gcSHADER_Save(
- IN gcSHADER Shader,
- IN gctPOINTER Buffer,
- IN OUT gctSIZE_T * BufferSize
- );
-
-/*******************************************************************************
-** gcSHADER_LoadEx
-********************************************************************************
-**
-** Load a gcSHADER object from a binary buffer.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctPOINTER Buffer
-** Pointer to a binary buffer containg the shader data to load.
-**
-** gctSIZE_T BufferSize
-** Number of bytes inside the binary buffer pointed to by 'Buffer'.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_LoadEx(
- IN gcSHADER Shader,
- IN gctPOINTER Buffer,
- IN gctSIZE_T BufferSize
- );
-
-/*******************************************************************************
-** gcSHADER_SaveEx
-********************************************************************************
-**
-** Save a gcSHADER object to a binary buffer.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctPOINTER Buffer
-** Pointer to a binary buffer to be used as storage for the gcSHADER
-** object. If 'Buffer' is gcvNULL, the gcSHADER object will not be saved,
-** but the number of bytes required to hold the binary output for the
-** gcSHADER object will be returned.
-**
-** gctSIZE_T * BufferSize
-** Pointer to a variable holding the number of bytes allocated in
-** 'Buffer'. Only valid if 'Buffer' is not gcvNULL.
-**
-** OUTPUT:
-**
-** gctSIZE_T * BufferSize
-** Pointer to a variable receiving the number of bytes required to hold
-** the binary form of the gcSHADER object.
-*/
-gceSTATUS
-gcSHADER_SaveEx(
- IN gcSHADER Shader,
- IN gctPOINTER Buffer,
- IN OUT gctSIZE_T * BufferSize
- );
-
-/*******************************************************************************
-** gcSHADER_ReallocateAttributes
-**
-** Reallocate an array of pointers to gcATTRIBUTE objects.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctSIZE_T Count
-** Array count to reallocate. 'Count' must be at least 1.
-*/
-gceSTATUS
-gcSHADER_ReallocateAttributes(
- IN gcSHADER Shader,
- IN gctSIZE_T Count
- );
-
-/*******************************************************************************
-** gcSHADER_AddAttribute
-********************************************************************************
-**
-** Add an attribute to a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctCONST_STRING Name
-** Name of the attribute to add.
-**
-** gcSHADER_TYPE Type
-** Type of the attribute to add.
-**
-** gctSIZE_T Length
-** Array length of the attribute to add. 'Length' must be at least 1.
-**
-** gctBOOL IsTexture
-** gcvTRUE if the attribute is used as a texture coordinate, gcvFALSE if not.
-**
-** OUTPUT:
-**
-** gcATTRIBUTE * Attribute
-** Pointer to a variable receiving the gcATTRIBUTE object pointer.
-*/
-gceSTATUS
-gcSHADER_AddAttribute(
- IN gcSHADER Shader,
- IN gctCONST_STRING Name,
- IN gcSHADER_TYPE Type,
- IN gctSIZE_T Length,
- IN gctBOOL IsTexture,
- OUT gcATTRIBUTE * Attribute
- );
-
-/*******************************************************************************
-** gcSHADER_GetAttributeCount
-********************************************************************************
-**
-** Get the number of attributes for this shader.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** OUTPUT:
-**
-** gctSIZE_T * Count
-** Pointer to a variable receiving the number of attributes.
-*/
-gceSTATUS
-gcSHADER_GetAttributeCount(
- IN gcSHADER Shader,
- OUT gctSIZE_T * Count
- );
-
-/*******************************************************************************
-** gcSHADER_GetAttribute
-********************************************************************************
-**
-** Get the gcATTRIBUTE object poniter for an indexed attribute for this shader.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctUINT Index
-** Index of the attribute to retrieve.
-**
-** OUTPUT:
-**
-** gcATTRIBUTE * Attribute
-** Pointer to a variable receiving the gcATTRIBUTE object pointer.
-*/
-gceSTATUS
-gcSHADER_GetAttribute(
- IN gcSHADER Shader,
- IN gctUINT Index,
- OUT gcATTRIBUTE * Attribute
- );
-
-/*******************************************************************************
-** gcSHADER_ReallocateUniforms
-**
-** Reallocate an array of pointers to gcUNIFORM objects.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctSIZE_T Count
-** Array count to reallocate. 'Count' must be at least 1.
-*/
-gceSTATUS
-gcSHADER_ReallocateUniforms(
- IN gcSHADER Shader,
- IN gctSIZE_T Count
- );
-
-/*******************************************************************************
-** gcSHADER_AddUniform
-********************************************************************************
-**
-** Add an uniform to a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctCONST_STRING Name
-** Name of the uniform to add.
-**
-** gcSHADER_TYPE Type
-** Type of the uniform to add.
-**
-** gctSIZE_T Length
-** Array length of the uniform to add. 'Length' must be at least 1.
-**
-** OUTPUT:
-**
-** gcUNIFORM * Uniform
-** Pointer to a variable receiving the gcUNIFORM object pointer.
-*/
-gceSTATUS
-gcSHADER_AddUniform(
- IN gcSHADER Shader,
- IN gctCONST_STRING Name,
- IN gcSHADER_TYPE Type,
- IN gctSIZE_T Length,
- OUT gcUNIFORM * Uniform
- );
-
-/*******************************************************************************
-** gcSHADER_AddPreRotationUniform
-********************************************************************************
-**
-** Add an uniform to a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctCONST_STRING Name
-** Name of the uniform to add.
-**
-** gcSHADER_TYPE Type
-** Type of the uniform to add.
-**
-** gctSIZE_T Length
-** Array length of the uniform to add. 'Length' must be at least 1.
-**
-** gctINT col
-** Which uniform.
-**
-** OUTPUT:
-**
-** gcUNIFORM * Uniform
-** Pointer to a variable receiving the gcUNIFORM object pointer.
-*/
-gceSTATUS
-gcSHADER_AddPreRotationUniform(
- IN gcSHADER Shader,
- IN gctCONST_STRING Name,
- IN gcSHADER_TYPE Type,
- IN gctSIZE_T Length,
- IN gctINT col,
- OUT gcUNIFORM * Uniform
- );
-
-/*******************************************************************************
-** gcSHADER_AddUniformEx
-********************************************************************************
-**
-** Add an uniform to a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctCONST_STRING Name
-** Name of the uniform to add.
-**
-** gcSHADER_TYPE Type
-** Type of the uniform to add.
-**
-** gcSHADER_PRECISION precision
-** Precision of the uniform to add.
-**
-** gctSIZE_T Length
-** Array length of the uniform to add. 'Length' must be at least 1.
-**
-** OUTPUT:
-**
-** gcUNIFORM * Uniform
-** Pointer to a variable receiving the gcUNIFORM object pointer.
-*/
-gceSTATUS
-gcSHADER_AddUniformEx(
- IN gcSHADER Shader,
- IN gctCONST_STRING Name,
- IN gcSHADER_TYPE Type,
- IN gcSHADER_PRECISION precision,
- IN gctSIZE_T Length,
- OUT gcUNIFORM * Uniform
- );
-
-/*******************************************************************************
-** gcSHADER_AddUniformEx1
-********************************************************************************
-**
-** Add an uniform to a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctCONST_STRING Name
-** Name of the uniform to add.
-**
-** gcSHADER_TYPE Type
-** Type of the uniform to add.
-**
-** gcSHADER_PRECISION precision
-** Precision of the uniform to add.
-**
-** gctSIZE_T Length
-** Array length of the uniform to add. 'Length' must be at least 1.
-**
-** gcSHADER_VAR_CATEGORY varCategory
-** Variable category, normal or struct.
-**
-** gctUINT16 numStructureElement
-** If struct, its element number.
-**
-** gctINT16 parent
-** If struct, parent index in gcSHADER.variables.
-**
-** gctINT16 prevSibling
-** If struct, previous sibling index in gcSHADER.variables.
-**
-** OUTPUT:
-**
-** gcUNIFORM * Uniform
-** Pointer to a variable receiving the gcUNIFORM object pointer.
-**
-** gctINT16* ThisUniformIndex
-** Returned value about uniform index in gcSHADER.
-*/
-gceSTATUS
-gcSHADER_AddUniformEx1(
- IN gcSHADER Shader,
- IN gctCONST_STRING Name,
- IN gcSHADER_TYPE Type,
- IN gcSHADER_PRECISION precision,
- IN gctSIZE_T Length,
- IN gctINT IsArray,
- IN gcSHADER_VAR_CATEGORY varCategory,
- IN gctUINT16 numStructureElement,
- IN gctINT16 parent,
- IN gctINT16 prevSibling,
- OUT gctINT16* ThisUniformIndex,
- OUT gcUNIFORM * Uniform
- );
-
-/*******************************************************************************
-** gcSHADER_GetUniformCount
-********************************************************************************
-**
-** Get the number of uniforms for this shader.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** OUTPUT:
-**
-** gctSIZE_T * Count
-** Pointer to a variable receiving the number of uniforms.
-*/
-gceSTATUS
-gcSHADER_GetUniformCount(
- IN gcSHADER Shader,
- OUT gctSIZE_T * Count
- );
-
-/*******************************************************************************
-** gcSHADER_GetPreRotationUniform
-********************************************************************************
-**
-** Get the preRotate Uniform.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** OUTPUT:
-**
-** gcUNIFORM ** pUniform
-** Pointer to a preRotation uniforms array.
-*/
-gceSTATUS
-gcSHADER_GetPreRotationUniform(
- IN gcSHADER Shader,
- OUT gcUNIFORM ** pUniform
- );
-
-/*******************************************************************************
-** gcSHADER_GetUniform
-********************************************************************************
-**
-** Get the gcUNIFORM object pointer for an indexed uniform for this shader.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctUINT Index
-** Index of the uniform to retrieve.
-**
-** OUTPUT:
-**
-** gcUNIFORM * Uniform
-** Pointer to a variable receiving the gcUNIFORM object pointer.
-*/
-gceSTATUS
-gcSHADER_GetUniform(
- IN gcSHADER Shader,
- IN gctUINT Index,
- OUT gcUNIFORM * Uniform
- );
-
-
-/*******************************************************************************
-** gcSHADER_GetUniformIndexingRange
-********************************************************************************
-**
-** Get the gcUNIFORM object pointer for an indexed uniform for this shader.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctINT uniformIndex
-** Index of the start uniform.
-**
-** gctINT offset
-** Offset to indexing.
-**
-** OUTPUT:
-**
-** gctINT * LastUniformIndex
-** Pointer to index of last uniform in indexing range.
-**
-** gctINT * OffsetUniformIndex
-** Pointer to index of uniform that indexing at offset.
-**
-** gctINT * DeviationInOffsetUniform
-** Pointer to offset in uniform picked up.
-*/
-gceSTATUS
-gcSHADER_GetUniformIndexingRange(
- IN gcSHADER Shader,
- IN gctINT uniformIndex,
- IN gctINT offset,
- OUT gctINT * LastUniformIndex,
- OUT gctINT * OffsetUniformIndex,
- OUT gctINT * DeviationInOffsetUniform
- );
-
-/*******************************************************************************
-** gcSHADER_GetKernelFucntion
-**
-** Get the gcKERNEL_FUNCTION object pointer for an indexed kernel function for this shader.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctUINT Index
-** Index of kernel function to retreive the name for.
-**
-** OUTPUT:
-**
-** gcKERNEL_FUNCTION * KernelFunction
-** Pointer to a variable receiving the gcKERNEL_FUNCTION object pointer.
-*/
-gceSTATUS
-gcSHADER_GetKernelFunction(
- IN gcSHADER Shader,
- IN gctUINT Index,
- OUT gcKERNEL_FUNCTION * KernelFunction
- );
-
-gceSTATUS
-gcSHADER_GetKernelFunctionByName(
- IN gcSHADER Shader,
- IN gctSTRING KernelName,
- OUT gcKERNEL_FUNCTION * KernelFunction
- );
-/*******************************************************************************
-** gcSHADER_GetKernelFunctionCount
-**
-** Get the number of kernel functions for this shader.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** OUTPUT:
-**
-** gctSIZE_T * Count
-** Pointer to a variable receiving the number of kernel functions.
-*/
-gceSTATUS
-gcSHADER_GetKernelFunctionCount(
- IN gcSHADER Shader,
- OUT gctSIZE_T * Count
- );
-
-/*******************************************************************************
-** gcSHADER_ReallocateOutputs
-**
-** Reallocate an array of pointers to gcOUTPUT objects.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctSIZE_T Count
-** Array count to reallocate. 'Count' must be at least 1.
-*/
-gceSTATUS
-gcSHADER_ReallocateOutputs(
- IN gcSHADER Shader,
- IN gctSIZE_T Count
- );
-
-/*******************************************************************************
-** gcSHADER_AddOutput
-********************************************************************************
-**
-** Add an output to a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctCONST_STRING Name
-** Name of the output to add.
-**
-** gcSHADER_TYPE Type
-** Type of the output to add.
-**
-** gctSIZE_T Length
-** Array length of the output to add. 'Length' must be at least 1.
-**
-** gctUINT16 TempRegister
-** Temporary register index that holds the output value.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_AddOutput(
- IN gcSHADER Shader,
- IN gctCONST_STRING Name,
- IN gcSHADER_TYPE Type,
- IN gctSIZE_T Length,
- IN gctUINT16 TempRegister
- );
-
-gceSTATUS
-gcSHADER_AddOutputIndexed(
- IN gcSHADER Shader,
- IN gctCONST_STRING Name,
- IN gctSIZE_T Index,
- IN gctUINT16 TempIndex
- );
-
-/*******************************************************************************
-** gcSHADER_GetOutputCount
-********************************************************************************
-**
-** Get the number of outputs for this shader.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** OUTPUT:
-**
-** gctSIZE_T * Count
-** Pointer to a variable receiving the number of outputs.
-*/
-gceSTATUS
-gcSHADER_GetOutputCount(
- IN gcSHADER Shader,
- OUT gctSIZE_T * Count
- );
-
-/*******************************************************************************
-** gcSHADER_GetOutput
-********************************************************************************
-**
-** Get the gcOUTPUT object pointer for an indexed output for this shader.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctUINT Index
-** Index of output to retrieve.
-**
-** OUTPUT:
-**
-** gcOUTPUT * Output
-** Pointer to a variable receiving the gcOUTPUT object pointer.
-*/
-gceSTATUS
-gcSHADER_GetOutput(
- IN gcSHADER Shader,
- IN gctUINT Index,
- OUT gcOUTPUT * Output
- );
-
-
-/*******************************************************************************
-** gcSHADER_GetOutputByName
-********************************************************************************
-**
-** Get the gcOUTPUT object pointer for this shader by output name.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctSTRING name
-** Name of output to retrieve.
-**
-** gctSIZE_T nameLength
-** Length of name to retrieve
-**
-** OUTPUT:
-**
-** gcOUTPUT * Output
-** Pointer to a variable receiving the gcOUTPUT object pointer.
-*/
-gceSTATUS
-gcSHADER_GetOutputByName(
- IN gcSHADER Shader,
- IN gctSTRING name,
- IN gctSIZE_T nameLength,
- OUT gcOUTPUT * Output
- );
-
-/*******************************************************************************
-** gcSHADER_ReallocateVariables
-**
-** Reallocate an array of pointers to gcVARIABLE objects.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctSIZE_T Count
-** Array count to reallocate. 'Count' must be at least 1.
-*/
-gceSTATUS
-gcSHADER_ReallocateVariables(
- IN gcSHADER Shader,
- IN gctSIZE_T Count
- );
-
-/*******************************************************************************
-** gcSHADER_AddVariable
-********************************************************************************
-**
-** Add a variable to a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctCONST_STRING Name
-** Name of the variable to add.
-**
-** gcSHADER_TYPE Type
-** Type of the variable to add.
-**
-** gctSIZE_T Length
-** Array length of the variable to add. 'Length' must be at least 1.
-**
-** gctUINT16 TempRegister
-** Temporary register index that holds the variable value.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_AddVariable(
- IN gcSHADER Shader,
- IN gctCONST_STRING Name,
- IN gcSHADER_TYPE Type,
- IN gctSIZE_T Length,
- IN gctUINT16 TempRegister
- );
-
-
-/*******************************************************************************
-** gcSHADER_AddVariableEx
-********************************************************************************
-**
-** Add a variable to a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctCONST_STRING Name
-** Name of the variable to add.
-**
-** gcSHADER_TYPE Type
-** Type of the variable to add.
-**
-** gctSIZE_T Length
-** Array length of the variable to add. 'Length' must be at least 1.
-**
-** gctUINT16 TempRegister
-** Temporary register index that holds the variable value.
-**
-** gcSHADER_VAR_CATEGORY varCategory
-** Variable category, normal or struct.
-**
-** gctUINT16 numStructureElement
-** If struct, its element number.
-**
-** gctINT16 parent
-** If struct, parent index in gcSHADER.variables.
-**
-** gctINT16 prevSibling
-** If struct, previous sibling index in gcSHADER.variables.
-**
-** OUTPUT:
-**
-** gctINT16* ThisVarIndex
-** Returned value about variable index in gcSHADER.
-*/
-gceSTATUS
-gcSHADER_AddVariableEx(
- IN gcSHADER Shader,
- IN gctCONST_STRING Name,
- IN gcSHADER_TYPE Type,
- IN gctSIZE_T Length,
- IN gctUINT16 TempRegister,
- IN gcSHADER_VAR_CATEGORY varCategory,
- IN gctUINT16 numStructureElement,
- IN gctINT16 parent,
- IN gctINT16 prevSibling,
- OUT gctINT16* ThisVarIndex
- );
-
-/*******************************************************************************
-** gcSHADER_UpdateVariable
-********************************************************************************
-**
-** Update a variable to a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctUINT Index
-** Index of variable to retrieve.
-**
-** gceVARIABLE_UPDATE_FLAGS flag
-** Flag which property of variable will be updated.
-**
-** gctUINT newValue
-** New value to update.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_UpdateVariable(
- IN gcSHADER Shader,
- IN gctUINT Index,
- IN gceVARIABLE_UPDATE_FLAGS flag,
- IN gctUINT newValue
- );
-
-/*******************************************************************************
-** gcSHADER_GetVariableCount
-********************************************************************************
-**
-** Get the number of variables for this shader.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** OUTPUT:
-**
-** gctSIZE_T * Count
-** Pointer to a variable receiving the number of variables.
-*/
-gceSTATUS
-gcSHADER_GetVariableCount(
- IN gcSHADER Shader,
- OUT gctSIZE_T * Count
- );
-
-/*******************************************************************************
-** gcSHADER_GetVariable
-********************************************************************************
-**
-** Get the gcVARIABLE object pointer for an indexed variable for this shader.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctUINT Index
-** Index of variable to retrieve.
-**
-** OUTPUT:
-**
-** gcVARIABLE * Variable
-** Pointer to a variable receiving the gcVARIABLE object pointer.
-*/
-gceSTATUS
-gcSHADER_GetVariable(
- IN gcSHADER Shader,
- IN gctUINT Index,
- OUT gcVARIABLE * Variable
- );
-
-/*******************************************************************************
-** gcSHADER_GetVariableIndexingRange
-********************************************************************************
-**
-** Get the gcVARIABLE indexing range.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gcVARIABLE variable
-** Start variable.
-**
-** gctBOOL whole
-** Indicate whether maximum indexing range is queried
-**
-** OUTPUT:
-**
-** gctUINT *Start
-** Pointer to range start (temp register index).
-**
-** gctUINT *End
-** Pointer to range end (temp register index).
-*/
-gceSTATUS
-gcSHADER_GetVariableIndexingRange(
- IN gcSHADER Shader,
- IN gcVARIABLE variable,
- IN gctBOOL whole,
- OUT gctUINT *Start,
- OUT gctUINT *End
- );
-
-/*******************************************************************************
-** gcSHADER_AddOpcode
-********************************************************************************
-**
-** Add an opcode to a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gcSL_OPCODE Opcode
-** Opcode to add.
-**
-** gctUINT16 TempRegister
-** Temporary register index that acts as the target of the opcode.
-**
-** gctUINT8 Enable
-** Write enable bits for the temporary register that acts as the target
-** of the opcode.
-**
-** gcSL_FORMAT Format
-** Format of the temporary register.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_AddOpcode(
- IN gcSHADER Shader,
- IN gcSL_OPCODE Opcode,
- IN gctUINT16 TempRegister,
- IN gctUINT8 Enable,
- IN gcSL_FORMAT Format
- );
-
-gceSTATUS
-gcSHADER_AddOpcode2(
- IN gcSHADER Shader,
- IN gcSL_OPCODE Opcode,
- IN gcSL_CONDITION Condition,
- IN gctUINT16 TempRegister,
- IN gctUINT8 Enable,
- IN gcSL_FORMAT Format
- );
-
-/*******************************************************************************
-** gcSHADER_AddOpcodeIndexed
-********************************************************************************
-**
-** Add an opcode to a gcSHADER object that writes to an dynamically indexed
-** target.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gcSL_OPCODE Opcode
-** Opcode to add.
-**
-** gctUINT16 TempRegister
-** Temporary register index that acts as the target of the opcode.
-**
-** gctUINT8 Enable
-** Write enable bits for the temporary register that acts as the
-** target of the opcode.
-**
-** gcSL_INDEXED Mode
-** Location of the dynamic index inside the temporary register. Valid
-** values can be:
-**
-** gcSL_INDEXED_X - Use x component of the temporary register.
-** gcSL_INDEXED_Y - Use y component of the temporary register.
-** gcSL_INDEXED_Z - Use z component of the temporary register.
-** gcSL_INDEXED_W - Use w component of the temporary register.
-**
-** gctUINT16 IndexRegister
-** Temporary register index that holds the dynamic index.
-**
-** gcSL_FORMAT Format
-** Format of the temporary register.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_AddOpcodeIndexed(
- IN gcSHADER Shader,
- IN gcSL_OPCODE Opcode,
- IN gctUINT16 TempRegister,
- IN gctUINT8 Enable,
- IN gcSL_INDEXED Mode,
- IN gctUINT16 IndexRegister,
- IN gcSL_FORMAT Format
- );
-
-/*******************************************************************************
-** gcSHADER_AddOpcodeConditionIndexed
-**
-** Add an opcode to a gcSHADER object that writes to an dynamically indexed
-** target.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gcSL_OPCODE Opcode
-** Opcode to add.
-**
-** gcSL_CONDITION Condition
-** Condition to check.
-**
-** gctUINT16 TempRegister
-** Temporary register index that acts as the target of the opcode.
-**
-** gctUINT8 Enable
-** Write enable bits for the temporary register that acts as the
-** target of the opcode.
-**
-** gcSL_INDEXED Indexed
-** Location of the dynamic index inside the temporary register. Valid
-** values can be:
-**
-** gcSL_INDEXED_X - Use x component of the temporary register.
-** gcSL_INDEXED_Y - Use y component of the temporary register.
-** gcSL_INDEXED_Z - Use z component of the temporary register.
-** gcSL_INDEXED_W - Use w component of the temporary register.
-**
-** gctUINT16 IndexRegister
-** Temporary register index that holds the dynamic index.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_AddOpcodeConditionIndexed(
- IN gcSHADER Shader,
- IN gcSL_OPCODE Opcode,
- IN gcSL_CONDITION Condition,
- IN gctUINT16 TempRegister,
- IN gctUINT8 Enable,
- IN gcSL_INDEXED Indexed,
- IN gctUINT16 IndexRegister,
- IN gcSL_FORMAT Format
- );
-
-/*******************************************************************************
-** gcSHADER_AddOpcodeConditional
-********************************************************************************
-**
-** Add an conditional opcode to a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gcSL_OPCODE Opcode
-** Opcode to add.
-**
-** gcSL_CONDITION Condition
-** Condition that needs to evaluate to gcvTRUE in order for the opcode to
-** execute.
-**
-** gctUINT Label
-** Target label if 'Condition' evaluates to gcvTRUE.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_AddOpcodeConditional(
- IN gcSHADER Shader,
- IN gcSL_OPCODE Opcode,
- IN gcSL_CONDITION Condition,
- IN gctUINT Label
- );
-
-/*******************************************************************************
-** gcSHADER_AddOpcodeConditionalFormatted
-**
-** Add an conditional jump or call opcode to a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gcSL_OPCODE Opcode
-** Opcode to add.
-**
-** gcSL_CONDITION Condition
-** Condition that needs to evaluate to gcvTRUE in order for the opcode to
-** execute.
-**
-** gcSL_FORMAT Format
-** Format of conditional operands
-**
-** gctUINT Label
-** Target label if 'Condition' evaluates to gcvTRUE.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_AddOpcodeConditionalFormatted(
- IN gcSHADER Shader,
- IN gcSL_OPCODE Opcode,
- IN gcSL_CONDITION Condition,
- IN gcSL_FORMAT Format,
- IN gctUINT Label
- );
-
-/*******************************************************************************
-** gcSHADER_AddOpcodeConditionalFormattedEnable
-**
-** Add an conditional jump or call opcode to a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gcSL_OPCODE Opcode
-** Opcode to add.
-**
-** gcSL_CONDITION Condition
-** Condition that needs to evaluate to gcvTRUE in order for the opcode to
-** execute.
-**
-** gcSL_FORMAT Format
-** Format of conditional operands
-**
-** gctUINT8 Enable
-** Write enable value for the target of the opcode.
-**
-** gctUINT Label
-** Target label if 'Condition' evaluates to gcvTRUE.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_AddOpcodeConditionalFormattedEnable(
- IN gcSHADER Shader,
- IN gcSL_OPCODE Opcode,
- IN gcSL_CONDITION Condition,
- IN gcSL_FORMAT Format,
- IN gctUINT8 Enable,
- IN gctUINT Label
- );
-
-/*******************************************************************************
-** gcSHADER_AddLabel
-********************************************************************************
-**
-** Define a label at the current instruction of a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctUINT Label
-** Label to define.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_AddLabel(
- IN gcSHADER Shader,
- IN gctUINT Label
- );
-
-/*******************************************************************************
-** gcSHADER_AddSource
-********************************************************************************
-**
-** Add a source operand to a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gcSL_TYPE Type
-** Type of the source operand.
-**
-** gctUINT16 SourceIndex
-** Index of the source operand.
-**
-** gctUINT8 Swizzle
-** x, y, z, and w swizzle values packed into one 8-bit value.
-**
-** gcSL_FORMAT Format
-** Format of the source operand.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_AddSource(
- IN gcSHADER Shader,
- IN gcSL_TYPE Type,
- IN gctUINT16 SourceIndex,
- IN gctUINT8 Swizzle,
- IN gcSL_FORMAT Format
- );
-
-/*******************************************************************************
-** gcSHADER_AddSourceIndexed
-********************************************************************************
-**
-** Add a dynamically indexed source operand to a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gcSL_TYPE Type
-** Type of the source operand.
-**
-** gctUINT16 SourceIndex
-** Index of the source operand.
-**
-** gctUINT8 Swizzle
-** x, y, z, and w swizzle values packed into one 8-bit value.
-**
-** gcSL_INDEXED Mode
-** Addressing mode for the index.
-**
-** gctUINT16 IndexRegister
-** Temporary register index that holds the dynamic index.
-**
-** gcSL_FORMAT Format
-** Format of the source operand.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_AddSourceIndexed(
- IN gcSHADER Shader,
- IN gcSL_TYPE Type,
- IN gctUINT16 SourceIndex,
- IN gctUINT8 Swizzle,
- IN gcSL_INDEXED Mode,
- IN gctUINT16 IndexRegister,
- IN gcSL_FORMAT Format
- );
-
-/*******************************************************************************
-** gcSHADER_AddSourceAttribute
-********************************************************************************
-**
-** Add an attribute as a source operand to a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gcATTRIBUTE Attribute
-** Pointer to a gcATTRIBUTE object.
-**
-** gctUINT8 Swizzle
-** x, y, z, and w swizzle values packed into one 8-bit value.
-**
-** gctINT Index
-** Static index into the attribute in case the attribute is a matrix
-** or array.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_AddSourceAttribute(
- IN gcSHADER Shader,
- IN gcATTRIBUTE Attribute,
- IN gctUINT8 Swizzle,
- IN gctINT Index
- );
-
-/*******************************************************************************
-** gcSHADER_AddSourceAttributeIndexed
-********************************************************************************
-**
-** Add an indexed attribute as a source operand to a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gcATTRIBUTE Attribute
-** Pointer to a gcATTRIBUTE object.
-**
-** gctUINT8 Swizzle
-** x, y, z, and w swizzle values packed into one 8-bit value.
-**
-** gctINT Index
-** Static index into the attribute in case the attribute is a matrix
-** or array.
-**
-** gcSL_INDEXED Mode
-** Addressing mode of the dynamic index.
-**
-** gctUINT16 IndexRegister
-** Temporary register index that holds the dynamic index.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_AddSourceAttributeIndexed(
- IN gcSHADER Shader,
- IN gcATTRIBUTE Attribute,
- IN gctUINT8 Swizzle,
- IN gctINT Index,
- IN gcSL_INDEXED Mode,
- IN gctUINT16 IndexRegister
- );
-
-/*******************************************************************************
-** gcSHADER_AddSourceUniform
-********************************************************************************
-**
-** Add a uniform as a source operand to a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gcUNIFORM Uniform
-** Pointer to a gcUNIFORM object.
-**
-** gctUINT8 Swizzle
-** x, y, z, and w swizzle values packed into one 8-bit value.
-**
-** gctINT Index
-** Static index into the uniform in case the uniform is a matrix or
-** array.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_AddSourceUniform(
- IN gcSHADER Shader,
- IN gcUNIFORM Uniform,
- IN gctUINT8 Swizzle,
- IN gctINT Index
- );
-
-/*******************************************************************************
-** gcSHADER_AddSourceUniformIndexed
-********************************************************************************
-**
-** Add an indexed uniform as a source operand to a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gcUNIFORM Uniform
-** Pointer to a gcUNIFORM object.
-**
-** gctUINT8 Swizzle
-** x, y, z, and w swizzle values packed into one 8-bit value.
-**
-** gctINT Index
-** Static index into the uniform in case the uniform is a matrix or
-** array.
-**
-** gcSL_INDEXED Mode
-** Addressing mode of the dynamic index.
-**
-** gctUINT16 IndexRegister
-** Temporary register index that holds the dynamic index.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_AddSourceUniformIndexed(
- IN gcSHADER Shader,
- IN gcUNIFORM Uniform,
- IN gctUINT8 Swizzle,
- IN gctINT Index,
- IN gcSL_INDEXED Mode,
- IN gctUINT16 IndexRegister
- );
-
-gceSTATUS
-gcSHADER_AddSourceSamplerIndexed(
- IN gcSHADER Shader,
- IN gctUINT8 Swizzle,
- IN gcSL_INDEXED Mode,
- IN gctUINT16 IndexRegister
- );
-
-gceSTATUS
-gcSHADER_AddSourceAttributeFormatted(
- IN gcSHADER Shader,
- IN gcATTRIBUTE Attribute,
- IN gctUINT8 Swizzle,
- IN gctINT Index,
- IN gcSL_FORMAT Format
- );
-
-gceSTATUS
-gcSHADER_AddSourceAttributeIndexedFormatted(
- IN gcSHADER Shader,
- IN gcATTRIBUTE Attribute,
- IN gctUINT8 Swizzle,
- IN gctINT Index,
- IN gcSL_INDEXED Mode,
- IN gctUINT16 IndexRegister,
- IN gcSL_FORMAT Format
- );
-
-gceSTATUS
-gcSHADER_AddSourceUniformFormatted(
- IN gcSHADER Shader,
- IN gcUNIFORM Uniform,
- IN gctUINT8 Swizzle,
- IN gctINT Index,
- IN gcSL_FORMAT Format
- );
-
-gceSTATUS
-gcSHADER_AddSourceUniformIndexedFormatted(
- IN gcSHADER Shader,
- IN gcUNIFORM Uniform,
- IN gctUINT8 Swizzle,
- IN gctINT Index,
- IN gcSL_INDEXED Mode,
- IN gctUINT16 IndexRegister,
- IN gcSL_FORMAT Format
- );
-
-gceSTATUS
-gcSHADER_AddSourceSamplerIndexedFormatted(
- IN gcSHADER Shader,
- IN gctUINT8 Swizzle,
- IN gcSL_INDEXED Mode,
- IN gctUINT16 IndexRegister,
- IN gcSL_FORMAT Format
- );
-
-/*******************************************************************************
-** gcSHADER_AddSourceConstant
-********************************************************************************
-**
-** Add a constant floating point value as a source operand to a gcSHADER
-** object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctFLOAT Constant
-** Floating point constant.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_AddSourceConstant(
- IN gcSHADER Shader,
- IN gctFLOAT Constant
- );
-
-/*******************************************************************************
-** gcSHADER_AddSourceConstantFormatted
-********************************************************************************
-**
-** Add a constant value as a source operand to a gcSHADER
-** object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** void * Constant
-** Pointer to constant.
-**
-** gcSL_FORMAT Format
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_AddSourceConstantFormatted(
- IN gcSHADER Shader,
- IN void *Constant,
- IN gcSL_FORMAT Format
- );
-
-/*******************************************************************************
-** gcSHADER_Pack
-********************************************************************************
-**
-** Pack a dynamically created gcSHADER object by trimming the allocated arrays
-** and resolving all the labeling.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_Pack(
- IN gcSHADER Shader
- );
-
-/*******************************************************************************
-** gcSHADER_SetOptimizationOption
-********************************************************************************
-**
-** Set optimization option of a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctUINT OptimizationOption
-** Optimization option. Can be one of the following:
-**
-** 0 - No optimization.
-** 1 - Full optimization.
-** Other value - For optimizer testing.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcSHADER_SetOptimizationOption(
- IN gcSHADER Shader,
- IN gctUINT OptimizationOption
- );
-
-/*******************************************************************************
-** gcSHADER_ReallocateFunctions
-**
-** Reallocate an array of pointers to gcFUNCTION objects.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctSIZE_T Count
-** Array count to reallocate. 'Count' must be at least 1.
-*/
-gceSTATUS
-gcSHADER_ReallocateFunctions(
- IN gcSHADER Shader,
- IN gctSIZE_T Count
- );
-
-gceSTATUS
-gcSHADER_AddFunction(
- IN gcSHADER Shader,
- IN gctCONST_STRING Name,
- OUT gcFUNCTION * Function
- );
-
-gceSTATUS
-gcSHADER_ReallocateKernelFunctions(
- IN gcSHADER Shader,
- IN gctSIZE_T Count
- );
-
-gceSTATUS
-gcSHADER_AddKernelFunction(
- IN gcSHADER Shader,
- IN gctCONST_STRING Name,
- OUT gcKERNEL_FUNCTION * KernelFunction
- );
-
-gceSTATUS
-gcSHADER_BeginFunction(
- IN gcSHADER Shader,
- IN gcFUNCTION Function
- );
-
-gceSTATUS
-gcSHADER_EndFunction(
- IN gcSHADER Shader,
- IN gcFUNCTION Function
- );
-
-gceSTATUS
-gcSHADER_BeginKernelFunction(
- IN gcSHADER Shader,
- IN gcKERNEL_FUNCTION KernelFunction
- );
-
-gceSTATUS
-gcSHADER_EndKernelFunction(
- IN gcSHADER Shader,
- IN gcKERNEL_FUNCTION KernelFunction,
- IN gctSIZE_T LocalMemorySize
- );
-
-gceSTATUS
-gcSHADER_SetMaxKernelFunctionArgs(
- IN gcSHADER Shader,
- IN gctUINT32 MaxKernelFunctionArgs
- );
-
-/*******************************************************************************
-** gcSHADER_SetConstantMemorySize
-**
-** Set the constant memory address space size of a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctSIZE_T ConstantMemorySize
-** Constant memory size in bytes
-**
-** gctCHAR *ConstantMemoryBuffer
-** Constant memory buffer
-*/
-gceSTATUS
-gcSHADER_SetConstantMemorySize(
- IN gcSHADER Shader,
- IN gctSIZE_T ConstantMemorySize,
- IN gctCHAR * ConstantMemoryBuffer
- );
-
-/*******************************************************************************
-** gcSHADER_GetConstantMemorySize
-**
-** Set the constant memory address space size of a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** OUTPUT:
-**
-** gctSIZE_T * ConstantMemorySize
-** Pointer to a variable receiving constant memory size in bytes
-**
-** gctCHAR **ConstantMemoryBuffer.
-** Pointer to a variable for returned shader constant memory buffer.
-*/
-gceSTATUS
-gcSHADER_GetConstantMemorySize(
- IN gcSHADER Shader,
- OUT gctSIZE_T * ConstantMemorySize,
- OUT gctCHAR ** ConstantMemoryBuffer
- );
-
-/*******************************************************************************
-** gcSHADER_SetPrivateMemorySize
-**
-** Set the private memory address space size of a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctSIZE_T PrivateMemorySize
-** Private memory size in bytes
-*/
-gceSTATUS
-gcSHADER_SetPrivateMemorySize(
- IN gcSHADER Shader,
- IN gctSIZE_T PrivateMemorySize
- );
-
-/*******************************************************************************
-** gcSHADER_GetPrivateMemorySize
-**
-** Set the private memory address space size of a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** OUTPUT:
-**
-** gctSIZE_T * PrivateMemorySize
-** Pointer to a variable receiving private memory size in bytes
-*/
-gceSTATUS
-gcSHADER_GetPrivateMemorySize(
- IN gcSHADER Shader,
- OUT gctSIZE_T * PrivateMemorySize
- );
-
-/*******************************************************************************
-** gcSHADER_SetLocalMemorySize
-**
-** Set the local memory address space size of a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** gctSIZE_T LocalMemorySize
-** Local memory size in bytes
-*/
-gceSTATUS
-gcSHADER_SetLocalMemorySize(
- IN gcSHADER Shader,
- IN gctSIZE_T LocalMemorySize
- );
-
-/*******************************************************************************
-** gcSHADER_GetLocalMemorySize
-**
-** Set the local memory address space size of a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-** OUTPUT:
-**
-** gctSIZE_T * LocalMemorySize
-** Pointer to a variable receiving lcoal memory size in bytes
-*/
-gceSTATUS
-gcSHADER_GetLocalMemorySize(
- IN gcSHADER Shader,
- OUT gctSIZE_T * LocalMemorySize
- );
-
-
-/*******************************************************************************
-** gcSHADER_CheckValidity
-**
-** Check validity for a gcSHADER object.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object.
-**
-*/
-gceSTATUS
-gcSHADER_CheckValidity(
- IN gcSHADER Shader
- );
-
-#if gcdUSE_WCLIP_PATCH
-gceSTATUS
-gcATTRIBUTE_IsPosition(
- IN gcATTRIBUTE Attribute,
- OUT gctBOOL * IsPosition
- );
-#endif
-
-/*******************************************************************************
-** gcATTRIBUTE_GetType
-********************************************************************************
-**
-** Get the type and array length of a gcATTRIBUTE object.
-**
-** INPUT:
-**
-** gcATTRIBUTE Attribute
-** Pointer to a gcATTRIBUTE object.
-**
-** OUTPUT:
-**
-** gcSHADER_TYPE * Type
-** Pointer to a variable receiving the type of the attribute. 'Type'
-** can be gcvNULL, in which case no type will be returned.
-**
-** gctSIZE_T * ArrayLength
-** Pointer to a variable receiving the length of the array if the
-** attribute was declared as an array. If the attribute was not
-** declared as an array, the array length will be 1. 'ArrayLength' can
-** be gcvNULL, in which case no array length will be returned.
-*/
-gceSTATUS
-gcATTRIBUTE_GetType(
- IN gcATTRIBUTE Attribute,
- OUT gcSHADER_TYPE * Type,
- OUT gctSIZE_T * ArrayLength
- );
-
-/*******************************************************************************
-** gcATTRIBUTE_GetName
-********************************************************************************
-**
-** Get the name of a gcATTRIBUTE object.
-**
-** INPUT:
-**
-** gcATTRIBUTE Attribute
-** Pointer to a gcATTRIBUTE object.
-**
-** OUTPUT:
-**
-** gctSIZE_T * Length
-** Pointer to a variable receiving the length of the attribute name.
-** 'Length' can be gcvNULL, in which case no length will be returned.
-**
-** gctCONST_STRING * Name
-** Pointer to a variable receiving the pointer to the attribute name.
-** 'Name' can be gcvNULL, in which case no name will be returned.
-*/
-gceSTATUS
-gcATTRIBUTE_GetName(
- IN gcATTRIBUTE Attribute,
- OUT gctSIZE_T * Length,
- OUT gctCONST_STRING * Name
- );
-
-/*******************************************************************************
-** gcATTRIBUTE_IsEnabled
-********************************************************************************
-**
-** Query the enabled state of a gcATTRIBUTE object.
-**
-** INPUT:
-**
-** gcATTRIBUTE Attribute
-** Pointer to a gcATTRIBUTE object.
-**
-** OUTPUT:
-**
-** gctBOOL * Enabled
-** Pointer to a variable receiving the enabled state of the attribute.
-*/
-gceSTATUS
-gcATTRIBUTE_IsEnabled(
- IN gcATTRIBUTE Attribute,
- OUT gctBOOL * Enabled
- );
-
-/*******************************************************************************
-** gcUNIFORM_GetType
-********************************************************************************
-**
-** Get the type and array length of a gcUNIFORM object.
-**
-** INPUT:
-**
-** gcUNIFORM Uniform
-** Pointer to a gcUNIFORM object.
-**
-** OUTPUT:
-**
-** gcSHADER_TYPE * Type
-** Pointer to a variable receiving the type of the uniform. 'Type' can
-** be gcvNULL, in which case no type will be returned.
-**
-** gctSIZE_T * ArrayLength
-** Pointer to a variable receiving the length of the array if the
-** uniform was declared as an array. If the uniform was not declared
-** as an array, the array length will be 1. 'ArrayLength' can be gcvNULL,
-** in which case no array length will be returned.
-*/
-gceSTATUS
-gcUNIFORM_GetType(
- IN gcUNIFORM Uniform,
- OUT gcSHADER_TYPE * Type,
- OUT gctSIZE_T * ArrayLength
- );
-
-/*******************************************************************************
-** gcUNIFORM_GetTypeEx
-********************************************************************************
-**
-** Get the type and array length of a gcUNIFORM object.
-**
-** INPUT:
-**
-** gcUNIFORM Uniform
-** Pointer to a gcUNIFORM object.
-**
-** OUTPUT:
-**
-** gcSHADER_TYPE * Type
-** Pointer to a variable receiving the type of the uniform. 'Type' can
-** be gcvNULL, in which case no type will be returned.
-**
-** gcSHADER_PRECISION * Precision
-** Pointer to a variable receiving the precision of the uniform. 'Precision' can
-** be gcvNULL, in which case no type will be returned.
-**
-** gctSIZE_T * ArrayLength
-** Pointer to a variable receiving the length of the array if the
-** uniform was declared as an array. If the uniform was not declared
-** as an array, the array length will be 1. 'ArrayLength' can be gcvNULL,
-** in which case no array length will be returned.
-*/
-gceSTATUS
-gcUNIFORM_GetTypeEx(
- IN gcUNIFORM Uniform,
- OUT gcSHADER_TYPE * Type,
- OUT gcSHADER_PRECISION * Precision,
- OUT gctSIZE_T * ArrayLength
- );
-
-/*******************************************************************************
-** gcUNIFORM_GetFlags
-********************************************************************************
-**
-** Get the flags of a gcUNIFORM object.
-**
-** INPUT:
-**
-** gcUNIFORM Uniform
-** Pointer to a gcUNIFORM object.
-**
-** OUTPUT:
-**
-** gceUNIFORM_FLAGS * Flags
-** Pointer to a variable receiving the flags of the uniform.
-**
-*/
-gceSTATUS
-gcUNIFORM_GetFlags(
- IN gcUNIFORM Uniform,
- OUT gceUNIFORM_FLAGS * Flags
- );
-
-/*******************************************************************************
-** gcUNIFORM_SetFlags
-********************************************************************************
-**
-** Set the flags of a gcUNIFORM object.
-**
-** INPUT:
-**
-** gcUNIFORM Uniform
-** Pointer to a gcUNIFORM object.
-**
-** gceUNIFORM_FLAGS Flags
-** Flags of the uniform to be set.
-**
-** OUTPUT:
-** Nothing.
-**
-*/
-gceSTATUS
-gcUNIFORM_SetFlags(
- IN gcUNIFORM Uniform,
- IN gceUNIFORM_FLAGS Flags
- );
-
-/*******************************************************************************
-** gcUNIFORM_GetName
-********************************************************************************
-**
-** Get the name of a gcUNIFORM object.
-**
-** INPUT:
-**
-** gcUNIFORM Uniform
-** Pointer to a gcUNIFORM object.
-**
-** OUTPUT:
-**
-** gctSIZE_T * Length
-** Pointer to a variable receiving the length of the uniform name.
-** 'Length' can be gcvNULL, in which case no length will be returned.
-**
-** gctCONST_STRING * Name
-** Pointer to a variable receiving the pointer to the uniform name.
-** 'Name' can be gcvNULL, in which case no name will be returned.
-*/
-gceSTATUS
-gcUNIFORM_GetName(
- IN gcUNIFORM Uniform,
- OUT gctSIZE_T * Length,
- OUT gctCONST_STRING * Name
- );
-
-/*******************************************************************************
-** gcUNIFORM_GetSampler
-********************************************************************************
-**
-** Get the physical sampler number for a sampler gcUNIFORM object.
-**
-** INPUT:
-**
-** gcUNIFORM Uniform
-** Pointer to a gcUNIFORM object.
-**
-** OUTPUT:
-**
-** gctUINT32 * Sampler
-** Pointer to a variable receiving the physical sampler.
-*/
-gceSTATUS
-gcUNIFORM_GetSampler(
- IN gcUNIFORM Uniform,
- OUT gctUINT32 * Sampler
- );
-
-/*******************************************************************************
-** gcUNIFORM_GetFormat
-**
-** Get the type and array length of a gcUNIFORM object.
-**
-** INPUT:
-**
-** gcUNIFORM Uniform
-** Pointer to a gcUNIFORM object.
-**
-** OUTPUT:
-**
-** gcSL_FORMAT * Format
-** Pointer to a variable receiving the format of element of the uniform.
-** 'Type' can be gcvNULL, in which case no type will be returned.
-**
-** gctBOOL * IsPointer
-** Pointer to a variable receiving the state wheter the uniform is a pointer.
-** 'IsPointer' can be gcvNULL, in which case no array length will be returned.
-*/
-gceSTATUS
-gcUNIFORM_GetFormat(
- IN gcUNIFORM Uniform,
- OUT gcSL_FORMAT * Format,
- OUT gctBOOL * IsPointer
- );
-
-/*******************************************************************************
-** gcUNIFORM_SetFormat
-**
-** Set the format and isPointer of a uniform.
-**
-** INPUT:
-**
-** gcUNIFORM Uniform
-** Pointer to a gcUNIFORM object.
-**
-** gcSL_FORMAT Format
-** Format of element of the uniform shaderType.
-**
-** gctBOOL IsPointer
-** Wheter the uniform is a pointer.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcUNIFORM_SetFormat(
- IN gcUNIFORM Uniform,
- IN gcSL_FORMAT Format,
- IN gctBOOL IsPointer
- );
-
-/*******************************************************************************
-** gcUNIFORM_SetValue
-********************************************************************************
-**
-** Set the value of a uniform in integer.
-**
-** INPUT:
-**
-** gcUNIFORM Uniform
-** Pointer to a gcUNIFORM object.
-**
-** gctSIZE_T Count
-** Number of entries to program if the uniform has been declared as an
-** array.
-**
-** const gctINT * Value
-** Pointer to a buffer holding the integer values for the uniform.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcUNIFORM_SetValue(
- IN gcUNIFORM Uniform,
- IN gctSIZE_T Count,
- IN const gctINT * Value
- );
-
-/*******************************************************************************
-** gcUNIFORM_SetValueX
-********************************************************************************
-**
-** Set the value of a uniform in fixed point.
-**
-** INPUT:
-**
-** gcUNIFORM Uniform
-** Pointer to a gcUNIFORM object.
-**
-** gctSIZE_T Count
-** Number of entries to program if the uniform has been declared as an
-** array.
-**
-** const gctFIXED_POINT * Value
-** Pointer to a buffer holding the fixed point values for the uniform.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcUNIFORM_SetValueX(
- IN gcUNIFORM Uniform,
- IN gctSIZE_T Count,
- IN gctFIXED_POINT * Value
- );
-
-/*******************************************************************************
-** gcUNIFORM_SetValueF
-********************************************************************************
-**
-** Set the value of a uniform in floating point.
-**
-** INPUT:
-**
-** gcUNIFORM Uniform
-** Pointer to a gcUNIFORM object.
-**
-** gctSIZE_T Count
-** Number of entries to program if the uniform has been declared as an
-** array.
-**
-** const gctFLOAT * Value
-** Pointer to a buffer holding the floating point values for the
-** uniform.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcUNIFORM_SetValueF(
- IN gcUNIFORM Uniform,
- IN gctSIZE_T Count,
- IN const gctFLOAT * Value
- );
-
-/*******************************************************************************
-** gcUNIFORM_ProgramF
-**
-** Set the value of a uniform in floating point.
-**
-** INPUT:
-**
-** gctUINT32 Address
-** Address of Uniform.
-**
-** gctSIZE_T Row/Col
-**
-** const gctFLOAT * Value
-** Pointer to a buffer holding the floating point values for the
-** uniform.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gceSTATUS
-gcUNIFORM_ProgramF(
- IN gctUINT32 Address,
- IN gctSIZE_T Row,
- IN gctSIZE_T Col,
- IN const gctFLOAT * Value
- );
-
-/*******************************************************************************
-** gcUNIFORM_GetModelViewProjMatrix
-********************************************************************************
-**
-** Get the value of uniform modelViewProjMatrix ID if present.
-**
-** INPUT:
-**
-** gcUNIFORM Uniform
-** Pointer to a gcUNIFORM object.
-**
-** OUTPUT:
-**
-** Nothing.
-*/
-gctUINT
-gcUNIFORM_GetModelViewProjMatrix(
- IN gcUNIFORM Uniform
- );
-
-/*******************************************************************************
-** gcOUTPUT_GetType
-********************************************************************************
-**
-** Get the type and array length of a gcOUTPUT object.
-**
-** INPUT:
-**
-** gcOUTPUT Output
-** Pointer to a gcOUTPUT object.
-**
-** OUTPUT:
-**
-** gcSHADER_TYPE * Type
-** Pointer to a variable receiving the type of the output. 'Type' can
-** be gcvNULL, in which case no type will be returned.
-**
-** gctSIZE_T * ArrayLength
-** Pointer to a variable receiving the length of the array if the
-** output was declared as an array. If the output was not declared
-** as an array, the array length will be 1. 'ArrayLength' can be gcvNULL,
-** in which case no array length will be returned.
-*/
-gceSTATUS
-gcOUTPUT_GetType(
- IN gcOUTPUT Output,
- OUT gcSHADER_TYPE * Type,
- OUT gctSIZE_T * ArrayLength
- );
-
-/*******************************************************************************
-** gcOUTPUT_GetIndex
-********************************************************************************
-**
-** Get the index of a gcOUTPUT object.
-**
-** INPUT:
-**
-** gcOUTPUT Output
-** Pointer to a gcOUTPUT object.
-**
-** OUTPUT:
-**
-** gctUINT * Index
-** Pointer to a variable receiving the temporary register index of the
-** output. 'Index' can be gcvNULL,. in which case no index will be
-** returned.
-*/
-gceSTATUS
-gcOUTPUT_GetIndex(
- IN gcOUTPUT Output,
- OUT gctUINT * Index
- );
-
-/*******************************************************************************
-** gcOUTPUT_GetName
-********************************************************************************
-**
-** Get the name of a gcOUTPUT object.
-**
-** INPUT:
-**
-** gcOUTPUT Output
-** Pointer to a gcOUTPUT object.
-**
-** OUTPUT:
-**
-** gctSIZE_T * Length
-** Pointer to a variable receiving the length of the output name.
-** 'Length' can be gcvNULL, in which case no length will be returned.
-**
-** gctCONST_STRING * Name
-** Pointer to a variable receiving the pointer to the output name.
-** 'Name' can be gcvNULL, in which case no name will be returned.
-*/
-gceSTATUS
-gcOUTPUT_GetName(
- IN gcOUTPUT Output,
- OUT gctSIZE_T * Length,
- OUT gctCONST_STRING * Name
- );
-
-/*******************************************************************************
-*********************************************************** F U N C T I O N S **
-*******************************************************************************/
-
-/*******************************************************************************
-** gcFUNCTION_ReallocateArguments
-**
-** Reallocate an array of gcsFUNCTION_ARGUMENT objects.
-**
-** INPUT:
-**
-** gcFUNCTION Function
-** Pointer to a gcFUNCTION object.
-**
-** gctSIZE_T Count
-** Array count to reallocate. 'Count' must be at least 1.
-*/
-gceSTATUS
-gcFUNCTION_ReallocateArguments(
- IN gcFUNCTION Function,
- IN gctSIZE_T Count
- );
-
-gceSTATUS
-gcFUNCTION_AddArgument(
- IN gcFUNCTION Function,
- IN gctUINT16 TempIndex,
- IN gctUINT8 Enable,
- IN gctUINT8 Qualifier
- );
-
-gceSTATUS
-gcFUNCTION_GetArgument(
- IN gcFUNCTION Function,
- IN gctUINT16 Index,
- OUT gctUINT16_PTR Temp,
- OUT gctUINT8_PTR Enable,
- OUT gctUINT8_PTR Swizzle
- );
-
-gceSTATUS
-gcFUNCTION_GetLabel(
- IN gcFUNCTION Function,
- OUT gctUINT_PTR Label
- );
-
-/*******************************************************************************
-************************* K E R N E L P R O P E R T Y F U N C T I O N S **
-*******************************************************************************/
-/*******************************************************************************/
-gceSTATUS
-gcKERNEL_FUNCTION_AddKernelFunctionProperties(
- IN gcKERNEL_FUNCTION KernelFunction,
- IN gctINT propertyType,
- IN gctSIZE_T propertySize,
- IN gctINT * values
- );
-
-gceSTATUS
-gcKERNEL_FUNCTION_GetPropertyCount(
- IN gcKERNEL_FUNCTION KernelFunction,
- OUT gctSIZE_T * Count
- );
-
-gceSTATUS
-gcKERNEL_FUNCTION_GetProperty(
- IN gcKERNEL_FUNCTION KernelFunction,
- IN gctUINT Index,
- OUT gctSIZE_T * propertySize,
- OUT gctINT * propertyType,
- OUT gctINT * propertyValues
- );
-
-
-/*******************************************************************************
-*******************************I M A G E S A M P L E R F U N C T I O N S **
-*******************************************************************************/
-/*******************************************************************************
-** gcKERNEL_FUNCTION_ReallocateImageSamplers
-**
-** Reallocate an array of pointers to image sampler pair.
-**
-** INPUT:
-**
-** gcKERNEL_FUNCTION KernelFunction
-** Pointer to a gcKERNEL_FUNCTION object.
-**
-** gctSIZE_T Count
-** Array count to reallocate. 'Count' must be at least 1.
-*/
-gceSTATUS
-gcKERNEL_FUNCTION_ReallocateImageSamplers(
- IN gcKERNEL_FUNCTION KernelFunction,
- IN gctSIZE_T Count
- );
-
-gceSTATUS
-gcKERNEL_FUNCTION_AddImageSampler(
- IN gcKERNEL_FUNCTION KernelFunction,
- IN gctUINT8 ImageNum,
- IN gctBOOL IsConstantSamplerType,
- IN gctUINT32 SamplerType
- );
-
-gceSTATUS
-gcKERNEL_FUNCTION_GetImageSamplerCount(
- IN gcKERNEL_FUNCTION KernelFunction,
- OUT gctSIZE_T * Count
- );
-
-gceSTATUS
-gcKERNEL_FUNCTION_GetImageSampler(
- IN gcKERNEL_FUNCTION KernelFunction,
- IN gctUINT Index,
- OUT gctUINT8 *ImageNum,
- OUT gctBOOL *IsConstantSamplerType,
- OUT gctUINT32 *SamplerType
- );
-
-/*******************************************************************************
-*********************************************K E R N E L F U N C T I O N S **
-*******************************************************************************/
-
-/*******************************************************************************
-** gcKERNEL_FUNCTION_ReallocateArguments
-**
-** Reallocate an array of gcsFUNCTION_ARGUMENT objects.
-**
-** INPUT:
-**
-** gcKERNEL_FUNCTION Function
-** Pointer to a gcKERNEL_FUNCTION object.
-**
-** gctSIZE_T Count
-** Array count to reallocate. 'Count' must be at least 1.
-*/
-gceSTATUS
-gcKERNEL_FUNCTION_ReallocateArguments(
- IN gcKERNEL_FUNCTION Function,
- IN gctSIZE_T Count
- );
-
-gceSTATUS
-gcKERNEL_FUNCTION_AddArgument(
- IN gcKERNEL_FUNCTION Function,
- IN gctUINT16 TempIndex,
- IN gctUINT8 Enable,
- IN gctUINT8 Qualifier
- );
-
-gceSTATUS
-gcKERNEL_FUNCTION_GetArgument(
- IN gcKERNEL_FUNCTION Function,
- IN gctUINT16 Index,
- OUT gctUINT16_PTR Temp,
- OUT gctUINT8_PTR Enable,
- OUT gctUINT8_PTR Swizzle
- );
-
-gceSTATUS
-gcKERNEL_FUNCTION_GetLabel(
- IN gcKERNEL_FUNCTION Function,
- OUT gctUINT_PTR Label
- );
-
-gceSTATUS
-gcKERNEL_FUNCTION_GetName(
- IN gcKERNEL_FUNCTION KernelFunction,
- OUT gctSIZE_T * Length,
- OUT gctCONST_STRING * Name
- );
-
-gceSTATUS
-gcKERNEL_FUNCTION_ReallocateUniformArguments(
- IN gcKERNEL_FUNCTION KernelFunction,
- IN gctSIZE_T Count
- );
-
-gceSTATUS
-gcKERNEL_FUNCTION_AddUniformArgument(
- IN gcKERNEL_FUNCTION KernelFunction,
- IN gctCONST_STRING Name,
- IN gcSHADER_TYPE Type,
- IN gctSIZE_T Length,
- OUT gcUNIFORM * UniformArgument
- );
-
-gceSTATUS
-gcKERNEL_FUNCTION_GetUniformArgumentCount(
- IN gcKERNEL_FUNCTION KernelFunction,
- OUT gctSIZE_T * Count
- );
-
-gceSTATUS
-gcKERNEL_FUNCTION_GetUniformArgument(
- IN gcKERNEL_FUNCTION KernelFunction,
- IN gctUINT Index,
- OUT gcUNIFORM * UniformArgument
- );
-
-gceSTATUS
-gcKERNEL_FUNCTION_SetCodeEnd(
- IN gcKERNEL_FUNCTION KernelFunction
- );
-
-/*******************************************************************************
-** gcCompileShader
-********************************************************************************
-**
-** Compile a shader.
-**
-** INPUT:
-**
-** gcoOS Hal
-** Pointer to an gcoHAL object.
-**
-** gctINT ShaderType
-** Shader type to compile. Can be one of the following values:
-**
-** gcSHADER_TYPE_VERTEX
-** Compile a vertex shader.
-**
-** gcSHADER_TYPE_FRAGMENT
-** Compile a fragment shader.
-**
-** gctSIZE_T SourceSize
-** Size of the source buffer in bytes.
-**
-** gctCONST_STRING Source
-** Pointer to the buffer containing the shader source code.
-**
-** OUTPUT:
-**
-** gcSHADER * Binary
-** Pointer to a variable receiving the pointer to a gcSHADER object
-** containg the compiled shader code.
-**
-** gctSTRING * Log
-** Pointer to a variable receiving a string pointer containging the
-** compile log.
-*/
-gceSTATUS
-gcCompileShader(
- IN gcoHAL Hal,
- IN gctINT ShaderType,
- IN gctSIZE_T SourceSize,
- IN gctCONST_STRING Source,
- OUT gcSHADER * Binary,
- OUT gctSTRING * Log
- );
-
-/*******************************************************************************
-** gcOptimizeShader
-********************************************************************************
-**
-** Optimize a shader.
-**
-** INPUT:
-**
-** gcSHADER Shader
-** Pointer to a gcSHADER object holding information about the compiled
-** shader.
-**
-** gctFILE LogFile
-** Pointer to an open FILE object.
-*/
-gceSTATUS
-gcOptimizeShader(
- IN gcSHADER Shader,
- IN gctFILE LogFile
- );
-
-/*******************************************************************************
-** gcLinkShaders
-********************************************************************************
-**
-** Link two shaders and generate a harwdare specific state buffer by compiling
-** the compiler generated code through the resource allocator and code
-** generator.
-**
-** INPUT:
-**
-** gcSHADER VertexShader
-** Pointer to a gcSHADER object holding information about the compiled
-** vertex shader.
-**
-** gcSHADER FragmentShader
-** Pointer to a gcSHADER object holding information about the compiled
-** fragment shader.
-**
-** gceSHADER_FLAGS Flags
-** Compiler flags. Can be any of the following:
-**
-** gcvSHADER_DEAD_CODE - Dead code elimination.
-** gcvSHADER_RESOURCE_USAGE - Resource usage optimizaion.
-** gcvSHADER_OPTIMIZER - Full optimization.
-** gcvSHADER_USE_GL_Z - Use OpenGL ES Z coordinate.
-** gcvSHADER_USE_GL_POSITION - Use OpenGL ES gl_Position.
-** gcvSHADER_USE_GL_FACE - Use OpenGL ES gl_FaceForward.
-**
-** OUTPUT:
-**
-** gctSIZE_T * StateBufferSize
-** Pointer to a variable receicing the number of bytes in the buffer
-** returned in 'StateBuffer'.
-**
-** gctPOINTER * StateBuffer
-** Pointer to a variable receiving a buffer pointer that contains the
-** states required to download the shaders into the hardware.
-**
-** gcsHINT_PTR * Hints
-** Pointer to a variable receiving a gcsHINT structure pointer that
-** contains information required when loading the shader states.
-*/
-gceSTATUS
-gcLinkShaders(
- IN gcSHADER VertexShader,
- IN gcSHADER FragmentShader,
- IN gceSHADER_FLAGS Flags,
- OUT gctSIZE_T * StateBufferSize,
- OUT gctPOINTER * StateBuffer,
- OUT gcsHINT_PTR * Hints,
- OUT gcMACHINECODE_PTR *ppVsMachineCode,
- OUT gcMACHINECODE_PTR *ppFsMachineCode
- );
-
-/*******************************************************************************
-** gcLoadShaders
-********************************************************************************
-**
-** Load a pre-compiled and pre-linked shader program into the hardware.
-**
-** INPUT:
-**
-** gcoHAL Hal
-** Pointer to a gcoHAL object.
-**
-** gctSIZE_T StateBufferSize
-** The number of bytes in the 'StateBuffer'.
-**
-** gctPOINTER StateBuffer
-** Pointer to the states that make up the shader program.
-**
-** gcsHINT_PTR Hints
-** Pointer to a gcsHINT structure that contains information required
-** when loading the shader states.
-*/
-gceSTATUS
-gcLoadShaders(
- IN gcoHAL Hal,
- IN gctSIZE_T StateBufferSize,
- IN gctPOINTER StateBuffer,
- IN gcsHINT_PTR Hints
- );
-
-gceSTATUS
-gcRecompileShaders(
- IN gcoHAL Hal,
- IN gcMACHINECODE_PTR pVsMachineCode,
- IN gcMACHINECODE_PTR pPsMachineCode,
- /*Recompile variables*/
- IN OUT gctPOINTER *ppRecompileStateBuffer,
- IN OUT gctSIZE_T *pRecompileStateBufferSize,
- IN OUT gcsHINT_PTR *ppRecompileHints,
- /* natvie state*/
- IN gctPOINTER pNativeStateBuffer,
- IN gctSIZE_T nativeStateBufferSize,
- IN gcsHINT_PTR pNativeHints,
- /* npt info */
- IN gctUINT32 Samplers,
- IN gctUINT32 *SamplerWrapS,
- IN gctUINT32 *SamplerWrapT
- );
-
-gceSTATUS
-gcRecompileDepthBias(
- IN gcoHAL Hal,
- IN gcMACHINECODE_PTR pVsMachineCode,
- /*Recompile variables*/
- IN OUT gctPOINTER *ppRecompileStateBuffer,
- IN OUT gctSIZE_T *pRecompileStateBufferSize,
- IN OUT gcsHINT_PTR *ppRecompileHints,
- /* natvie state*/
- IN gctPOINTER pNativeStateBuffer,
- IN gctSIZE_T nativeStateBufferSize,
- IN gcsHINT_PTR pNativeHints,
- OUT gctINT * uniformAddr,
- OUT gctINT * uniformChannel
- );
-
-/*******************************************************************************
-** gcSaveProgram
-********************************************************************************
-**
-** Save pre-compiled shaders and pre-linked programs to a binary file.
-**
-** INPUT:
-**
-** gcSHADER VertexShader
-** Pointer to vertex shader object.
-**
-** gcSHADER FragmentShader
-** Pointer to fragment shader object.
-**
-** gctSIZE_T ProgramBufferSize
-** Number of bytes in 'ProgramBuffer'.
-**
-** gctPOINTER ProgramBuffer
-** Pointer to buffer containing the program states.
-**
-** gcsHINT_PTR Hints
-** Pointer to HINTS structure for program states.
-**
-** OUTPUT:
-**
-** gctPOINTER * Binary
-** Pointer to a variable receiving the binary data to be saved.
-**
-** gctSIZE_T * BinarySize
-** Pointer to a variable receiving the number of bytes inside 'Binary'.
-*/
-gceSTATUS
-gcSaveProgram(
- IN gcSHADER VertexShader,
- IN gcSHADER FragmentShader,
- IN gctSIZE_T ProgramBufferSize,
- IN gctPOINTER ProgramBuffer,
- IN gcsHINT_PTR Hints,
- OUT gctPOINTER * Binary,
- OUT gctSIZE_T * BinarySize
- );
-
-/*******************************************************************************
-** gcLoadProgram
-********************************************************************************
-**
-** Load pre-compiled shaders and pre-linked programs from a binary file.
-**
-** INPUT:
-**
-** gctPOINTER Binary
-** Pointer to the binary data loaded.
-**
-** gctSIZE_T BinarySize
-** Number of bytes in 'Binary'.
-**
-** OUTPUT:
-**
-** gcSHADER VertexShader
-** Pointer to a vertex shader object.
-**
-** gcSHADER FragmentShader
-** Pointer to a fragment shader object.
-**
-** gctSIZE_T * ProgramBufferSize
-** Pointer to a variable receicing the number of bytes in the buffer
-** returned in 'ProgramBuffer'.
-**
-** gctPOINTER * ProgramBuffer
-** Pointer to a variable receiving a buffer pointer that contains the
-** states required to download the shaders into the hardware.
-**
-** gcsHINT_PTR * Hints
-** Pointer to a variable receiving a gcsHINT structure pointer that
-** contains information required when loading the shader states.
-*/
-gceSTATUS
-gcLoadProgram(
- IN gctPOINTER Binary,
- IN gctSIZE_T BinarySize,
- OUT gcSHADER VertexShader,
- OUT gcSHADER FragmentShader,
- OUT gctSIZE_T * ProgramBufferSize,
- OUT gctPOINTER * ProgramBuffer,
- OUT gcsHINT_PTR * Hints
- );
-
-/*******************************************************************************
-** gcCompileKernel
-********************************************************************************
-**
-** Compile a OpenCL kernel shader.
-**
-** INPUT:
-**
-** gcoOS Hal
-** Pointer to an gcoHAL object.
-**
-** gctSIZE_T SourceSize
-** Size of the source buffer in bytes.
-**
-** gctCONST_STRING Source
-** Pointer to the buffer containing the shader source code.
-**
-** OUTPUT:
-**
-** gcSHADER * Binary
-** Pointer to a variable receiving the pointer to a gcSHADER object
-** containg the compiled shader code.
-**
-** gctSTRING * Log
-** Pointer to a variable receiving a string pointer containging the
-** compile log.
-*/
-gceSTATUS
-gcCompileKernel(
- IN gcoHAL Hal,
- IN gctSIZE_T SourceSize,
- IN gctCONST_STRING Source,
- IN gctCONST_STRING Options,
- OUT gcSHADER * Binary,
- OUT gctSTRING * Log
- );
-
-/*******************************************************************************
-** gcLinkKernel
-********************************************************************************
-**
-** Link OpenCL kernel and generate a harwdare specific state buffer by compiling
-** the compiler generated code through the resource allocator and code
-** generator.
-**
-** INPUT:
-**
-** gcSHADER Kernel
-** Pointer to a gcSHADER object holding information about the compiled
-** OpenCL kernel.
-**
-** gceSHADER_FLAGS Flags
-** Compiler flags. Can be any of the following:
-**
-** gcvSHADER_DEAD_CODE - Dead code elimination.
-** gcvSHADER_RESOURCE_USAGE - Resource usage optimizaion.
-** gcvSHADER_OPTIMIZER - Full optimization.
-** gcvSHADER_USE_GL_Z - Use OpenGL ES Z coordinate.
-** gcvSHADER_USE_GL_POSITION - Use OpenGL ES gl_Position.
-** gcvSHADER_USE_GL_FACE - Use OpenGL ES gl_FaceForward.
-**
-** OUTPUT:
-**
-** gctSIZE_T * StateBufferSize
-** Pointer to a variable receiving the number of bytes in the buffer
-** returned in 'StateBuffer'.
-**
-** gctPOINTER * StateBuffer
-** Pointer to a variable receiving a buffer pointer that contains the
-** states required to download the shaders into the hardware.
-**
-** gcsHINT_PTR * Hints
-** Pointer to a variable receiving a gcsHINT structure pointer that
-** contains information required when loading the shader states.
-*/
-gceSTATUS
-gcLinkKernel(
- IN gcSHADER Kernel,
- IN gceSHADER_FLAGS Flags,
- OUT gctSIZE_T * StateBufferSize,
- OUT gctPOINTER * StateBuffer,
- OUT gcsHINT_PTR * Hints
- );
-
-/*******************************************************************************
-** gcLoadKernel
-********************************************************************************
-**
-** Load a pre-compiled and pre-linked kernel program into the hardware.
-**
-** INPUT:
-**
-** gctSIZE_T StateBufferSize
-** The number of bytes in the 'StateBuffer'.
-**
-** gctPOINTER StateBuffer
-** Pointer to the states that make up the shader program.
-**
-** gcsHINT_PTR Hints
-** Pointer to a gcsHINT structure that contains information required
-** when loading the shader states.
-*/
-gceSTATUS
-gcLoadKernel(
- IN gctSIZE_T StateBufferSize,
- IN gctPOINTER StateBuffer,
- IN gcsHINT_PTR Hints
- );
-
-gceSTATUS
-gcInvokeThreadWalker(
- IN gcsTHREAD_WALKER_INFO_PTR Info
- );
-
-void
-gcTYPE_GetTypeInfo(
- IN gcSHADER_TYPE Type,
- OUT gctINT * Components,
- OUT gctINT * Rows,
- OUT gctCONST_STRING * Name
- );
-
-gctBOOL
-gcOPT_doVaryingPackingForShader(
- IN gcSHADER Shader
- );
-
-gceSTATUS
-gcSHADER_PatchNPOTForMachineCode(
- IN gcSHADER_KIND shaderType,
- IN gcMACHINECODE_PTR pMachineCode,
- IN gcNPOT_PATCH_PARAM_PTR pPatchParam,
- IN gctUINT countOfPatchParam,
- IN gctUINT hwSupportedInstCount,
- OUT gctPOINTER* ppCmdBuffer,
- OUT gctUINT32* pByteSizeOfCmdBuffer,
- IN OUT gcsHINT_PTR pHints /* User needs copy original hints to this one, then passed this one in */
- );
-
-gceSTATUS
-gcSHADER_PatchZBiasForMachineCodeVS(
- IN gcMACHINECODE_PTR pMachineCode,
- IN OUT gcZBIAS_PATCH_PARAM_PTR pPatchParam,
- IN gctUINT hwSupportedInstCount,
- OUT gctPOINTER* ppCmdBuffer,
- OUT gctUINT32* pByteSizeOfCmdBuffer,
- IN OUT gcsHINT_PTR pHints /* User needs copy original hints to this one, then passed this one in */
- );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* VIVANTE_NO_3D */
-#endif /* __gc_hal_compiler_h_ */
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
*
*****************************************************************************/
-
#ifndef __gc_hal_driver_h_
#define __gc_hal_driver_h_
#define IOCTL_GCHAL_KERNEL_INTERFACE 30001
#define IOCTL_GCHAL_TERMINATE 30002
+#undef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
/******************************************************************************\
********************************* Command Codes ********************************
\******************************************************************************/
/* Video memory allocation. */
gcvHAL_ALLOCATE_VIDEO_MEMORY, /* Enforced alignment. */
gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY, /* No alignment. */
- gcvHAL_FREE_VIDEO_MEMORY,
+ gcvHAL_RELEASE_VIDEO_MEMORY,
/* Physical-to-logical mapping. */
gcvHAL_MAP_MEMORY,
/* Frame database. */
gcvHAL_GET_FRAME_INFO,
- /* Shared info for each process */
- gcvHAL_GET_SHARED_INFO,
- gcvHAL_SET_SHARED_INFO,
gcvHAL_QUERY_COMMAND_BUFFER,
gcvHAL_COMMIT_DONE,
gcvHAL_SET_FSCALE_VALUE,
gcvHAL_GET_FSCALE_VALUE,
+ gcvHAL_NAME_VIDEO_MEMORY,
+ gcvHAL_IMPORT_VIDEO_MEMORY,
+
/* Reset time stamp. */
gcvHAL_QUERY_RESET_TIME_STAMP,
+ /* Multi-GPU read/write. */
+ gcvHAL_READ_REGISTER_EX,
+ gcvHAL_WRITE_REGISTER_EX,
+
/* Sync point operations. */
gcvHAL_SYNC_POINT,
/* Create native fence and return its fd. */
gcvHAL_CREATE_NATIVE_FENCE,
- /* Video memory database */
- gcvHAL_VIDMEM_DATABASE,
+ /* Destory MMU. */
+ gcvHAL_DESTROY_MMU,
+
+ /* Shared buffer. */
+ gcvHAL_SHBUF,
+
+ /* Config power management. */
+ gcvHAL_CONFIG_POWER_MANAGEMENT,
+
+ /* Connect a video node to an OS native fd. */
+ gcvHAL_GET_VIDEO_MEMORY_FD,
}
gceHAL_COMMAND_CODES;
/* Supported minor feature 4 fields. */
gctUINT32 chipMinorFeatures4;
+ /* Supported minor feature 5 fields. */
+ gctUINT32 chipMinorFeatures5;
+
/* Number of streams supported. */
gctUINT32 streamCount;
/* Supertile layout style in hardware */
gctUINT32 superTileMode;
+
+#if gcdMULTI_GPU
+ /* Number of 3D GPUs */
+ gctUINT32 gpuCoreCount;
+#endif
+
+ /* Special control bits for 2D chip. */
+ gctUINT32 chip2DControl;
+
+ /* Product ID */
+ gctUINT32 productID;
}
gcsHAL_QUERY_CHIP_IDENTITY;
/* Type of allocation. */
IN gceSURF_TYPE type;
+ /* Flag of allocation. */
+ IN gctUINT32 flag;
+
/* Memory pool to allocate from. */
IN OUT gcePOOL pool;
- /* Allocated video memory in gcuVIDMEM_NODE. */
- OUT gctUINT64 node;
+ /* Allocated video memory. */
+ OUT gctUINT32 node;
}
AllocateLinearVideoMemory;
/* Memory pool to allocate from. */
IN OUT gcePOOL pool;
- /* Allocated video memory in gcuVIDMEM_NODE. */
- OUT gctUINT64 node;
+ /* Allocated video memory. */
+ OUT gctUINT32 node;
}
AllocateVideoMemory;
- /* gcvHAL_FREE_VIDEO_MEMORY */
- struct _gcsHAL_FREE_VIDEO_MEMORY
+ /* gcvHAL_RELEASE_VIDEO_MEMORY */
+ struct _gcsHAL_RELEASE_VIDEO_MEMORY
{
- /* Allocated video memory in gcuVIDMEM_NODE. */
- IN gctUINT64 node;
+ /* Allocated video memory. */
+ IN gctUINT32 node;
#ifdef __QNXNTO__
/* TODO: This is part of the unlock - why is it here? */
/* Mapped logical address to unmap in user space. */
- OUT gctUINT64 memory;
+ OUT gctUINT64 memory;
/* Number of bytes to allocated. */
- OUT gctUINT64 bytes;
+ OUT gctUINT64 bytes;
#endif
}
- FreeVideoMemory;
+ ReleaseVideoMemory;
/* gcvHAL_LOCK_VIDEO_MEMORY */
struct _gcsHAL_LOCK_VIDEO_MEMORY
{
- /* Allocated video memory gcuVIDMEM_NODE gcuVIDMEM_NODE. */
- IN gctUINT64 node;
+ /* Allocated video memory. */
+ IN gctUINT32 node;
/* Cache configuration. */
/* Only gcvPOOL_CONTIGUOUS and gcvPOOL_VIRUTAL
** can be configured */
- IN gctBOOL cacheable;
+ IN gctBOOL cacheable;
/* Hardware specific address. */
- OUT gctUINT32 address;
+ OUT gctUINT32 address;
/* Mapped logical address. */
- OUT gctUINT64 memory;
+ OUT gctUINT64 memory;
+
+ /* Customer priviate handle*/
+ OUT gctUINT32 gid;
+
+ /* Bus address of a contiguous video node. */
+ OUT gctUINT64 physicalAddress;
}
LockVideoMemory;
/* gcvHAL_UNLOCK_VIDEO_MEMORY */
struct _gcsHAL_UNLOCK_VIDEO_MEMORY
{
- /* Allocated video memory in gcuVIDMEM_NODE. */
- IN gctUINT64 node;
+ /* Allocated video memory. */
+ IN gctUINT64 node;
/* Type of surface. */
- IN gceSURF_TYPE type;
+ IN gceSURF_TYPE type;
/* Flag to unlock surface asynchroneously. */
- IN OUT gctBOOL asynchroneous;
+ IN OUT gctBOOL asynchroneous;
}
UnlockVideoMemory;
struct _gcsHAL_EVENT_COMMIT
{
/* Event queue in gcsQUEUE. */
- IN gctUINT64 queue;
+ IN gctUINT64 queue;
+
+#if gcdMULTI_GPU
+ IN gceCORE_3D_MASK chipEnable;
+
+ IN gceMULTI_GPU_MODE gpuMode;
+#endif
}
Event;
/* Event queue in gcsQUEUE. */
IN gctUINT64 queue;
+
+#if gcdMULTI_GPU
+ IN gceCORE_3D_MASK chipEnable;
+
+ IN gceMULTI_GPU_MODE gpuMode;
+#endif
}
Commit;
}
WriteRegisterData;
+#if gcdMULTI_GPU
+ /* gcvHAL_READ_REGISTER_EX */
+ struct _gcsHAL_READ_REGISTER_EX
+ {
+ /* Logical address of memory to write data to. */
+ IN gctUINT32 address;
+
+ IN gctUINT32 coreSelect;
+
+ /* Data read. */
+ OUT gctUINT32 data[gcdMULTI_GPU];
+ }
+ ReadRegisterDataEx;
+
+ /* gcvHAL_WRITE_REGISTER_EX */
+ struct _gcsHAL_WRITE_REGISTER_EX
+ {
+ /* Logical address of memory to write data to. */
+ IN gctUINT32 address;
+
+ IN gctUINT32 coreSelect;
+
+ /* Data read. */
+ IN gctUINT32 data[gcdMULTI_GPU];
+ }
+ WriteRegisterDataEx;
+#endif
+
#if VIVANTE_PROFILER
/* gcvHAL_GET_PROFILE_SETTING */
struct _gcsHAL_GET_PROFILE_SETTING
{
/* Enable profiling */
OUT gctBOOL enable;
-
- /* The profile file name */
- OUT gctCHAR fileName[gcdMAX_PROFILE_FILE_NAME];
}
GetProfileSetting;
{
/* Enable profiling */
IN gctBOOL enable;
-
- /* The profile file name */
- IN gctCHAR fileName[gcdMAX_PROFILE_FILE_NAME];
}
SetProfileSetting;
/* Context buffer object gckCONTEXT. Just a name. */
IN gctUINT32 context;
#endif
+
/* Data read. */
OUT gcsPROFILER_COUNTERS counters;
}
}
RegisterProfileData2D;
#endif
+
/* Power management. */
/* gcvHAL_SET_POWER_MANAGEMENT_STATE */
struct _gcsHAL_SET_POWER_MANAGEMENT
struct _gcsHAL_CACHE
{
IN gceCACHEOPERATION operation;
- /* gctHANDLE */
IN gctUINT64 process;
IN gctUINT64 logical;
IN gctUINT64 bytes;
- /* gcuVIDMEM_NODE_PTR */
- IN gctUINT64 node;
+ IN gctUINT32 node;
}
Cache;
OUT gcuDATABASE_INFO nonPaged;
OUT gcuDATABASE_INFO contiguous;
OUT gcuDATABASE_INFO gpuIdle;
- }
- Database;
- /* gcvHAL_VIDMEM_DATABASE */
- struct _gcsHAL_VIDMEM_DATABASE
- {
- /* Set to gcvTRUE if you want to query a particular process ID.
- ** Set to gcvFALSE to query the last detached process. */
- IN gctBOOL validProcessID;
-
- /* Process ID to query. */
- IN gctUINT32 processID;
-
- /* Information. */
- OUT gcuDATABASE_INFO vidMemResv;
- OUT gcuDATABASE_INFO vidMemCont;
- OUT gcuDATABASE_INFO vidMemVirt;
+ /* Detail information about video memory. */
+ OUT gcuDATABASE_INFO vidMemPool[3];
}
- VidMemDatabase;
+ Database;
/* gcvHAL_VERSION */
struct _gcsHAL_VERSION
/* gcvHAL_ATTACH */
struct _gcsHAL_ATTACH
{
- /* Context buffer object gckCONTEXT. Just a name. */
+ /* Handle of context buffer object. */
OUT gctUINT32 context;
/* Number of states in the buffer. */
OUT gctUINT64 stateCount;
+
+ /* Map context buffer to user or not. */
+ IN gctBOOL map;
+
+ /* Physical of context buffer. */
+ OUT gctUINT32 physicals[2];
+
+ /* Physical of context buffer. */
+ OUT gctUINT64 logicals[2];
+
+ /* Bytes of context buffer. */
+ OUT gctUINT32 bytes;
}
Attach;
SetTimeOut;
#if gcdENABLE_VG
- /* gcvHAL_COMMIT */
- struct _gcsHAL_VGCOMMIT
- {
- /* Context buffer in gcsVGCONTEXT. */
- IN gctUINT64 context;
-
- /* Command queue in gcsVGCMDQUEUE. */
- IN gctUINT64 queue;
-
- /* Number of entries in the queue. */
- IN gctUINT entryCount;
-
- /* Task table in gcsTASK_MASTER_TABLE. */
- IN gctUINT64 taskTable;
- }
- VGCommit;
-
- /* gcvHAL_QUERY_COMMAND_BUFFER */
- struct _gcsHAL_QUERY_COMMAND_BUFFER
- {
- /* Command buffer attributes. */
- OUT gcsCOMMAND_BUFFER_INFO information;
- }
- QueryCommandBuffer;
-
-#endif
-
- struct _gcsHAL_GET_SHARED_INFO
+ /* gcvHAL_COMMIT */
+ struct _gcsHAL_VGCOMMIT
{
- /* Process id. */
- IN gctUINT32 pid;
+ /* Context buffer. gcsVGCONTEXT_PTR */
+ IN gctUINT64 context;
- /* Data id. */
- IN gctUINT32 dataId;
+ /* Command queue. gcsVGCMDQUEUE_PTR */
+ IN gctUINT64 queue;
- /* Data size. */
- IN gctSIZE_T bytes;
+ /* Number of entries in the queue. */
+ IN gctUINT entryCount;
- /* Pointer to save the shared data. */
- OUT gctPOINTER data;
+ /* Task table. gcsTASK_MASTER_TABLE_PTR */
+ IN gctUINT64 taskTable;
}
- GetSharedInfo;
+ VGCommit;
- struct _gcsHAL_SET_SHARED_INFO
+ /* gcvHAL_QUERY_COMMAND_BUFFER */
+ struct _gcsHAL_QUERY_COMMAND_BUFFER
{
- /* Data id. */
- IN gctUINT32 dataId;
-
- /* Data to be shared. */
- IN gctPOINTER data;
-
- /* Data size. */
- IN gctSIZE_T bytes;
+ /* Command buffer attributes. */
+ OUT gcsCOMMAND_BUFFER_INFO information;
}
- SetSharedInfo;
+ QueryCommandBuffer;
+
+#endif
struct _gcsHAL_SET_FSCALE_VALUE
{
}
GetFscaleValue;
+ struct _gcsHAL_NAME_VIDEO_MEMORY
+ {
+ IN gctUINT32 handle;
+ OUT gctUINT32 name;
+ }
+ NameVideoMemory;
+
+ struct _gcsHAL_IMPORT_VIDEO_MEMORY
+ {
+ IN gctUINT32 name;
+ OUT gctUINT32 handle;
+ }
+ ImportVideoMemory;
+
struct _gcsHAL_QUERY_RESET_TIME_STAMP
{
OUT gctUINT64 timeStamp;
}
CreateNativeFence;
+
+ struct _gcsHAL_DESTROY_MMU
+ {
+ /* Mmu object. */
+ IN gctUINT64 mmu;
+ }
+ DestroyMmu;
+
+ struct _gcsHAL_SHBUF
+ {
+ gceSHBUF_COMMAND_CODES command;
+
+ /* Shared buffer. */
+ IN OUT gctUINT64 id;
+
+ /* User data to be shared. */
+ IN gctUINT64 data;
+
+ /* Data size. */
+ IN OUT gctUINT32 bytes;
+ }
+ ShBuf;
+
+ struct _gcsHAL_CONFIG_POWER_MANAGEMENT
+ {
+ IN gctBOOL enable;
+ }
+ ConfigPowerManagement;
+
+ struct _gcsHAL_GET_VIDEO_MEMORY_FD
+ {
+ IN gctUINT32 handle;
+ OUT gctINT fd;
+ }
+ GetVideoMemoryFd;
}
u;
}
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
/* Alignment and mask for the buffer address. */
gctUINT addressMask;
- gctSIZE_T addressAlignment;
+ gctUINT32 addressAlignment;
/* Alignment for each command. */
- gctSIZE_T commandAlignment;
+ gctUINT32 commandAlignment;
/* Number of bytes required by the STATE command. */
- gctSIZE_T stateCommandSize;
+ gctUINT32 stateCommandSize;
/* Number of bytes required by the RESTART command. */
- gctSIZE_T restartCommandSize;
+ gctUINT32 restartCommandSize;
/* Number of bytes required by the FETCH command. */
- gctSIZE_T fetchCommandSize;
+ gctUINT32 fetchCommandSize;
/* Number of bytes required by the CALL command. */
- gctSIZE_T callCommandSize;
+ gctUINT32 callCommandSize;
/* Number of bytes required by the RETURN command. */
- gctSIZE_T returnCommandSize;
+ gctUINT32 returnCommandSize;
/* Number of bytes required by the EVENT command. */
- gctSIZE_T eventCommandSize;
+ gctUINT32 eventCommandSize;
/* Number of bytes required by the END command. */
- gctSIZE_T endCommandSize;
+ gctUINT32 endCommandSize;
/* Number of bytes reserved at the tail of a static command buffer. */
- gctSIZE_T staticTailSize;
+ gctUINT32 staticTailSize;
/* Number of bytes reserved at the tail of a dynamic command buffer. */
- gctSIZE_T dynamicTailSize;
+ gctUINT32 dynamicTailSize;
}
gcsCOMMAND_BUFFER_INFO;
IN gceTASK id;
/* Allocated video memory. */
- IN gctUINT64 node;
+ IN gctUINT32 node;
}
gcsTASK_FREE_VIDEO_MEMORY;
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#endif
/*
-** FILE LAYOUT:
+** FILE LAYOUT:
**
-** gcsDUMP_FILE structure
+** gcsDUMP_FILE structure
**
-** gcsDUMP_DATA frame
-** gcsDUMP_DATA or gcDUMP_DATA_SIZE records rendingring the frame
-** gctUINT8 data[length]
+** gcsDUMP_DATA frame
+** gcsDUMP_DATA or gcDUMP_DATA_SIZE records rendingring the frame
+** gctUINT8 data[length]
*/
-#define gcvDUMP_FILE_SIGNATURE gcmCC('g','c','D','B')
+#define gcvDUMP_FILE_SIGNATURE gcmCC('g','c','D','B')
typedef struct _gcsDUMP_FILE
{
- gctUINT32 signature; /* File signature */
- gctSIZE_T length; /* Length of file */
- gctUINT32 frames; /* Number of frames in file */
+ gctUINT32 signature; /* File signature */
+ gctSIZE_T length; /* Length of file */
+ gctUINT32 frames; /* Number of frames in file */
}
gcsDUMP_FILE;
typedef enum _gceDUMP_TAG
{
- gcvTAG_SURFACE = gcmCC('s','u','r','f'),
- gcvTAG_FRAME = gcmCC('f','r','m',' '),
- gcvTAG_COMMAND = gcmCC('c','m','d',' '),
- gcvTAG_INDEX = gcmCC('i','n','d','x'),
- gcvTAG_STREAM = gcmCC('s','t','r','m'),
- gcvTAG_TEXTURE = gcmCC('t','e','x','t'),
- gcvTAG_RENDER_TARGET = gcmCC('r','n','d','r'),
- gcvTAG_DEPTH = gcmCC('z','b','u','f'),
- gcvTAG_RESOLVE = gcmCC('r','s','l','v'),
- gcvTAG_DELETE = gcmCC('d','e','l',' '),
+ gcvTAG_SURFACE = gcmCC('s','u','r','f'),
+ gcvTAG_FRAME = gcmCC('f','r','m',' '),
+ gcvTAG_COMMAND = gcmCC('c','m','d',' '),
+ gcvTAG_INDEX = gcmCC('i','n','d','x'),
+ gcvTAG_STREAM = gcmCC('s','t','r','m'),
+ gcvTAG_TEXTURE = gcmCC('t','e','x','t'),
+ gcvTAG_RENDER_TARGET = gcmCC('r','n','d','r'),
+ gcvTAG_DEPTH = gcmCC('z','b','u','f'),
+ gcvTAG_RESOLVE = gcmCC('r','s','l','v'),
+ gcvTAG_DELETE = gcmCC('d','e','l',' '),
+ gcvTAG_BUFOBJ = gcmCC('b','u','f','o'),
}
gceDUMP_TAG;
typedef struct _gcsDUMP_SURFACE
{
- gceDUMP_TAG type; /* Type of record. */
- gctUINT32 address; /* Address of the surface. */
- gctINT16 width; /* Width of surface. */
- gctINT16 height; /* Height of surface. */
- gceSURF_FORMAT format; /* Surface pixel format. */
- gctSIZE_T length; /* Number of bytes inside the surface. */
+ gceDUMP_TAG type; /* Type of record. */
+ gctUINT32 address; /* Address of the surface. */
+ gctINT16 width; /* Width of surface. */
+ gctINT16 height; /* Height of surface. */
+ gceSURF_FORMAT format; /* Surface pixel format. */
+ gctSIZE_T length; /* Number of bytes inside the surface. */
}
gcsDUMP_SURFACE;
typedef struct _gcsDUMP_DATA
{
- gceDUMP_TAG type; /* Type of record. */
- gctSIZE_T length; /* Number of bytes of data. */
- gctUINT32 address; /* Address for the data. */
+ gceDUMP_TAG type; /* Type of record. */
+ gctSIZE_T length; /* Number of bytes of data. */
+ gctUINT32 address; /* Address for the data. */
}
gcsDUMP_DATA;
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
*
*****************************************************************************/
+
#ifndef __gc_hal_eglplatform_h_
#define __gc_hal_eglplatform_h_
#elif defined(LINUX) && defined(EGL_API_FB) && !defined(__APPLE__)
#if defined(EGL_API_WL)
+
+#if defined(__GNUC__)
+# define inline __inline__ /* GNU keyword. */
+#endif
+
/* Wayland platform. */
-#include "wayland-server.h"
#include <wayland-egl.h>
-#define WL_EGL_NUM_BACKBUFFERS 2
+#define WL_EGL_NUM_BACKBUFFERS 3
typedef struct _gcsWL_VIV_BUFFER
{
- struct wl_buffer wl_buffer;
+ struct wl_resource *wl_buffer;
gcoSURF surface;
+ gctINT32 width, height;
} gcsWL_VIV_BUFFER;
typedef struct _gcsWL_EGL_DISPLAY
{
struct wl_display* wl_display;
struct wl_viv* wl_viv;
+ struct wl_registry *registry;
+ struct wl_event_queue *wl_queue;
+ gctINT swapInterval;
} gcsWL_EGL_DISPLAY;
typedef struct _gcsWL_EGL_BUFFER_INFO
gcePOOL pool;
gctUINT bytes;
gcoSURF surface;
+ gcoSURF attached_surface;
+ gctINT32 invalidate;
+ gctBOOL locked;
} gcsWL_EGL_BUFFER_INFO;
typedef struct _gcsWL_EGL_BUFFER
typedef struct _gcsWL_EGL_WINDOW_INFO
{
+ gctINT32 dx;
+ gctINT32 dy;
gctUINT width;
gctUINT height;
+ gctINT32 attached_width;
+ gctINT32 attached_height;
gceSURF_FORMAT format;
gctUINT bpp;
} gcsWL_EGL_WINDOW_INFO;
struct wl_egl_window
{
+ gcsWL_EGL_DISPLAY* display;
gcsWL_EGL_BUFFER backbuffers[WL_EGL_NUM_BACKBUFFERS];
gcsWL_EGL_WINDOW_INFO info;
gctUINT current;
struct wl_surface* surface;
- struct wl_callback* pending;
+ struct wl_callback* frame_callback;
};
typedef void* HALNativeDisplayType;
IN gctINT Interval
);
+gceSTATUS
+gcoOS_SetSwapIntervalEx(
+ IN HALNativeDisplayType Display,
+ IN gctINT Interval,
+ IN gctPOINTER localDisplay);
+
gceSTATUS
gcoOS_GetSwapInterval(
IN HALNativeDisplayType Display,
OUT gctUINT *Width,
OUT gctUINT *Height
);
+
+#ifdef EGL_API_DRI
+gceSTATUS
+gcoOS_ResizeWindow(
+ IN gctPOINTER localDisplay,
+ IN HALNativeWindowType Drawable,
+ IN gctUINT Width,
+ IN gctUINT Height)
+ ;
+
+#ifdef USE_FREESCALE_EGL_ACCEL
+gceSTATUS
+gcoOS_SwapBuffersGeneric_Async(
+ IN gctPOINTER localDisplay,
+ IN HALNativeWindowType Drawable,
+ IN gcoSURF RenderTarget,
+ IN gcoSURF ResolveTarget,
+ IN gctPOINTER ResolveBits,
+ OUT gctUINT *Width,
+ OUT gctUINT *Height,
+ IN void * resolveRect
+ );
+
+gceSTATUS
+gcoOS_DrawSurface(
+ IN gctPOINTER localDisplay,
+ IN HALNativeWindowType Drawable
+ );
+#endif
+
+#endif
+
#ifdef __cplusplus
}
#endif
#endif /* __gc_hal_eglplatform_h_ */
+
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
typedef enum _halEventType
{
- /* Keyboard event. */
+ /* Keyboard event. */
HAL_KEYBOARD,
- /* Mouse move event. */
+ /* Mouse move event. */
HAL_POINTER,
- /* Mouse button event. */
+ /* Mouse button event. */
HAL_BUTTON,
- /* Application close event. */
- HAL_CLOSE,
+ /* Application close event. */
+ HAL_CLOSE,
- /* Application window has been updated. */
- HAL_WINDOW_UPDATE
+ /* Application window has been updated. */
+ HAL_WINDOW_UPDATE
}
halEventType;
/* Structure that defined keyboard mapping. */
typedef struct _halKeyMap
{
- /* Normal key. */
+ /* Normal key. */
halKeys normal;
- /* Extended key. */
+ /* Extended key. */
halKeys extended;
}
halKeyMap;
/* Event structure. */
typedef struct _halEvent
{
- /* Event type. */
+ /* Event type. */
halEventType type;
- /* Event data union. */
+ /* Event data union. */
union _halEventData
{
- /* Event data for keyboard. */
+ /* Event data for keyboard. */
struct _halKeyboard
{
- /* Scancode. */
- halKeys scancode;
+ /* Scancode. */
+ halKeys scancode;
- /* ASCII characte of the key pressed. */
- char key;
+ /* ASCII characte of the key pressed. */
+ char key;
- /* Flag whether the key was pressed (1) or released (0). */
- char pressed;
+ /* Flag whether the key was pressed (1) or released (0). */
+ char pressed;
}
keyboard;
- /* Event data for pointer. */
+ /* Event data for pointer. */
struct _halPointer
{
- /* Current pointer coordinate. */
- int x;
- int y;
+ /* Current pointer coordinate. */
+ int x;
+ int y;
}
pointer;
- /* Event data for mouse buttons. */
+ /* Event data for mouse buttons. */
struct _halButton
{
- /* Left button state. */
- int left;
+ /* Left button state. */
+ int left;
- /* Middle button state. */
- int middle;
+ /* Middle button state. */
+ int middle;
- /* Right button state. */
- int right;
+ /* Right button state. */
+ int right;
- /* Current pointer coordinate. */
- int x;
- int y;
+ /* Current pointer coordinate. */
+ int x;
+ int y;
}
button;
}
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#ifndef __gc_hal_engine_h_
#define __gc_hal_engine_h_
-#ifndef VIVANTE_NO_3D
#include "gc_hal_types.h"
#include "gc_hal_enum.h"
+#if gcdENABLE_3D
#if gcdENABLE_VG
#include "gc_hal_engine_vg.h"
#endif
typedef struct _gcoINDEX * gcoINDEX;
typedef struct _gcsVERTEX_ATTRIBUTES * gcsVERTEX_ATTRIBUTES_PTR;
typedef struct _gcoVERTEXARRAY * gcoVERTEXARRAY;
+typedef struct _gcoBUFOBJ * gcoBUFOBJ;
#define gcdATTRIBUTE_COUNT 16
-/******************************************************************************\
-********************************* Enumerations *********************************
-\******************************************************************************/
-
-/* Shading format. */
-typedef enum _gceSHADING
-{
- gcvSHADING_SMOOTH,
- gcvSHADING_FLAT_D3D,
- gcvSHADING_FLAT_OPENGL,
-}
-gceSHADING;
-
-/* Culling modes. */
-typedef enum _gceCULL
-{
- gcvCULL_NONE,
- gcvCULL_CCW,
- gcvCULL_CW,
-}
-gceCULL;
-
-/* Fill modes. */
-typedef enum _gceFILL
-{
- gcvFILL_POINT,
- gcvFILL_WIRE_FRAME,
- gcvFILL_SOLID,
-}
-gceFILL;
-
-/* Compare modes. */
-typedef enum _gceCOMPARE
-{
- gcvCOMPARE_NEVER,
- gcvCOMPARE_NOT_EQUAL,
- gcvCOMPARE_LESS,
- gcvCOMPARE_LESS_OR_EQUAL,
- gcvCOMPARE_EQUAL,
- gcvCOMPARE_GREATER,
- gcvCOMPARE_GREATER_OR_EQUAL,
- gcvCOMPARE_ALWAYS,
- gcvCOMPARE_INVALID = -1
-}
-gceCOMPARE;
-
-/* Stencil modes. */
-typedef enum _gceSTENCIL_MODE
-{
- gcvSTENCIL_NONE,
- gcvSTENCIL_SINGLE_SIDED,
- gcvSTENCIL_DOUBLE_SIDED,
-}
-gceSTENCIL_MODE;
-
-/* Stencil operations. */
-typedef enum _gceSTENCIL_OPERATION
-{
- gcvSTENCIL_KEEP,
- gcvSTENCIL_REPLACE,
- gcvSTENCIL_ZERO,
- gcvSTENCIL_INVERT,
- gcvSTENCIL_INCREMENT,
- gcvSTENCIL_DECREMENT,
- gcvSTENCIL_INCREMENT_SATURATE,
- gcvSTENCIL_DECREMENT_SATURATE,
- gcvSTENCIL_OPERATION_INVALID = -1
-}
-gceSTENCIL_OPERATION;
-
-/* Stencil selection. */
-typedef enum _gceSTENCIL_WHERE
-{
- gcvSTENCIL_FRONT,
- gcvSTENCIL_BACK,
-}
-gceSTENCIL_WHERE;
-
-/* Texture addressing selection. */
-typedef enum _gceTEXTURE_WHICH
+typedef enum _gcePROGRAM_STAGE
{
- gcvTEXTURE_S,
- gcvTEXTURE_T,
- gcvTEXTURE_R,
+ gcvPROGRAM_STAGE_VERTEX = 0x0,
+ gcvPROGRAM_STAGE_TES = 0x1,
+ gcvPROGRAM_STAGE_TCS = 0x2,
+ gcvPROGRAM_STAGE_GEOMETRY = 0x3,
+ gcvPROGRAM_STAGE_FRAGMENT = 0x4,
+ gcvPROGRAM_STAGE_COMPUTE = 0x5,
+ gcvPROGRAM_STAGE_OPENCL = 0x6,
+ gcvPROGRAM_STAGE_LAST
}
-gceTEXTURE_WHICH;
+gcePROGRAM_STAGE;
-/* Texture addressing modes. */
-typedef enum _gceTEXTURE_ADDRESSING
+typedef enum _gcePROGRAM_STAGE_BIT
{
- gcvTEXTURE_WRAP,
- gcvTEXTURE_CLAMP,
- gcvTEXTURE_BORDER,
- gcvTEXTURE_MIRROR,
- gcvTEXTURE_MIRROR_ONCE,
+ gcvPROGRAM_STAGE_VERTEX_BIT = 1 << gcvPROGRAM_STAGE_VERTEX,
+ gcvPROGRAM_STAGE_TES_BIT = 1 << gcvPROGRAM_STAGE_TES,
+ gcvPROGRAM_STAGE_TCS_BIT = 1 << gcvPROGRAM_STAGE_TCS,
+ gcvPROGRAM_STAGE_GEOMETRY_BIT = 1 << gcvPROGRAM_STAGE_GEOMETRY,
+ gcvPROGRAM_STAGE_FRAGMENT_BIT = 1 << gcvPROGRAM_STAGE_FRAGMENT,
+ gcvPROGRAM_STAGE_COMPUTE_BIT = 1 << gcvPROGRAM_STAGE_COMPUTE,
+ gcvPROGRAM_STAGE_OPENCL_BIT = 1 << gcvPROGRAM_STAGE_OPENCL,
}
-gceTEXTURE_ADDRESSING;
+gcePROGRAM_STAGE_BIT;
-/* Texture filters. */
-typedef enum _gceTEXTURE_FILTER
-{
- gcvTEXTURE_NONE,
- gcvTEXTURE_POINT,
- gcvTEXTURE_LINEAR,
- gcvTEXTURE_ANISOTROPIC,
-}
-gceTEXTURE_FILTER;
-
-/* Primitive types. */
-typedef enum _gcePRIMITIVE
-{
- gcvPRIMITIVE_POINT_LIST,
- gcvPRIMITIVE_LINE_LIST,
- gcvPRIMITIVE_LINE_STRIP,
- gcvPRIMITIVE_LINE_LOOP,
- gcvPRIMITIVE_TRIANGLE_LIST,
- gcvPRIMITIVE_TRIANGLE_STRIP,
- gcvPRIMITIVE_TRIANGLE_FAN,
- gcvPRIMITIVE_RECTANGLE,
-}
-gcePRIMITIVE;
-
-/* Index types. */
-typedef enum _gceINDEX_TYPE
-{
- gcvINDEX_8,
- gcvINDEX_16,
- gcvINDEX_32,
-}
-gceINDEX_TYPE;
/******************************************************************************\
********************************* gcoHAL Object *********************************
\******************************************************************************/
-/* Query the target capabilities. */
-gceSTATUS
-gcoHAL_QueryTargetCaps(
- IN gcoHAL Hal,
- OUT gctUINT * MaxWidth,
- OUT gctUINT * MaxHeight,
- OUT gctUINT * MultiTargetCount,
- OUT gctUINT * MaxSamples
- );
-
-gceSTATUS
-gcoHAL_SetDepthOnly(
- IN gcoHAL Hal,
- IN gctBOOL Enable
- );
-
gceSTATUS
gcoHAL_QueryShaderCaps(
IN gcoHAL Hal,
OUT gctUINT * Varyings
);
+gceSTATUS
+gcoHAL_QueryShaderCapsEx(
+ IN gcoHAL Hal,
+ OUT gctUINT * ShaderCoreCount,
+ OUT gctUINT * ThreadCount,
+ OUT gctUINT * VertexInstructionCount,
+ OUT gctUINT * FragmentInstructionCount
+ );
+
+gceSTATUS
+gcoHAL_QuerySamplerBase(
+ IN gcoHAL Hal,
+ OUT gctUINT32 * VertexCount,
+ OUT gctINT_PTR VertexBase,
+ OUT gctUINT32 * FragmentCount,
+ OUT gctINT_PTR FragmentBase
+ );
+
+gceSTATUS
+gcoHAL_QueryUniformBase(
+ IN gcoHAL Hal,
+ OUT gctUINT32 * VertexBase,
+ OUT gctUINT32 * FragmentBase
+ );
+
gceSTATUS
gcoHAL_QueryTextureCaps(
IN gcoHAL Hal,
/*----------------------------------------------------------------------------*/
/*--------------------------------- gcoSURF 3D --------------------------------*/
+typedef enum _gceBLIT_FLAG
+{
+ gcvBLIT_FLAG_SKIP_DEPTH_WRITE = 0x1,
+ gcvBLIT_FLAG_SKIP_STENCIL_WRITE = 0x2,
+} gceBLIT_FLAG;
-/* Copy surface. */
-gceSTATUS
-gcoSURF_Copy(
- IN gcoSURF Surface,
- IN gcoSURF Source
- );
+typedef struct _gcsSURF_BLIT_ARGS
+{
+ gcoSURF srcSurface;
+ gctINT srcX, srcY, srcZ;
+ gctINT srcWidth, srcHeight, srcDepth;
+ gcoSURF dstSurface;
+ gctINT dstX, dstY, dstZ;
+ gctINT dstWidth, dstHeight, dstDepth;
+ gctBOOL xReverse;
+ gctBOOL yReverse;
+ gctBOOL scissorTest;
+ gcsRECT scissor;
+ gctUINT flags;
+}
+gcsSURF_BLIT_ARGS;
+
+
+
+
+/* Clear flags. */
+typedef enum _gceCLEAR
+{
+ gcvCLEAR_COLOR = 0x1,
+ gcvCLEAR_DEPTH = 0x2,
+ gcvCLEAR_STENCIL = 0x4,
+ gcvCLEAR_HZ = 0x8,
+ gcvCLEAR_HAS_VAA = 0x10,
+ gcvCLEAR_WITH_GPU_ONLY = 0x100,
+ gcvCLEAR_WITH_CPU_ONLY = 0x200,
+}
+gceCLEAR;
+
+typedef struct _gcsSURF_CLEAR_ARGS
+{
+ /*
+ ** Color to fill the color portion of the framebuffer when clear
+ ** is called.
+ */
+ struct {
+ gcuVALUE r;
+ gcuVALUE g;
+ gcuVALUE b;
+ gcuVALUE a;
+ /*
+ ** Color has multiple value type so we must specify it.
+ */
+ gceVALUE_TYPE valueType;
+ } color;
+
+ gcuVALUE depth;
+
+ gctUINT stencil;
+
+
+
+ /*
+ ** stencil bit-wise mask
+ */
+ gctUINT8 stencilMask;
+ /*
+ ** Depth Write Mask
+ */
+ gctBOOL depthMask;
+ /*
+ ** 4-bit channel Mask: ABGR:MSB->LSB
+ */
+ gctUINT8 colorMask;
+ /*
+ ** If ClearRect is NULL, it means full clear
+ */
+ gcsRECT_PTR clearRect;
+ /*
+ ** clear flags
+ */
+ gceCLEAR flags;
+
+ /*
+ ** Offset in surface to cube/array/3D
+ */
+ gctUINT32 offset;
+
+} gcsSURF_CLEAR_ARGS;
+
+
+typedef gcsSURF_CLEAR_ARGS* gcsSURF_CLEAR_ARGS_PTR;
+
+typedef struct _gscSURF_BLITDRAW_BLIT
+{
+ gcoSURF srcSurface;
+ gcoSURF dstSurface;
+ gcsRECT srcRect;
+ gcsRECT dstRect;
+ gceTEXTURE_FILTER filterMode;
+ gctBOOL xReverse;
+ gctBOOL yReverse;
+ gctBOOL scissorEnabled;
+ gcsRECT scissor;
+}gscSURF_BLITDRAW_BLIT;
+
+
+typedef enum _gceBLITDRAW_TYPE
+{
+ gcvBLITDRAW_CLEAR = 0,
+ gcvBLITDRAW_BLIT = 1,
+
+ /* last number, not a real type */
+ gcvBLITDRAW_NUM_TYPE
+ }
+gceBLITDRAW_TYPE;
+
+
+typedef struct _gscSURF_BLITDRAW_ARGS
+{
+ /* always the fist member */
+ gceHAL_ARG_VERSION version;
+
+ union _gcsSURF_BLITDRAW_ARGS_UNION
+ {
+ struct _gscSURF_BLITDRAW_ARG_v1
+ {
+ /* Whether it's clear or blit operation, can be extended. */
+ gceBLITDRAW_TYPE type;
+
+ union _gscSURF_BLITDRAW_UNION
+ {
+ gscSURF_BLITDRAW_BLIT blit;
+
+ struct _gscSURF_BLITDRAW_CLEAR
+ {
+ gcsSURF_CLEAR_ARGS clearArgs;
+ gcoSURF rtSurface;
+ gcoSURF dsSurface;
+ } clear;
+ } u;
+ } v1;
+ } uArgs;
+}
+gcsSURF_BLITDRAW_ARGS;
+
+
+typedef struct _gcsSURF_RESOLVE_ARGS
+{
+ gceHAL_ARG_VERSION version;
+ union _gcsSURF_RESOLVE_ARGS_UNION
+ {
+ struct _gcsSURF_RESOLVE_ARG_v1
+ {
+ gctBOOL yInverted;
+ }v1;
+ } uArgs;
+}
+gcsSURF_RESOLVE_ARGS;
-/* Clear surface. */
+
+/* CPU Blit with format (including linear <-> tile) conversion*/
gceSTATUS
-gcoSURF_Clear(
- IN gcoSURF Surface,
- IN gctUINT Flags
+gcoSURF_BlitCPU(
+ gcsSURF_BLIT_ARGS* args
);
-/* Set number of samples for a gcoSURF object. */
+
gceSTATUS
-gcoSURF_SetSamples(
- IN gcoSURF Surface,
- IN gctUINT Samples
+gcoSURF_BlitDraw(
+ IN gcsSURF_BLITDRAW_ARGS *args
);
+#endif /* gcdENABLE_3D */
+
-/* Get the number of samples per pixel. */
+
+#if gcdENABLE_3D
+/* Clear surface function. */
gceSTATUS
-gcoSURF_GetSamples(
+gcoSURF_Clear(
IN gcoSURF Surface,
- OUT gctUINT_PTR Samples
+ IN gcsSURF_CLEAR_ARGS_PTR clearArg
);
-/* Clear rectangular surface. */
+/* Preserve pixels from source. */
gceSTATUS
-gcoSURF_ClearRect(
- IN gcoSURF Surface,
- IN gctINT Left,
- IN gctINT Top,
- IN gctINT Right,
- IN gctINT Bottom,
- IN gctUINT Flags
+gcoSURF_Preserve(
+ IN gcoSURF Source,
+ IN gcoSURF Dest,
+ IN gcsRECT_PTR MaskRect
);
+
/* TO BE REMOVED */
gceSTATUS
depr_gcoSURF_Resolve(
);
gceSTATUS
-gcoSURF_IsHWResolveable(
+gcoSURF_ResolveEx(
+ IN gcoSURF SrcSurface,
+ IN gcoSURF DestSurface,
+ IN gcsSURF_RESOLVE_ARGS *args
+ );
+
+
+/* Resolve rectangular area of a surface. */
+gceSTATUS
+gcoSURF_ResolveRect(
IN gcoSURF SrcSurface,
IN gcoSURF DestSurface,
IN gcsPOINT_PTR SrcOrigin,
/* Resolve rectangular area of a surface. */
gceSTATUS
-gcoSURF_ResolveRect(
+gcoSURF_ResolveRectEx(
+ IN gcoSURF SrcSurface,
+ IN gcoSURF DestSurface,
+ IN gcsPOINT_PTR SrcOrigin,
+ IN gcsPOINT_PTR DestOrigin,
+ IN gcsPOINT_PTR RectSize,
+ IN gcsSURF_RESOLVE_ARGS *args
+ );
+
+
+gceSTATUS
+gcoSURF_GetResolveAlignment(
+ IN gcoSURF Surface,
+ OUT gctUINT *originX,
+ OUT gctUINT *originY,
+ OUT gctUINT *sizeX,
+ OUT gctUINT *sizeY
+ );
+
+gceSTATUS
+gcoSURF_IsHWResolveable(
IN gcoSURF SrcSurface,
IN gcoSURF DestSurface,
IN gcsPOINT_PTR SrcOrigin,
IN gcoSURF Surface
);
-#if gcdSYNC
gceSTATUS
gcoSURF_GetFence(
IN gcoSURF Surface
);
+
+gceSTATUS
+gcoBUFOBJ_GetFence(
+ IN gcoBUFOBJ bufObj
+ );
+
+gceSTATUS
+gcoBUFOBJ_WaitFence(
+ IN gcoBUFOBJ bufObj
+ );
+
+gceSTATUS
+gcoBUFOBJ_IsFenceEnabled(
+ IN gcoBUFOBJ bufObj
+ );
+
gceSTATUS
gcoSURF_WaitFence(
IN gcoSURF Surface
gcoINDEX_WaitFence(
IN gcoINDEX index
);
-#endif
+
+gceSTATUS
+gcoSURF_3DBlitClearRect(
+ IN gcoSURF Surface,
+ IN gcsSURF_CLEAR_ARGS_PTR ClearArgs
+ );
+
+
+gceSTATUS
+gcoSURF_3DBlitBltRect(
+ IN gcoSURF SrcSurf,
+ IN gcoSURF DestSurf,
+ IN gcsPOINT_PTR SrcOrigin,
+ IN gcsPOINT_PTR DestOrigin,
+ IN gcsPOINT_PTR RectSize
+ );
+
+gceSTATUS
+gcoSURF_3DBlitCopy(
+ IN gctUINT32 SrcAddress,
+ IN gctUINT32 DestAddress,
+ IN gctUINT32 Bytes
+ );
+
/******************************************************************************\
******************************** gcoINDEX Object *******************************
gceSTATUS
gcoINDEX_UploadOffset(
IN gcoINDEX Index,
- IN gctUINT32 Offset,
+ IN gctSIZE_T Offset,
IN gctCONST_POINTER Buffer,
IN gctSIZE_T Bytes
);
IN gctUINT Buffers
);
-gceSTATUS
-gcoINDEX_UploadDynamic(
- IN gcoINDEX Index,
- IN gctCONST_POINTER Data,
- IN gctSIZE_T Bytes
- );
-
/******************************************************************************\
********************************** gco3D Object *********************************
\******************************************************************************/
-/* Clear flags. */
-typedef enum _gceCLEAR
-{
- gcvCLEAR_COLOR = 0x1,
- gcvCLEAR_DEPTH = 0x2,
- gcvCLEAR_STENCIL = 0x4,
- gcvCLEAR_HZ = 0x8,
- gcvCLEAR_HAS_VAA = 0x10,
-}
-gceCLEAR;
-
/* Blending targets. */
typedef enum _gceBLEND_UNIT
{
IN gceAPI ApiType
);
+/* Get 3D API type. */
+gceSTATUS
+gco3D_GetAPI(
+ IN gco3D Engine,
+ OUT gceAPI * ApiType
+ );
+
/* Set render target. */
gceSTATUS
gco3D_SetTarget(
IN gcoSURF Surface
);
+gceSTATUS
+gco3D_SetTargetEx(
+ IN gco3D Engine,
+ IN gctUINT32 TargetIndex,
+ IN gcoSURF Surface,
+ IN gctUINT32 LayerIndex
+ );
+
+gceSTATUS
+gco3D_UnsetTargetEx(
+ IN gco3D Engine,
+ IN gctUINT32 TargetIndex,
+ IN gcoSURF Surface
+ );
+
+gceSTATUS
+gco3D_SetTargetOffsetEx(
+ IN gco3D Engine,
+ IN gctUINT32 TargetIndex,
+ IN gctSIZE_T Offset
+ );
+
+
+gceSTATUS
+gco3D_SetPSOutputMapping(
+ IN gco3D Engine,
+ IN gctINT32 * psOutputMapping
+ );
+
+
/* Set depth buffer. */
gceSTATUS
gco3D_SetDepth(
IN gcoSURF Surface
);
+gceSTATUS
+gco3D_SetDepthBufferOffset(
+ IN gco3D Engine,
+ IN gctSIZE_T Offset
+ );
+
/* Unset depth buffer. */
gceSTATUS
gco3D_UnsetDepth(
IN gctUINT32 Stencil
);
-/* Clear a Rect sub-surface. */
-gceSTATUS
-gco3D_ClearRect(
- IN gco3D Engine,
- IN gctUINT32 Address,
- IN gctPOINTER Memory,
- IN gctUINT32 Stride,
- IN gceSURF_FORMAT Format,
- IN gctINT32 Left,
- IN gctINT32 Top,
- IN gctINT32 Right,
- IN gctINT32 Bottom,
- IN gctUINT32 Width,
- IN gctUINT32 Height,
- IN gctUINT32 Flags
- );
-
-/* Clear surface. */
-gceSTATUS
-gco3D_Clear(
- IN gco3D Engine,
- IN gctUINT32 Address,
- IN gctUINT32 Stride,
- IN gceSURF_FORMAT Format,
- IN gctUINT32 Width,
- IN gctUINT32 Height,
- IN gctUINT32 Flags
- );
-
-
-/* Clear tile status. */
-gceSTATUS
-gco3D_ClearTileStatus(
- IN gco3D Engine,
- IN gcsSURF_INFO_PTR Surface,
- IN gctUINT32 TileStatusAddress,
- IN gctUINT32 Flags
- );
-
/* Set shading mode. */
gceSTATUS
gco3D_SetShading(
IN gctBOOL Enable
);
-/* Enable or disable all early depth operations. */
+/* Deprecated: Enable or disable all early depth operations. */
gceSTATUS
gco3D_SetAllEarlyDepthModes(
IN gco3D Engine,
IN gctBOOL Disable
);
+/* Enable or disable all early depth operations. */
+gceSTATUS
+gco3D_SetAllEarlyDepthModesEx(
+ IN gco3D Engine,
+ IN gctBOOL Disable,
+ IN gctBOOL DisableModify,
+ IN gctBOOL DisablePassZ
+ );
+
/* Switch dynamic early mode */
gceSTATUS
gco3D_SwitchDynamicEarlyDepthMode(
gceSTENCIL_MODE mode;
gctUINT8 maskFront;
- gctUINT8 maskBack;
+ gctUINT8 maskBack;
gctUINT8 writeMaskFront;
gctUINT8 writeMaskBack;
gco3D_DrawPrimitives(
IN gco3D Engine,
IN gcePRIMITIVE Type,
- IN gctINT StartVertex,
+ IN gctSIZE_T StartVertex,
IN gctSIZE_T PrimitiveCount
);
+gceSTATUS
+gco3D_DrawInstancedPrimitives(
+ IN gco3D Engine,
+ IN gcePRIMITIVE Type,
+ IN gctBOOL DrawIndex,
+ IN gctSIZE_T StartVertex,
+ IN gctSIZE_T StartIndex,
+ IN gctSIZE_T PrimitiveCount,
+ IN gctSIZE_T VertexCount,
+ IN gctSIZE_T InstanceCount
+ );
+
gceSTATUS
gco3D_DrawPrimitivesCount(
IN gco3D Engine,
gco3D_DrawIndexedPrimitives(
IN gco3D Engine,
IN gcePRIMITIVE Type,
- IN gctINT BaseVertex,
- IN gctINT StartIndex,
+ IN gctSIZE_T BaseVertex,
+ IN gctSIZE_T StartIndex,
IN gctSIZE_T PrimitiveCount
);
IN gctSIZE_T PrimitiveCount
);
+/* Draw a element from pattern */
+gceSTATUS
+gco3D_DrawPattern(
+ IN gco3D Engine,
+ IN gcsFAST_FLUSH_PTR FastFlushInfo
+ );
+
/* Enable or disable anti-aliasing. */
gceSTATUS
gco3D_SetAntiAlias(
IN gceWHERE To,
IN gceHOW How);
+/* Explicitly flush shader L1 cache */
+gceSTATUS
+gco3D_FlushSHL1Cache(
+ IN gco3D Engine
+ );
+
/* Set the subpixels center. */
gceSTATUS
gco3D_SetCentroids(
IN gctUINT8 Rop
);
+gceSTATUS
+gco3D_SetOQ(
+ IN gco3D Engine,
+ INOUT gctPOINTER * Result,
+ IN gctBOOL Enable
+ );
+
+gceSTATUS
+gco3D_GetOQ(
+ IN gco3D Engine,
+ IN gctPOINTER Result,
+ OUT gctINT64 * Logical
+ );
+
+gceSTATUS
+gco3D_DeleteOQ(
+ IN gco3D Engine,
+ INOUT gctPOINTER Result
+ );
+
+gceSTATUS
+gco3D_SetColorOutCount(
+ IN gco3D Engine,
+ IN gctUINT32 ColorOutCount
+ );
+
+gceSTATUS
+gco3D_Set3DEngine(
+ IN gco3D Engine
+ );
+
+gceSTATUS
+gco3D_UnSet3DEngine(
+ IN gco3D Engine
+ );
+
+gceSTATUS
+gco3D_Get3DEngine(
+ OUT gco3D * Engine
+ );
+
+
/* OCL thread walker information. */
typedef struct _gcsTHREAD_WALKER_INFO * gcsTHREAD_WALKER_INFO_PTR;
typedef struct _gcsTHREAD_WALKER_INFO
IN gcsTHREAD_WALKER_INFO_PTR Info
);
-/* Set w clip and w plane limit value. */
gceSTATUS
-gco3D_SetWClipEnable(
- IN gco3D Engine,
- IN gctBOOL Enable
+gco3D_GetClosestRenderFormat(
+ IN gco3D Engine,
+ IN gceSURF_FORMAT InFormat,
+ OUT gceSURF_FORMAT* OutFormat
+ );
+
+/* Set w clip and w plane limit value. */
+gceSTATUS
+gco3D_SetWClipEnable(
+ IN gco3D Engine,
+ IN gctBOOL Enable
);
gceSTATUS
gceSTATUS
gco3D_SetWPlaneLimitF(
- IN gco3D Engine,
- IN gctFLOAT Value
+ IN gco3D Engine,
+ IN gctFLOAT Value
);
gceSTATUS
gco3D_SetWPlaneLimitX(
- IN gco3D Engine,
- IN gctFIXED_POINT Value
+ IN gco3D Engine,
+ IN gctFIXED_POINT Value
);
-
gceSTATUS
gco3D_SetWPlaneLimit(
IN gco3D Engine,
IN gctFLOAT Value
);
+gceSTATUS
+gco3D_PrimitiveRestart(
+ IN gco3D Engine,
+ IN gctBOOL PrimitiveRestart);
+
+#if gcdSTREAM_OUT_BUFFER
+
+gceSTATUS
+gco3D_QueryStreamOut(
+ IN gco3D Engine,
+ IN gctUINT32 OriginalIndexAddress,
+ IN gctUINT32 OriginalIndexOffset,
+ IN gctUINT32 OriginalIndexCount,
+ OUT gctBOOL_PTR Found
+ );
+
+gceSTATUS
+gco3D_StartStreamOut(
+ IN gco3D Engine,
+ IN gctINT StreamOutStatus,
+ IN gctUINT32 IndexAddress,
+ IN gctUINT32 IndexOffset,
+ IN gctUINT32 IndexCount
+ );
+
+gceSTATUS
+gco3D_StopStreamOut(
+ IN gco3D Engine
+ );
+
+gceSTATUS
+gco3D_ReplayStreamOut(
+ IN gco3D Engine,
+ IN gctUINT32 IndexAddress,
+ IN gctUINT32 IndexOffset,
+ IN gctUINT32 IndexCount
+ );
+
+gceSTATUS
+gco3D_EndStreamOut(
+ IN gco3D Engine
+ );
+
+#endif
+
/*----------------------------------------------------------------------------*/
/*-------------------------- gco3D Fragment Processor ------------------------*/
IN gctINT Scale
);
-/* Invoke OCL thread walker. */
-gceSTATUS
-gcoHARDWARE_InvokeThreadWalker(
- IN gcsTHREAD_WALKER_INFO_PTR Info
- );
-
/******************************************************************************\
******************************* gcoTEXTURE Object *******************************
\******************************************************************************/
}
gceTEXTURE_FACE;
-#if gcdFORCE_MIPMAP
-typedef enum
-{
- gcvForceMipDisabled = 0,
- gcvForceMipEnable = 1,
- gcvForceMipGenerated = 2,
- gcvForceMipNever = 3,
-}gceFORCE_MIPMAP;
-#endif
-
typedef struct _gcsTEXTURE
{
/* Addressing modes. */
gceTEXTURE_ADDRESSING t;
gceTEXTURE_ADDRESSING r;
+ gceTEXTURE_SWIZZLE swizzle[gcvTEXTURE_COMPONENT_NUM];
+
/* Border color. */
- gctUINT8 border[4];
+ gctUINT8 border[gcvTEXTURE_COMPONENT_NUM];
/* Filters. */
gceTEXTURE_FILTER minFilter;
gceTEXTURE_FILTER magFilter;
gceTEXTURE_FILTER mipFilter;
gctUINT anisoFilter;
- gctBOOL forceTopLevel;
- gctBOOL autoMipmap;
-#if gcdFORCE_MIPMAP
- gceFORCE_MIPMAP forceMipmap;
-#endif
+
/* Level of detail. */
- gctFIXED_POINT lodBias;
- gctFIXED_POINT lodMin;
- gctFIXED_POINT lodMax;
+ gctFLOAT lodBias;
+ gctFLOAT lodMin;
+ gctFLOAT lodMax;
+
+ /* base/max level */
+ gctINT32 baseLevel;
+ gctINT32 maxLevel;
+
+ /* depth texture comparison */
+ gceTEXTURE_COMPARE_MODE compareMode;
+ gceCOMPARE compareFunc;
+
}
gcsTEXTURE, * gcsTEXTURE_PTR;
OUT gcoTEXTURE * Texture
);
+/* Construct a new gcoTEXTURE object with type information. */
+gceSTATUS
+gcoTEXTURE_ConstructEx(
+ IN gcoHAL Hal,
+ IN gceTEXTURE_TYPE Type,
+ OUT gcoTEXTURE * Texture
+ );
+
+
/* Construct a new sized gcoTEXTURE object. */
gceSTATUS
gcoTEXTURE_ConstructSized(
gcoTEXTURE_Destroy(
IN gcoTEXTURE Texture
);
-#if gcdFORCE_MIPMAP
-gceSTATUS
-gcoTEXTURE_DestroyForceMipmap(
- IN gcoTEXTURE Texture
- );
-
-gceSTATUS
-gcoTEXTURE_GetMipLevels(
- IN gcoTEXTURE Texture,
- OUT gctINT * levels
- );
-#endif
-/* Replace a mipmap in gcoTEXTURE object. */
-gceSTATUS
-gcoTEXTURE_ReplaceMipMap(
- IN gcoTEXTURE Texture,
- IN gctUINT Level,
- IN gctUINT Width,
- IN gctUINT Height,
- IN gctINT imageFormat,
- IN gceSURF_FORMAT Format,
- IN gctUINT Depth,
- IN gctUINT Faces,
- IN gcePOOL Pool
- );
/* Upload data to an gcoTEXTURE object. */
gceSTATUS
gcoTEXTURE_Upload(
IN gcoTEXTURE Texture,
+ IN gctINT MipMap,
IN gceTEXTURE_FACE Face,
- IN gctUINT Width,
- IN gctUINT Height,
+ IN gctSIZE_T Width,
+ IN gctSIZE_T Height,
IN gctUINT Slice,
IN gctCONST_POINTER Memory,
- IN gctINT Stride,
- IN gceSURF_FORMAT Format
+ IN gctSIZE_T Stride,
+ IN gceSURF_FORMAT Format,
+ IN gceSURF_COLOR_SPACE SrcColorSpace
);
/* Upload data to an gcoTEXTURE object. */
gceSTATUS
gcoTEXTURE_UploadSub(
IN gcoTEXTURE Texture,
- IN gctUINT MipMap,
+ IN gctINT MipMap,
IN gceTEXTURE_FACE Face,
- IN gctUINT X,
- IN gctUINT Y,
- IN gctUINT Width,
- IN gctUINT Height,
+ IN gctSIZE_T X,
+ IN gctSIZE_T Y,
+ IN gctSIZE_T Width,
+ IN gctSIZE_T Height,
IN gctUINT Slice,
IN gctCONST_POINTER Memory,
- IN gctINT Stride,
- IN gceSURF_FORMAT Format
+ IN gctSIZE_T Stride,
+ IN gceSURF_FORMAT Format,
+ IN gceSURF_COLOR_SPACE SrcColorSpace,
+ IN gctUINT32 PhysicalAddress
);
+
/* Upload YUV data to an gcoTEXTURE object. */
gceSTATUS
gcoTEXTURE_UploadYUV(
gceSTATUS
gcoTEXTURE_UploadCompressed(
IN gcoTEXTURE Texture,
+ IN gctINT MipMap,
IN gceTEXTURE_FACE Face,
- IN gctUINT Width,
- IN gctUINT Height,
+ IN gctSIZE_T Width,
+ IN gctSIZE_T Height,
IN gctUINT Slice,
IN gctCONST_POINTER Memory,
IN gctSIZE_T Bytes
gceSTATUS
gcoTEXTURE_UploadCompressedSub(
IN gcoTEXTURE Texture,
- IN gctUINT MipMap,
+ IN gctINT MipMap,
IN gceTEXTURE_FACE Face,
- IN gctUINT XOffset,
- IN gctUINT YOffset,
- IN gctUINT Width,
- IN gctUINT Height,
+ IN gctSIZE_T XOffset,
+ IN gctSIZE_T YOffset,
+ IN gctSIZE_T Width,
+ IN gctSIZE_T Height,
IN gctUINT Slice,
IN gctCONST_POINTER Memory,
IN gctSIZE_T Size
);
-/* GetImageFormat of texture. */
-gceSTATUS
-gcoTEXTURE_GetImageFormat(
- IN gcoTEXTURE Texture,
- IN gctUINT MipMap,
- OUT gctINT * ImageFormat
- );
-
/* Get gcoSURF object for a mipmap level. */
gceSTATUS
gcoTEXTURE_GetMipMap(
IN gctUINT MipMap,
IN gceTEXTURE_FACE Face,
OUT gcoSURF * Surface,
- OUT gctUINT32_PTR Offset
+ OUT gctSIZE_T_PTR Offset
+ );
+
+gceSTATUS
+gcoTEXTURE_GetMipMapSlice(
+ IN gcoTEXTURE Texture,
+ IN gctUINT MipMap,
+ IN gctUINT Slice,
+ OUT gcoSURF * Surface,
+ OUT gctSIZE_T_PTR Offset
);
gceSTATUS
gcoTEXTURE_AddMipMap(
IN gcoTEXTURE Texture,
IN gctINT Level,
- IN gctINT imageFormat,
+ IN gctINT InternalFormat,
IN gceSURF_FORMAT Format,
- IN gctUINT Width,
- IN gctUINT Height,
- IN gctUINT Depth,
+ IN gctSIZE_T Width,
+ IN gctSIZE_T Height,
+ IN gctSIZE_T Depth,
IN gctUINT Faces,
IN gcePOOL Pool,
OUT gcoSURF * Surface
);
gceSTATUS
-gcoTEXTURE_AddMipMapFromClient(
+gcoTEXTURE_AddMipMapWithFlag(
IN gcoTEXTURE Texture,
- IN gctINT Level,
- IN gcoSURF Surface
+ IN gctINT Level,
+ IN gctINT InternalFormat,
+ IN gceSURF_FORMAT Format,
+ IN gctSIZE_T Width,
+ IN gctSIZE_T Height,
+ IN gctSIZE_T Depth,
+ IN gctUINT Faces,
+ IN gcePOOL Pool,
+ IN gctBOOL Protected,
+ OUT gcoSURF * Surface
);
gceSTATUS
-gcoTEXTURE_AddMipMapFromSurface(
+gcoTEXTURE_AddMipMapFromClient(
IN gcoTEXTURE Texture,
IN gctINT Level,
IN gcoSURF Surface
);
gceSTATUS
-gcoTEXTURE_SetMaxLevel(
+gcoTEXTURE_AddMipMapFromSurface(
IN gcoTEXTURE Texture,
- IN gctUINT Levels
+ IN gctINT Level,
+ IN gcoSURF Surface
);
gceSTATUS
IN gcoTEXTURE Texture
);
+gceSTATUS
+gcoTEXTURE_FlushVS(
+ IN gcoTEXTURE Texture
+ );
+
gceSTATUS
gcoTEXTURE_QueryCaps(
IN gcoHAL Hal,
);
gceSTATUS
-gcoTEXTURE_GetTiling(
- IN gcoTEXTURE Texture,
- IN gctINT preferLevel,
- OUT gceTILING * Tiling
+gcoTEXTURE_GetClosestFormat(
+ IN gcoHAL Hal,
+ IN gceSURF_FORMAT InFormat,
+ OUT gceSURF_FORMAT* OutFormat
);
gceSTATUS
-gcoTEXTURE_GetClosestFormat(
+gcoTEXTURE_GetClosestFormatEx(
IN gcoHAL Hal,
IN gceSURF_FORMAT InFormat,
+ IN gceTEXTURE_TYPE TextureType,
OUT gceSURF_FORMAT* OutFormat
);
+gceSTATUS
+gcoTEXTURE_GetFormatInfo(
+ IN gcoTEXTURE Texture,
+ IN gctINT preferLevel,
+ OUT gcsSURF_FORMAT_INFO_PTR * TxFormatInfo
+ );
+
+gceSTATUS
+gcoTEXTURE_GetTextureFormatName(
+ IN gcsSURF_FORMAT_INFO_PTR TxFormatInfo,
+ OUT gctCONST_STRING * TxName
+ );
+
gceSTATUS
gcoTEXTURE_RenderIntoMipMap(
IN gcoTEXTURE Texture,
);
gceSTATUS
-gcoTEXTURE_IsRenderable(
+gcoTEXTURE_RenderIntoMipMap2(
IN gcoTEXTURE Texture,
- IN gctUINT Level
+ IN gctINT Level,
+ IN gctBOOL Sync
);
gceSTATUS
-gcoTEXTURE_IsRenderableEx(
+gcoTEXTURE_IsRenderable(
IN gcoTEXTURE Texture,
IN gctUINT Level
);
gceSTATUS
gcoTEXTURE_IsComplete(
IN gcoTEXTURE Texture,
+ IN gcsTEXTURE_PTR Info,
+ IN gctINT BaseLevel,
IN gctINT MaxLevel
);
IN gcsTEXTURE_PTR Info
);
+gceSTATUS
+gcoTEXTURE_BindTextureEx(
+ IN gcoTEXTURE Texture,
+ IN gctINT Target,
+ IN gctINT Sampler,
+ IN gcsTEXTURE_PTR Info,
+ IN gctINT textureLayer
+ );
+
+gceSTATUS
+gcoTEXTURE_InitParams(
+ IN gcoHAL Hal,
+ IN gcsTEXTURE_PTR TexParams
+ );
+
+gceSTATUS
+gcoTEXTURE_SetDepthTextureFlag(
+ IN gcoTEXTURE Texture,
+ IN gctBOOL unsized
+ );
+
+
/******************************************************************************\
******************************* gcoSTREAM Object ******************************
\******************************************************************************/
gcvVERTEX_FLOAT,
gcvVERTEX_UNSIGNED_INT_10_10_10_2,
gcvVERTEX_INT_10_10_10_2,
+ gcvVERTEX_UNSIGNED_INT_2_10_10_10_REV,
+ gcvVERTEX_INT_2_10_10_10_REV,
+ /* integer format */
+ gcvVERTEX_INT8,
+ gcvVERTEX_INT16,
+ gcvVERTEX_INT32,
}
gceVERTEX_FORMAT;
+/* What the SW converting scheme to create temp attrib */
+typedef enum _gceATTRIB_SCHEME
+{
+ gcvATTRIB_SCHEME_KEEP = 0,
+ gcvATTRIB_SCHEME_2_10_10_10_REV_TO_FLOAT,
+ gcvATTRIB_SCHEME_BYTE_TO_INT,
+ gcvATTRIB_SCHEME_SHORT_TO_INT,
+ gcvATTRIB_SCHEME_UBYTE_TO_UINT,
+ gcvATTRIB_SCHEME_USHORT_TO_UINT,
+} gceATTRIB_SCHEME;
+
gceSTATUS
gcoSTREAM_Construct(
IN gcoHAL Hal,
gcoSTREAM_Upload(
IN gcoSTREAM Stream,
IN gctCONST_POINTER Buffer,
- IN gctUINT32 Offset,
+ IN gctSIZE_T Offset,
IN gctSIZE_T Bytes,
IN gctBOOL Dynamic
);
IN gctUINT32 Stride
);
+gceSTATUS
+gcoSTREAM_Size(
+ IN gcoSTREAM Stream,
+ OUT gctSIZE_T *Size
+ );
+
+gceSTATUS
+gcoSTREAM_Node(
+ IN gcoSTREAM Stream,
+ OUT gcsSURF_NODE_PTR * Node
+ );
+
gceSTATUS
gcoSTREAM_Lock(
IN gcoSTREAM Stream,
IN gceCACHEOPERATION Operation
);
+gceSTATUS
+gcoSTREAM_CPUCacheOperation_Range(
+ IN gcoSTREAM Stream,
+ IN gctSIZE_T Offset,
+ IN gctSIZE_T Length,
+ IN gceCACHEOPERATION Operation
+ );
+
/******************************************************************************\
******************************** gcoVERTEX Object ******************************
\******************************************************************************/
/*******************************************************************************
***** gcoVERTEXARRAY Object ***************************************************/
+typedef struct _gcsATTRIBUTE
+{
+ /* Enabled. */
+ gctBOOL enable;
+
+ /* Number of components. */
+ gctINT size;
+
+ /* Attribute format. */
+ gceVERTEX_FORMAT format;
+
+ /* Flag whether the attribute is normalized or not. */
+ gctBOOL normalized;
+
+ /* Stride of the component. */
+ gctSIZE_T stride;
+
+ /* Divisor of the attribute */
+ gctUINT divisor;
+
+ /* Pointer to the attribute data. */
+ gctCONST_POINTER pointer;
+
+ /* Stream object owning the attribute data. */
+ gcoBUFOBJ stream;
+
+ /* Generic values for attribute. */
+ gctFLOAT genericValue[4];
+
+ /* Generic size for attribute. */
+ gctINT genericSize;
+
+ /* Vertex shader linkage. */
+ gctUINT linkage;
+
+#if gcdUSE_WCLIP_PATCH
+ /* Does it hold positions? */
+ gctBOOL isPosition;
+#endif
+
+ /* Index to vertex array */
+ gctINT arrayIdx;
+
+ gceATTRIB_SCHEME convertScheme;
+
+ /* Pointer to the temporary buffer to be freed */
+ gcoBUFOBJ tempStream;
+
+ /* Pointer to the temporary memory to be freed */
+ gctCONST_POINTER tempMemory;
+}
+gcsATTRIBUTE,
+* gcsATTRIBUTE_PTR;
+
+
typedef struct _gcsVERTEXARRAY
{
/* Enabled. */
/* Stride of the component. */
gctUINT stride;
+ /* Divisor of the attribute */
+ gctUINT divisor;
+
/* Pointer to the attribute data. */
gctCONST_POINTER pointer;
/* Vertex shader linkage. */
gctUINT linkage;
-#if gcdUSE_WCLIP_PATCH
gctBOOL isPosition;
-#endif
}
gcsVERTEXARRAY,
* gcsVERTEXARRAY_PTR;
);
gceSTATUS
-gcoVERTEXARRAY_Bind(
+gcoVERTEXARRAY_Bind_Ex(
IN gcoVERTEXARRAY Vertex,
IN gctUINT32 EnableBits,
IN gcsVERTEXARRAY_PTR VertexArray,
IN gctUINT First,
IN gctSIZE_T Count,
+ IN gctBOOL DrawArraysInstanced,
+ IN gctSIZE_T InstanceCount,
IN gceINDEX_TYPE IndexType,
IN gcoINDEX IndexObject,
IN gctPOINTER IndexMemory,
#endif
);
-gctUINT
-gcoVERTEXARRAY_GetMaxStream(
- IN gcoVERTEXARRAY Vertex
-);
+gceSTATUS
+gcoVERTEXARRAY_Bind_Ex2(
+ IN gcoVERTEXARRAY Vertex,
+ IN gctUINT32 EnableBits,
+ IN gcsATTRIBUTE_PTR VertexArray,
+ IN gctSIZE_T First,
+ IN gctSIZE_T Count,
+ IN gctBOOL DrawArraysInstanced,
+ IN gctSIZE_T InstanceCount,
+ IN gceINDEX_TYPE IndexType,
+ IN gcoBUFOBJ IndexObject,
+ IN gctPOINTER IndexMemory,
+ IN OUT gcePRIMITIVE * PrimitiveType,
+#if gcdUSE_WCLIP_PATCH
+ IN OUT gctSIZE_T * PrimitiveCount,
+ IN OUT gctFLOAT * wLimitRms,
+ IN OUT gctBOOL * wLimitDirty,
+#else
+ IN OUT gctUINT * PrimitiveCount,
+#endif
+ IN gctINT VertexInstanceIdLinkage
+ );
gceSTATUS
-gcoVERTEXARRAY_SetMaxStream(
+gcoVERTEXARRAY_Bind(
IN gcoVERTEXARRAY Vertex,
- gctUINT maxStreams
-);
+ IN gctUINT32 EnableBits,
+ IN gcsVERTEXARRAY_PTR VertexArray,
+ IN gctUINT First,
+ IN gctSIZE_T Count,
+ IN gceINDEX_TYPE IndexType,
+ IN gcoINDEX IndexObject,
+ IN gctPOINTER IndexMemory,
+ IN OUT gcePRIMITIVE * PrimitiveType,
+#if gcdUSE_WCLIP_PATCH
+ IN OUT gctUINT * PrimitiveCount,
+ IN OUT gctFLOAT * wLimitRms,
+ IN OUT gctBOOL * wLimitDirty
+#else
+ IN OUT gctUINT * PrimitiveCount
+#endif
+ );
+
/*******************************************************************************
***** Composition *************************************************************/
gceSTATUS
gco3D_ProbeComposition(
- gctBOOL ResetIfEmpty
+ IN gcoHARDWARE Hardware,
+ IN gctBOOL ResetIfEmpty
);
gceSTATUS
gco3D_CompositionBegin(
- void
+ IN gcoHARDWARE Hardware
);
gceSTATUS
gco3D_ComposeLayer(
+ IN gcoHARDWARE Hardware,
IN gcsCOMPOSITION_PTR Layer
);
gceSTATUS
gco3D_CompositionSignals(
+ IN gcoHARDWARE Hardware,
IN gctHANDLE Process,
IN gctSIGNAL Signal1,
IN gctSIGNAL Signal2
gceSTATUS
gco3D_CompositionEnd(
+ IN gcoHARDWARE Hardware,
IN gcoSURF Target,
IN gctBOOL Synchronous
);
gctCONST_STRING Filename OPTIONAL
);
+/******************************************************************************
+**********************gcoBUFOBJ object*****************************************
+*******************************************************************************/
+typedef enum _gceBUFOBJ_TYPE
+{
+ gcvBUFOBJ_TYPE_ARRAY_BUFFER = 1,
+ gcvBUFOBJ_TYPE_ELEMENT_ARRAY_BUFFER = 2,
+ gcvBUFOBJ_TYPE_GENERIC_BUFFER = 100
+
+} gceBUFOBJ_TYPE;
+
+typedef enum _gceBUFOBJ_USAGE
+{
+ gcvBUFOBJ_USAGE_STREAM_DRAW = 1,
+ gcvBUFOBJ_USAGE_STREAM_READ,
+ gcvBUFOBJ_USAGE_STREAM_COPY,
+ gcvBUFOBJ_USAGE_STATIC_DRAW,
+ gcvBUFOBJ_USAGE_STATIC_READ,
+ gcvBUFOBJ_USAGE_STATIC_COPY,
+ gcvBUFOBJ_USAGE_DYNAMIC_DRAW,
+ gcvBUFOBJ_USAGE_DYNAMIC_READ,
+ gcvBUFOBJ_USAGE_DYNAMIC_COPY,
+
+} gceBUFOBJ_USAGE;
+
+/* Construct a new gcoBUFOBJ object. */
+gceSTATUS
+gcoBUFOBJ_Construct(
+ IN gcoHAL Hal,
+ IN gceBUFOBJ_TYPE Type,
+ OUT gcoBUFOBJ * BufObj
+ );
+
+/* Destroy a gcoBUFOBJ object. */
+gceSTATUS
+gcoBUFOBJ_Destroy(
+ IN gcoBUFOBJ BufObj
+ );
+
+/* Lock pbo in memory. */
+gceSTATUS
+gcoBUFOBJ_Lock(
+ IN gcoBUFOBJ BufObj,
+ OUT gctUINT32 * Address,
+ OUT gctPOINTER * Memory
+ );
+
+/* Lock pbo in memory. */
+gceSTATUS
+gcoBUFOBJ_FastLock(
+ IN gcoBUFOBJ BufObj,
+ OUT gctUINT32 * Address,
+ OUT gctPOINTER * Memory
+ );
+
+/* Unlock pbo that was previously locked with gcoBUFOBJ_Lock. */
gceSTATUS
-gcoHAL_GetSharedInfo(
- IN gctUINT32 Pid,
- IN gctUINT32 DataId,
+gcoBUFOBJ_Unlock(
+ IN gcoBUFOBJ BufObj
+ );
+
+/* Free existing pbo buffer. */
+gceSTATUS
+gcoBUFOBJ_Free(
+ IN gcoBUFOBJ BufObj
+ );
+
+/* Upload data into an pbo buffer. */
+gceSTATUS
+gcoBUFOBJ_Upload(
+ IN gcoBUFOBJ BufObj,
+ IN gctCONST_POINTER Buffer,
+ IN gctSIZE_T Offset,
IN gctSIZE_T Bytes,
- OUT gctPOINTER Data
+ IN gceBUFOBJ_USAGE Usage
);
+/* Bind an index object to the hardware. */
gceSTATUS
-gcoHAL_SetSharedInfo(
- IN gctUINT32 DataId,
- IN gctPOINTER Data,
- IN gctSIZE_T Bytes
+gcoBUFOBJ_IndexBind (
+ IN gcoBUFOBJ Index,
+ IN gceINDEX_TYPE Type,
+ IN gctUINT32 Offset,
+ IN gctSIZE_T Count
);
-#if VIVANTE_PROFILER_CONTEXT
+/* Find min and max index for the index buffer */
gceSTATUS
-gcoHARDWARE_GetContext(
- IN gcoHARDWARE Hardware,
- OUT gctUINT32 * Context
+gcoBUFOBJ_IndexGetRange(
+ IN gcoBUFOBJ Index,
+ IN gceINDEX_TYPE Type,
+ IN gctUINT32 Offset,
+ IN gctUINT32 Count,
+ OUT gctUINT32 * MinimumIndex,
+ OUT gctUINT32 * MaximumIndex
+ );
+
+/* Sets a buffer object as dirty */
+gceSTATUS
+gcoBUFOBJ_SetDirty(
+ IN gcoBUFOBJ BufObj
+ );
+
+/* Creates a new buffer if needed */
+gceSTATUS
+gcoBUFOBJ_AlignIndexBufferWhenNeeded(
+ IN gcoBUFOBJ BufObj,
+ IN gctSIZE_T Offset,
+ OUT gcoBUFOBJ * AlignedBufObj
+ );
+
+/* Cache operations on whole range */
+gceSTATUS
+gcoBUFOBJ_CPUCacheOperation(
+ IN gcoBUFOBJ BufObj,
+ IN gceCACHEOPERATION Operation
+ );
+
+/* Cache operations on a specified range */
+gceSTATUS
+gcoBUFOBJ_CPUCacheOperation_Range(
+ IN gcoBUFOBJ BufObj,
+ IN gctSIZE_T Offset,
+ IN gctSIZE_T Length,
+ IN gceCACHEOPERATION Operation
+ );
+
+/* Return size of the bufobj */
+gceSTATUS
+gcoBUFOBJ_GetSize(
+ IN gcoBUFOBJ BufObj,
+ OUT gctSIZE_T_PTR Size
+ );
+
+/* Return memory node of the bufobj */
+gceSTATUS
+gcoBUFOBJ_GetNode(
+ IN gcoBUFOBJ BufObj,
+ OUT gcsSURF_NODE_PTR * Node
+ );
+
+/* Handle GPU cache operations */
+gceSTATUS
+gcoBUFOBJ_GPUCacheOperation(
+ gcoBUFOBJ BufObj
+ );
+
+/* Dump buffer. */
+void
+gcoBUFOBJ_Dump(
+ IN gcoBUFOBJ BufObj
);
-#endif
#ifdef __cplusplus
}
#endif
-#endif /* VIVANTE_NO_3D */
+#endif /* gcdENABLE_3D */
#endif /* __gc_hal_engine_h_ */
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
gceSTATUS
gcoHAL_QueryPathStorage(
IN gcoHAL Hal,
+#if GC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
OUT gcsPATH_BUFFER_INFO_PTR Information
);
gceSTATUS
gcoHAL_AssociateCompletion(
IN gcoHAL Hal,
+#if GC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gcsPATH_DATA_PTR PathData
);
gceSTATUS
gcoHAL_DeassociateCompletion(
IN gcoHAL Hal,
+#if GC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gcsPATH_DATA_PTR PathData
);
gceSTATUS
gcoHAL_CheckCompletion(
IN gcoHAL Hal,
+#if GC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gcsPATH_DATA_PTR PathData
);
gceSTATUS
gcoHAL_WaitCompletion(
IN gcoHAL Hal,
+#if GC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gcsPATH_DATA_PTR PathData
);
gceSTATUS
gcoHAL_Flush(
IN gcoHAL Hal
+#if GC355_PROFILER
+ ,
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth
+#endif
);
/* Split a harwdare address into pool and offset. */
gceSTATUS
gcoHAL_SplitAddress(
IN gcoHAL Hal,
+#if GC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gctUINT32 Address,
OUT gcePOOL * Pool,
OUT gctUINT32 * Offset
gceSTATUS
gcoHAL_CombineAddress(
IN gcoHAL Hal,
+#if GC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gcePOOL Pool,
IN gctUINT32 Offset,
OUT gctUINT32 * Address
gceSTATUS
gcoHAL_ScheduleVideoMemory(
IN gcoHAL Hal,
- IN gctUINT64 Node
+#if GC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctUINT32 Node
);
/* Free linear video memory allocated with gcoHAL_AllocateLinearVideoMemory. */
gceSTATUS
gcoHAL_FreeVideoMemory(
IN gcoHAL Hal,
- IN gctUINT64 Node
+#if GC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctUINT32 Node
);
/* Query command buffer attributes. */
gceSTATUS
gcoHAL_QueryCommandBuffer(
IN gcoHAL Hal,
+#if GC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
OUT gcsCOMMAND_BUFFER_INFO_PTR Information
);
/* Allocate and lock linear video memory. */
gceSTATUS
gcoHAL_AllocateLinearVideoMemory(
IN gcoHAL Hal,
+#if GC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gctUINT Size,
IN gctUINT Alignment,
IN gcePOOL Pool,
- OUT gctUINT64 * Node,
+ OUT gctUINT32 * Node,
OUT gctUINT32 * Address,
OUT gctPOINTER * Memory
);
gceSTATUS
gcoHAL_GetAlignedSurfaceSize(
IN gcoHAL Hal,
+#if GC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gceSURF_TYPE Type,
IN OUT gctUINT32_PTR Width,
IN OUT gctUINT32_PTR Height
gceSTATUS
gcoHAL_ReserveTask(
IN gcoHAL Hal,
+#if GC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gceBLOCK Block,
IN gctUINT TaskCount,
- IN gctSIZE_T Bytes,
+ IN gctUINT32 Bytes,
OUT gctPOINTER * Memory
);
/******************************************************************************\
**
** The gcoVG object abstracts the VG hardware pipe.
*/
+#if GC355_PROFILER
+void
+gcoVG_ProfilerEnableDisable(
+ IN gcoVG Vg,
+ IN gctUINT enableGetAPITimes,
+ IN gctFILE apiTimeFile
+ );
+
+void
+gcoVG_ProfilerTreeDepth(
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth
+ );
+
+void
+gcoVG_ProfilerSetStates(
+ IN gcoVG Vg,
+ IN gctUINT treeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth
+ );
+#endif
gctBOOL
gcoVG_IsMaskSupported(
+#if GC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gceSURF_FORMAT Format
);
gctBOOL
gcoVG_IsTargetSupported(
+#if GC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gceSURF_FORMAT Format
);
gctBOOL
gcoVG_IsImageSupported(
+#if GC355_PROFILER
+ IN gcoVG Vg,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gceSURF_FORMAT Format
);
gctUINT8 gcoVG_PackColorComponent(
+#if GC355_PROFILER
+ gcoVG Vg,
+ gctUINT TreeDepth,
+ gctUINT saveLayerTreeDepth,
+ gctUINT varTreeDepth,
+#endif
gctFLOAT Value
);
gceSTATUS
gcoVG_Destroy(
IN gcoVG Vg
+#if GC355_PROFILER
+ ,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth
+#endif
);
gceSTATUS
gcoVG_SetTarget(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gcoSURF Target
);
gceSTATUS
gcoVG_UnsetTarget(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gcoSURF Surface
);
gceSTATUS
gcoVG_SetUserToSurface(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gctFLOAT UserToSurface[9]
);
gceSTATUS
gcoVG_SetSurfaceToImage(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gctFLOAT SurfaceToImage[9]
);
gceSTATUS
gcoVG_EnableMask(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gctBOOL Enable
);
gceSTATUS
gcoVG_SetMask(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gcoSURF Mask
);
gceSTATUS
gcoVG_UnsetMask(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gcoSURF Surface
);
gceSTATUS
gcoVG_FlushMask(
IN gcoVG Vg
+#if GC355_PROFILER
+ ,
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth
+#endif
);
gceSTATUS
gcoVG_EnableScissor(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gctBOOL Enable
);
gceSTATUS
gcoVG_SetScissor(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gctSIZE_T RectangleCount,
IN gcsVG_RECT_PTR Rectangles
);
gceSTATUS
gcoVG_EnableColorTransform(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gctBOOL Enable
);
gceSTATUS
gcoVG_SetColorTransform(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gctFLOAT ColorTransform[8]
);
gceSTATUS
gcoVG_SetTileFillColor(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gctFLOAT Red,
IN gctFLOAT Green,
IN gctFLOAT Blue,
gceSTATUS
gcoVG_SetSolidPaint(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gctUINT8 Red,
IN gctUINT8 Green,
IN gctUINT8 Blue,
gceSTATUS
gcoVG_SetLinearPaint(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gctFLOAT Constant,
IN gctFLOAT StepX,
IN gctFLOAT StepY
gceSTATUS
gcoVG_SetRadialPaint(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gctFLOAT LinConstant,
IN gctFLOAT LinStepX,
IN gctFLOAT LinStepY,
gceSTATUS
gcoVG_SetPatternPaint(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gctFLOAT UConstant,
IN gctFLOAT UStepX,
IN gctFLOAT UStepY,
gceSTATUS
gcoVG_SetColorRamp(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gcoSURF ColorRamp,
IN gceTILE_MODE ColorRampSpreadMode
);
gceSTATUS
gcoVG_SetPattern(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
+ IN gctINT32 width,
+ IN gctINT32 height,
IN gcoSURF Pattern,
IN gceTILE_MODE TileMode,
IN gceIMAGE_FILTER Filter
gceSTATUS
gcoVG_SetImageMode(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gceVG_IMAGE Mode
);
gceSTATUS
gcoVG_SetBlendMode(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gceVG_BLEND Mode
);
gceSTATUS
gcoVG_SetRenderingQuality(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gceRENDER_QUALITY Quality
);
gceSTATUS
gcoVG_SetFillRule(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gceFILL_RULE FillRule
);
gceSTATUS
gcoVG_Clear(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gctINT X,
IN gctINT Y,
IN gctINT Width,
gceSTATUS
gcoVG_DrawPath(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gcsPATH_DATA_PTR PathData,
IN gctFLOAT Scale,
IN gctFLOAT Bias,
+#if gcdMOVG
+ IN gctUINT32 Width,
+ IN gctUINT32 Height,
+ IN gctFLOAT *Bounds,
+#endif
IN gctBOOL SoftwareTesselation
);
gceSTATUS
gcoVG_DrawImage(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gcoSURF Source,
IN gcsPOINT_PTR SourceOrigin,
IN gcsPOINT_PTR TargetOrigin,
IN gctINT TargetY,
IN gctINT Width,
IN gctINT Height,
- IN gctBOOL Mask
+ IN gctBOOL Mask,
+ IN gctBOOL isDrawImage
);
gceSTATUS
gcoVG_TesselateImage(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gcoSURF Image,
IN gcsVG_RECT_PTR Rectangle,
IN gceIMAGE_FILTER Filter,
IN gctBOOL Mask,
+#if gcdMOVG
+ IN gctBOOL SoftwareTesselation,
+ IN gceVG_BLEND BlendMode
+#else
IN gctBOOL SoftwareTesselation
+#endif
);
gceSTATUS
gcoVG_Blit(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gcoSURF Source,
IN gcoSURF Target,
IN gcsVG_RECT_PTR SrcRect,
gceSTATUS
gcoVG_ColorMatrix(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gcoSURF Source,
IN gcoSURF Target,
IN const gctFLOAT * Matrix,
gceSTATUS
gcoVG_SeparableConvolve(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gcoSURF Source,
IN gcoSURF Target,
IN gctINT KernelWidth,
gceSTATUS
gcoVG_GaussianBlur(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gcoSURF Source,
IN gcoSURF Target,
IN gctFLOAT StdDeviationX,
gceSTATUS
gcoVG_EnableDither(
IN gcoVG Vg,
+#if GC355_PROFILER
+ IN gctUINT TreeDepth,
+ IN gctUINT saveLayerTreeDepth,
+ IN gctUINT varTreeDepth,
+#endif
IN gctBOOL Enable
);
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
/* Chip models. */
typedef enum _gceCHIPMODEL
{
+ gcv200 = 0x0200,
gcv300 = 0x0300,
gcv320 = 0x0320,
+ gcv328 = 0x0328,
gcv350 = 0x0350,
gcv355 = 0x0355,
gcv400 = 0x0400,
gcv410 = 0x0410,
gcv420 = 0x0420,
+ gcv428 = 0x0428,
gcv450 = 0x0450,
gcv500 = 0x0500,
+ gcv520 = 0x0520,
gcv530 = 0x0530,
gcv600 = 0x0600,
gcv700 = 0x0700,
gcv860 = 0x0860,
gcv880 = 0x0880,
gcv1000 = 0x1000,
+ gcv1500 = 0x1500,
gcv2000 = 0x2000,
gcv2100 = 0x2100,
+ gcv2200 = 0x2200,
+ gcv2500 = 0x2500,
+ gcv3000 = 0x3000,
gcv4000 = 0x4000,
+ gcv5000 = 0x5000,
+ gcv5200 = 0x5200,
+ gcv6400 = 0x6400,
}
gceCHIPMODEL;
gcvFEATURE_YUY2_AVERAGING,
gcvFEATURE_FLIP_Y,
gcvFEATURE_EARLY_Z,
- gcvFEATURE_Z_COMPRESSION,
+ gcvFEATURE_COMPRESSION,
gcvFEATURE_MSAA,
gcvFEATURE_SPECIAL_ANTI_ALIASING,
gcvFEATURE_SPECIAL_MSAA_LOD,
gcvFEATURE_VG_DOUBLE_BUFFER,
gcvFEATURE_MC20,
gcvFEATURE_SUPER_TILED,
+ gcvFEATURE_FAST_CLEAR_FLUSH,
gcvFEATURE_2D_FILTERBLIT_PLUS_ALPHABLEND,
gcvFEATURE_2D_DITHER,
gcvFEATURE_2D_A8_TARGET,
+ gcvFEATURE_2D_A8_NO_ALPHA,
gcvFEATURE_2D_FILTERBLIT_FULLROTATION,
gcvFEATURE_2D_BITBLIT_FULLROTATION,
gcvFEATURE_WIDE_LINE,
gcvFEATURE_TEXTURE_10_10_10_2,
gcvFEATURE_TEXTURE_ANISOTROPIC_FILTERING,
gcvFEATURE_TEXTURE_FLOAT_HALF_FLOAT,
- gcvFEATURE_2D_ROTATION_STALL_FIX,
+ gcvFEATURE_2D_ROTATION_STALL_FIX,
gcvFEATURE_2D_MULTI_SOURCE_BLT_EX,
- gcvFEATURE_BUG_FIXES10,
+ gcvFEATURE_BUG_FIXES10,
gcvFEATURE_2D_MINOR_TILING,
/* Supertiled compressed textures are supported. */
gcvFEATURE_TEX_COMPRRESSION_SUPERTILED,
gcvFEATURE_FAST_MSAA,
gcvFEATURE_BUG_FIXED_INDEXED_TRIANGLE_STRIP,
- gcvFEATURE_TEXTURE_TILED_READ,
+ gcvFEATURE_TEXTURE_TILE_STATUS_READ,
gcvFEATURE_DEPTH_BIAS_FIX,
gcvFEATURE_RECT_PRIMITIVE,
- gcvFEATURE_BUG_FIXES11,
- gcvFEATURE_SUPERTILED_TEXTURE,
+ gcvFEATURE_BUG_FIXES11,
+ gcvFEATURE_SUPERTILED_TEXTURE,
gcvFEATURE_2D_NO_COLORBRUSH_INDEX8,
gcvFEATURE_RS_YUV_TARGET,
gcvFEATURE_2D_FC_SOURCE,
- gcvFEATURE_PE_DITHER_FIX,
+ gcvFEATURE_2D_CC_NOAA_SOURCE,
+ gcvFEATURE_PE_DITHER_FIX,
gcvFEATURE_2D_YUV_SEPARATE_STRIDE,
gcvFEATURE_FRUSTUM_CLIP_FIX,
+ gcvFEATURE_TEXTURE_SWIZZLE,
+ gcvFEATURE_PRIMITIVE_RESTART,
gcvFEATURE_TEXTURE_LINEAR,
gcvFEATURE_TEXTURE_YUV_ASSEMBLER,
+ gcvFEATURE_LINEAR_RENDER_TARGET,
+ gcvFEATURE_SHADER_HAS_ATOMIC,
gcvFEATURE_SHADER_HAS_INSTRUCTION_CACHE,
+ gcvFEATURE_SHADER_ENHANCEMENTS2,
+ gcvFEATURE_BUG_FIXES7,
+ gcvFEATURE_SHADER_HAS_RTNE,
+ gcvFEATURE_SHADER_HAS_EXTRA_INSTRUCTIONS2,
+ gcvFEATURE_SHADER_ENHANCEMENTS3,
gcvFEATURE_DYNAMIC_FREQUENCY_SCALING,
- gcvFEATURE_BUGFIX15,
+ gcvFEATURE_SINGLE_BUFFER,
+ gcvFEATURE_OCCLUSION_QUERY,
gcvFEATURE_2D_GAMMA,
gcvFEATURE_2D_COLOR_SPACE_CONVERSION,
gcvFEATURE_2D_SUPER_TILE_VERSION,
+ gcvFEATURE_HALTI0,
+ gcvFEATURE_HALTI1,
+ gcvFEATURE_HALTI2,
gcvFEATURE_2D_MIRROR_EXTENSION,
+ gcvFEATURE_TEXTURE_ASTC,
gcvFEATURE_2D_SUPER_TILE_V1,
gcvFEATURE_2D_SUPER_TILE_V2,
gcvFEATURE_2D_SUPER_TILE_V3,
gcvFEATURE_2D_MULTI_SOURCE_BLT_EX2,
- gcvFEATURE_ELEMENT_INDEX_UINT,
+ gcvFEATURE_NEW_RA,
+ gcvFEATURE_BUG_FIXED_IMPLICIT_PRIMITIVE_RESTART,
+ gcvFEATURE_PE_MULTI_RT_BLEND_ENABLE_CONTROL,
+ gcvFEATURE_SMALL_MSAA, /* An upgraded version of Fast MSAA */
+ gcvFEATURE_VERTEX_INST_ID_AS_ATTRIBUTE,
+ gcvFEATURE_DUAL_16,
+ gcvFEATURE_BRANCH_ON_IMMEDIATE_REG,
gcvFEATURE_2D_COMPRESSION,
+ gcvFEATURE_TPC_COMPRESSION,
gcvFEATURE_2D_OPF_YUV_OUTPUT,
+ gcvFEATURE_2D_FILTERBLIT_A8_ALPHA,
gcvFEATURE_2D_MULTI_SRC_BLT_TO_UNIFIED_DST_RECT,
+ gcvFEATURE_V2_COMPRESSION_Z16_FIX,
+
+ gcvFEATURE_VERTEX_INST_ID_AS_INTEGER,
gcvFEATURE_2D_YUV_MODE,
- gcvFEATURE_DECOMPRESS_Z16,
- gcvFEATURE_LINEAR_RENDER_TARGET,
- gcvFEATURE_BUG_FIXES8,
- gcvFEATURE_HALTI2,
+ gcvFEATURE_ACE,
+ gcvFEATURE_COLOR_COMPRESSION,
+
+ gcvFEATURE_32BPP_COMPONENT_TEXTURE_CHANNEL_SWIZZLE,
+ gcvFEATURE_64BPP_HW_CLEAR_SUPPORT,
+ gcvFEATURE_TX_LERP_PRECISION_FIX,
+ gcvFEATURE_COMPRESSION_V2,
gcvFEATURE_MMU,
+ gcvFEATURE_COMPRESSION_V3,
+ gcvFEATURE_TX_DECOMPRESSOR,
+ gcvFEATURE_MRT_TILE_STATUS_BUFFER,
+ gcvFEATURE_COMPRESSION_V1,
+ gcvFEATURE_V1_COMPRESSION_Z16_DECOMPRESS_FIX,
+ gcvFEATURE_RTT,
+ gcvFEATURE_GENERICS,
+ gcvFEATURE_2D_ONE_PASS_FILTER,
+ gcvFEATURE_2D_ONE_PASS_FILTER_TAP,
+ gcvFEATURE_2D_POST_FLIP,
+ gcvFEATURE_2D_PIXEL_ALIGNMENT,
+ gcvFEATURE_CORRECT_AUTO_DISABLE_COUNT,
+ gcvFEATURE_CORRECT_AUTO_DISABLE_COUNT_WIDTH,
+
+ gcvFEATURE_HALTI3,
+ gcvFEATURE_EEZ,
+ gcvFEATURE_INTEGER_PIPE_FIX,
+ gcvFEATURE_PSOUTPUT_MAPPING,
+ gcvFEATURE_8K_RT_FIX,
+ gcvFEATURE_TX_TILE_STATUS_MAPPING,
+ gcvFEATURE_SRGB_RT_SUPPORT,
+ gcvFEATURE_UNIFORM_APERTURE,
+ gcvFEATURE_TEXTURE_16K,
+ gcvFEATURE_PA_FARZCLIPPING_FIX,
+ gcvFEATURE_PE_DITHER_COLORMASK_FIX,
+ gcvFEATURE_ZSCALE_FIX,
+
+ gcvFEATURE_MULTI_PIXELPIPES,
+ gcvFEATURE_PIPE_CL,
+
+ gcvFEATURE_BUG_FIXES18,
+
+ gcvFEATURE_UNIFIED_SAMPLERS,
+ gcvFEATURE_CL_PS_WALKER,
+ gcvFEATURE_NEW_HZ,
+
+ gcvFEATURE_TX_FRAC_PRECISION_6BIT,
+ gcvFEATURE_SH_INSTRUCTION_PREFETCH,
+ gcvFEATURE_PROBE,
+
+ gcvFEATURE_BUG_FIXES8,
+ gcvFEATURE_2D_ALL_QUAD,
+
+ gcvFEATURE_SINGLE_PIPE_HALTI1,
+
+ gcvFEATURE_BLOCK_SIZE_16x16,
+
+ gcvFEATURE_NO_USER_CSC,
+ gcvFEATURE_ANDROID_ONLY,
+ gcvFEATURE_HAS_PRODUCTID,
+
+ gcvFEATURE_V2_MSAA_COMP_FIX,
+
+ gcvFEATURE_S8_ONLY_RENDERING,
+
+ gcvFEATURE_SEPARATE_SRC_DST,
+
+ gcvFEATURE_FE_START_VERTEX_SUPPORT,
+ gcvFEATURE_RS_DEPTHSTENCIL_NATIVE_SUPPORT,
+
+ /* Insert features above this comment only. */
+ gcvFEATURE_COUNT /* Not a feature. */
}
gceFEATURE;
+/* Chip SWWA. */
+typedef enum _gceSWWA
+{
+ gcvSWWA_601 = 0,
+ gcvSWWA_706,
+ gcvSWWA_1163,
+ gcvSWWA_1165,
+ /* Insert SWWA above this comment only. */
+ gcvSWWA_COUNT /* Not a SWWA. */
+}
+gceSWWA;
+
+
+/* Option Set*/
+typedef enum _gceOPITON
+{
+ /* HW setting we take PREFER */
+ gcvOPTION_PREFER_MULTIPIPE_RS = 0,
+ gcvOPTION_PREFER_ZCONVERT_BYPASS =1,
+
+
+ gcvOPTION_HW_NULL = 50,
+ gcvOPTION_PRINT_OPTION = 51,
+
+ gcvOPTION_FBO_PREFER_MEM = 80,
+
+ /* Insert option above this comment only */
+ gcvOPTION_COUNT /* Not a OPTION*/
+}
+gceOPTION;
+
+typedef enum _gceFRAMEINFO
+{
+ gcvFRAMEINFO_FRAME_NUM = 0,
+ gcvFRAMEINFO_DRAW_NUM = 1,
+ gcvFRAMEINFO_DRAW_DUAL16_NUM = 2,
+ gcvFRAMEINFO_DRAW_FL32_NUM = 3,
+
+
+ gcvFRAMEINFO_COUNT,
+}
+gceFRAMEINFO;
+
+typedef enum _gceFRAMEINFO_OP
+{
+ gcvFRAMEINFO_OP_INC = 0,
+ gcvFRAMEINFO_OP_DEC = 1,
+ gcvFRAMEINFO_OP_ZERO = 2,
+ gcvFRAMEINFO_OP_GET = 3,
+
+
+ gcvFRAMEINFO_OP_COUNT,
+}
+gceFRAMEINFO_OP;
+
+
/* Chip Power Status. */
typedef enum _gceCHIPPOWERSTATE
{
gcvSURF_DEPTH,
gcvSURF_BITMAP,
gcvSURF_TILE_STATUS,
- gcvSURF_IMAGE,
+ gcvSURF_IMAGE,
gcvSURF_MASK,
gcvSURF_SCISSOR,
gcvSURF_HIERARCHICAL_DEPTH,
gcvSURF_NO_VIDMEM = 0x200, /* Used to allocate surfaces with no underlying vidmem node.
In Android, vidmem node is allocated by another process. */
gcvSURF_CACHEABLE = 0x400, /* Used to allocate a cacheable surface */
+
gcvSURF_FLIP = 0x800, /* The Resolve Target the will been flip resolve from RT */
+
gcvSURF_TILE_STATUS_DIRTY = 0x1000, /* Init tile status to all dirty */
gcvSURF_LINEAR = 0x2000,
- gcvSURF_VG = 0x4000,
+
+ gcvSURF_CREATE_AS_TEXTURE = 0x4000, /* create it as a texture */
+
+ gcvSURF_PROTECTED_CONTENT = 0x8000, /* create it as content protected */
+
+ /* Create it as no compression, valid on when it has tile status. */
+ gcvSURF_NO_COMPRESSION = 0x40000,
+
+ gcvSURF_CONTIGUOUS = 0x20000, /*create it as contiguous */
gcvSURF_TEXTURE_LINEAR = gcvSURF_TEXTURE
| gcvSURF_LINEAR,
+ gcvSURF_RENDER_TARGET_LINEAR = gcvSURF_RENDER_TARGET
+ | gcvSURF_LINEAR,
+
gcvSURF_RENDER_TARGET_NO_TILE_STATUS = gcvSURF_RENDER_TARGET
| gcvSURF_NO_TILE_STATUS,
}
gceSURF_USAGE;
+typedef enum _gceSURF_COLOR_SPACE
+{
+ gcvSURF_COLOR_SPACE_UNKNOWN,
+ gcvSURF_COLOR_SPACE_LINEAR,
+ gcvSURF_COLOR_SPACE_NONLINEAR,
+}
+gceSURF_COLOR_SPACE;
+
typedef enum _gceSURF_COLOR_TYPE
{
gcvSURF_COLOR_UNKNOWN = 0,
gcvSURF_FLIP_X,
gcvSURF_FLIP_Y,
- gcvSURF_POST_FLIP_X = 0x40000000,
+ gcvSURF_POST_FLIP_X = 0x40000000,
gcvSURF_POST_FLIP_Y = 0x80000000,
}
gceSURF_ROTATION;
+/* Surface flag */
+typedef enum _gceSURF_FLAG
+{
+ /* None flag */
+ gcvSURF_FLAG_NONE = 0x0,
+ /* content is preserved after swap */
+ gcvSURF_FLAG_CONTENT_PRESERVED = 0x1,
+ /* content is updated after swap*/
+ gcvSURF_FLAG_CONTENT_UPDATED = 0x2,
+ /* content is y inverted */
+ gcvSURF_FLAG_CONTENT_YINVERTED = 0x4,
+ /* content is protected */
+ gcvSURF_FLAG_CONTENT_PROTECTED = 0x8,
+ /* surface is contiguous. */
+ gcvSURF_FLAG_CONTIGUOUS = (1 << 4),
+}
+gceSURF_FLAG;
+
typedef enum _gceMIPMAP_IMAGE_FORMAT
{
gcvUNKNOWN_MIPMAP_IMAGE_FORMAT = -2
}
gceMIPMAP_IMAGE_FORMAT;
-
/* Surface formats. */
typedef enum _gceSURF_FORMAT
{
gcvSURF_R8G8B8X8,
gcvSURF_R5G5B5X1,
gcvSURF_R4G4B4X4,
+ gcvSURF_X16R16G16B16_2_A8R8G8B8,
+ gcvSURF_A16R16G16B16_2_A8R8G8B8,
+ gcvSURF_A32R32G32B32_2_G32R32F,
+ gcvSURF_A32R32G32B32_4_A8R8G8B8,
/* BGR formats. */
gcvSURF_A4B4G4R4 = 300,
gcvSURF_B4G4R4X4,
gcvSURF_B5G5R5X1,
gcvSURF_X2B10G10R10,
+ gcvSURF_B8G8R8_SNORM,
+ gcvSURF_X8B8G8R8_SNORM,
+ gcvSURF_A8B8G8R8_SNORM,
+ gcvSURF_A8B12G12R12_2_A8R8G8B8,
/* Compressed formats. */
gcvSURF_DXT1 = 400,
gcvSURF_D24S8,
gcvSURF_D32,
gcvSURF_D24X8,
+ gcvSURF_D32F,
+ gcvSURF_S8D32F,
+ gcvSURF_S8D32F_1_G32R32F,
+ gcvSURF_S8D32F_2_A8R8G8B8,
+ gcvSURF_D24S8_1_A8R8G8B8,
+ gcvSURF_S8,
/* Alpha formats. */
gcvSURF_A4 = 700,
gcvSURF_X32G32R32,
gcvSURF_A32R32,
gcvSURF_RG16,
+ gcvSURF_R8_SNORM,
+ gcvSURF_G8R8_SNORM,
+
+ gcvSURF_R8_1_X8R8G8B8,
+ gcvSURF_G8R8_1_X8R8G8B8,
/* Floating point formats. */
gcvSURF_R16F = 1200,
gcvSURF_L32F,
gcvSURF_A32L32F,
gcvSURF_A32R32F,
-
+ gcvSURF_E5B9G9R9,
+ gcvSURF_B10G11R11F,
+
+ gcvSURF_X16B16G16R16F_2_A8R8G8B8,
+ gcvSURF_A16B16G16R16F_2_A8R8G8B8,
+ gcvSURF_G32R32F_2_A8R8G8B8,
+ gcvSURF_X32B32G32R32F_2_G32R32F,
+ gcvSURF_A32B32G32R32F_2_G32R32F,
+ gcvSURF_X32B32G32R32F_4_A8R8G8B8,
+ gcvSURF_A32B32G32R32F_4_A8R8G8B8,
+
+ gcvSURF_R16F_1_A4R4G4B4,
+ gcvSURF_G16R16F_1_A8R8G8B8,
+ gcvSURF_B16G16R16F_2_A8R8G8B8,
+
+ gcvSURF_R32F_1_A8R8G8B8,
+ gcvSURF_B32G32R32F_3_A8R8G8B8,
+
+ gcvSURF_B10G11R11F_1_A8R8G8B8,
+
+
+ /* sRGB format. */
+ gcvSURF_SBGR8 = 1400,
+ gcvSURF_A8_SBGR8,
+ gcvSURF_X8_SBGR8,
+
+ /* Integer formats. */
+ gcvSURF_R8I = 1500,
+ gcvSURF_R8UI,
+ gcvSURF_R16I,
+ gcvSURF_R16UI,
+ gcvSURF_R32I,
+ gcvSURF_R32UI,
+ gcvSURF_X8R8I,
+ gcvSURF_G8R8I,
+ gcvSURF_X8R8UI,
+ gcvSURF_G8R8UI,
+ gcvSURF_X16R16I,
+ gcvSURF_G16R16I,
+ gcvSURF_X16R16UI,
+ gcvSURF_G16R16UI,
+ gcvSURF_X32R32I,
+ gcvSURF_G32R32I,
+ gcvSURF_X32R32UI,
+ gcvSURF_G32R32UI,
+ gcvSURF_X8G8R8I,
+ gcvSURF_B8G8R8I,
+ gcvSURF_X8G8R8UI,
+ gcvSURF_B8G8R8UI,
+ gcvSURF_X16G16R16I,
+ gcvSURF_B16G16R16I,
+ gcvSURF_X16G16R16UI,
+ gcvSURF_B16G16R16UI,
+ gcvSURF_X32G32R32I,
+ gcvSURF_B32G32R32I,
+ gcvSURF_X32G32R32UI,
+ gcvSURF_B32G32R32UI,
+ gcvSURF_X8B8G8R8I,
+ gcvSURF_A8B8G8R8I,
+ gcvSURF_X8B8G8R8UI,
+ gcvSURF_A8B8G8R8UI,
+ gcvSURF_X16B16G16R16I,
+ gcvSURF_A16B16G16R16I,
+ gcvSURF_X16B16G16R16UI,
+ gcvSURF_A16B16G16R16UI,
+ gcvSURF_X32B32G32R32I,
+ gcvSURF_A32B32G32R32I,
+ gcvSURF_X32B32G32R32UI,
+ gcvSURF_A32B32G32R32UI,
+ gcvSURF_A2B10G10R10UI,
+ gcvSURF_G32R32I_2_A8R8G8B8,
+ gcvSURF_G32R32UI_2_A8R8G8B8,
+ gcvSURF_X16B16G16R16I_2_A8R8G8B8,
+ gcvSURF_A16B16G16R16I_2_A8R8G8B8,
+ gcvSURF_X16B16G16R16UI_2_A8R8G8B8,
+ gcvSURF_A16B16G16R16UI_2_A8R8G8B8,
+ gcvSURF_X32B32G32R32I_2_G32R32I,
+ gcvSURF_A32B32G32R32I_2_G32R32I,
+ gcvSURF_X32B32G32R32I_3_A8R8G8B8,
+ gcvSURF_A32B32G32R32I_4_A8R8G8B8,
+ gcvSURF_X32B32G32R32UI_2_G32R32UI,
+ gcvSURF_A32B32G32R32UI_2_G32R32UI,
+ gcvSURF_X32B32G32R32UI_3_A8R8G8B8,
+ gcvSURF_A32B32G32R32UI_4_A8R8G8B8,
+ gcvSURF_A2B10G10R10UI_1_A8R8G8B8,
+ gcvSURF_A8B8G8R8I_1_A8R8G8B8,
+ gcvSURF_A8B8G8R8UI_1_A8R8G8B8,
+ gcvSURF_R8I_1_A4R4G4B4,
+ gcvSURF_R8UI_1_A4R4G4B4,
+ gcvSURF_R16I_1_A4R4G4B4,
+ gcvSURF_R16UI_1_A4R4G4B4,
+ gcvSURF_R32I_1_A8R8G8B8,
+ gcvSURF_R32UI_1_A8R8G8B8,
+ gcvSURF_X8R8I_1_A4R4G4B4,
+ gcvSURF_X8R8UI_1_A4R4G4B4,
+ gcvSURF_G8R8I_1_A4R4G4B4,
+ gcvSURF_G8R8UI_1_A4R4G4B4,
+ gcvSURF_X16R16I_1_A4R4G4B4,
+ gcvSURF_X16R16UI_1_A4R4G4B4,
+ gcvSURF_G16R16I_1_A8R8G8B8,
+ gcvSURF_G16R16UI_1_A8R8G8B8,
+ gcvSURF_X32R32I_1_A8R8G8B8,
+ gcvSURF_X32R32UI_1_A8R8G8B8,
+ gcvSURF_X8G8R8I_1_A4R4G4B4,
+ gcvSURF_X8G8R8UI_1_A4R4G4B4,
+ gcvSURF_B8G8R8I_1_A8R8G8B8,
+ gcvSURF_B8G8R8UI_1_A8R8G8B8,
+ gcvSURF_B16G16R16I_2_A8R8G8B8,
+ gcvSURF_B16G16R16UI_2_A8R8G8B8,
+ gcvSURF_B32G32R32I_3_A8R8G8B8,
+ gcvSURF_B32G32R32UI_3_A8R8G8B8,
+
+ /* ASTC formats. */
+ gcvSURF_ASTC4x4 = 1600,
+ gcvSURF_ASTC5x4,
+ gcvSURF_ASTC5x5,
+ gcvSURF_ASTC6x5,
+ gcvSURF_ASTC6x6,
+ gcvSURF_ASTC8x5,
+ gcvSURF_ASTC8x6,
+ gcvSURF_ASTC8x8,
+ gcvSURF_ASTC10x5,
+ gcvSURF_ASTC10x6,
+ gcvSURF_ASTC10x8,
+ gcvSURF_ASTC10x10,
+ gcvSURF_ASTC12x10,
+ gcvSURF_ASTC12x12,
+ gcvSURF_ASTC4x4_SRGB,
+ gcvSURF_ASTC5x4_SRGB,
+ gcvSURF_ASTC5x5_SRGB,
+ gcvSURF_ASTC6x5_SRGB,
+ gcvSURF_ASTC6x6_SRGB,
+ gcvSURF_ASTC8x5_SRGB,
+ gcvSURF_ASTC8x6_SRGB,
+ gcvSURF_ASTC8x8_SRGB,
+ gcvSURF_ASTC10x5_SRGB,
+ gcvSURF_ASTC10x6_SRGB,
+ gcvSURF_ASTC10x8_SRGB,
+ gcvSURF_ASTC10x10_SRGB,
+ gcvSURF_ASTC12x10_SRGB,
+ gcvSURF_ASTC12x12_SRGB,
+
+ gcvSURF_FORMAT_COUNT
}
gceSURF_FORMAT;
+/* Format modifiers. */
+typedef enum _gceSURF_FORMAT_MODE
+{
+ gcvSURF_FORMAT_OCL = 0x80000000
+}
+gceSURF_FORMAT_MODE;
+
/* Pixel swizzle modes. */
typedef enum _gceSURF_SWIZZLE
{
gcvSURF_SIXTEEN,
gcvSURF_SUPER_TILED,
gcvSURF_SPLIT_TILED,
- gcvSURF_SPLIT_SUPER_TILED,
+ gcvSURF_SPLIT_SUPER_TILED
}
gceSURF_ALIGNMENT;
-
/* Surface Addressing. */
typedef enum _gceSURF_ADDRESSING
{
gcv2D_HOR_FILTER,
gcv2D_VER_FILTER,
gcv2D_MULTI_SOURCE_BLT,
+ gcv2D_FILTER_BLT,
}
gce2D_COMMAND;
gcv2D_TSC_COMPRESSED = 0x00000002,
gcv2D_TSC_DOWN_SAMPLER = 0x00000004,
gcv2D_TSC_2D_COMPRESSED = 0x00000008,
+ gcv2D_TSC_TPC_COMPRESSED = 0x00000010,
}
gce2D_TILE_STATUS_CONFIG;
gcv2D_STATE_EN_GAMMA,
gcv2D_STATE_DE_GAMMA,
gcv2D_STATE_MULTI_SRC_BLIT_UNIFIED_DST_RECT,
+ gcv2D_STATE_PROFILE_ENABLE,
+ gcv2D_STATE_XRGB_ENABLE,
gcv2D_STATE_ARRAY_EN_GAMMA = 0x10001,
gcv2D_STATE_ARRAY_DE_GAMMA,
}
gce2D_STATE;
-#ifndef VIVANTE_NO_3D
+typedef enum _gce2D_STATE_PROFILE
+{
+ gcv2D_STATE_PROFILE_NONE = 0x0,
+ gcv2D_STATE_PROFILE_COMMAND = 0x1,
+ gcv2D_STATE_PROFILE_SURFACE = 0x2,
+ gcv2D_STATE_PROFILE_ALL = 0xFFFF,
+}
+gce2D_STATE_PROFILE;
+
+/* Texture object types */
+typedef enum _gceTEXTURE_TYPE
+{
+ gcvTEXTURE_UNKNOWN = 0,
+ gcvTEXTURE_1D,
+ gcvTEXTURE_2D,
+ gcvTEXTURE_3D,
+ gcvTEXTURE_CUBEMAP,
+ gcvTEXTURE_1D_ARRAY,
+ gcvTEXTURE_2D_ARRAY,
+ gcvTEXTURE_EXTERNAL
+}
+gceTEXTURE_TYPE;
+
+#if gcdENABLE_3D
/* Texture functions. */
typedef enum _gceTEXTURE_FUNCTION
{
gcvFROM_ONE_MINUS_ALPHA
}
gceTEXTURE_CHANNEL;
-#endif /* VIVANTE_NO_3D */
+#endif /* gcdENABLE_3D */
/* Filter types. */
typedef enum _gceFILTER_TYPE
/* Tiling modes. */
typedef enum _gceTILING
{
- gcvLINEAR = 0,
- gcvTILED,
- gcvSUPERTILED,
- gcvMULTI_TILED,
- gcvMULTI_SUPERTILED,
- gcvMINORTILED,
+ gcvINVALIDTILED = 0x0, /* Invalid tiling */
+ /* Tiling basic modes enum'ed in power of 2. */
+ gcvLINEAR = 0x1, /* No tiling. */
+ gcvTILED = 0x2, /* 4x4 tiling. */
+ gcvSUPERTILED = 0x4, /* 64x64 tiling. */
+ gcvMINORTILED = 0x8, /* 2x2 tiling. */
+
+ /* Tiling special layouts. */
+ gcvTILING_SPLIT_BUFFER = 0x100,
+
+ /* Tiling combination layouts. */
+ gcvMULTI_TILED = gcvTILED
+ | gcvTILING_SPLIT_BUFFER,
+
+ gcvMULTI_SUPERTILED = gcvSUPERTILED
+ | gcvTILING_SPLIT_BUFFER,
}
gceTILING;
gcvHARDWARE_3D = 0x01,
gcvHARDWARE_2D = 0x02,
gcvHARDWARE_VG = 0x04,
-
+#if gcdMULTI_GPU_AFFINITY
+ gcvHARDWARE_OCL = 0x05,
+#endif
gcvHARDWARE_3D2D = gcvHARDWARE_3D | gcvHARDWARE_2D
}
gceHARDWARE_TYPE;
}
gceSYNC_POINT_COMMAND_CODES;
+/* Shared buffer command codes. */
+typedef enum _gceSHBUF_COMMAND_CODES
+{
+ gcvSHBUF_CREATE,
+ gcvSHBUF_DESTROY,
+ gcvSHBUF_MAP,
+ gcvSHBUF_WRITE,
+ gcvSHBUF_READ,
+}
+gceSHBUF_COMMAND_CODES;
+
/* Event locations. */
typedef enum _gceKERNEL_WHERE
{
/* Hardware blocks. */
typedef enum _gceBLOCK
{
- gcvBLOCK_COMMAND,
- gcvBLOCK_TESSELLATOR,
- gcvBLOCK_TESSELLATOR2,
- gcvBLOCK_TESSELLATOR3,
- gcvBLOCK_RASTER,
- gcvBLOCK_VG,
- gcvBLOCK_VG2,
- gcvBLOCK_VG3,
- gcvBLOCK_PIXEL,
-
- /* Number of defined blocks. */
- gcvBLOCK_COUNT
+ gcvBLOCK_COMMAND,
+ gcvBLOCK_TESSELLATOR,
+ gcvBLOCK_TESSELLATOR2,
+ gcvBLOCK_TESSELLATOR3,
+ gcvBLOCK_RASTER,
+ gcvBLOCK_VG,
+ gcvBLOCK_VG2,
+ gcvBLOCK_VG3,
+ gcvBLOCK_PIXEL,
+
+ /* Number of defined blocks. */
+ gcvBLOCK_COUNT
}
gceBLOCK;
#endif
}
gceDEBUG_MESSAGE_TYPE;
-typedef enum _gceSPECIAL_HINT
+/* Shading format. */
+typedef enum _gceSHADING
{
- gceSPECIAL_HINT0,
- gceSPECIAL_HINT1,
- gceSPECIAL_HINT2,
- gceSPECIAL_HINT3,
- /* For disable dynamic stream/index */
- gceSPECIAL_HINT4
+ gcvSHADING_SMOOTH,
+ gcvSHADING_FLAT_D3D,
+ gcvSHADING_FLAT_OPENGL,
}
-gceSPECIAL_HINT;
+gceSHADING;
-typedef enum _gceMACHINECODE
+/* Culling modes. */
+typedef enum _gceCULL
{
- gcvMACHINECODE_HOVERJET0 = 0x0,
- gcvMACHINECODE_HOVERJET1 ,
+ gcvCULL_NONE,
+ gcvCULL_CCW,
+ gcvCULL_CW,
+}
+gceCULL;
- gcvMACHINECODE_TAIJI0 ,
- gcvMACHINECODE_TAIJI1 ,
- gcvMACHINECODE_TAIJI2 ,
+/* Fill modes. */
+typedef enum _gceFILL
+{
+ gcvFILL_POINT,
+ gcvFILL_WIRE_FRAME,
+ gcvFILL_SOLID,
+}
+gceFILL;
- gcvMACHINECODE_ANTUTU0 ,
+/* Compare modes. */
+typedef enum _gceCOMPARE
+{
+ gcvCOMPARE_INVALID = 0,
+ gcvCOMPARE_NEVER,
+ gcvCOMPARE_NOT_EQUAL,
+ gcvCOMPARE_LESS,
+ gcvCOMPARE_LESS_OR_EQUAL,
+ gcvCOMPARE_EQUAL,
+ gcvCOMPARE_GREATER,
+ gcvCOMPARE_GREATER_OR_EQUAL,
+ gcvCOMPARE_ALWAYS,
+}
+gceCOMPARE;
- gcvMACHINECODE_GLB27_RELEASE_0,
- gcvMACHINECODE_GLB27_RELEASE_1,
+/* Stencil modes. */
+typedef enum _gceSTENCIL_MODE
+{
+ gcvSTENCIL_NONE,
+ gcvSTENCIL_SINGLE_SIDED,
+ gcvSTENCIL_DOUBLE_SIDED,
+}
+gceSTENCIL_MODE;
+
+/* Stencil operations. */
+typedef enum _gceSTENCIL_OPERATION
+{
+ gcvSTENCIL_KEEP,
+ gcvSTENCIL_REPLACE,
+ gcvSTENCIL_ZERO,
+ gcvSTENCIL_INVERT,
+ gcvSTENCIL_INCREMENT,
+ gcvSTENCIL_DECREMENT,
+ gcvSTENCIL_INCREMENT_SATURATE,
+ gcvSTENCIL_DECREMENT_SATURATE,
+ gcvSTENCIL_OPERATION_INVALID = -1
+}
+gceSTENCIL_OPERATION;
+
+/* Stencil selection. */
+typedef enum _gceSTENCIL_WHERE
+{
+ gcvSTENCIL_FRONT,
+ gcvSTENCIL_BACK,
+}
+gceSTENCIL_WHERE;
+
+/* Texture addressing selection. */
+typedef enum _gceTEXTURE_WHICH
+{
+ gcvTEXTURE_S,
+ gcvTEXTURE_T,
+ gcvTEXTURE_R,
+}
+gceTEXTURE_WHICH;
+
+/* Texture addressing modes. */
+typedef enum _gceTEXTURE_ADDRESSING
+{
+ gcvTEXTURE_INVALID = 0,
+ gcvTEXTURE_CLAMP,
+ gcvTEXTURE_WRAP,
+ gcvTEXTURE_MIRROR,
+ gcvTEXTURE_BORDER,
+ gcvTEXTURE_MIRROR_ONCE,
+}
+gceTEXTURE_ADDRESSING;
+
+/* Texture filters. */
+typedef enum _gceTEXTURE_FILTER
+{
+ gcvTEXTURE_NONE,
+ gcvTEXTURE_POINT,
+ gcvTEXTURE_LINEAR,
+ gcvTEXTURE_ANISOTROPIC,
+}
+gceTEXTURE_FILTER;
+
+typedef enum _gceTEXTURE_COMPONENT
+{
+ gcvTEXTURE_COMPONENT_R,
+ gcvTEXTURE_COMPONENT_G,
+ gcvTEXTURE_COMPONENT_B,
+ gcvTEXTURE_COMPONENT_A,
+
+ gcvTEXTURE_COMPONENT_NUM,
+} gceTEXTURE_COMPONENT;
+
+/* Texture swizzle modes. */
+typedef enum _gceTEXTURE_SWIZZLE
+{
+ gcvTEXTURE_SWIZZLE_R = 0,
+ gcvTEXTURE_SWIZZLE_G,
+ gcvTEXTURE_SWIZZLE_B,
+ gcvTEXTURE_SWIZZLE_A,
+ gcvTEXTURE_SWIZZLE_0,
+ gcvTEXTURE_SWIZZLE_1,
+
+ gcvTEXTURE_SWIZZLE_INVALID,
+} gceTEXTURE_SWIZZLE;
+
+typedef enum _gceTEXTURE_COMPARE_MODE
+{
+ gcvTEXTURE_COMPARE_MODE_INVALID = 0,
+ gcvTEXTURE_COMPARE_MODE_NONE,
+ gcvTEXTURE_COMPARE_MODE_REF,
+} gceTEXTURE_COMPARE_MODE;
- gcvMACHINECODE_WAVESCAPE0 ,
- gcvMACHINECODE_WAVESCAPE1 ,
+/* Pixel output swizzle modes. */
+typedef enum _gcePIXEL_SWIZZLE
+{
+ gcvPIXEL_SWIZZLE_R = gcvTEXTURE_SWIZZLE_R,
+ gcvPIXEL_SWIZZLE_G = gcvTEXTURE_SWIZZLE_G,
+ gcvPIXEL_SWIZZLE_B = gcvTEXTURE_SWIZZLE_B,
+ gcvPIXEL_SWIZZLE_A = gcvTEXTURE_SWIZZLE_A,
+
+ gcvPIXEL_SWIZZLE_INVALID,
+} gcePIXEL_SWIZZLE;
+
+/* Primitive types. */
+typedef enum _gcePRIMITIVE
+{
+ gcvPRIMITIVE_POINT_LIST,
+ gcvPRIMITIVE_LINE_LIST,
+ gcvPRIMITIVE_LINE_STRIP,
+ gcvPRIMITIVE_LINE_LOOP,
+ gcvPRIMITIVE_TRIANGLE_LIST,
+ gcvPRIMITIVE_TRIANGLE_STRIP,
+ gcvPRIMITIVE_TRIANGLE_FAN,
+ gcvPRIMITIVE_RECTANGLE,
+}
+gcePRIMITIVE;
+
+/* Index types. */
+typedef enum _gceINDEX_TYPE
+{
+ gcvINDEX_8,
+ gcvINDEX_16,
+ gcvINDEX_32,
+}
+gceINDEX_TYPE;
+
+/* Multi GPU rendering modes. */
+typedef enum _gceMULTI_GPU_RENDERING_MODE
+{
+ gcvMULTI_GPU_RENDERING_MODE_OFF,
+ gcvMULTI_GPU_RENDERING_MODE_SPLIT_WIDTH,
+ gcvMULTI_GPU_RENDERING_MODE_SPLIT_HEIGHT,
+ gcvMULTI_GPU_RENDERING_MODE_INTERLEAVED_64x64,
+ gcvMULTI_GPU_RENDERING_MODE_INTERLEAVED_128x64,
+ gcvMULTI_GPU_RENDERING_MODE_INTERLEAVED_128x128
+}
+gceMULTI_GPU_RENDERING_MODE;
+
+typedef enum _gceCORE_3D_MASK
+{
+ gcvCORE_3D_0_MASK = (1 << 0),
+ gcvCORE_3D_1_MASK = (1 << 1),
+
+ gcvCORE_3D_ALL_MASK = (0xFFFF)
+}
+gceCORE_3D_MASK;
+
+typedef enum _gceCORE_3D_ID
+{
+ gcvCORE_3D_0_ID = 0,
+ gcvCORE_3D_1_ID = 1,
- gcvMACHINECODE_NENAMARKV2_4_0 ,
- gcvMACHINECODE_NENAMARKV2_4_1 ,
+ gcvCORE_3D_ID_INVALID = ~0UL
+}
+gceCORE_3D_ID;
+
+typedef enum _gceMULTI_GPU_MODE
+{
+ gcvMULTI_GPU_MODE_COMBINED = 0,
+ gcvMULTI_GPU_MODE_INDEPENDENT = 1
+}
+gceMULTI_GPU_MODE;
+
+typedef enum _gceMACHINECODE
+{
+ gcvMACHINECODE_ANTUTU0 = 0x0,
+
+ gcvMACHINECODE_GLB27_RELEASE_0,
gcvMACHINECODE_GLB25_RELEASE_0,
gcvMACHINECODE_GLB25_RELEASE_1,
gcvMACHINECODE_GLB25_RELEASE_2,
+
+ /* keep it as the last enum */
+ gcvMACHINECODE_COUNT
}
gceMACHINECODE;
+typedef enum _gceUNIFORMCVT
+{
+ gcvUNIFORMCVT_NONE = 0,
+ gcvUNIFORMCVT_TO_BOOL,
+ gcvUNIFORMCVT_TO_FLOAT,
+} gceUNIFORMCVT;
+
+typedef enum _gceHAL_ARG_VERSION
+{
+ gcvHAL_ARG_VERSION_V1 = 0x0,
+}
+gceHAL_ARG_VERSION;
+
+
+/*
+* Bit of a requirment is 1 means requirement is a must, 0 means requirement can
+* be ignored.
+*/
+#define gcvALLOC_FLAG_CONTIGUOUS_BIT 0
+#define gcvALLOC_FLAG_CACHEABLE_BIT 1
+#define gcvALLOC_FLAG_SECURITY_BIT 2
+#define gcvALLOC_FLAG_NON_CONTIGUOUS_BIT 3
+#define gcvALLOC_FLAG_MEMLIMIT_BIT 4
+
+/* No special needs. */
+#define gcvALLOC_FLAG_NONE (0)
+/* Physical contiguous. */
+#define gcvALLOC_FLAG_CONTIGUOUS (1 << gcvALLOC_FLAG_CONTIGUOUS_BIT)
+/* Can be remapped as cacheable. */
+#define gcvALLOC_FLAG_CACHEABLE (1 << gcvALLOC_FLAG_CACHEABLE_BIT)
+/* Secure buffer. */
+#define gcvALLOC_FLAG_SECURITY (1 << gcvALLOC_FLAG_SECURITY_BIT)
+/* Physical non contiguous. */
+#define gcvALLOC_FLAG_NON_CONTIGUOUS (1 << gcvALLOC_FLAG_NON_CONTIGUOUS_BIT)
+#define gcvALLOC_FLAG_MEMLIMIT (1 << gcvALLOC_FLAG_MEMLIMIT_BIT)
+
+/* GL_VIV internal usage */
+#ifndef GL_MAP_BUFFER_OBJ_VIV
+#define GL_MAP_BUFFER_OBJ_VIV 0x10000
+#endif
+
+/* Command buffer usage. */
+#define gcvCOMMAND_2D (1 << 0)
+#define gcvCOMMAND_3D (1 << 1)
/******************************************************************************\
****************************** Object Declarations *****************************
typedef struct _gckCONTEXT * gckCONTEXT;
typedef struct _gcoCMDBUF * gcoCMDBUF;
+
typedef struct _gcsSTATE_DELTA * gcsSTATE_DELTA_PTR;
typedef struct _gcsQUEUE * gcsQUEUE_PTR;
typedef struct _gcoQUEUE * gcoQUEUE;
typedef struct _gcs2D_PROFILE * gcs2D_PROFILE_PTR;
#if gcdENABLE_VG
-typedef struct _gcoVGHARDWARE * gcoVGHARDWARE;
+typedef struct _gcoVGHARDWARE * gcoVGHARDWARE;
typedef struct _gcoVGBUFFER * gcoVGBUFFER;
typedef struct _gckVGHARDWARE * gckVGHARDWARE;
-typedef struct _gcsVGCONTEXT * gcsVGCONTEXT_PTR;
-typedef struct _gcsVGCONTEXT_MAP * gcsVGCONTEXT_MAP_PTR;
-typedef struct _gcsVGCMDQUEUE * gcsVGCMDQUEUE_PTR;
-typedef struct _gcsTASK_MASTER_TABLE * gcsTASK_MASTER_TABLE_PTR;
-typedef struct _gckVGKERNEL * gckVGKERNEL;
-typedef void * gctTHREAD;
+typedef struct _gcsVGCONTEXT * gcsVGCONTEXT_PTR;
+typedef struct _gcsVGCONTEXT_MAP * gcsVGCONTEXT_MAP_PTR;
+typedef struct _gcsVGCMDQUEUE * gcsVGCMDQUEUE_PTR;
+typedef struct _gcsTASK_MASTER_TABLE * gcsTASK_MASTER_TABLE_PTR;
+typedef struct _gckVGKERNEL * gckVGKERNEL;
+typedef void * gctTHREAD;
#endif
#ifdef __cplusplus
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#ifndef __gc_hal_kernel_buffer_h_
#define __gc_hal_kernel_buffer_h_
-
#ifdef __cplusplus
extern "C" {
#endif
}
gcsSTATE_DELTA;
+/* Command buffer patch record. */
+struct _gcsPATCH
+{
+ /* Pointer within the buffer. */
+ gctUINT32_PTR pointer;
+
+ /* 32-bit data to write at the specified offset. */
+ gctUINT32 data;
+};
+
+/* List of patches for the command buffer. */
+struct _gcsPATCH_LIST
+{
+ /* Array of patch records. */
+ struct _gcsPATCH patch[1024];
+
+ /* Number of patches in the array. */
+ gctUINT count;
+
+ /* Next item in the list. */
+ struct _gcsPATCH_LIST *next;
+};
+
/* Command buffer object. */
struct _gcoCMDBUF
{
/* The object. */
gcsOBJECT object;
+ /* Commit count. */
+ gctUINT count;
+
/* Command buffer entry and exit pipes. */
gcePIPE_SELECT entryPipe;
gcePIPE_SELECT exitPipe;
gctUINT64 logical;
/* Number of bytes in command buffer. */
- gctUINT bytes;
+ gctUINT32 bytes;
/* Start offset into the command buffer. */
- gctUINT startOffset;
+ gctUINT32 startOffset;
/* Current offset into the command buffer. */
- gctUINT offset;
+ gctUINT32 offset;
/* Number of free bytes in command buffer. */
- gctUINT free;
+ gctUINT32 free;
/* Location of the last reserved area. */
gctUINT64 lastReserve;
- gctUINT lastOffset;
+ gctUINT32 lastOffset;
#if gcdSECURE_USER
/* Hint array for the current command buffer. */
gctUINT32 lastLoadStateAddress;
gctUINT32 lastLoadStateCount;
#endif
+
+ /* Completion signal. */
+ gctSIGNAL signal;
+
+ /* List of patches. */
+ struct _gcsPATCH_LIST *patchHead;
+ struct _gcsPATCH_LIST *patchTail;
+
+ /* Link to the siblings. */
+ gcoCMDBUF prev;
+ gcoCMDBUF next;
};
typedef struct _gcsQUEUE
gcsQUEUE_PTR head;
gcsQUEUE_PTR tail;
-#ifdef __QNXNTO__
- /* Buffer for records. */
- gcsQUEUE_PTR records;
- gctUINT32 freeBytes;
- gctUINT32 offset;
-#else
+ /* chunks of the records. */
+ gctPOINTER chunks;
+
/* List of free records. */
gcsQUEUE_PTR freeList;
-#endif
+
#define gcdIN_QUEUE_RECORD_LIMIT 16
/* Number of records currently in queue */
gctUINT32 recordCount;
};
+struct _gcsTEMPCMDBUF
+{
+ gctUINT32 currentByteSize;
+ gctPOINTER buffer;
+ gctBOOL inUse;
+};
+
#ifdef __cplusplus
}
#endif
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
/*
-** Include file for the local memory management.
+** Include file for the local memory management.
*/
#ifndef __gc_hal_mem_h_
#define __gc_hal_mem_h_
-#ifndef VIVANTE_NO_3D
+#if (gcdENABLE_3D || gcdENABLE_VG)
#ifdef __cplusplus
extern "C" {
/*******************************************************************************
** Usage:
- The macros to declare MemPool type and functions are
- gcmMEM_DeclareFSMemPool (Type, TypeName, Prefix)
- gcmMEM_DeclareVSMemPool (Type, TypeName, Prefix)
- gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix)
-
- The data structures for MemPool are
- typedef struct _gcsMEM_FS_MEM_POOL * gcsMEM_FS_MEM_POOL;
- typedef struct _gcsMEM_VS_MEM_POOL * gcsMEM_VS_MEM_POOL;
- typedef struct _gcsMEM_AFS_MEM_POOL * gcsMEM_AFS_MEM_POOL;
-
- The MemPool constructor and destructor functions are
- gcfMEM_InitFSMemPool(gcsMEM_FS_MEM_POOL *, gcoOS, gctUINT, gctUINT);
- gcfMEM_FreeFSMemPool(gcsMEM_FS_MEM_POOL *);
- gcfMEM_InitVSMemPool(gcsMEM_VS_MEM_POOL *, gcoOS, gctUINT, gctBOOL);
- gcfMEM_FreeVSMemPool(gcsMEM_VS_MEM_POOL *);
- gcfMEM_InitAFSMemPool(gcsMEM_AFS_MEM_POOL *, gcoOS, gctUINT);
- gcfMEM_FreeAFSMemPool(gcsMEM_AFS_MEM_POOL *);
-
- FS: for Fixed-Size data structures
- VS: for Variable-size data structures
- AFS: for Array of Fixed-Size data structures
-
-
- // Example 1: For a fixed-size data structure, struct gcsNode.
- // It is used locally in a file, so the functions are static without prefix.
- // At top level, declear allocate and free functions.
- // The first argument is the data type.
- // The second armument is the short name used in the fuctions.
- gcmMEM_DeclareFSMemPool(struct gcsNode, Node, );
-
- // The previous macro creates two inline functions,
- // _AllocateNode and _FreeNode.
-
- // In function or struct
- gcsMEM_FS_MEM_POOL nodeMemPool;
-
- // In function,
- struct gcsNode * node;
- gceSTATUS status;
-
- // Before using the memory pool, initialize it.
- // The second argument is the gcoOS object.
- // The third argument is the number of data structures to allocate for each chunk.
- status = gcfMEM_InitFSMemPool(&nodeMemPool, os, 100, sizeof(struct gcsNode));
- ...
-
- // Allocate a node.
- status = _AllocateNode(nodeMemPool, &node);
- ...
- // Free a node.
- _FreeNode(nodeMemPool, node);
-
- // After using the memory pool, free it.
- gcfMEM_FreeFSMemPool(&nodeMemPool);
-
-
- // Example 2: For array of fixed-size data structures, struct gcsNode.
- // It is used in several files, so the functions are extern with prefix.
- // At top level, declear allocate and free functions.
- // The first argument is the data type, and the second one is the short name
- // used in the fuctions.
- gcmMEM_DeclareAFSMemPool(struct gcsNode, NodeArray, gcfOpt);
-
- // The previous macro creates two inline functions,
- // gcfOpt_AllocateNodeArray and gcfOpt_FreeNodeArray.
-
- // In function or struct
- gcsMEM_AFS_MEM_POOL nodeArrayMemPool;
-
- // In function,
- struct gcsNode * nodeArray;
- gceSTATUS status;
-
- // Before using the array memory pool, initialize it.
- // The second argument is the gcoOS object, the third is the number of data
- // structures to allocate for each chunk.
- status = gcfMEM_InitAFSMemPool(&nodeArrayMemPool, os, sizeof(struct gcsNode));
- ...
-
- // Allocate a node array of size 100.
- status = gcfOpt_AllocateNodeArray(nodeArrayMemPool, &nodeArray, 100);
- ...
- // Free a node array.
- gcfOpt_FreeNodeArray(&nodeArrayMemPool, nodeArray);
-
- // After using the array memory pool, free it.
- gcfMEM_FreeAFSMemPool(&nodeArrayMemPool);
+ The macros to declare MemPool type and functions are
+ gcmMEM_DeclareFSMemPool (Type, TypeName, Prefix)
+ gcmMEM_DeclareVSMemPool (Type, TypeName, Prefix)
+ gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix)
+
+ The data structures for MemPool are
+ typedef struct _gcsMEM_FS_MEM_POOL * gcsMEM_FS_MEM_POOL;
+ typedef struct _gcsMEM_VS_MEM_POOL * gcsMEM_VS_MEM_POOL;
+ typedef struct _gcsMEM_AFS_MEM_POOL * gcsMEM_AFS_MEM_POOL;
+
+ The MemPool constructor and destructor functions are
+ gcfMEM_InitFSMemPool(gcsMEM_FS_MEM_POOL *, gcoOS, gctUINT, gctUINT);
+ gcfMEM_FreeFSMemPool(gcsMEM_FS_MEM_POOL *);
+ gcfMEM_InitVSMemPool(gcsMEM_VS_MEM_POOL *, gcoOS, gctUINT, gctBOOL);
+ gcfMEM_FreeVSMemPool(gcsMEM_VS_MEM_POOL *);
+ gcfMEM_InitAFSMemPool(gcsMEM_AFS_MEM_POOL *, gcoOS, gctUINT);
+ gcfMEM_FreeAFSMemPool(gcsMEM_AFS_MEM_POOL *);
+
+ FS: for Fixed-Size data structures
+ VS: for Variable-size data structures
+ AFS: for Array of Fixed-Size data structures
+
+
+ // Example 1: For a fixed-size data structure, struct gcsNode.
+ // It is used locally in a file, so the functions are static without prefix.
+ // At top level, declear allocate and free functions.
+ // The first argument is the data type.
+ // The second armument is the short name used in the fuctions.
+ gcmMEM_DeclareFSMemPool(struct gcsNode, Node, );
+
+ // The previous macro creates two inline functions,
+ // _AllocateNode and _FreeNode.
+
+ // In function or struct
+ gcsMEM_FS_MEM_POOL nodeMemPool;
+
+ // In function,
+ struct gcsNode * node;
+ gceSTATUS status;
+
+ // Before using the memory pool, initialize it.
+ // The second argument is the gcoOS object.
+ // The third argument is the number of data structures to allocate for each chunk.
+ status = gcfMEM_InitFSMemPool(&nodeMemPool, os, 100, sizeof(struct gcsNode));
+ ...
+
+ // Allocate a node.
+ status = _AllocateNode(nodeMemPool, &node);
+ ...
+ // Free a node.
+ _FreeNode(nodeMemPool, node);
+
+ // After using the memory pool, free it.
+ gcfMEM_FreeFSMemPool(&nodeMemPool);
+
+
+ // Example 2: For array of fixed-size data structures, struct gcsNode.
+ // It is used in several files, so the functions are extern with prefix.
+ // At top level, declear allocate and free functions.
+ // The first argument is the data type, and the second one is the short name
+ // used in the fuctions.
+ gcmMEM_DeclareAFSMemPool(struct gcsNode, NodeArray, gcfOpt);
+
+ // The previous macro creates two inline functions,
+ // gcfOpt_AllocateNodeArray and gcfOpt_FreeNodeArray.
+
+ // In function or struct
+ gcsMEM_AFS_MEM_POOL nodeArrayMemPool;
+
+ // In function,
+ struct gcsNode * nodeArray;
+ gceSTATUS status;
+
+ // Before using the array memory pool, initialize it.
+ // The second argument is the gcoOS object, the third is the number of data
+ // structures to allocate for each chunk.
+ status = gcfMEM_InitAFSMemPool(&nodeArrayMemPool, os, sizeof(struct gcsNode));
+ ...
+
+ // Allocate a node array of size 100.
+ status = gcfOpt_AllocateNodeArray(nodeArrayMemPool, &nodeArray, 100);
+ ...
+ // Free a node array.
+ gcfOpt_FreeNodeArray(&nodeArrayMemPool, nodeArray);
+
+ // After using the array memory pool, free it.
+ gcfMEM_FreeAFSMemPool(&nodeArrayMemPool);
*******************************************************************************/
/*******************************************************************************
-** To switch back to use gcoOS_Allocate and gcoOS_Free, add
-** #define USE_LOCAL_MEMORY_POOL 0
-** before including this file.
+** To switch back to use gcoOS_Allocate and gcoOS_Free, add
+** #define USE_LOCAL_MEMORY_POOL 0
+** before including this file.
*******************************************************************************/
#ifndef USE_LOCAL_MEMORY_POOL
/*
This define enables the local memory management to improve performance.
*/
-#define USE_LOCAL_MEMORY_POOL 1
+#define USE_LOCAL_MEMORY_POOL 1
#endif
/*******************************************************************************
-** Memory Pool Data Structures
+** Memory Pool Data Structures
*******************************************************************************/
#if USE_LOCAL_MEMORY_POOL
- typedef struct _gcsMEM_FS_MEM_POOL * gcsMEM_FS_MEM_POOL;
- typedef struct _gcsMEM_VS_MEM_POOL * gcsMEM_VS_MEM_POOL;
- typedef struct _gcsMEM_AFS_MEM_POOL * gcsMEM_AFS_MEM_POOL;
+ typedef struct _gcsMEM_FS_MEM_POOL * gcsMEM_FS_MEM_POOL;
+ typedef struct _gcsMEM_VS_MEM_POOL * gcsMEM_VS_MEM_POOL;
+ typedef struct _gcsMEM_AFS_MEM_POOL * gcsMEM_AFS_MEM_POOL;
#else
- typedef gcoOS gcsMEM_FS_MEM_POOL;
- typedef gcoOS gcsMEM_VS_MEM_POOL;
- typedef gcoOS gcsMEM_AFS_MEM_POOL;
+ typedef gcoOS gcsMEM_FS_MEM_POOL;
+ typedef gcoOS gcsMEM_VS_MEM_POOL;
+ typedef gcoOS gcsMEM_AFS_MEM_POOL;
#endif
/*******************************************************************************
-** Memory Pool Macros
+** Memory Pool Macros
*******************************************************************************/
#if USE_LOCAL_MEMORY_POOL
#define gcmMEM_DeclareFSMemPool(Type, TypeName, Prefix) \
gceSTATUS \
Prefix##_Allocate##TypeName( \
- gcsMEM_FS_MEM_POOL MemPool, \
- Type ** Pointer \
- ) \
+ gcsMEM_FS_MEM_POOL MemPool, \
+ Type ** Pointer \
+ ) \
{ \
- return(gcfMEM_FSMemPoolGetANode(MemPool, (gctPOINTER *) Pointer)); \
+ return(gcfMEM_FSMemPoolGetANode(MemPool, (gctPOINTER *) Pointer)); \
} \
\
gceSTATUS \
Prefix##_CAllocate##TypeName( \
- gcsMEM_FS_MEM_POOL MemPool, \
- Type ** Pointer \
- ) \
+ gcsMEM_FS_MEM_POOL MemPool, \
+ Type ** Pointer \
+ ) \
{ \
- gceSTATUS status; \
+ gceSTATUS status; \
gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
- gcmERR_RETURN(gcfMEM_FSMemPoolGetANode(MemPool, (gctPOINTER *) Pointer)); \
- gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, gcmSIZEOF(Type)); \
+ gcmERR_RETURN(gcfMEM_FSMemPoolGetANode(MemPool, (gctPOINTER *) Pointer)); \
+ gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, gcmSIZEOF(Type)); \
gcmFOOTER(); \
- return gcvSTATUS_OK; \
+ return gcvSTATUS_OK; \
} \
\
gceSTATUS \
Prefix##_Free##TypeName( \
- gcsMEM_FS_MEM_POOL MemPool, \
- Type * Pointer \
- ) \
+ gcsMEM_FS_MEM_POOL MemPool, \
+ Type * Pointer \
+ ) \
{ \
- gceSTATUS status; \
+ gceSTATUS status; \
gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
status = gcfMEM_FSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \
gcmFOOTER(); \
- return status; \
+ return status; \
} \
\
gceSTATUS \
Prefix##_Free##TypeName##List( \
- gcsMEM_FS_MEM_POOL MemPool, \
- Type * FirstPointer, \
- Type * LastPointer \
- ) \
+ gcsMEM_FS_MEM_POOL MemPool, \
+ Type * FirstPointer, \
+ Type * LastPointer \
+ ) \
{ \
gceSTATUS status; \
gcmHEADER_ARG("MemPool=0x%x FirstPointer=0x%x LastPointer=0x%x", MemPool, FirstPointer, LastPointer); \
status = gcfMEM_FSMemPoolFreeAList(MemPool, (gctPOINTER) FirstPointer, (gctPOINTER) LastPointer); \
gcmFOOTER(); \
- return status; \
+ return status; \
}
#define gcmMEM_DeclareVSMemPool(Type, TypeName, Prefix) \
gceSTATUS \
Prefix##_Allocate##TypeName( \
- gcsMEM_FS_MEM_POOL MemPool, \
- Type ** Pointer, \
- gctUINT Size \
- ) \
+ gcsMEM_FS_MEM_POOL MemPool, \
+ Type ** Pointer, \
+ gctUINT Size \
+ ) \
{ \
gceSTATUS status;\
gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
status = gcfMEM_VSMemPoolGetANode(MemPool, Size, (gctPOINTER *) Pointer); \
gcmFOOTER(); \
- return status; \
+ return status; \
} \
\
gceSTATUS \
Prefix##_CAllocate##TypeName( \
- gcsMEM_FS_MEM_POOL MemPool, \
- Type ** Pointer, \
- gctUINT Size \
- ) \
+ gcsMEM_FS_MEM_POOL MemPool, \
+ Type ** Pointer, \
+ gctUINT Size \
+ ) \
{ \
- gceSTATUS status; \
+ gceSTATUS status; \
gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
- gcmERR_RETURN(gcfMEM_VSMemPoolGetANode(MemPool, Size, (gctPOINTER *) Pointer)); \
- gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, size); \
+ gcmERR_RETURN(gcfMEM_VSMemPoolGetANode(MemPool, Size, (gctPOINTER *) Pointer)); \
+ gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, size); \
gcmFOOTER(); \
- return gcvSTATUS_OK; \
+ return gcvSTATUS_OK; \
} \
\
gceSTATUS \
Prefix##_Free##TypeName( \
- gcsMEM_FS_MEM_POOL MemPool, \
- Type * Pointer \
- ) \
+ gcsMEM_FS_MEM_POOL MemPool, \
+ Type * Pointer \
+ ) \
{ \
gceSTATUS status; \
gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pinter); \
status = gcfMEM_VSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \
gcmFOOTER(); \
- return status; \
+ return status; \
}
#define gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix) \
gceSTATUS \
Prefix##_Allocate##TypeName( \
- gcsMEM_AFS_MEM_POOL MemPool, \
- Type ** Pointer, \
- gctUINT Count \
- ) \
+ gcsMEM_AFS_MEM_POOL MemPool, \
+ Type ** Pointer, \
+ gctUINT Count \
+ ) \
{ \
gceSTATUS status; \
gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
status = gcfMEM_AFSMemPoolGetANode(MemPool, Count, (gctPOINTER *) Pointer); \
gcmFOOTER(); \
- return status; \
+ return status; \
} \
\
gceSTATUS \
Prefix##_CAllocate##TypeName( \
- gcsMEM_AFS_MEM_POOL MemPool, \
- Type ** Pointer, \
- gctUINT Count \
- ) \
+ gcsMEM_AFS_MEM_POOL MemPool, \
+ Type ** Pointer, \
+ gctUINT Count \
+ ) \
{ \
- gceSTATUS status; \
+ gceSTATUS status; \
gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
- gcmERR_RETURN(gcfMEM_AFSMemPoolGetANode(MemPool, Count, (gctPOINTER *) Pointer)); \
- gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Count * gcmSIZEOF(Type)); \
+ gcmERR_RETURN(gcfMEM_AFSMemPoolGetANode(MemPool, Count, (gctPOINTER *) Pointer)); \
+ gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Count * gcmSIZEOF(Type)); \
gcmFOOTER(); \
- return gcvSTATUS_OK; \
+ return gcvSTATUS_OK; \
} \
\
gceSTATUS \
Prefix##_Free##TypeName( \
- gcsMEM_AFS_MEM_POOL MemPool, \
- Type * Pointer \
- ) \
+ gcsMEM_AFS_MEM_POOL MemPool, \
+ Type * Pointer \
+ ) \
{ \
gceSTATUS status; \
gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
status = gcfMEM_AFSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \
gcmFOOTER(); \
- return status; \
+ return status; \
}
#else
#define gcmMEM_DeclareFSMemPool(Type, TypeName, Prefix) \
gceSTATUS \
Prefix##_Allocate##TypeName( \
- gcsMEM_FS_MEM_POOL MemPool, \
- Type ** Pointer \
- ) \
+ gcsMEM_FS_MEM_POOL MemPool, \
+ Type ** Pointer \
+ ) \
{ \
gceSTATUS status; \
gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
status = gcoOS_Allocate(MemPool, \
- gcmSIZEOF(Type), \
- (gctPOINTER *) Pointer); \
+ gcmSIZEOF(Type), \
+ (gctPOINTER *) Pointer); \
gcmFOOTER(); \
- return status; \
+ return status; \
} \
\
gceSTATUS \
Prefix##_CAllocate##TypeName( \
- gcsMEM_FS_MEM_POOL MemPool, \
- Type ** Pointer \
- ) \
+ gcsMEM_FS_MEM_POOL MemPool, \
+ Type ** Pointer \
+ ) \
{ \
- gceSTATUS status; \
+ gceSTATUS status; \
gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
- gcmERR_RETURN(gcoOS_Allocate(MemPool, \
- gcmSIZEOF(Type), \
- (gctPOINTER *) Pointer)); \
- gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, gcmSIZEOF(Type)); \
+ gcmERR_RETURN(gcoOS_Allocate(MemPool, \
+ gcmSIZEOF(Type), \
+ (gctPOINTER *) Pointer)); \
+ gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, gcmSIZEOF(Type)); \
gcmFOOTER(); \
- return gcvSTATUS_OK; \
+ return gcvSTATUS_OK; \
} \
\
gceSTATUS \
Prefix##_Free##TypeName( \
- gcsMEM_FS_MEM_POOL MemPool, \
- Type * Pointer \
- ) \
+ gcsMEM_FS_MEM_POOL MemPool, \
+ Type * Pointer \
+ ) \
{ \
- gceSTATUS status; \
+ gceSTATUS status; \
gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
status = gcmOS_SAFE_FREE(MemPool, Pointer); \
gcmFOOTER(); \
- return status; \
+ return status; \
}
#define gcmMEM_DeclareVSMemPool(Type, TypeName, Prefix) \
gceSTATUS \
Prefix##_Allocate##TypeName( \
- gcsMEM_VS_MEM_POOL MemPool, \
- Type ** Pointer, \
- gctUINT Size \
- ) \
+ gcsMEM_VS_MEM_POOL MemPool, \
+ Type ** Pointer, \
+ gctUINT Size \
+ ) \
{ \
- gceSTATUS status; \
+ gceSTATUS status; \
gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
status = gcoOS_Allocate(MemPool, \
- Size, \
- (gctPOINTER *) Pointer); \
+ Size, \
+ (gctPOINTER *) Pointer); \
gcmFOOTER(); \
- return status; \
+ return status; \
} \
\
gceSTATUS \
Prefix##_CAllocate##TypeName( \
- gcsMEM_VS_MEM_POOL MemPool, \
- Type ** Pointer, \
- gctUINT Size \
- ) \
+ gcsMEM_VS_MEM_POOL MemPool, \
+ Type ** Pointer, \
+ gctUINT Size \
+ ) \
{ \
- gceSTATUS status; \
+ gceSTATUS status; \
gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
- gcmERR_RETURN(gcoOS_Allocate(MemPool, \
- Size, \
- (gctPOINTER *) Pointer)); \
- gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Size); \
+ gcmERR_RETURN(gcoOS_Allocate(MemPool, \
+ Size, \
+ (gctPOINTER *) Pointer)); \
+ gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Size); \
gcmFOOTER(); \
- return gcvSTATUS_OK; \
+ return gcvSTATUS_OK; \
} \
\
gceSTATUS \
Prefix##_Free##TypeName( \
- gcsMEM_VS_MEM_POOL MemPool, \
- Type * Pointer \
- ) \
+ gcsMEM_VS_MEM_POOL MemPool, \
+ Type * Pointer \
+ ) \
{ \
- gceSTATUS status; \
+ gceSTATUS status; \
gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
status = gcmOS_SAFE_FREE(MemPool, Pointer); \
gcmFOOTER(); \
- return status; \
+ return status; \
}
#define gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix) \
gceSTATUS \
Prefix##_Allocate##TypeName( \
- gcsMEM_AFS_MEM_POOL MemPool, \
- Type ** Pointer, \
- gctUINT Count \
- ) \
+ gcsMEM_AFS_MEM_POOL MemPool, \
+ Type ** Pointer, \
+ gctUINT Count \
+ ) \
{ \
- gceSTATUS status; \
+ gceSTATUS status; \
gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
status = gcoOS_Allocate(MemPool, \
- Count * gcmSIZEOF(Type), \
- (gctPOINTER *) Pointer); \
+ Count * gcmSIZEOF(Type), \
+ (gctPOINTER *) Pointer); \
gcmFOOTER(); \
- return status; \
+ return status; \
} \
\
gceSTATUS \
Prefix##_CAllocate##TypeName( \
- gcsMEM_AFS_MEM_POOL MemPool, \
- Type ** Pointer, \
- gctUINT Count \
- ) \
+ gcsMEM_AFS_MEM_POOL MemPool, \
+ Type ** Pointer, \
+ gctUINT Count \
+ ) \
{ \
- gceSTATUS status; \
+ gceSTATUS status; \
gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
- gcmERR_RETURN(gcoOS_Allocate(MemPool, \
- Count * gcmSIZEOF(Type), \
- (gctPOINTER *) Pointer)); \
- gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Count * gcmSIZEOF(Type)); \
+ gcmERR_RETURN(gcoOS_Allocate(MemPool, \
+ Count * gcmSIZEOF(Type), \
+ (gctPOINTER *) Pointer)); \
+ gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Count * gcmSIZEOF(Type)); \
gcmFOOTER(); \
- return gcvSTATUS_OK; \
+ return gcvSTATUS_OK; \
} \
\
gceSTATUS \
Prefix##_Free##TypeName( \
- gcsMEM_AFS_MEM_POOL MemPool, \
- Type * Pointer \
- ) \
+ gcsMEM_AFS_MEM_POOL MemPool, \
+ Type * Pointer \
+ ) \
{ \
- gceSTATUS status; \
+ gceSTATUS status; \
gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
status = gcmOS_SAFE_FREE(MemPool, Pointer); \
gcmFOOTER(); \
- return status; \
+ return status; \
}
#endif
/*******************************************************************************
-** Memory Pool Data Functions
+** Memory Pool Data Functions
*******************************************************************************/
gceSTATUS
gcfMEM_InitFSMemPool(
- IN gcsMEM_FS_MEM_POOL * MemPool,
- IN gcoOS OS,
- IN gctUINT NodeCount,
- IN gctUINT NodeSize
- );
+ IN gcsMEM_FS_MEM_POOL * MemPool,
+ IN gcoOS OS,
+ IN gctUINT NodeCount,
+ IN gctUINT NodeSize
+ );
gceSTATUS
gcfMEM_FreeFSMemPool(
- IN gcsMEM_FS_MEM_POOL * MemPool
- );
+ IN gcsMEM_FS_MEM_POOL * MemPool
+ );
gceSTATUS
gcfMEM_FSMemPoolGetANode(
- IN gcsMEM_FS_MEM_POOL MemPool,
- OUT gctPOINTER * Node
- );
+ IN gcsMEM_FS_MEM_POOL MemPool,
+ OUT gctPOINTER * Node
+ );
gceSTATUS
gcfMEM_FSMemPoolFreeANode(
- IN gcsMEM_FS_MEM_POOL MemPool,
- IN gctPOINTER Node
- );
+ IN gcsMEM_FS_MEM_POOL MemPool,
+ IN gctPOINTER Node
+ );
gceSTATUS
gcfMEM_FSMemPoolFreeAList(
- IN gcsMEM_FS_MEM_POOL MemPool,
- IN gctPOINTER FirstNode,
- IN gctPOINTER LastNode
- );
+ IN gcsMEM_FS_MEM_POOL MemPool,
+ IN gctPOINTER FirstNode,
+ IN gctPOINTER LastNode
+ );
gceSTATUS
gcfMEM_InitVSMemPool(
- IN gcsMEM_VS_MEM_POOL * MemPool,
- IN gcoOS OS,
- IN gctUINT BlockSize,
- IN gctBOOL RecycleFreeNode
- );
+ IN gcsMEM_VS_MEM_POOL * MemPool,
+ IN gcoOS OS,
+ IN gctUINT BlockSize,
+ IN gctBOOL RecycleFreeNode
+ );
gceSTATUS
gcfMEM_FreeVSMemPool(
- IN gcsMEM_VS_MEM_POOL * MemPool
- );
+ IN gcsMEM_VS_MEM_POOL * MemPool
+ );
gceSTATUS
gcfMEM_VSMemPoolGetANode(
- IN gcsMEM_VS_MEM_POOL MemPool,
- IN gctUINT Size,
- IN gctUINT Alignment,
- OUT gctPOINTER * Node
- );
+ IN gcsMEM_VS_MEM_POOL MemPool,
+ IN gctUINT Size,
+ IN gctUINT Alignment,
+ OUT gctPOINTER * Node
+ );
gceSTATUS
gcfMEM_VSMemPoolFreeANode(
- IN gcsMEM_VS_MEM_POOL MemPool,
- IN gctPOINTER Node
- );
+ IN gcsMEM_VS_MEM_POOL MemPool,
+ IN gctPOINTER Node
+ );
gceSTATUS
gcfMEM_InitAFSMemPool(
- IN gcsMEM_AFS_MEM_POOL *MemPool,
- IN gcoOS OS,
- IN gctUINT NodeCount,
- IN gctUINT NodeSize
- );
+ IN gcsMEM_AFS_MEM_POOL *MemPool,
+ IN gcoOS OS,
+ IN gctUINT NodeCount,
+ IN gctUINT NodeSize
+ );
gceSTATUS
gcfMEM_FreeAFSMemPool(
- IN gcsMEM_AFS_MEM_POOL *MemPool
- );
+ IN gcsMEM_AFS_MEM_POOL *MemPool
+ );
gceSTATUS
gcfMEM_AFSMemPoolGetANode(
- IN gcsMEM_AFS_MEM_POOL MemPool,
- IN gctUINT Count,
- OUT gctPOINTER * Node
- );
+ IN gcsMEM_AFS_MEM_POOL MemPool,
+ IN gctUINT Count,
+ OUT gctPOINTER * Node
+ );
gceSTATUS
gcfMEM_AFSMemPoolFreeANode(
- IN gcsMEM_AFS_MEM_POOL MemPool,
- IN gctPOINTER Node
- );
+ IN gcsMEM_AFS_MEM_POOL MemPool,
+ IN gctPOINTER Node
+ );
#ifdef __cplusplus
}
#endif
-#endif /* VIVANTE_NO_3D */
+#endif /* (gcdENABLE_3D || gcdENABLE_VG) */
#endif /* __gc_hal_mem_h_ */
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
*
*****************************************************************************/
-
#ifndef __gc_hal_options_h_
#define __gc_hal_options_h_
+/*
+ gcdSECURITY
+
+*/
+#ifndef gcdSECURITY
+# define gcdSECURITY 0
+#endif
+
/*
gcdPRINT_VERSION
# define VIVANTE_PROFILER 1
#endif
-#ifndef VIVANTE_PROFILER_PERDRAW
-# define VIVANTE_PROFILER_PERDRAW 0
-#endif
-
/*
VIVANTE_PROFILER_CONTEXT
- This define enables the profiler according to each hw context.
+ This define enables the profiler according each context.
*/
#ifndef VIVANTE_PROFILER_CONTEXT
# define VIVANTE_PROFILER_CONTEXT 1
#endif
+#ifndef VIVANTE_PROFILER_PERDRAW
+# define VIVANTE_PROFILER_PERDRAW 0
+#endif
+
+#ifndef VIVANTE_PROFILER_NEW
+# define VIVANTE_PROFILER_NEW 0
+#endif
+
+#ifndef VIVANTE_PROFILER_PM
+# define VIVANTE_PROFILER_PM 1
+#endif
/*
gcdUSE_VG
# define USE_SW_FB 0
#endif
-/*
- USE_SUPER_SAMPLING
-
- This define enables super-sampling support.
-*/
-#define USE_SUPER_SAMPLING 0
-
/*
PROFILE_HAL_COUNTERS
# define gcdDUMP_API 0
#endif
+
+
+/*
+ gcdDEBUG_OPTION
+ When set to 1, the debug options are enabled. We must set other MACRO to enable
+ sub case.
+*/
+#ifndef gcdDEBUG_OPTION
+# define gcdDEBUG_OPTION 0
+
+#if gcdDEBUG_OPTION
+/*
+ gcdDEBUG_OPTION_KEY
+ The process name of debug application.
+*/
+#ifndef gcdDEBUG_OPTION_KEY
+# define gcdDEBUG_OPTION_KEY "process"
+# endif
+/*
+ gcdDEBUG_OPTION_NO_GL_DRAWS
+ When set to 1, all glDrawArrays and glDrawElements will be skip.
+*/
+#ifndef gcdDEBUG_OPTION_NO_GL_DRAWS
+# define gcdDEBUG_OPTION_NO_GL_DRAWS 0
+# endif
+/*
+ gcdDEBUG_OPTION_NO_DRAW_PRIMITIVES
+ When set to 1, all DrawPrimitives will be skip.
+*/
+#ifndef gcdDEBUG_OPTION_NO_DRAW_PRIMITIVES
+# define gcdDEBUG_OPTION_NO_DRAW_PRIMITIVES 0
+# endif
+/*
+ gcdDEBUG_OPTION_SKIP_SWAP
+ When set to 1, just one out of gcdDEBUG_OPTION_SKIP_FRAMES(such as 1/10) eglSwapBuffers will be resolve,
+ others skip.
+*/
+#ifndef gcdDEBUG_OPTION_SKIP_SWAP
+# define gcdDEBUG_OPTION_SKIP_SWAP 0
+# define gcdDEBUG_OPTION_SKIP_FRAMES 10
+# endif
+/*
+ gcdDEBUG_OPTION_FORCE_16BIT_RENDER_TARGET
+ When set to 1, the format of render target will force to RGB565.
+*/
+#ifndef gcdDEBUG_OPTION_FORCE_16BIT_RENDER_TARGET
+# define gcdDEBUG_OPTION_FORCE_16BIT_RENDER_TARGET 0
+# endif
+/*
+ gcdDEBUG_OPTION_NONE_TEXTURE
+ When set to 1, the type of texture will be set to AQ_TEXTURE_SAMPLE_MODE_TYPE_NONE.
+*/
+#ifndef gcdDEBUG_OPTION_NONE_TEXTURE
+# define gcdDEBUG_OPTION_NONE_TEXTURE 0
+# endif
+/*
+ gcdDEBUG_OPTION_NONE_DEPTH
+ When set to 1, the depth format of surface will be set to gcvSURF_UNKNOWN.
+*/
+#ifndef gcdDEBUG_OPTION_NONE_DEPTH
+# define gcdDEBUG_OPTION_NONE_DEPTH 0
+# endif
+
+# endif
+#endif
+
+/*
+ gcdDUMP_SWAP_PER_DRAW
+
+ When set to 1, dump swap command for every single draw to make simulation comparison happy.
+ Only valid for ES3 driver for now.
+*/
+#ifndef gcdDUMP_SWAP_PER_DRAW
+# define gcdDUMP_SWAP_PER_DRAW 0
+#endif
+
/*
gcdDUMP_FRAMERATE
When set to a value other than zero, averaqe frame rate will be dumped.
in the average. Frame count starts from 1.
*/
#ifndef gcdDUMP_FRAMERATE
-# define gcdDUMP_FRAMERATE 0
-#endif
-
-/*
- gcdVIRTUAL_COMMAND_BUFFER
- When set to 1, user command buffer and context buffer will be allocated
- from gcvPOOL_VIRTUAL.
-*/
-#ifndef gcdVIRTUAL_COMMAND_BUFFER
-# define gcdVIRTUAL_COMMAND_BUFFER 0
+# define gcdDUMP_FRAMERATE 0
#endif
/*
# define gcdDUMP_COMMAND 0
#endif
+/*
+ gcdDUMP_2D
+
+ When set to non-zero, it will dump the 2D command and surface.
+*/
+#ifndef gcdDUMP_2D
+# define gcdDUMP_2D 0
+#endif
+
/*
gcdDUMP_FRAME_TGA
will be done into frame.tga. Frame count starts from 1.
*/
#ifndef gcdDUMP_FRAME_TGA
-#define gcdDUMP_FRAME_TGA 0
+# define gcdDUMP_FRAME_TGA 0
#endif
/*
gcdNULL_DRIVER
Set to 3 for bypassing the drivers.
*/
#ifndef gcdNULL_DRIVER
-# define gcdNULL_DRIVER 0
+# define gcdNULL_DRIVER 0
#endif
/*
# define gcdREGISTER_ACCESS_FROM_USER 1
#endif
-/*
- gcdUSER_HEAP_ALLOCATOR
-
- Set to 1 to enable user mode heap allocator for fast memory allocation
- and destroying. Otherwise, memory allocation/destroying in user mode
- will be directly managed by system. Only for linux for now.
-*/
-#ifndef gcdUSER_HEAP_ALLOCATOR
-# define gcdUSER_HEAP_ALLOCATOR 1
-#endif
-
/*
gcdHEAP_SIZE
#endif
/*
- gcdPOWER_SUSNPEND_WHEN_IDLE
+ gcdPOWER_SUSPEND_WHEN_IDLE
Set to 1 to make GPU enter gcvPOWER_SUSPEND when idle detected,
otherwise GPU will enter gcvPOWER_IDLE.
*/
-#ifndef gcdPOWER_SUSNPEND_WHEN_IDLE
-# define gcdPOWER_SUSNPEND_WHEN_IDLE 1
+#ifndef gcdPOWER_SUSPEND_WHEN_IDLE
+# define gcdPOWER_SUSPEND_WHEN_IDLE 1
#endif
-/*
- gcdFPGA_BUILD
-
- This define enables work arounds for FPGA images.
-*/
#ifndef gcdFPGA_BUILD
-# define gcdFPGA_BUILD 0
+# define gcdFPGA_BUILD 0
#endif
/*
#ifndef gcdGPU_TIMEOUT
#if gcdFPGA_BUILD
# define gcdGPU_TIMEOUT 0
+# define gcdGPU_2D_TIMEOUT 0
# else
# define gcdGPU_TIMEOUT 20000
+# define gcdGPU_2D_TIMEOUT 4000
# endif
#endif
# define gcdCMD_NO_2D_CONTEXT 1
#endif
+/*
+ gcdENABLE_BUFFER_ALIGNMENT
+
+ When enabled, video memory is allocated with atleast 16KB aligment
+ between multiple sub-buffers.
+*/
+#ifndef gcdENABLE_BUFFER_ALIGNMENT
+# define gcdENABLE_BUFFER_ALIGNMENT 1
+#endif
+
/*
gcdENABLE_BANK_ALIGNMENT
When enabled, video memory is allocated bank aligned. The vendor can modify
- _GetSurfaceBankAlignment() and gcoSURF_GetBankOffsetBytes() to define how
+ _GetSurfaceBankAlignment() and _GetBankOffsetBytes() to define how
different types of allocations are bank and channel aligned.
When disabled (default), no bank alignment is done.
*/
#endif
/*
- gcdENABLE_VG
- enable the 2D openVG
-*/
-
-#ifndef gcdENABLE_VG
-# define gcdENABLE_VG 0
-#endif
-
-/*
- gcdDYNAMIC_MAP_RESERVED_MEMORY
-
- When gcvPOOL_SYSTEM is constructed from RESERVED memory,
- driver can map the whole reserved memory to kernel space
- at the beginning, or just map a piece of memory when need
- to access.
-
- Notice:
- - It's only for the 2D openVG. For other cores, there is
- _NO_ need to map reserved memory to kernel.
- - It's meaningless when memory is allocated by
- gckOS_AllocateContiguous, in that case, memory is always
- mapped by system when allocated.
+ gcdDISABLE_CORES_2D3D
+ disable the 2D3D cores for 2D openVG
*/
-#ifndef gcdDYNAMIC_MAP_RESERVED_MEMORY
-# define gcdDYNAMIC_MAP_RESERVED_MEMORY 1
+#ifndef gcdDISABLE_CORES_2D3D
+# define gcdDISABLE_CORES_2D3D 0
#endif
/*
This option is only for those SOC which can't enable
writecombine without enabling cacheable.
*/
-
#ifndef gcdPAGED_MEMORY_CACHEABLE
# define gcdPAGED_MEMORY_CACHEABLE 0
#endif
When non-zero, non paged memory will be cacheable.
*/
-
#ifndef gcdNONPAGED_MEMORY_CACHEABLE
# define gcdNONPAGED_MEMORY_CACHEABLE 0
#endif
gcdNONPAGED_MEMORY_BUFFERABLE and gcdNONPAGED_MEMORY_CACHEABLE
can't be set 1 at same time
*/
-
#ifndef gcdNONPAGED_MEMORY_BUFFERABLE
# define gcdNONPAGED_MEMORY_BUFFERABLE 1
#endif
gcdENABLE_INFINITE_SPEED_HW
enable the Infinte HW , this is for 2D openVG
*/
-
#ifndef gcdENABLE_INFINITE_SPEED_HW
# define gcdENABLE_INFINITE_SPEED_HW 0
#endif
/*
- gcdENABLE_TS_DOUBLE_BUFFER
- enable the TS double buffer, this is for 2D openVG
-*/
+ gcdMULTI_GPU
-#ifndef gcdENABLE_TS_DOUBLE_BUFFER
-# define gcdENABLE_TS_DOUBLE_BUFFER 1
+ Enable/disable multi-GPU support.
+ 0 : Disable multi-GPU support
+ 1 : Enable one of the 3D cores
+ [2..X] : Number of 3D GPU Cores
+*/
+#ifndef gcdMULTI_GPU
+# define gcdMULTI_GPU 0
#endif
/*
- gcd6000_SUPPORT
+ gcdMULTI_GPU_AFFINITY
- Temporary define to enable/disable 6000 support.
- */
-#ifndef gcd6000_SUPPORT
-# define gcd6000_SUPPORT 0
+ Enable/disable the binding of a context to one GPU
+*/
+#ifndef gcdMULTI_GPU_AFFINITY
+# define gcdMULTI_GPU_AFFINITY 0
#endif
/*
idle state, and gcdPOWEROFF_TIMEOUT is also the default
timeout in milliseconds.
*/
-
#ifndef gcdPOWEROFF_TIMEOUT
# define gcdPOWEROFF_TIMEOUT 300
#endif
-/*
- gcdUSE_VIDMEM_PER_PID
-*/
-#ifndef gcdUSE_VIDMEM_PER_PID
-# define gcdUSE_VIDMEM_PER_PID 0
-#endif
-
/*
QNX_SINGLE_THREADED_DEBUGGING
*/
# define QNX_SINGLE_THREADED_DEBUGGING 0
#endif
-/*
- gcdENABLE_RECOVERY
-
- This define enables the recovery code.
-*/
-#ifndef gcdENABLE_RECOVERY
-# define gcdENABLE_RECOVERY 1
-#endif
-
/*
gcdRENDER_THREADS
*/
#ifndef gcdSMP
+#ifdef __APPLE__
+# define gcdSMP 1
+#else
# define gcdSMP 0
#endif
-
-/*
- gcdSUPPORT_SWAP_RECTANGLE
-
- Support swap with a specific rectangle.
-
- Set the rectangle with eglSetSwapRectangleANDROID api.
-*/
-#ifndef gcdSUPPORT_SWAP_RECTANGLE
-# define gcdSUPPORT_SWAP_RECTANGLE 0
-#endif
-
-/*
- gcdGPU_LINEAR_BUFFER_ENABLED
-
- Use linear buffer for GPU apps so HWC can do 2D composition.
-*/
-#ifndef gcdGPU_LINEAR_BUFFER_ENABLED
-# define gcdGPU_LINEAR_BUFFER_ENABLED 1
-#endif
-
-/*
- gcdENABLE_RENDER_INTO_WINDOW
-
- Enable Render-Into-Window (ie, No-Resolve) feature on android.
- NOTE that even if enabled, it still depends on hardware feature and
- android application behavior. When hardware feature or application
- behavior can not support render into window mode, it will fail back
- to normal mode.
- When Render-Into-Window is finally used, window back buffer of android
- applications will be allocated matching render target tiling format.
- Otherwise buffer tiling is decided by the above option
- 'gcdGPU_LINEAR_BUFFER_ENABLED'.
-*/
-#ifndef gcdENABLE_RENDER_INTO_WINDOW
-# define gcdENABLE_RENDER_INTO_WINDOW 1
#endif
/*
Use shared resolve buffer for all app buffers.
*/
#ifndef gcdSHARED_RESOLVE_BUFFER_ENABLED
-# define gcdSHARED_RESOLVE_BUFFER_ENABLED 0
+# define gcdSHARED_RESOLVE_BUFFER_ENABLED 0
#endif
/*
gcdUSE_TRIANGLE_STRIP_PATCH
*/
#ifndef gcdUSE_TRIANGLE_STRIP_PATCH
-# define gcdUSE_TRIANGLE_STRIP_PATCH 1
+# define gcdUSE_TRIANGLE_STRIP_PATCH 1
#endif
/*
# define gcdENABLE_OUTER_CACHE_PATCH 0
#endif
-#ifndef gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST
-# ifdef ANDROID
-# define gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST 1
-# else
-# define gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST 0
-# endif
-#endif
+/*
+ gcdPROCESS_ADDRESS_SPACE
-#ifndef gcdENABLE_PE_DITHER_FIX
-# define gcdENABLE_PE_DITHER_FIX 1
+ When non-zero, every process which attaches to galcore has its own GPU
+ address space, size of which is gcdPROCESS_ADDRESS_SPACE_SIZE.
+*/
+#ifndef gcdPROCESS_ADDRESS_SPACE
+# define gcdPROCESS_ADDRESS_SPACE 0
+# define gcdPROCESS_ADDRESS_SPACE_SIZE 0x80000000
#endif
+/*
+ gcdSHARED_PAGETABLE
+
+ When non-zero, multiple GPUs in one chip with same MMU use
+ one shared pagetable. So that when accessing same surface,
+ they can use same GPU virtual address.
+*/
#ifndef gcdSHARED_PAGETABLE
-# define gcdSHARED_PAGETABLE 1
+# define gcdSHARED_PAGETABLE !gcdPROCESS_ADDRESS_SPACE
#endif
+
#ifndef gcdUSE_PVR
-# define gcdUSE_PVR 1
+# define gcdUSE_PVR 1
#endif
/*
For Linux, it's the size of a page. If this requeset fallbacks
to gcvPOOL_CONTIGUOUS or gcvPOOL_VIRTUAL, memory will be wasted
because they allocate a page at least.
- */
+*/
#ifndef gcdSMALL_BLOCK_SIZE
# define gcdSMALL_BLOCK_SIZE 4096
# define gcdRATIO_FOR_SMALL_MEMORY 32
gcdCONTIGUOUS_SIZE_LIMIT
When non-zero, size of video node from gcvPOOL_CONTIGUOUS is
limited by gcdCONTIGUOUS_SIZE_LIMIT.
- */
+*/
#ifndef gcdCONTIGUOUS_SIZE_LIMIT
# define gcdCONTIGUOUS_SIZE_LIMIT 0
#endif
-#ifndef gcdDISALBE_EARLY_EARLY_Z
-# define gcdDISALBE_EARLY_EARLY_Z 1
-#endif
-
-#ifndef gcdSHADER_SRC_BY_MACHINECODE
-# define gcdSHADER_SRC_BY_MACHINECODE 1
-#endif
-
/*
gcdLINK_QUEUE_SIZE
is be used to debug.
*/
#ifndef gcdLINK_QUEUE_SIZE
-# define gcdLINK_QUEUE_SIZE 0
+# define gcdLINK_QUEUE_SIZE 5
#endif
/* gcdALPHA_KILL_IN_SHADER
- *
- * Enable alpha kill inside the shader. This will be set automatically by the
- * HAL if certain states match a criteria.
- */
+
+ Enable alpha kill inside the shader. This will be set automatically by the
+ HAL if certain states match a criteria.
+*/
#ifndef gcdALPHA_KILL_IN_SHADER
# define gcdALPHA_KILL_IN_SHADER 1
#endif
-/* gcdHIGH_PRECISION_DELAY_ENABLE
- *
- * Enable high precision schedule delay with 1ms unit. otherwise schedule delay up to 10ms.
- * Browser app performance will have obvious drop without this enablement
+
+
+/*
+ gcdDVFS
+
+ When non-zero, software will make use of dynamic voltage and
+ frequency feature.
*/
-#ifndef gcdHIGH_PRECISION_DELAY_ENABLE
-# define gcdHIGH_PRECISION_DELAY_ENABLE 1
+#ifndef gcdDVFS
+# define gcdDVFS 0
+# define gcdDVFS_ANAYLSE_WINDOW 4
+# define gcdDVFS_POLLING_TIME (gcdDVFS_ANAYLSE_WINDOW * 4)
#endif
-#ifndef gcdUSE_WCLIP_PATCH
-# define gcdUSE_WCLIP_PATCH 1
+#ifndef gcdSYNC
+# define gcdSYNC 1
#endif
-#ifndef gcdHZ_L2_DISALBE
-# define gcdHZ_L2_DISALBE 1
+#ifndef gcdSHADER_SRC_BY_MACHINECODE
+# define gcdSHADER_SRC_BY_MACHINECODE 1
#endif
-#ifndef gcdBUGFIX15_DISABLE
-# define gcdBUGFIX15_DISABLE 1
+#ifndef gcdGLB27_SHADER_REPLACE_OPTIMIZATION
+# define gcdGLB27_SHADER_REPLACE_OPTIMIZATION 1
#endif
-#ifndef gcdDISABLE_HZ_FAST_CLEAR
-# define gcdDISABLE_HZ_FAST_CLEAR 1
+/*
+ gcdSTREAM_OUT_BUFFER
+
+ Enable suppport for the secondary stream out buffer.
+*/
+#ifndef gcdSTREAM_OUT_BUFFER
+# define gcdSTREAM_OUT_BUFFER 0
+# define gcdSTREAM_OUT_NAIVE_SYNC 0
#endif
-#ifndef gcdUSE_NPOT_PATCH
-#define gcdUSE_NPOT_PATCH 1
+/*
+ gcdUSE_HARDWARE_CONFIGURATION_TABLES
+
+ Enable the use of hardware configuration tables,
+ instead of query hardware and determine the features.
+*/
+#ifndef gcdUSE_HARDWARE_CONFIGURATION_TABLES
+# define gcdUSE_HARDWARE_CONFIGURATION_TABLES 0
#endif
-#ifndef gcdSYNC
-# define gcdSYNC 1
+/*
+ gcdSUPPORT_SWAP_RECTANGLE
+
+ Support swap with a specific rectangle.
+
+ Set the rectangle with eglSetSwapRectangleVIV api.
+ Android only.
+*/
+#ifndef gcdSUPPORT_SWAP_RECTANGLE
+# define gcdSUPPORT_SWAP_RECTANGLE 1
#endif
-#ifndef gcdENABLE_SPECIAL_HINT3
-# define gcdENABLE_SPECIAL_HINT3 1
+/*
+ gcdGPU_LINEAR_BUFFER_ENABLED
+
+ Use linear buffer for GPU apps so HWC can do 2D composition.
+ Android only.
+*/
+#ifndef gcdGPU_LINEAR_BUFFER_ENABLED
+# define gcdGPU_LINEAR_BUFFER_ENABLED 1
#endif
-#if defined(ANDROID)
-#ifndef gcdPRE_ROTATION
-# define gcdPRE_ROTATION 1
+/*
+ gcdENABLE_RENDER_INTO_WINDOW
+
+ Enable Render-Into-Window (ie, No-Resolve) feature on android.
+ NOTE that even if enabled, it still depends on hardware feature and
+ android application behavior. When hardware feature or application
+ behavior can not support render into window mode, it will fail back
+ to normal mode.
+ When Render-Into-Window is finally used, window back buffer of android
+ applications will be allocated matching render target tiling format.
+ Otherwise buffer tiling is decided by the above option
+ 'gcdGPU_LINEAR_BUFFER_ENABLED'.
+ Android only for now.
+*/
+#ifndef gcdENABLE_RENDER_INTO_WINDOW
+# define gcdENABLE_RENDER_INTO_WINDOW 1
#endif
+
+/*
+ gcdENABLE_RENDER_INTO_WINDOW_WITH_FC
+
+ Enable Direct-rendering (ie, No-Resolve) with tile status.
+ This is expremental and in development stage.
+ This will dynamically check if color compression is available.
+*/
+#ifndef gcdENABLE_RENDER_INTO_WINDOW_WITH_FC
+# define gcdENABLE_RENDER_INTO_WINDOW_WITH_FC 1
#endif
/*
- gcdDVFS
+ gcdENABLE_BLIT_BUFFER_PRESERVE
- When non-zero, software will make use of dynamic voltage and
- frequency feature.
- */
-#ifndef gcdDVFS
-# define gcdDVFS 0
-# define gcdDVFS_ANAYLSE_WINDOW 4
-# define gcdDVFS_POLLING_TIME (gcdDVFS_ANAYLSE_WINDOW * 4)
+ Render-Into-Window (ie, No-Resolve) does not include preserved swap
+ behavior. This feature can enable buffer preserve in No-Resolve mode.
+ When enabled, previous buffer (may be part of ) will be resolve-blitted
+ to current buffer.
+*/
+#ifndef gcdENABLE_BLIT_BUFFER_PRESERVE
+# define gcdENABLE_BLIT_BUFFER_PRESERVE 1
#endif
/*
'acquireFenceFd' for framebuffer target for DC
*/
#ifndef gcdANDROID_NATIVE_FENCE_SYNC
-# define gcdANDROID_NATIVE_FENCE_SYNC 0
+# define gcdANDROID_NATIVE_FENCE_SYNC 0
+#endif
+
+/*
+ gcdANDROID_IMPLICIT_NATIVE_BUFFER_SYNC
+
+ Enable implicit android native buffer sync.
+
+ For non-HW_RENDER buffer, CPU (or other hardware) and GPU can access
+ the buffer at the same time. This is to add implicit synchronization
+ between CPU (or the hardware) and GPU.
+
+ Eventually, please do not use implicit native buffer sync, but use
+ "fence sync" or "android native fence sync" instead in libgui, which
+ can be enabled in frameworks/native/libs/gui/Android.mk. This kind
+ of synchronization should be done by app but not driver itself.
+
+ Please disable this option when either "fence sync" or
+ "android native fence sync" is enabled.
+ */
+#ifndef gcdANDROID_IMPLICIT_NATIVE_BUFFER_SYNC
+# define gcdANDROID_IMPLICIT_NATIVE_BUFFER_SYNC 1
+#endif
+
+/*
+ * Implicit native buffer sync is not needed when ANDROID_native_fence_sync
+ * is available.
+ */
+#if gcdANDROID_NATIVE_FENCE_SYNC
+# undef gcdANDROID_IMPLICIT_NATIVE_BUFFER_SYNC
+# define gcdANDROID_IMPLICIT_NATIVE_BUFFER_SYNC 0
+#endif
+
+/*
+ gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST
+
+ Enable source surface address adjust when composition on android.
+ Android only.
+*/
+#ifndef gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST
+# define gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST 1
+#endif
+
+/*
+ gcdUSE_WCLIP_PATCH
+
+ Enable wclipping patch.
+*/
+#ifndef gcdUSE_WCLIP_PATCH
+# define gcdUSE_WCLIP_PATCH 1
+#endif
+
+#ifndef gcdUSE_NPOT_PATCH
+# define gcdUSE_NPOT_PATCH 1
+#endif
+
+/*
+ gcd3DBLIT
+
+ TODO: Should be replaced by feature bit if available.
+*/
+#ifndef gcd3DBLIT
+# define gcd3DBLIT 0
+#endif
+
+/*
+ gcdINTERNAL_COMMENT
+
+ Wrap internal comment, content wrapped by it and the macor itself
+ will be removed in release driver.
+*/
+#ifndef gcdINTERNAL_COMMENT
+# define gcdINTERNAL_COMMENT 1
#endif
+/*
+ gcdRTT_DISABLE_FC
+
+ Disable RTT FC support. For test only.
+*/
+#ifndef gcdRTT_DISABLE_FC
+# define gcdRTT_DISABLE_FC 0
+#endif
+
+/*
+ gcdFORCE_MIPMAP
+
+ Force generate mipmap for texture.
+*/
#ifndef gcdFORCE_MIPMAP
-# define gcdFORCE_MIPMAP 0
+# define gcdFORCE_MIPMAP 0
+#endif
+
+/*
+ gcdFORCE_BILINEAR
+
+ Force bilinear for mipfilter.
+*/
+#ifndef gcdFORCE_BILINEAR
+# define gcdFORCE_BILINEAR 1
#endif
/*
- gcdFORCE_GAL_LOAD_TWICE
+ gcdBINARY_TRACE
+
+ When non-zero, binary trace will be generated.
+
+ When gcdBINARY_TRACE_FILE_SIZE is non-zero, binary trace buffer will
+ be written to a file which size is limited to
+ gcdBINARY_TRACE_FILE_SIZE.
+*/
+#ifndef gcdBINARY_TRACE
+# define gcdBINARY_TRACE 0
+# define gcdBINARY_TRACE_FILE_SIZE 0
+#endif
+
+#ifndef gcdMOVG
+# define gcdMOVG 0
+#if gcdMOVG
+# define GC355_PROFILER 1
+# endif
+# define gcdENABLE_TS_DOUBLE_BUFFER 1
+#else
+#if gcdMOVG
+# define GC355_PROFILER 1
+# define gcdENABLE_TS_DOUBLE_BUFFER 0
+#else
+# define gcdENABLE_TS_DOUBLE_BUFFER 1
+#endif
+#endif
- When non-zero, each thread except the main one will load libGAL.so twice to avoid potential segmetantion fault when app using dlopen/dlclose.
- If threads exit arbitrarily, libGAL.so may not unload until the process quit.
+/* gcdINTERRUPT_STATISTIC
+ *
+ * Monitor the event send to GPU and interrupt issued by GPU.
*/
-#ifndef gcdFORCE_GAL_LOAD_TWICE
-# define gcdFORCE_GAL_LOAD_TWICE 0
+
+#ifndef gcdINTERRUPT_STATISTIC
+#if defined(LINUX)
+# define gcdINTERRUPT_STATISTIC 1
+#else
+# define gcdINTERRUPT_STATISTIC 0
+#endif
+#endif
+
+/*
+ gcdYINVERTED_RENDERING
+ When it's not zero, we will rendering display buffer
+ with top-bottom direction. All other offscreen rendering
+ will be bottom-top, which follow OpenGL ES spec.
+*/
+#ifndef gcdYINVERTED_RENDERING
+# define gcdYINVERTED_RENDERING 1
+#endif
+
+#if gcdYINVERTED_RENDERING
+/* disable unaligned linear composition adjust in Y-inverted rendering mode. */
+# undef gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST
+# define gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST 0
+#endif
+
+/*
+ gcdFENCE_WAIT_LOOP_COUNT
+ Wait fence, loop count.
+*/
+#ifndef gcdFENCE_WAIT_LOOP_COUNT
+# define gcdFENCE_WAIT_LOOP_COUNT 100
+#endif
+
+/*
+ gcdHAL_3D_DRAWBLIT
+ When it's not zero, we will enable HAL 3D drawblit
+ to replace client 3dblit.
+*/
+#ifndef gcdHAL_3D_DRAWBLIT
+# define gcdHAL_3D_DRAWBLIT 1
+#endif
+
+/*
+ gcdPARTIAL_FAST_CLEAR
+ When it's not zero, partial fast clear is enabled.
+ Depends on gcdHAL_3D_DRAWBLIT, if gcdHAL_3D_DRAWBLIT is not enabled,
+ only available when scissor box is completely aligned.
+ Expremental, under test.
+*/
+#ifndef gcdPARTIAL_FAST_CLEAR
+# define gcdPARTIAL_FAST_CLEAR 1
+#endif
+
+/*
+ gcdREMOVE_SURF_ORIENTATION
+ When it's not zero, we will remove surface orientation function.
+ It wil become to a parameter of resolve function.
+*/
+#ifndef gcdREMOVE_SURF_ORIENTATION
+# define gcdREMOVE_SURF_ORIENTATION 0
+#endif
+
+/*
+ gcdPATTERN_FAST_PATH
+ For pattern match
+*/
+#ifndef gcdPATTERN_FAST_PATH
+# define gcdPATTERN_FAST_PATH 1
+#endif
+
+/*
+ gcdUSE_INPUT_DEVICE
+ disable input devices usage under fb mode to support fb+vdk multi-process
+*/
+#ifndef gcdUSE_INPUT_DEVICE
+# define gcdUSE_INPUT_DEVICE 1
+#endif
+
+
+/*
+ gcdFRAMEINFO_STATISTIC
+ When enable, collect frame information.
+*/
+#ifndef gcdFRAMEINFO_STATISTIC
+
+#if (defined(DBG) && DBG) || defined(DEBUG) || defined(_DEBUG) || gcdDUMP
+# define gcdFRAMEINFO_STATISTIC 1
+#else
+# define gcdFRAMEINFO_STATISTIC 0
+#endif
+
+#endif
+
+/*
+ gcdPACKED_OUTPUT_ADDRESS
+ When it's not zero, ps output is already packed after linked
+*/
+#ifndef gcdPACKED_OUTPUT_ADDRESS
+# define gcdPACKED_OUTPUT_ADDRESS 1
+#endif
+
+/*
+ gcdENABLE_THIRD_PARTY_OPERATION
+ Enable third party operation like tpc or not.
+*/
+#ifndef gcdENABLE_THIRD_PARTY_OPERATION
+# define gcdENABLE_THIRD_PARTY_OPERATION 1
+#endif
+
+
+/*
+ Core configurations. By default enable all cores.
+*/
+#ifndef gcdENABLE_3D
+# define gcdENABLE_3D 1
+#endif
+
+#ifndef gcdENABLE_2D
+# define gcdENABLE_2D 1
+#endif
+
+#ifndef gcdENABLE_VG
+# define gcdENABLE_VG 0
+#endif
+
+#ifndef gcdGC355_MEM_PRINT
+# define gcdGC355_MEM_PRINT 0
+#else
+#if (!((gcdENABLE_3D == 0) && (gcdENABLE_2D == 0) && (gcdENABLE_VG == 1)))
+# undef gcdGC355_MEM_PRINT
+# define gcdGC355_MEM_PRINT 0
+# endif
+#endif
+
+#ifndef gcdENABLE_UNIFIED_CONSTANT
+# define gcdENABLE_UNIFIED_CONSTANT 1
+#endif
+
+/*
+ gcdRECORD_COMMAND
+*/
+#ifndef gcdRECORD_COMMAND
+# define gcdRECORD_COMMAND 0
#endif
#endif /* __gc_hal_options_h_ */
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#ifndef __gc_hal_profiler_h_
#define __gc_hal_profiler_h_
+#if VIVANTE_PROFILER_NEW
+#include "gc_hal_engine.h"
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
#define GLTEXTURE_OBJECT 30
#define GLTEXTURE_OBJECT_BYTES 31
+#define GLBUFOBJ_OBJECT 40
+#define GLBUFOBJ_OBJECT_BYTES 41
+
#if VIVANTE_PROFILER
#define gcmPROFILE_GC(Enum, Value) gcoPROFILER_Count(gcvNULL, Enum, Value)
#else
#define ES11_LINECOUNT (ES11_POINTCOUNT + 1)
#define ES11_TRIANGLECOUNT (ES11_LINECOUNT + 1)
-#define ES20_CALLS 159
-#define ES20_DRAWCALLS (ES20_CALLS + 1)
-#define ES20_STATECHANGECALLS (ES20_DRAWCALLS + 1)
-#define ES20_POINTCOUNT (ES20_STATECHANGECALLS + 1)
-#define ES20_LINECOUNT (ES20_POINTCOUNT + 1)
-#define ES20_TRIANGLECOUNT (ES20_LINECOUNT + 1)
+#define ES30_CALLS 159
+#define ES30_DRAWCALLS (ES30_CALLS + 1)
+#define ES30_STATECHANGECALLS (ES30_DRAWCALLS + 1)
+#define ES30_POINTCOUNT (ES30_STATECHANGECALLS + 1)
+#define ES30_LINECOUNT (ES30_POINTCOUNT + 1)
+#define ES30_TRIANGLECOUNT (ES30_LINECOUNT + 1)
#define VG11_CALLS 88
#define VG11_DRAWCALLS (VG11_CALLS + 1)
#define VPG_TIME 0x030000
#define VPG_MEM 0x040000
#define VPG_ES11 0x050000
-#define VPG_ES20 0x060000
+#define VPG_ES30 0x060000
#define VPG_VG11 0x070000
#define VPG_HAL 0x080000
#define VPG_HW 0x090000
#define VPG_PVS 0x150000
#define VPG_PPS 0x160000
#define VPG_ES11_TIME 0x170000
-#define VPG_ES20_TIME 0x180000
+#define VPG_ES30_TIME 0x180000
#define VPG_FRAME 0x190000
#define VPG_ES11_DRAW 0x200000
-#define VPG_ES20_DRAW 0x210000
+#define VPG_ES30_DRAW 0x210000
+#define VPG_VG11_TIME 0x220000
#define VPG_END 0xff0000
/* Info. */
#define VPC_ES11LINECOUNT (VPG_ES11 + ES11_LINECOUNT)
#define VPC_ES11TRIANGLECOUNT (VPG_ES11 + ES11_TRIANGLECOUNT)
-/* OpenGL ES20 Statistics Counter IDs. */
-#define VPC_ES20CALLS (VPG_ES20 + ES20_CALLS)
-#define VPC_ES20DRAWCALLS (VPG_ES20 + ES20_DRAWCALLS)
-#define VPC_ES20STATECHANGECALLS (VPG_ES20 + ES20_STATECHANGECALLS)
-#define VPC_ES20POINTCOUNT (VPG_ES20 + ES20_POINTCOUNT)
-#define VPC_ES20LINECOUNT (VPG_ES20 + ES20_LINECOUNT)
-#define VPC_ES20TRIANGLECOUNT (VPG_ES20 + ES20_TRIANGLECOUNT)
+/* OpenGL ES30 Statistics Counter IDs. */
+#define VPC_ES30CALLS (VPG_ES30 + ES30_CALLS)
+#define VPC_ES30DRAWCALLS (VPG_ES30 + ES30_DRAWCALLS)
+#define VPC_ES30STATECHANGECALLS (VPG_ES30 + ES30_STATECHANGECALLS)
+#define VPC_ES30POINTCOUNT (VPG_ES30 + ES30_POINTCOUNT)
+#define VPC_ES30LINECOUNT (VPG_ES30 + ES30_LINECOUNT)
+#define VPC_ES30TRIANGLECOUNT (VPG_ES30 + ES30_TRIANGLECOUNT)
/* OpenVG Statistics Counter IDs. */
#define VPC_VG11CALLS (VPG_VG11 + VG11_CALLS)
#define VPC_PROGRAMHANDLE (VPG_PROG + 1)
-#define VPG_ES20_DRAW_NO (VPG_ES20_DRAW + 1)
-#define VPG_ES11_DRAW_NO (VPG_ES11_DRAW + 1)
-
-#define VPG_FRAME_USEVBO (VPG_FRAME + 1)
-
+#define VPC_ES30_DRAW_NO (VPG_ES30_DRAW + 1)
+#define VPC_ES11_DRAW_NO (VPG_ES11_DRAW + 1)
#endif
}
gcsPROFILER_COUNTERS;
+#if VIVANTE_PROFILER_NEW
+#define NumOfDrawBuf 64
+#endif
+
/* HAL profile information. */
typedef struct _gcsPROFILER
{
gctBOOL enableHW;
gctBOOL enableSH;
gctBOOL isSyncMode;
+ gctBOOL disableOutputCounter;
gctBOOL useSocket;
gctINT sockFd;
gctUINT32 prevPSTexInstCount;
gctUINT32 prevPSPixelCount;
- char* psSource;
- char* vsSource;
+#if VIVANTE_PROFILER_NEW
+ gcoBUFOBJ newCounterBuf[NumOfDrawBuf];
+ gctUINT32 curBufId;
+#endif
}
gcsPROFILER;
/* Initialize the gcsProfiler. */
gceSTATUS
gcoPROFILER_Initialize(
- IN gcoHAL Hal
+ IN gcoHAL Hal,
+ IN gctBOOL Enable
);
/* Destroy the gcProfiler. */
/* Increase profile counter Enum by Value. */
gceSTATUS
gcoPROFILER_Count(
- IN gcoHAL Hal,
- IN gctUINT32 Enum,
- IN gctINT Value
- );
-
-gceSTATUS
-gcoPROFILER_ShaderSourceFS(
- IN gcoHAL Hal,
- IN char* source
- );
-
-gceSTATUS
-gcoPROFILER_ShaderSourceVS(
IN gcoHAL Hal,
- IN char* source
+ IN gctUINT32 Enum,
+ IN gctINT Value
);
/* Profile input vertex shader. */
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
****************************** Object Declarations *****************************
\******************************************************************************/
-typedef struct _gcoBRUSH * gcoBRUSH;
-typedef struct _gcoBRUSH_CACHE * gcoBRUSH_CACHE;
+typedef struct _gcoBRUSH * gcoBRUSH;
+typedef struct _gcoBRUSH_CACHE * gcoBRUSH_CACHE;
/******************************************************************************\
******************************** gcoBRUSH Object *******************************
/* Create a new solid color gcoBRUSH object. */
gceSTATUS
gcoBRUSH_ConstructSingleColor(
- IN gcoHAL Hal,
- IN gctUINT32 ColorConvert,
- IN gctUINT32 Color,
- IN gctUINT64 Mask,
- gcoBRUSH * Brush
- );
+ IN gcoHAL Hal,
+ IN gctUINT32 ColorConvert,
+ IN gctUINT32 Color,
+ IN gctUINT64 Mask,
+ gcoBRUSH * Brush
+ );
/* Create a new monochrome gcoBRUSH object. */
gceSTATUS
gcoBRUSH_ConstructMonochrome(
- IN gcoHAL Hal,
- IN gctUINT32 OriginX,
- IN gctUINT32 OriginY,
- IN gctUINT32 ColorConvert,
- IN gctUINT32 FgColor,
- IN gctUINT32 BgColor,
- IN gctUINT64 Bits,
- IN gctUINT64 Mask,
- gcoBRUSH * Brush
- );
+ IN gcoHAL Hal,
+ IN gctUINT32 OriginX,
+ IN gctUINT32 OriginY,
+ IN gctUINT32 ColorConvert,
+ IN gctUINT32 FgColor,
+ IN gctUINT32 BgColor,
+ IN gctUINT64 Bits,
+ IN gctUINT64 Mask,
+ gcoBRUSH * Brush
+ );
/* Create a color gcoBRUSH object. */
gceSTATUS
gcoBRUSH_ConstructColor(
- IN gcoHAL Hal,
- IN gctUINT32 OriginX,
- IN gctUINT32 OriginY,
- IN gctPOINTER Address,
- IN gceSURF_FORMAT Format,
- IN gctUINT64 Mask,
- gcoBRUSH * Brush
- );
+ IN gcoHAL Hal,
+ IN gctUINT32 OriginX,
+ IN gctUINT32 OriginY,
+ IN gctPOINTER Address,
+ IN gceSURF_FORMAT Format,
+ IN gctUINT64 Mask,
+ gcoBRUSH * Brush
+ );
/* Destroy an gcoBRUSH object. */
gceSTATUS
gcoBRUSH_Destroy(
- IN gcoBRUSH Brush
- );
+ IN gcoBRUSH Brush
+ );
/******************************************************************************\
******************************** gcoSURF Object *******************************
/* Set cipping rectangle. */
gceSTATUS
gcoSURF_SetClipping(
- IN gcoSURF Surface
- );
+ IN gcoSURF Surface
+ );
/* Clear one or more rectangular areas. */
gceSTATUS
gcoSURF_Clear2D(
- IN gcoSURF DestSurface,
- IN gctUINT32 RectCount,
- IN gcsRECT_PTR DestRect,
- IN gctUINT32 LoColor,
- IN gctUINT32 HiColor
- );
+ IN gcoSURF DestSurface,
+ IN gctUINT32 RectCount,
+ IN gcsRECT_PTR DestRect,
+ IN gctUINT32 LoColor,
+ IN gctUINT32 HiColor
+ );
/* Draw one or more Bresenham lines. */
gceSTATUS
gcoSURF_Line(
- IN gcoSURF Surface,
- IN gctUINT32 LineCount,
- IN gcsRECT_PTR Position,
- IN gcoBRUSH Brush,
- IN gctUINT8 FgRop,
- IN gctUINT8 BgRop
- );
+ IN gcoSURF Surface,
+ IN gctUINT32 LineCount,
+ IN gcsRECT_PTR Position,
+ IN gcoBRUSH Brush,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop
+ );
/* Generic rectangular blit. */
gceSTATUS
gcoSURF_Blit(
- IN OPTIONAL gcoSURF SrcSurface,
- IN gcoSURF DestSurface,
- IN gctUINT32 RectCount,
- IN OPTIONAL gcsRECT_PTR SrcRect,
- IN gcsRECT_PTR DestRect,
- IN OPTIONAL gcoBRUSH Brush,
- IN gctUINT8 FgRop,
- IN gctUINT8 BgRop,
- IN OPTIONAL gceSURF_TRANSPARENCY Transparency,
- IN OPTIONAL gctUINT32 TransparencyColor,
- IN OPTIONAL gctPOINTER Mask,
- IN OPTIONAL gceSURF_MONOPACK MaskPack
- );
+ IN OPTIONAL gcoSURF SrcSurface,
+ IN gcoSURF DestSurface,
+ IN gctUINT32 RectCount,
+ IN OPTIONAL gcsRECT_PTR SrcRect,
+ IN gcsRECT_PTR DestRect,
+ IN OPTIONAL gcoBRUSH Brush,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop,
+ IN OPTIONAL gceSURF_TRANSPARENCY Transparency,
+ IN OPTIONAL gctUINT32 TransparencyColor,
+ IN OPTIONAL gctPOINTER Mask,
+ IN OPTIONAL gceSURF_MONOPACK MaskPack
+ );
/* Monochrome blit. */
gceSTATUS
gcoSURF_MonoBlit(
- IN gcoSURF DestSurface,
- IN gctPOINTER Source,
- IN gceSURF_MONOPACK SourcePack,
- IN gcsPOINT_PTR SourceSize,
- IN gcsPOINT_PTR SourceOrigin,
- IN gcsRECT_PTR DestRect,
- IN OPTIONAL gcoBRUSH Brush,
- IN gctUINT8 FgRop,
- IN gctUINT8 BgRop,
- IN gctBOOL ColorConvert,
- IN gctUINT8 MonoTransparency,
- IN gceSURF_TRANSPARENCY Transparency,
- IN gctUINT32 FgColor,
- IN gctUINT32 BgColor
- );
+ IN gcoSURF DestSurface,
+ IN gctPOINTER Source,
+ IN gceSURF_MONOPACK SourcePack,
+ IN gcsPOINT_PTR SourceSize,
+ IN gcsPOINT_PTR SourceOrigin,
+ IN gcsRECT_PTR DestRect,
+ IN OPTIONAL gcoBRUSH Brush,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop,
+ IN gctBOOL ColorConvert,
+ IN gctUINT8 MonoTransparency,
+ IN gceSURF_TRANSPARENCY Transparency,
+ IN gctUINT32 FgColor,
+ IN gctUINT32 BgColor
+ );
/* Filter blit. */
gceSTATUS
gcoSURF_FilterBlit(
- IN gcoSURF SrcSurface,
- IN gcoSURF DestSurface,
- IN gcsRECT_PTR SrcRect,
- IN gcsRECT_PTR DestRect,
- IN gcsRECT_PTR DestSubRect
- );
+ IN gcoSURF SrcSurface,
+ IN gcoSURF DestSurface,
+ IN gcsRECT_PTR SrcRect,
+ IN gcsRECT_PTR DestRect,
+ IN gcsRECT_PTR DestSubRect
+ );
/* Enable alpha blending engine in the hardware and disengage the ROP engine. */
gceSTATUS
gcoSURF_EnableAlphaBlend(
- IN gcoSURF Surface,
- IN gctUINT8 SrcGlobalAlphaValue,
- IN gctUINT8 DstGlobalAlphaValue,
- IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode,
- IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode,
- IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode,
- IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode,
- IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode,
- IN gceSURF_BLEND_FACTOR_MODE DstFactorMode,
- IN gceSURF_PIXEL_COLOR_MODE SrcColorMode,
- IN gceSURF_PIXEL_COLOR_MODE DstColorMode
- );
+ IN gcoSURF Surface,
+ IN gctUINT8 SrcGlobalAlphaValue,
+ IN gctUINT8 DstGlobalAlphaValue,
+ IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode,
+ IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode,
+ IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode,
+ IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode,
+ IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode,
+ IN gceSURF_BLEND_FACTOR_MODE DstFactorMode,
+ IN gceSURF_PIXEL_COLOR_MODE SrcColorMode,
+ IN gceSURF_PIXEL_COLOR_MODE DstColorMode
+ );
/* Disable alpha blending engine in the hardware and engage the ROP engine. */
gceSTATUS
gcoSURF_DisableAlphaBlend(
- IN gcoSURF Surface
- );
+ IN gcoSURF Surface
+ );
/* Copy a rectangular area with format conversion. */
gceSTATUS
gcoSURF_CopyPixels(
- IN gcoSURF Source,
- IN gcoSURF Target,
- IN gctINT SourceX,
- IN gctINT SourceY,
- IN gctINT TargetX,
- IN gctINT TargetY,
- IN gctINT Width,
- IN gctINT Height
- );
+ IN gcoSURF Source,
+ IN gcoSURF Target,
+ IN gctINT SourceX,
+ IN gctINT SourceY,
+ IN gctINT TargetX,
+ IN gctINT TargetY,
+ IN gctINT Width,
+ IN gctINT Height
+ );
/* Read surface pixel. */
gceSTATUS
gcoSURF_ReadPixel(
- IN gcoSURF Surface,
- IN gctPOINTER Memory,
- IN gctINT X,
- IN gctINT Y,
- IN gceSURF_FORMAT Format,
- OUT gctPOINTER PixelValue
- );
+ IN gcoSURF Surface,
+ IN gctPOINTER Memory,
+ IN gctINT X,
+ IN gctINT Y,
+ IN gceSURF_FORMAT Format,
+ OUT gctPOINTER PixelValue
+ );
/* Write surface pixel. */
gceSTATUS
gcoSURF_WritePixel(
- IN gcoSURF Surface,
- IN gctPOINTER Memory,
- IN gctINT X,
- IN gctINT Y,
- IN gceSURF_FORMAT Format,
- IN gctPOINTER PixelValue
- );
+ IN gcoSURF Surface,
+ IN gctPOINTER Memory,
+ IN gctINT X,
+ IN gctINT Y,
+ IN gceSURF_FORMAT Format,
+ IN gctPOINTER PixelValue
+ );
gceSTATUS
gcoSURF_SetDither(
IN gcoSURF Surface,
IN gctBOOL Dither
);
+
+gceSTATUS
+gcoSURF_Set2DSource(
+ gcoSURF Surface,
+ gceSURF_ROTATION Rotation
+ );
+
+gceSTATUS
+gcoSURF_Set2DTarget(
+ gcoSURF Surface,
+ gceSURF_ROTATION Rotation
+ );
+
/******************************************************************************\
********************************** gco2D Object *********************************
\******************************************************************************/
/* Construct a new gco2D object. */
gceSTATUS
gco2D_Construct(
- IN gcoHAL Hal,
- OUT gco2D * Hardware
- );
+ IN gcoHAL Hal,
+ OUT gco2D * Hardware
+ );
/* Destroy an gco2D object. */
gceSTATUS
gco2D_Destroy(
- IN gco2D Hardware
- );
+ IN gco2D Hardware
+ );
/* Sets the maximum number of brushes in the brush cache. */
gceSTATUS
gco2D_SetBrushLimit(
- IN gco2D Hardware,
- IN gctUINT MaxCount
- );
+ IN gco2D Hardware,
+ IN gctUINT MaxCount
+ );
/* Flush the brush. */
gceSTATUS
gco2D_FlushBrush(
- IN gco2D Engine,
- IN gcoBRUSH Brush,
- IN gceSURF_FORMAT Format
- );
+ IN gco2D Engine,
+ IN gcoBRUSH Brush,
+ IN gceSURF_FORMAT Format
+ );
/* Program the specified solid color brush. */
gceSTATUS
gco2D_LoadSolidBrush(
- IN gco2D Engine,
- IN gceSURF_FORMAT Format,
- IN gctUINT32 ColorConvert,
- IN gctUINT32 Color,
- IN gctUINT64 Mask
- );
+ IN gco2D Engine,
+ IN gceSURF_FORMAT Format,
+ IN gctUINT32 ColorConvert,
+ IN gctUINT32 Color,
+ IN gctUINT64 Mask
+ );
gceSTATUS
gco2D_LoadMonochromeBrush(
/* Configure monochrome source. */
gceSTATUS
gco2D_SetMonochromeSource(
- IN gco2D Engine,
- IN gctBOOL ColorConvert,
- IN gctUINT8 MonoTransparency,
- IN gceSURF_MONOPACK DataPack,
- IN gctBOOL CoordRelative,
- IN gceSURF_TRANSPARENCY Transparency,
- IN gctUINT32 FgColor,
- IN gctUINT32 BgColor
- );
+ IN gco2D Engine,
+ IN gctBOOL ColorConvert,
+ IN gctUINT8 MonoTransparency,
+ IN gceSURF_MONOPACK DataPack,
+ IN gctBOOL CoordRelative,
+ IN gceSURF_TRANSPARENCY Transparency,
+ IN gctUINT32 FgColor,
+ IN gctUINT32 BgColor
+ );
/* Configure color source. */
gceSTATUS
gco2D_SetColorSource(
- IN gco2D Engine,
- IN gctUINT32 Address,
- IN gctUINT32 Stride,
- IN gceSURF_FORMAT Format,
- IN gceSURF_ROTATION Rotation,
- IN gctUINT32 SurfaceWidth,
- IN gctBOOL CoordRelative,
- IN gceSURF_TRANSPARENCY Transparency,
- IN gctUINT32 TransparencyColor
- );
+ IN gco2D Engine,
+ IN gctUINT32 Address,
+ IN gctUINT32 Stride,
+ IN gceSURF_FORMAT Format,
+ IN gceSURF_ROTATION Rotation,
+ IN gctUINT32 SurfaceWidth,
+ IN gctBOOL CoordRelative,
+ IN gceSURF_TRANSPARENCY Transparency,
+ IN gctUINT32 TransparencyColor
+ );
/* Configure color source extension for full rotation. */
gceSTATUS
gco2D_SetColorSourceEx(
- IN gco2D Engine,
- IN gctUINT32 Address,
- IN gctUINT32 Stride,
- IN gceSURF_FORMAT Format,
- IN gceSURF_ROTATION Rotation,
- IN gctUINT32 SurfaceWidth,
- IN gctUINT32 SurfaceHeight,
- IN gctBOOL CoordRelative,
- IN gceSURF_TRANSPARENCY Transparency,
- IN gctUINT32 TransparencyColor
- );
+ IN gco2D Engine,
+ IN gctUINT32 Address,
+ IN gctUINT32 Stride,
+ IN gceSURF_FORMAT Format,
+ IN gceSURF_ROTATION Rotation,
+ IN gctUINT32 SurfaceWidth,
+ IN gctUINT32 SurfaceHeight,
+ IN gctBOOL CoordRelative,
+ IN gceSURF_TRANSPARENCY Transparency,
+ IN gctUINT32 TransparencyColor
+ );
/* Configure color source. */
gceSTATUS
gco2D_SetColorSourceAdvanced(
- IN gco2D Engine,
- IN gctUINT32 Address,
- IN gctUINT32 Stride,
- IN gceSURF_FORMAT Format,
- IN gceSURF_ROTATION Rotation,
- IN gctUINT32 SurfaceWidth,
- IN gctUINT32 SurfaceHeight,
- IN gctBOOL CoordRelative
- );
+ IN gco2D Engine,
+ IN gctUINT32 Address,
+ IN gctUINT32 Stride,
+ IN gceSURF_FORMAT Format,
+ IN gceSURF_ROTATION Rotation,
+ IN gctUINT32 SurfaceWidth,
+ IN gctUINT32 SurfaceHeight,
+ IN gctBOOL CoordRelative
+ );
gceSTATUS
gco2D_SetColorSourceN(
/* Configure masked color source. */
gceSTATUS
gco2D_SetMaskedSource(
- IN gco2D Engine,
- IN gctUINT32 Address,
- IN gctUINT32 Stride,
- IN gceSURF_FORMAT Format,
- IN gctBOOL CoordRelative,
- IN gceSURF_MONOPACK MaskPack
- );
+ IN gco2D Engine,
+ IN gctUINT32 Address,
+ IN gctUINT32 Stride,
+ IN gceSURF_FORMAT Format,
+ IN gctBOOL CoordRelative,
+ IN gceSURF_MONOPACK MaskPack
+ );
/* Configure masked color source extension for full rotation. */
gceSTATUS
gco2D_SetMaskedSourceEx(
- IN gco2D Engine,
- IN gctUINT32 Address,
- IN gctUINT32 Stride,
- IN gceSURF_FORMAT Format,
- IN gctBOOL CoordRelative,
- IN gceSURF_MONOPACK MaskPack,
- IN gceSURF_ROTATION Rotation,
- IN gctUINT32 SurfaceWidth,
- IN gctUINT32 SurfaceHeight
- );
+ IN gco2D Engine,
+ IN gctUINT32 Address,
+ IN gctUINT32 Stride,
+ IN gceSURF_FORMAT Format,
+ IN gctBOOL CoordRelative,
+ IN gceSURF_MONOPACK MaskPack,
+ IN gceSURF_ROTATION Rotation,
+ IN gctUINT32 SurfaceWidth,
+ IN gctUINT32 SurfaceHeight
+ );
/* Setup the source rectangle. */
gceSTATUS
gco2D_SetSource(
- IN gco2D Engine,
- IN gcsRECT_PTR SrcRect
- );
+ IN gco2D Engine,
+ IN gcsRECT_PTR SrcRect
+ );
/* Set clipping rectangle. */
gceSTATUS
gco2D_SetClipping(
- IN gco2D Engine,
- IN gcsRECT_PTR Rect
- );
+ IN gco2D Engine,
+ IN gcsRECT_PTR Rect
+ );
/* Configure destination. */
gceSTATUS
gco2D_SetTarget(
- IN gco2D Engine,
- IN gctUINT32 Address,
- IN gctUINT32 Stride,
- IN gceSURF_ROTATION Rotation,
- IN gctUINT32 SurfaceWidth
- );
+ IN gco2D Engine,
+ IN gctUINT32 Address,
+ IN gctUINT32 Stride,
+ IN gceSURF_ROTATION Rotation,
+ IN gctUINT32 SurfaceWidth
+ );
/* Configure destination extension for full rotation. */
gceSTATUS
gco2D_SetTargetEx(
- IN gco2D Engine,
- IN gctUINT32 Address,
- IN gctUINT32 Stride,
- IN gceSURF_ROTATION Rotation,
- IN gctUINT32 SurfaceWidth,
- IN gctUINT32 SurfaceHeight
- );
+ IN gco2D Engine,
+ IN gctUINT32 Address,
+ IN gctUINT32 Stride,
+ IN gceSURF_ROTATION Rotation,
+ IN gctUINT32 SurfaceWidth,
+ IN gctUINT32 SurfaceHeight
+ );
/* Calculate and program the stretch factors. */
gceSTATUS
gceSTATUS
gco2D_SetStretchFactors(
- IN gco2D Engine,
- IN gctUINT32 HorFactor,
- IN gctUINT32 VerFactor
- );
+ IN gco2D Engine,
+ IN gctUINT32 HorFactor,
+ IN gctUINT32 VerFactor
+ );
/* Calculate and program the stretch factors based on the rectangles. */
gceSTATUS
gco2D_SetStretchRectFactors(
- IN gco2D Engine,
- IN gcsRECT_PTR SrcRect,
- IN gcsRECT_PTR DestRect
- );
+ IN gco2D Engine,
+ IN gcsRECT_PTR SrcRect,
+ IN gcsRECT_PTR DestRect
+ );
/* Create a new solid color gcoBRUSH object. */
gceSTATUS
gco2D_ConstructSingleColorBrush(
- IN gco2D Engine,
- IN gctUINT32 ColorConvert,
- IN gctUINT32 Color,
- IN gctUINT64 Mask,
- gcoBRUSH * Brush
- );
+ IN gco2D Engine,
+ IN gctUINT32 ColorConvert,
+ IN gctUINT32 Color,
+ IN gctUINT64 Mask,
+ gcoBRUSH * Brush
+ );
/* Create a new monochrome gcoBRUSH object. */
gceSTATUS
gco2D_ConstructMonochromeBrush(
- IN gco2D Engine,
- IN gctUINT32 OriginX,
- IN gctUINT32 OriginY,
- IN gctUINT32 ColorConvert,
- IN gctUINT32 FgColor,
- IN gctUINT32 BgColor,
- IN gctUINT64 Bits,
- IN gctUINT64 Mask,
- gcoBRUSH * Brush
- );
+ IN gco2D Engine,
+ IN gctUINT32 OriginX,
+ IN gctUINT32 OriginY,
+ IN gctUINT32 ColorConvert,
+ IN gctUINT32 FgColor,
+ IN gctUINT32 BgColor,
+ IN gctUINT64 Bits,
+ IN gctUINT64 Mask,
+ gcoBRUSH * Brush
+ );
/* Create a color gcoBRUSH object. */
gceSTATUS
gco2D_ConstructColorBrush(
- IN gco2D Engine,
- IN gctUINT32 OriginX,
- IN gctUINT32 OriginY,
- IN gctPOINTER Address,
- IN gceSURF_FORMAT Format,
- IN gctUINT64 Mask,
- gcoBRUSH * Brush
- );
+ IN gco2D Engine,
+ IN gctUINT32 OriginX,
+ IN gctUINT32 OriginY,
+ IN gctPOINTER Address,
+ IN gceSURF_FORMAT Format,
+ IN gctUINT64 Mask,
+ gcoBRUSH * Brush
+ );
/* Clear one or more rectangular areas. */
gceSTATUS
gco2D_Clear(
- IN gco2D Engine,
- IN gctUINT32 RectCount,
- IN gcsRECT_PTR Rect,
- IN gctUINT32 Color32,
- IN gctUINT8 FgRop,
- IN gctUINT8 BgRop,
- IN gceSURF_FORMAT DestFormat
- );
+ IN gco2D Engine,
+ IN gctUINT32 RectCount,
+ IN gcsRECT_PTR Rect,
+ IN gctUINT32 Color32,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop,
+ IN gceSURF_FORMAT DestFormat
+ );
/* Draw one or more Bresenham lines. */
gceSTATUS
gco2D_Line(
- IN gco2D Engine,
- IN gctUINT32 LineCount,
- IN gcsRECT_PTR Position,
- IN gcoBRUSH Brush,
- IN gctUINT8 FgRop,
- IN gctUINT8 BgRop,
- IN gceSURF_FORMAT DestFormat
- );
+ IN gco2D Engine,
+ IN gctUINT32 LineCount,
+ IN gcsRECT_PTR Position,
+ IN gcoBRUSH Brush,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop,
+ IN gceSURF_FORMAT DestFormat
+ );
/* Draw one or more Bresenham lines based on the 32-bit color. */
gceSTATUS
gco2D_ColorLine(
- IN gco2D Engine,
- IN gctUINT32 LineCount,
- IN gcsRECT_PTR Position,
- IN gctUINT32 Color32,
- IN gctUINT8 FgRop,
- IN gctUINT8 BgRop,
- IN gceSURF_FORMAT DestFormat
- );
+ IN gco2D Engine,
+ IN gctUINT32 LineCount,
+ IN gcsRECT_PTR Position,
+ IN gctUINT32 Color32,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop,
+ IN gceSURF_FORMAT DestFormat
+ );
/* Generic blit. */
gceSTATUS
gco2D_Blit(
- IN gco2D Engine,
- IN gctUINT32 RectCount,
- IN gcsRECT_PTR Rect,
- IN gctUINT8 FgRop,
- IN gctUINT8 BgRop,
- IN gceSURF_FORMAT DestFormat
- );
+ IN gco2D Engine,
+ IN gctUINT32 RectCount,
+ IN gcsRECT_PTR Rect,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop,
+ IN gceSURF_FORMAT DestFormat
+ );
gceSTATUS
gco2D_Blend(
/* Batch blit. */
gceSTATUS
gco2D_BatchBlit(
- IN gco2D Engine,
- IN gctUINT32 RectCount,
- IN gcsRECT_PTR SrcRect,
- IN gcsRECT_PTR DestRect,
- IN gctUINT8 FgRop,
- IN gctUINT8 BgRop,
- IN gceSURF_FORMAT DestFormat
- );
+ IN gco2D Engine,
+ IN gctUINT32 RectCount,
+ IN gcsRECT_PTR SrcRect,
+ IN gcsRECT_PTR DestRect,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop,
+ IN gceSURF_FORMAT DestFormat
+ );
/* Stretch blit. */
gceSTATUS
gco2D_StretchBlit(
- IN gco2D Engine,
- IN gctUINT32 RectCount,
- IN gcsRECT_PTR Rect,
- IN gctUINT8 FgRop,
- IN gctUINT8 BgRop,
- IN gceSURF_FORMAT DestFormat
- );
+ IN gco2D Engine,
+ IN gctUINT32 RectCount,
+ IN gcsRECT_PTR Rect,
+ IN gctUINT8 FgRop,
+ IN gctUINT8 BgRop,
+ IN gceSURF_FORMAT DestFormat
+ );
/* Monochrome blit. */
gceSTATUS
gco2D_MonoBlit(
- IN gco2D Engine,
- IN gctPOINTER StreamBits,
- IN gcsPOINT_PTR StreamSize,
- IN gcsRECT_PTR StreamRect,
- IN gceSURF_MONOPACK SrcStreamPack,
- IN gceSURF_MONOPACK DestStreamPack,
- IN gcsRECT_PTR DestRect,
- IN gctUINT32 FgRop,
- IN gctUINT32 BgRop,
- IN gceSURF_FORMAT DestFormat
- );
+ IN gco2D Engine,
+ IN gctPOINTER StreamBits,
+ IN gcsPOINT_PTR StreamSize,
+ IN gcsRECT_PTR StreamRect,
+ IN gceSURF_MONOPACK SrcStreamPack,
+ IN gceSURF_MONOPACK DestStreamPack,
+ IN gcsRECT_PTR DestRect,
+ IN gctUINT32 FgRop,
+ IN gctUINT32 BgRop,
+ IN gceSURF_FORMAT DestFormat
+ );
gceSTATUS
gco2D_MonoBlitEx(
/* Set kernel size. */
gceSTATUS
gco2D_SetKernelSize(
- IN gco2D Engine,
- IN gctUINT8 HorKernelSize,
- IN gctUINT8 VerKernelSize
- );
+ IN gco2D Engine,
+ IN gctUINT8 HorKernelSize,
+ IN gctUINT8 VerKernelSize
+ );
/* Set filter type. */
gceSTATUS
gco2D_SetFilterType(
- IN gco2D Engine,
- IN gceFILTER_TYPE FilterType
- );
+ IN gco2D Engine,
+ IN gceFILTER_TYPE FilterType
+ );
/* Set the filter kernel by user. */
gceSTATUS
gco2D_SetUserFilterKernel(
- IN gco2D Engine,
- IN gceFILTER_PASS_TYPE PassType,
- IN gctUINT16_PTR KernelArray
- );
+ IN gco2D Engine,
+ IN gceFILTER_PASS_TYPE PassType,
+ IN gctUINT16_PTR KernelArray
+ );
/* Select the pass(es) to be done for user defined filter. */
gceSTATUS
gco2D_EnableUserFilterPasses(
- IN gco2D Engine,
- IN gctBOOL HorPass,
- IN gctBOOL VerPass
- );
+ IN gco2D Engine,
+ IN gctBOOL HorPass,
+ IN gctBOOL VerPass
+ );
/* Frees the temporary buffer allocated by filter blit operation. */
gceSTATUS
gco2D_FreeFilterBuffer(
- IN gco2D Engine
- );
+ IN gco2D Engine
+ );
/* Filter blit. */
gceSTATUS
gco2D_FilterBlit(
- IN gco2D Engine,
- IN gctUINT32 SrcAddress,
- IN gctUINT SrcStride,
- IN gctUINT32 SrcUAddress,
- IN gctUINT SrcUStride,
- IN gctUINT32 SrcVAddress,
- IN gctUINT SrcVStride,
- IN gceSURF_FORMAT SrcFormat,
- IN gceSURF_ROTATION SrcRotation,
- IN gctUINT32 SrcSurfaceWidth,
- IN gcsRECT_PTR SrcRect,
- IN gctUINT32 DestAddress,
- IN gctUINT DestStride,
- IN gceSURF_FORMAT DestFormat,
- IN gceSURF_ROTATION DestRotation,
- IN gctUINT32 DestSurfaceWidth,
- IN gcsRECT_PTR DestRect,
- IN gcsRECT_PTR DestSubRect
- );
+ IN gco2D Engine,
+ IN gctUINT32 SrcAddress,
+ IN gctUINT SrcStride,
+ IN gctUINT32 SrcUAddress,
+ IN gctUINT SrcUStride,
+ IN gctUINT32 SrcVAddress,
+ IN gctUINT SrcVStride,
+ IN gceSURF_FORMAT SrcFormat,
+ IN gceSURF_ROTATION SrcRotation,
+ IN gctUINT32 SrcSurfaceWidth,
+ IN gcsRECT_PTR SrcRect,
+ IN gctUINT32 DestAddress,
+ IN gctUINT DestStride,
+ IN gceSURF_FORMAT DestFormat,
+ IN gceSURF_ROTATION DestRotation,
+ IN gctUINT32 DestSurfaceWidth,
+ IN gcsRECT_PTR DestRect,
+ IN gcsRECT_PTR DestSubRect
+ );
/* Filter blit extension for full rotation. */
gceSTATUS
gco2D_FilterBlitEx(
- IN gco2D Engine,
- IN gctUINT32 SrcAddress,
- IN gctUINT SrcStride,
- IN gctUINT32 SrcUAddress,
- IN gctUINT SrcUStride,
- IN gctUINT32 SrcVAddress,
- IN gctUINT SrcVStride,
- IN gceSURF_FORMAT SrcFormat,
- IN gceSURF_ROTATION SrcRotation,
- IN gctUINT32 SrcSurfaceWidth,
- IN gctUINT32 SrcSurfaceHeight,
- IN gcsRECT_PTR SrcRect,
- IN gctUINT32 DestAddress,
- IN gctUINT DestStride,
- IN gceSURF_FORMAT DestFormat,
- IN gceSURF_ROTATION DestRotation,
- IN gctUINT32 DestSurfaceWidth,
- IN gctUINT32 DestSurfaceHeight,
- IN gcsRECT_PTR DestRect,
- IN gcsRECT_PTR DestSubRect
- );
+ IN gco2D Engine,
+ IN gctUINT32 SrcAddress,
+ IN gctUINT SrcStride,
+ IN gctUINT32 SrcUAddress,
+ IN gctUINT SrcUStride,
+ IN gctUINT32 SrcVAddress,
+ IN gctUINT SrcVStride,
+ IN gceSURF_FORMAT SrcFormat,
+ IN gceSURF_ROTATION SrcRotation,
+ IN gctUINT32 SrcSurfaceWidth,
+ IN gctUINT32 SrcSurfaceHeight,
+ IN gcsRECT_PTR SrcRect,
+ IN gctUINT32 DestAddress,
+ IN gctUINT DestStride,
+ IN gceSURF_FORMAT DestFormat,
+ IN gceSURF_ROTATION DestRotation,
+ IN gctUINT32 DestSurfaceWidth,
+ IN gctUINT32 DestSurfaceHeight,
+ IN gcsRECT_PTR DestRect,
+ IN gcsRECT_PTR DestSubRect
+ );
gceSTATUS
gco2D_FilterBlitEx2(
/* Enable alpha blending engine in the hardware and disengage the ROP engine. */
gceSTATUS
gco2D_EnableAlphaBlend(
- IN gco2D Engine,
- IN gctUINT8 SrcGlobalAlphaValue,
- IN gctUINT8 DstGlobalAlphaValue,
- IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode,
- IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode,
- IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode,
- IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode,
- IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode,
- IN gceSURF_BLEND_FACTOR_MODE DstFactorMode,
- IN gceSURF_PIXEL_COLOR_MODE SrcColorMode,
- IN gceSURF_PIXEL_COLOR_MODE DstColorMode
- );
+ IN gco2D Engine,
+ IN gctUINT8 SrcGlobalAlphaValue,
+ IN gctUINT8 DstGlobalAlphaValue,
+ IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode,
+ IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode,
+ IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode,
+ IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode,
+ IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode,
+ IN gceSURF_BLEND_FACTOR_MODE DstFactorMode,
+ IN gceSURF_PIXEL_COLOR_MODE SrcColorMode,
+ IN gceSURF_PIXEL_COLOR_MODE DstColorMode
+ );
/* Enable alpha blending engine in the hardware. */
gceSTATUS
gco2D_EnableAlphaBlendAdvanced(
- IN gco2D Engine,
- IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode,
- IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode,
- IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode,
- IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode,
- IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode,
- IN gceSURF_BLEND_FACTOR_MODE DstFactorMode
- );
+ IN gco2D Engine,
+ IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode,
+ IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode,
+ IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode,
+ IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode,
+ IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode,
+ IN gceSURF_BLEND_FACTOR_MODE DstFactorMode
+ );
/* Enable alpha blending engine with Porter Duff rule. */
gceSTATUS
gco2D_SetPorterDuffBlending(
- IN gco2D Engine,
- IN gce2D_PORTER_DUFF_RULE Rule
- );
+ IN gco2D Engine,
+ IN gce2D_PORTER_DUFF_RULE Rule
+ );
/* Disable alpha blending engine in the hardware and engage the ROP engine. */
gceSTATUS
gco2D_DisableAlphaBlend(
- IN gco2D Engine
- );
+ IN gco2D Engine
+ );
/* Retrieve the maximum number of 32-bit data chunks for a single DE command. */
gctUINT32
gco2D_GetMaximumDataCount(
- void
- );
+ void
+ );
/* Retrieve the maximum number of rectangles, that can be passed in a single DE command. */
gctUINT32
gco2D_GetMaximumRectCount(
- void
- );
+ void
+ );
/* Returns the pixel alignment of the surface. */
gceSTATUS
gco2D_GetPixelAlignment(
- gceSURF_FORMAT Format,
- gcsPOINT_PTR Alignment
- );
+ gceSURF_FORMAT Format,
+ gcsPOINT_PTR Alignment
+ );
/* Retrieve monochrome stream pack size. */
gceSTATUS
gco2D_GetPackSize(
- IN gceSURF_MONOPACK StreamPack,
- OUT gctUINT32 * PackWidth,
- OUT gctUINT32 * PackHeight
- );
+ IN gceSURF_MONOPACK StreamPack,
+ OUT gctUINT32 * PackWidth,
+ OUT gctUINT32 * PackHeight
+ );
/* Flush the 2D pipeline. */
gceSTATUS
gco2D_Flush(
- IN gco2D Engine
- );
+ IN gco2D Engine
+ );
/* Load 256-entry color table for INDEX8 source surfaces. */
gceSTATUS
gco2D_LoadPalette(
- IN gco2D Engine,
- IN gctUINT FirstIndex,
- IN gctUINT IndexCount,
- IN gctPOINTER ColorTable,
- IN gctBOOL ColorConvert
- );
+ IN gco2D Engine,
+ IN gctUINT FirstIndex,
+ IN gctUINT IndexCount,
+ IN gctPOINTER ColorTable,
+ IN gctBOOL ColorConvert
+ );
/* Enable/disable 2D BitBlt mirrorring. */
gceSTATUS
gco2D_SetBitBlitMirror(
- IN gco2D Engine,
- IN gctBOOL HorizontalMirror,
- IN gctBOOL VerticalMirror
- );
+ IN gco2D Engine,
+ IN gctBOOL HorizontalMirror,
+ IN gctBOOL VerticalMirror
+ );
/*
* Set the transparency for source, destination and pattern.
IN gce2D_TRANSPARENCY DstTransparency,
IN gce2D_TRANSPARENCY PatTransparency,
IN gctBOOL EnableDFBColorKeyMode
- );
+ );
/* Set the transparency for source, destination and pattern. */
gceSTATUS
gco2D_SetTransparencyAdvanced(
- IN gco2D Engine,
- IN gce2D_TRANSPARENCY SrcTransparency,
- IN gce2D_TRANSPARENCY DstTransparency,
- IN gce2D_TRANSPARENCY PatTransparency
- );
+ IN gco2D Engine,
+ IN gce2D_TRANSPARENCY SrcTransparency,
+ IN gce2D_TRANSPARENCY DstTransparency,
+ IN gce2D_TRANSPARENCY PatTransparency
+ );
/* Set the source color key. */
gceSTATUS
gco2D_SetSourceColorKeyAdvanced(
- IN gco2D Engine,
- IN gctUINT32 ColorKey
- );
+ IN gco2D Engine,
+ IN gctUINT32 ColorKey
+ );
/* Set the source color key range. */
gceSTATUS
gco2D_SetSourceColorKeyRangeAdvanced(
- IN gco2D Engine,
- IN gctUINT32 ColorKeyLow,
- IN gctUINT32 ColorKeyHigh
- );
+ IN gco2D Engine,
+ IN gctUINT32 ColorKeyLow,
+ IN gctUINT32 ColorKeyHigh
+ );
/* Set the target color key. */
gceSTATUS
gco2D_SetTargetColorKeyAdvanced(
- IN gco2D Engine,
- IN gctUINT32 ColorKey
- );
+ IN gco2D Engine,
+ IN gctUINT32 ColorKey
+ );
/* Set the target color key range. */
gceSTATUS
gco2D_SetTargetColorKeyRangeAdvanced(
- IN gco2D Engine,
- IN gctUINT32 ColorKeyLow,
- IN gctUINT32 ColorKeyHigh
- );
+ IN gco2D Engine,
+ IN gctUINT32 ColorKeyLow,
+ IN gctUINT32 ColorKeyHigh
+ );
/* Set the YUV color space mode. */
gceSTATUS
gco2D_SetYUVColorMode(
- IN gco2D Engine,
- IN gce2D_YUV_COLOR_MODE Mode
- );
+ IN gco2D Engine,
+ IN gce2D_YUV_COLOR_MODE Mode
+ );
/* Setup the source global color value in ARGB8 format. */
gceSTATUS gco2D_SetSourceGlobalColorAdvanced(
- IN gco2D Engine,
- IN gctUINT32 Color32
- );
+ IN gco2D Engine,
+ IN gctUINT32 Color32
+ );
/* Setup the target global color value in ARGB8 format. */
gceSTATUS gco2D_SetTargetGlobalColorAdvanced(
- IN gco2D Engine,
- IN gctUINT32 Color32
- );
+ IN gco2D Engine,
+ IN gctUINT32 Color32
+ );
/* Setup the source and target pixel multiply modes. */
gceSTATUS
gco2D_SetPixelMultiplyModeAdvanced(
- IN gco2D Engine,
- IN gce2D_PIXEL_COLOR_MULTIPLY_MODE SrcPremultiplySrcAlpha,
- IN gce2D_PIXEL_COLOR_MULTIPLY_MODE DstPremultiplyDstAlpha,
- IN gce2D_GLOBAL_COLOR_MULTIPLY_MODE SrcPremultiplyGlobalMode,
- IN gce2D_PIXEL_COLOR_MULTIPLY_MODE DstDemultiplyDstAlpha
- );
+ IN gco2D Engine,
+ IN gce2D_PIXEL_COLOR_MULTIPLY_MODE SrcPremultiplySrcAlpha,
+ IN gce2D_PIXEL_COLOR_MULTIPLY_MODE DstPremultiplyDstAlpha,
+ IN gce2D_GLOBAL_COLOR_MULTIPLY_MODE SrcPremultiplyGlobalMode,
+ IN gce2D_PIXEL_COLOR_MULTIPLY_MODE DstDemultiplyDstAlpha
+ );
/* Set the GPU clock cycles after which the idle engine will keep auto-flushing. */
gceSTATUS
gco2D_SetAutoFlushCycles(
- IN gco2D Engine,
- IN gctUINT32 Cycles
- );
+ IN gco2D Engine,
+ IN gctUINT32 Cycles
+ );
#if VIVANTE_PROFILER
/* Read the profile registers available in the 2D engine and sets them in the profile.
*/
gceSTATUS
gco2D_ProfileEngine(
- IN gco2D Engine,
- OPTIONAL gcs2D_PROFILE_PTR Profile
- );
+ IN gco2D Engine,
+ OPTIONAL gcs2D_PROFILE_PTR Profile
+ );
#endif
/* Enable or disable 2D dithering. */
gceSTATUS
gco2D_EnableDither(
- IN gco2D Engine,
- IN gctBOOL Enable
- );
+ IN gco2D Engine,
+ IN gctBOOL Enable
+ );
gceSTATUS
gco2D_SetGenericSource(
IN gcsRECT_PTR Rect
);
+gceSTATUS
+gco2D_Set2DEngine(
+ IN gco2D Engine
+ );
+
+gceSTATUS
+gco2D_UnSet2DEngine(
+ IN gco2D Engine
+ );
+
+gceSTATUS
+gco2D_Get2DEngine(
+ OUT gco2D * Engine
+ );
+
#ifdef __cplusplus
}
#endif
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#define gckOS_FreeContiguous gcmHAL2D(gckOS_FreeContiguous)
#define gckOS_GetPageSize gcmHAL2D(gckOS_GetPageSize)
#define gckOS_GetPhysicalAddress gcmHAL2D(gckOS_GetPhysicalAddress)
-#define gckOS_GetPhysicalAddressProcess gcmHAL2D(gckOS_GetPhysicalAddressProcess)
-#define gckOS_MapPhysical gcmHAL2D(gckOS_MapPhysical)
+#define gckOS_UserLogicalToPhysical gcmHAL2D(gckOS_UserLogicalToPhysical)
+#define gckOS_GetPhysicalAddressProcess gcmHAL2D(gckOS_GetPhysicalAddressProcess)
+#define gckOS_MapPhysical gcmHAL2D(gckOS_MapPhysical)
#define gckOS_UnmapPhysical gcmHAL2D(gckOS_UnmapPhysical)
#define gckOS_ReadRegister gcmHAL2D(gckOS_ReadRegister)
#define gckOS_WriteRegister gcmHAL2D(gckOS_WriteRegister)
#define gckOS_QueryNeedCopy gcmHAL2D(gckOS_QueryNeedCopy)
#define gckOS_CopyFromUserData gcmHAL2D(gckOS_CopyFromUserData)
#define gckOS_CopyToUserData gcmHAL2D(gckOS_CopyToUserData)
-#define gckOS_MapUserPhysical gcmHAL2D(gckOS_MapUserPhysical)
#define gckOS_SuspendInterrupt gcmHAL2D(gckOS_SuspendInterrupt)
#define gckOS_ResumeInterrupt gcmHAL2D(gckOS_ResumeInterrupt)
#define gckOS_GetBaseAddress gcmHAL2D(gckOS_GetBaseAddress)
#define gckHARDWARE_Execute gcmHAL2D(gckHARDWARE_Execute)
#define gckHARDWARE_End gcmHAL2D(gckHARDWARE_End)
#define gckHARDWARE_Nop gcmHAL2D(gckHARDWARE_Nop)
-#define gckHARDWARE_Wait gcmHAL2D(gckHARDWARE_Wait)
#define gckHARDWARE_PipeSelect gcmHAL2D(gckHARDWARE_PipeSelect)
#define gckHARDWARE_Link gcmHAL2D(gckHARDWARE_Link)
#define gckHARDWARE_Event gcmHAL2D(gckHARDWARE_Event)
#define gckHARDWARE_AlignToTile gcmHAL2D(gckHARDWARE_AlignToTile)
#define gckHARDWARE_UpdateQueueTail gcmHAL2D(gckHARDWARE_UpdateQueueTail)
#define gckHARDWARE_ConvertLogical gcmHAL2D(gckHARDWARE_ConvertLogical)
-#define gckHARDWARE_ConvertPhysical gcmHAL2D(gckHARDWARE_ConvertPhysical)
#define gckHARDWARE_Interrupt gcmHAL2D(gckHARDWARE_Interrupt)
#define gckHARDWARE_SetMMU gcmHAL2D(gckHARDWARE_SetMMU)
#define gckHARDWARE_FlushMMU gcmHAL2D(gckHARDWARE_FlushMMU)
#define gckMMU_Destroy gcmHAL2D(gckMMU_Destroy)
#define gckMMU_AllocatePages gcmHAL2D(gckMMU_AllocatePages)
#define gckMMU_FreePages gcmHAL2D(gckMMU_FreePages)
-#define gckMMU_InsertNode gcmHAL2D(gckMMU_InsertNode)
-#define gckMMU_RemoveNode gcmHAL2D(gckMMU_RemoveNode)
-#define gckMMU_FreeHandleMemory gcmHAL2D(gckMMU_FreeHandleMemory)
#define gckMMU_Test gcmHAL2D(gckMMU_Test)
#define gckHARDWARE_QueryProfileRegisters gcmHAL2D(gckHARDWARE_QueryProfileRegisters)
--- /dev/null
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2014 by Vivante Corp.
+*
+* 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.
+*
+*****************************************************************************/
+
+
+#ifndef _GC_HAL_SECURITY_INTERFACE_H_
+#define _GC_HAL_SECURITY_INTERFACE_H_
+/*!
+ @brief Command codes between kernel module and TrustZone
+ @discussion
+ Critical services must be done in TrustZone to avoid sensitive content leak. Most of kernel module is kept in non-Secure os to minimize
+ code in TrustZone.
+ */
+typedef enum kernel_packet_command {
+ KERNEL_START_COMMAND,
+ KERNEL_SUBMIT,
+ KERNEL_MAP_MEMORY, /* */
+ KERNEL_UNMAP_MEMORY,
+ KERNEL_ALLOCATE_SECRUE_MEMORY, /*! Security memory management. */
+ KERNEL_FREE_SECURE_MEMORY,
+ KERNEL_EXECUTE, /* Execute a command buffer. */
+} kernel_packet_command_t;
+
+/*!
+ @brief gckCOMMAND Object requests TrustZone to start FE.
+ @discussion
+ DMA enabled register can only be written in TrustZone to avoid GPU from jumping to a hacked code.
+ Kernel module need use these command to ask TrustZone start command parser.
+ */
+struct kernel_start_command {
+ kernel_packet_command_t command; /*! The command (always needs to be the first entry in a structure). */
+ gctUINT8 gpu; /*! Which GPU. */
+};
+
+/*!
+ @brief gckCOMMAND Object requests TrustZone to submit command buffer.
+ @discussion
+ Code in trustzone will check content of command buffer after copying command buffer to TrustZone.
+ */
+struct kernel_submit {
+ kernel_packet_command_t command; /*! The command (always needs to be the first entry in a structure). */
+ gctUINT8 gpu; /*! Which GPU. */
+ gctUINT8 kernel_command; /*! Whether it is a kernel command. */
+ gctUINT32 command_buffer_handle; /*! Handle to command buffer. */
+ gctUINT32 offset; /* Offset in command buffer. */
+ gctUINT32 * command_buffer; /*! Content of command buffer need to be submit. */
+ gctUINT32 command_buffer_length; /*! Length of command buffer. */
+};
+
+
+/*!
+ @brief gckVIDMEM Object requests TrustZone to allocate security memory.
+ @discussion
+ Allocate a buffer from security GPU memory.
+ */
+struct kernel_allocate_security_memory {
+ kernel_packet_command_t command; /*! The command (always needs to be the first entry in a structure). */
+ gctUINT32 bytes; /*! Requested bytes. */
+ gctUINT32 memory_handle; /*! Handle of allocated memory. */
+};
+
+/*!
+ @brief gckVIDMEM Object requests TrustZone to allocate security memory.
+ @discussion
+ Free a video memory buffer from security GPU memory.
+ */
+struct kernel_free_security_memory {
+ kernel_packet_command_t command; /*! The command (always needs to be the first entry in a structure). */
+ gctUINT32 memory_handle; /*! Handle of allocated memory. */
+};
+
+struct kernel_execute {
+ kernel_packet_command_t command; /*! The command (always needs to be the first entry in a structure). */
+ gctUINT8 gpu; /*! Which GPU. */
+ gctUINT8 kernel_command; /*! Whether it is a kernel command. */
+ gctUINT32 * command_buffer; /*! Content of command buffer need to be submit. */
+ gctUINT32 command_buffer_length; /*! Length of command buffer. */
+};
+
+typedef struct kernel_map_scatter_gather {
+ gctUINT32 bytes;
+ gctUINT32 physical;
+ struct kernel_map_scatter_gather *next;
+}
+kernel_map_scatter_gather_t;
+
+struct kernel_map_memory {
+ kernel_packet_command_t command;
+ kernel_map_scatter_gather_t *scatter;
+ gctUINT32 *physicals;
+ gctUINT32 pageCount;
+ gctUINT32 gpuAddress;
+};
+
+struct kernel_unmap_memory {
+ gctUINT32 gpuAddress;
+ gctUINT32 pageCount;
+};
+
+typedef struct _gcsTA_INTERFACE {
+ kernel_packet_command_t command;
+ union {
+ struct kernel_submit Submit;
+ struct kernel_start_command StartCommand;
+ struct kernel_allocate_security_memory AllocateSecurityMemory;
+ struct kernel_execute Execute;
+ struct kernel_map_memory MapMemory;
+ struct kernel_unmap_memory UnmapMemory;
+ } u;
+ gceSTATUS result;
+} gcsTA_INTERFACE;
+
+enum {
+ gcvTA_COMMAND_INIT,
+ gcvTA_COMMAND_DISPATCH,
+
+ gcvTA_CALLBACK_ALLOC_SECURE_MEM,
+ gcvTA_CALLBACK_FREE_SECURE_MEM,
+};
+
+#endif
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
*/
#define VIV_STAT_FRAME_BUFFER_SIZE 30
+
/*
Total number of frames sampled for a mode. This means
gcsSTATISTICS_EARLYZ;
-/* Defines the statistical data keys monitored by the statistics module */
-typedef enum _gceSTATISTICS_Call
-{
- gcvSTAT_ES11_GLDRAWELEMENTS = 1,
-}
-gceSTATISTICS_Call;
-
-
/* HAL statistics information. */
typedef struct _gcsSTATISTICS
{
gctUINT64 previousFrameTime;
gctUINT frame;
gcsSTATISTICS_EARLYZ earlyZ;
- gctUINT ES11_drawElementsCount;
- gctBOOL applyRTestVAFix;
}
gcsSTATISTICS;
IN gctBOOL Disabled
);
-/* Checks whether or not glDrawArray function call will be discarded */
-gctBOOL
-gcfSTATISTICS_DiscardCall(
- gceSTATISTICS_Call Function
- );
-
-
#endif /*__gc_hal_statistics_h_ */
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#include "gc_hal_version.h"
#include "gc_hal_options.h"
+#if !defined(VIV_KMD)
+#if defined(__KERNEL__)
+#include "linux/version.h"
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ typedef unsigned long uintptr_t;
+# endif
+# include "linux/types.h"
+#elif defined(UNDER_CE)
+#include <crtdefs.h>
+#elif defined(_MSC_VER) && (_MSC_VER <= 1500)
+#include <crtdefs.h>
+#include "vadefs.h"
+#elif defined(__QNXNTO__)
+#define _QNX_SOURCE
+#include <stdint.h>
+#include <stddef.h>
+#else
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdint.h>
+#endif
+#endif
+
#ifdef _WIN32
#pragma warning(disable:4127) /* Conditional expression is constant (do { }
** while(0)). */
#pragma warning(disable:4131) /* Uses old-style declarator (for Bison and
** Flex generated files). */
#pragma warning(disable:4206) /* Translation unit is empty. */
+#pragma warning(disable:4214) /* Nonstandard extension used :
+ ** bit field types other than int. */
#endif
#ifdef __cplusplus
*/
#if defined(__GNUC__)
-# define gcdHAS_ELLIPSES 1 /* GCC always has it. */
+# define gcdHAS_ELLIPSIS 1 /* GCC always has it. */
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
-# define gcdHAS_ELLIPSES 1 /* C99 has it. */
+# define gcdHAS_ELLIPSIS 1 /* C99 has it. */
#elif defined(_MSC_VER) && (_MSC_VER >= 1500)
-# define gcdHAS_ELLIPSES 1 /* MSVC 2007+ has it. */
+# define gcdHAS_ELLIPSIS 1 /* MSVC 2007+ has it. */
#elif defined(UNDER_CE)
#if UNDER_CE >= 600
-# define gcdHAS_ELLIPSES 1
+# define gcdHAS_ELLIPSIS 1
# else
-# define gcdHAS_ELLIPSES 0
+# define gcdHAS_ELLIPSIS 0
# endif
#else
-# error "gcdHAS_ELLIPSES: Platform could not be determined"
+# error "gcdHAS_ELLIPSIS: Platform could not be determined"
#endif
/******************************************************************************\
************************************ Keyword ***********************************
\******************************************************************************/
-
-#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L))
+#if defined(ANDROID) && defined(__BIONIC_FORTIFY)
+# define gcmINLINE __inline__ __attribute__ ((always_inline)) __attribute__ ((gnu_inline)) __attribute__ ((artificial))
+#elif ((defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || defined(__APPLE__))
# define gcmINLINE inline /* C99 keyword. */
#elif defined(__GNUC__)
# define gcmINLINE __inline__ /* GNU keyword. */
typedef gctBOOL * gctBOOL_PTR;
typedef int gctINT;
-typedef long gctLONG;
typedef signed char gctINT8;
typedef signed short gctINT16;
typedef signed int gctINT32;
typedef unsigned short gctUINT16;
typedef unsigned int gctUINT32;
typedef unsigned long long gctUINT64;
-typedef unsigned long gctUINTPTR_T;
+typedef uintptr_t gctUINTPTR_T;
typedef gctUINT * gctUINT_PTR;
typedef gctUINT8 * gctUINT8_PTR;
typedef gctUINT32 * gctUINT32_PTR;
typedef gctUINT64 * gctUINT64_PTR;
-typedef unsigned long gctSIZE_T;
+typedef size_t gctSIZE_T;
typedef gctSIZE_T * gctSIZE_T_PTR;
+typedef gctUINT32 gctTRACE;
#ifdef __cplusplus
# define gcvNULL 0
# define gcvNULL ((void *) 0)
#endif
+#define gcvMAXINT8 0x7f
+#define gcvMININT8 0x80
+#define gcvMAXINT16 0x7fff
+#define gcvMININT16 0x8000
+#define gcvMAXINT32 0x7fffffff
+#define gcvMININT32 0x80000000
+#define gcvMAXINT64 0x7fffffffffffffff
+#define gcvMININT64 0x8000000000000000
+#define gcvMAXUINT8 0xff
+#define gcvMINUINT8 0x0
+#define gcvMAXUINT16 0xffff
+#define gcvMINUINT16 0x8000
+#define gcvMAXUINT32 0xffffffff
+#define gcvMINUINT32 0x80000000
+#define gcvMAXUINT64 0xffffffffffffffff
+#define gcvMINUINT64 0x8000000000000000
+#define gcvMAXUINTPTR_T (~(gctUINTPTR_T)0)
+
typedef float gctFLOAT;
typedef signed int gctFIXED_POINT;
typedef float * gctFLOAT_PTR;
typedef void * gctWINDOW;
typedef void * gctIMAGE;
typedef void * gctSYNC_POINT;
+typedef void * gctSHBUF;
-typedef void * gctSEMAPHORE;
+typedef void * gctSEMAPHORE;
typedef void * gctPOINTER;
typedef const void * gctCONST_POINTER;
#define gcvNEGONE_X ((gctFIXED_POINT) 0xFFFF0000)
#define gcvTWO_X ((gctFIXED_POINT) 0x00020000)
+
+
+#define gcmFIXEDCLAMP_NEG1_TO_1(_x) \
+ (((_x) < gcvNEGONE_X) \
+ ? gcvNEGONE_X \
+ : (((_x) > gcvONE_X) \
+ ? gcvONE_X \
+ : (_x)))
+
+#define gcmFLOATCLAMP_NEG1_TO_1(_f) \
+ (((_f) < -1.0f) \
+ ? -1.0f \
+ : (((_f) > 1.0f) \
+ ? 1.0f \
+ : (_f)))
+
+
+#define gcmFIXEDCLAMP_0_TO_1(_x) \
+ (((_x) < 0) \
+ ? 0 \
+ : (((_x) > gcvONE_X) \
+ ? gcvONE_X \
+ : (_x)))
+
+#define gcmFLOATCLAMP_0_TO_1(_f) \
+ (((_f) < 0.0f) \
+ ? 0.0f \
+ : (((_f) > 1.0f) \
+ ? 1.0f \
+ : (_f)))
+
+
+/******************************************************************************\
+******************************* Multicast Values *******************************
+\******************************************************************************/
+
+/* Value types. */
+typedef enum _gceVALUE_TYPE
+{
+ gcvVALUE_UINT = 0x0,
+ gcvVALUE_FIXED,
+ gcvVALUE_FLOAT,
+ gcvVALUE_INT,
+
+ /*
+ ** The value need be unsigned denormalized. clamp (0.0-1.0) should be done first.
+ */
+ gcvVALUE_FLAG_UNSIGNED_DENORM = 0x00010000,
+
+ /*
+ ** The value need be signed denormalized. clamp (-1.0-1.0) should be done first.
+ */
+ gcvVALUE_FLAG_SIGNED_DENORM = 0x00020000,
+
+ /*
+ ** The value need to gammar
+ */
+ gcvVALUE_FLAG_GAMMAR = 0x00040000,
+
+ /*
+ ** The value need to convert from float to float16
+ */
+ gcvVALUE_FLAG_FLOAT_TO_FLOAT16 = 0x0080000,
+
+ /*
+ ** Mask for flag field.
+ */
+ gcvVALUE_FLAG_MASK = 0xFFFF0000,
+}
+gceVALUE_TYPE;
+
+/* Value unions. */
+typedef union _gcuVALUE
+{
+ gctUINT uintValue;
+ gctFIXED_POINT fixedValue;
+ gctFLOAT floatValue;
+ gctINT intValue;
+}
+gcuVALUE;
+
+
+
+
/* Stringizing macro. */
#define gcmSTRING(Value) #Value
#define IN
#define OUT
+#define INOUT
#define OPTIONAL
/******************************************************************************\
gcvSTATUS_INVALID_CONFIG = 15,
gcvSTATUS_CHANGED = 16,
gcvSTATUS_NOT_SUPPORT_DITHER = 17,
- gcvSTATUS_EXECUTED = 18,
+ gcvSTATUS_EXECUTED = 18,
gcvSTATUS_TERMINATE = 19,
- gcvSTATUS_CONVERT_TO_SINGLE_STREAM = 20,
-
gcvSTATUS_INVALID_ARGUMENT = -1,
gcvSTATUS_INVALID_OBJECT = -2,
gcvSTATUS_OUT_OF_MEMORY = -3,
gcvSTATUS_NOT_MULTI_PIPE_ALIGNED = -28,
/* Linker errors. */
- gcvSTATUS_GLOBAL_TYPE_MISMATCH = -1000,
- gcvSTATUS_TOO_MANY_ATTRIBUTES = -1001,
- gcvSTATUS_TOO_MANY_UNIFORMS = -1002,
- gcvSTATUS_TOO_MANY_VARYINGS = -1003,
- gcvSTATUS_UNDECLARED_VARYING = -1004,
- gcvSTATUS_VARYING_TYPE_MISMATCH = -1005,
- gcvSTATUS_MISSING_MAIN = -1006,
- gcvSTATUS_NAME_MISMATCH = -1007,
- gcvSTATUS_INVALID_INDEX = -1008,
- gcvSTATUS_UNIFORM_TYPE_MISMATCH = -1009,
+ gcvSTATUS_GLOBAL_TYPE_MISMATCH = -1000,
+ gcvSTATUS_TOO_MANY_ATTRIBUTES = -1001,
+ gcvSTATUS_TOO_MANY_UNIFORMS = -1002,
+ gcvSTATUS_TOO_MANY_VARYINGS = -1003,
+ gcvSTATUS_UNDECLARED_VARYING = -1004,
+ gcvSTATUS_VARYING_TYPE_MISMATCH = -1005,
+ gcvSTATUS_MISSING_MAIN = -1006,
+ gcvSTATUS_NAME_MISMATCH = -1007,
+ gcvSTATUS_INVALID_INDEX = -1008,
+ gcvSTATUS_UNIFORM_MISMATCH = -1009,
+ gcvSTATUS_UNSAT_LIB_SYMBOL = -1010,
+ gcvSTATUS_TOO_MANY_SHADERS = -1011,
+ gcvSTATUS_LINK_INVALID_SHADERS = -1012,
+ gcvSTATUS_CS_NO_WORKGROUP_SIZE = -1013,
+ gcvSTATUS_LINK_LIB_ERROR = -1014,
+ gcvSTATUS_SHADER_VERSION_MISMATCH = -1015,
+ gcvSTATUS_TOO_MANY_INSTRUCTION = -1016,
+ gcvSTATUS_SSBO_MISMATCH = -1017,
+ gcvSTATUS_TOO_MANY_OUTPUT = -1018,
+ gcvSTATUS_TOO_MANY_INPUT = -1019,
+ gcvSTATUS_NOT_SUPPORT_CL = -1020,
+ gcvSTATUS_NOT_SUPPORT_INTEGER = -1021,
+ gcvSTATUS_UNIFORM_TYPE_MISMATCH = -1022,
+ gcvSTATUS_TOO_MANY_SAMPLER = -1023,
/* Compiler errors. */
- gcvSTATUS_COMPILER_FE_PREPROCESSOR_ERROR = -2000,
- gcvSTATUS_COMPILER_FE_PARSER_ERROR = -2001,
+ gcvSTATUS_COMPILER_FE_PREPROCESSOR_ERROR = -2000,
+ gcvSTATUS_COMPILER_FE_PARSER_ERROR = -2001,
+
+ /* Recompilation Errors */
+ gcvSTATUS_RECOMPILER_CONVERT_UNIMPLEMENTED = -3000,
}
gceSTATUS;
((Address & (~0U << Name ## _LSB)) == (Name ## _Address >> 2)) \
)
-/*******************************************************************************
-**
-** A set of macros to aid state loading.
-**
-** ARGUMENTS:
-**
-** CommandBuffer Pointer to a gcoCMDBUF object.
-** StateDelta Pointer to a gcsSTATE_DELTA state delta structure.
-** Memory Destination memory pointer of gctUINT32_PTR type.
-** PartOfContext Whether or not the state is a part of the context.
-** FixedPoint Whether or not the state is of the fixed point format.
-** Count Number of consecutive states to be loaded.
-** Address State address.
-** Data Data to be set to the state.
-*/
-
-/*----------------------------------------------------------------------------*/
-
-#if gcmIS_DEBUG(gcdDEBUG_CODE)
-
-# define gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count) \
- CommandBuffer->lastLoadStatePtr = gcmPTR_TO_UINT64(Memory); \
- CommandBuffer->lastLoadStateAddress = Address; \
- CommandBuffer->lastLoadStateCount = Count
-
-# define gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address) \
- gcmASSERT( \
- (gctUINT) (Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastLoadStatePtr, gctUINT32_PTR) - 1) \
- == \
- (gctUINT) (Address - CommandBuffer->lastLoadStateAddress) \
- ); \
- \
- gcmASSERT(CommandBuffer->lastLoadStateCount > 0); \
- \
- CommandBuffer->lastLoadStateCount -= 1
-
-# define gcmVERIFYLOADSTATEDONE(CommandBuffer) \
- gcmASSERT(CommandBuffer->lastLoadStateCount == 0)
-
-#else
-
-# define gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count)
-# define gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address)
-# define gcmVERIFYLOADSTATEDONE(CommandBuffer)
-
-#endif
-
-#if gcdSECURE_USER
-
-# define gcmDEFINESECUREUSER() \
- gctUINT __secure_user_offset__; \
- gctUINT32_PTR __secure_user_hintArray__;
-
-# define gcmBEGINSECUREUSER() \
- __secure_user_offset__ = reserve->lastOffset; \
- \
- __secure_user_hintArray__ = gcmUINT64_TO_PTR(reserve->hintArrayTail)
-
-# define gcmENDSECUREUSER() \
- reserve->hintArrayTail = gcmPTR_TO_UINT64(__secure_user_hintArray__)
-
-# define gcmSKIPSECUREUSER() \
- __secure_user_offset__ += gcmSIZEOF(gctUINT32)
-
-# define gcmUPDATESECUREUSER() \
- *__secure_user_hintArray__ = __secure_user_offset__; \
- \
- __secure_user_offset__ += gcmSIZEOF(gctUINT32); \
- __secure_user_hintArray__ += 1
-
-#else
-
-# define gcmDEFINESECUREUSER()
-# define gcmBEGINSECUREUSER()
-# define gcmENDSECUREUSER()
-# define gcmSKIPSECUREUSER()
-# define gcmUPDATESECUREUSER()
-
-#endif
-
-/*----------------------------------------------------------------------------*/
-
-#if gcdDUMP
-# define gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, Data) \
- if (FixedPoint) \
- { \
- gcmDUMP(gcvNULL, "@[state.x 0x%04X 0x%08X]", \
- Address, Data \
- ); \
- } \
- else \
- { \
- gcmDUMP(gcvNULL, "@[state 0x%04X 0x%08X]", \
- Address, Data \
- ); \
- }
-#else
-# define gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, Data)
-#endif
-
-/*----------------------------------------------------------------------------*/
-
-#define gcmDEFINESTATEBUFFER(CommandBuffer, StateDelta, Memory, ReserveSize) \
- gcmDEFINESECUREUSER() \
- gctSIZE_T ReserveSize; \
- gcoCMDBUF CommandBuffer; \
- gctUINT32_PTR Memory; \
- gcsSTATE_DELTA_PTR StateDelta
-
-#define gcmBEGINSTATEBUFFER(Hardware, CommandBuffer, StateDelta, Memory, ReserveSize) \
-{ \
- gcmONERROR(gcoBUFFER_Reserve( \
- Hardware->buffer, ReserveSize, gcvTRUE, &CommandBuffer \
- )); \
- \
- Memory = gcmUINT64_TO_PTR(CommandBuffer->lastReserve); \
- \
- StateDelta = Hardware->delta; \
- \
- gcmBEGINSECUREUSER(); \
-}
-
-#define gcmENDSTATEBUFFER(CommandBuffer, Memory, ReserveSize) \
-{ \
- gcmENDSECUREUSER(); \
- \
- gcmASSERT( \
- gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT8_PTR) + ReserveSize \
- == \
- (gctUINT8_PTR) Memory \
- ); \
-}
-
-/*----------------------------------------------------------------------------*/
-
-#define gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, Count) \
-{ \
- gcmASSERT(((Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT32_PTR)) & 1) == 0); \
- gcmASSERT((gctUINT32)Count <= 1024); \
- \
- gcmVERIFYLOADSTATEDONE(CommandBuffer); \
- \
- gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count); \
- \
- *Memory++ \
- = gcmSETFIELDVALUE(0, AQ_COMMAND_LOAD_STATE_COMMAND, OPCODE, LOAD_STATE) \
- | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, FLOAT, FixedPoint) \
- | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, COUNT, Count) \
- | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, ADDRESS, Address); \
- \
- gcmSKIPSECUREUSER(); \
-}
-
-#define gcmENDSTATEBATCH(CommandBuffer, Memory) \
-{ \
- gcmVERIFYLOADSTATEDONE(CommandBuffer); \
- \
- gcmASSERT(((Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT32_PTR)) & 1) == 0); \
-}
-
-/*----------------------------------------------------------------------------*/
-
-#define gcmSETSTATEDATA(StateDelta, CommandBuffer, Memory, FixedPoint, \
- Address, Data) \
-{ \
- gctUINT32 __temp_data32__; \
- \
- gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \
- \
- __temp_data32__ = Data; \
- \
- *Memory++ = __temp_data32__; \
- \
- gcoHARDWARE_UpdateDelta( \
- StateDelta, FixedPoint, Address, 0, __temp_data32__ \
- ); \
- \
- gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
- \
- gcmUPDATESECUREUSER(); \
-}
-
-#define gcmSETCTRLSTATE(StateDelta, CommandBuffer, Memory, Address, Data) \
-{ \
- gctUINT32 __temp_data32__; \
- \
- gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \
- \
- __temp_data32__ = Data; \
- \
- *Memory++ = __temp_data32__; \
- \
- gcmDUMPSTATEDATA(StateDelta, gcvFALSE, Address, __temp_data32__); \
- \
- gcmSKIPSECUREUSER(); \
-}
-
-#define gcmSETFILLER(CommandBuffer, Memory) \
-{ \
- gcmVERIFYLOADSTATEDONE(CommandBuffer); \
- \
- Memory += 1; \
- \
- gcmSKIPSECUREUSER(); \
-}
-
-/*----------------------------------------------------------------------------*/
-
-#define gcmSETSINGLESTATE(StateDelta, CommandBuffer, Memory, FixedPoint, \
- Address, Data) \
-{ \
- gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \
- gcmSETSTATEDATA(StateDelta, CommandBuffer, Memory, FixedPoint, \
- Address, Data); \
- gcmENDSTATEBATCH(CommandBuffer, Memory); \
-}
-
-#define gcmSETSINGLECTRLSTATE(StateDelta, CommandBuffer, Memory, FixedPoint, \
- Address, Data) \
-{ \
- gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \
- gcmSETCTRLSTATE(StateDelta, CommandBuffer, Memory, Address, Data); \
- gcmENDSTATEBATCH(CommandBuffer, Memory); \
-}
-
-
-/*******************************************************************************
-**
-** gcmSETSTARTDECOMMAND
-**
-** Form a START_DE command.
-**
-** ARGUMENTS:
-**
-** Memory Destination memory pointer of gctUINT32_PTR type.
-** Count Number of the rectangles.
-*/
-
-#define gcmSETSTARTDECOMMAND(Memory, Count) \
-{ \
- *Memory++ \
- = gcmSETFIELDVALUE(0, AQ_COMMAND_START_DE_COMMAND, OPCODE, START_DE) \
- | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, COUNT, Count) \
- | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, DATA_COUNT, 0); \
- \
- *Memory++ = 0xDEADDEED; \
-}
-
/******************************************************************************\
******************************** Ceiling Macro ********************************
\******************************************************************************/
#define gcmABS(x) (((x) < 0) ? -(x) : (x))
#define gcmNEG(x) (((x) < 0) ? (x) : -(x))
+/******************************************************************************\
+******************************** Bit Macro ********************************
+\******************************************************************************/
+#define gcmBITSET(x, y) ((x) & (y))
/*******************************************************************************
**
** gcmPTR2INT
**
** p Pointer value.
*/
-#if defined(_WIN32) || (defined(__LP64__) && __LP64__)
-# define gcmPTR2INT(p) \
- ( \
- (gctUINT32) (gctUINT64) (p) \
- )
-#else
-# define gcmPTR2INT(p) \
- ( \
- (gctUINT32) (p) \
- )
-#endif
+#define gcmPTR2INT(p) \
+( \
+ (gctUINTPTR_T) (p) \
+)
+
+#define gcmPTR2INT32(p) \
+( \
+ (gctUINT32)(gctUINTPTR_T) (p) \
+)
/*******************************************************************************
**
**
** v Integer value.
*/
-#ifdef __LP64__
-# define gcmINT2PTR(i) \
- ( \
- (gctPOINTER) (gctINT64) (i) \
- )
-#else
-# define gcmINT2PTR(i) \
- ( \
- (gctPOINTER) (i) \
- )
-#endif
+
+#define gcmINT2PTR(i) \
+( \
+ (gctPOINTER) (gctUINTPTR_T)(i) \
+)
/*******************************************************************************
**
*/
#define gcmOFFSETOF(s, field) \
( \
- gcmPTR2INT(& (((struct s *) 0)->field)) \
+ gcmPTR2INT32(& (((struct s *) 0)->field)) \
)
+/*******************************************************************************
+**
+** gcmSWAB32
+**
+** Return a value with all bytes in the 32 bit argument swapped.
+*/
#define gcmSWAB32(x) ((gctUINT32)( \
(((gctUINT32)(x) & (gctUINT32)0x000000FFUL) << 24) | \
(((gctUINT32)(x) & (gctUINT32)0x0000FF00UL) << 8) | \
OUT gctUINT readRequests[8];
OUT gctUINT writeRequests[8];
- /* FE counters. */
- OUT gctUINT drawCount;
- OUT gctUINT vertexOutCount;
- OUT gctUINT vertexMissCount;
-
/* 3D counters. */
OUT gctUINT vertexCount;
OUT gctUINT primitiveCount;
OUT gctUINT rejectedPrimitives;
OUT gctUINT culledPrimitives;
OUT gctUINT clippedPrimitives;
- OUT gctUINT droppedPrimitives;
- OUT gctUINT frustumClippedPrimitives;
OUT gctUINT outPrimitives;
OUT gctUINT inPrimitives;
OUT gctUINT culledQuadCount;
OUT gctUINT shaderCycles;
OUT gctUINT vsInstructionCount;
OUT gctUINT vsTextureCount;
- OUT gctUINT vsBranchCount;
- OUT gctUINT vsVertices;
OUT gctUINT psInstructionCount;
OUT gctUINT psTextureCount;
- OUT gctUINT psBranchCount;
- OUT gctUINT psPixels;
/* Texture counters. */
OUT gctUINT bilinearRequests;
OUT gctUINT trilinearRequests;
- OUT gctUINT txBytes8[2];
+ OUT gctUINT txBytes8;
OUT gctUINT txHitCount;
OUT gctUINT txMissCount;
}
gcsHAL_FRAME_INFO;
-typedef enum _gcePATCH_ID
-{
- gcePATCH_UNKNOWN = 0xFFFFFFFF,
-
- /* Benchmark list*/
- gcePATCH_GLB11 = 0x0,
- gcePATCH_GLB21,
- gcePATCH_GLB25,
- gcePATCH_GLB27,
-
- gcePATCH_BM21,
- gcePATCH_MM,
- gcePATCH_MM06,
- gcePATCH_MM07,
- gcePATCH_QUADRANT,
- gcePATCH_ANTUTU,
- gcePATCH_SMARTBENCH,
- gcePATCH_JPCT,
- gcePATCH_NENAMARK,
- gcePATCH_NENAMARK2,
- gcePATCH_NEOCORE,
- gcePATCH_GLB,
- gcePATCH_GB,
- gcePATCH_RTESTVA,
- gcePATCH_BMX,
- gcePATCH_BMGUI,
-
- /* Game list */
- gcePATCH_NBA2013,
- gcePATCH_BARDTALE,
- gcePATCH_BUSPARKING3D,
- gcePATCH_FISHBOODLE,
- gcePATCH_SUBWAYSURFER,
- gcePATCH_HIGHWAYDRIVER,
- gcePATCH_PREMIUM,
- gcePATCH_RACEILLEGAL,
- gcePATCH_BLABLA,
- gcePATCH_MEGARUN,
- gcePATCH_GALAXYONFIRE2,
- gcePATCH_GLOFTR3HM,
- gcePATCH_GLOFTSXHM,
- gcePATCH_GLOFTF3HM,
- gcePATCH_GLOFTGANG,
- gcePATCH_XRUNNER,
- gcePATCH_WP,
- gcePATCH_DEVIL,
- gcePATCH_HOLYARCH,
- gcePATCH_MUSE,
- gcePATCH_SG,
- gcePATCH_SIEGECRAFT,
- gcePATCH_CARCHALLENGE,
- gcePATCH_HEROESCALL,
- gcePATCH_MONOPOLY,
- gcePATCH_CTGL20,
- gcePATCH_FIREFOX,
- gcePATCH_CHORME,
- gcePATCH_DUOKANTV,
- gcePATCH_TESTAPP,
- gcePATCH_GOOGLEEARTH,
-
- /* Count enum*/
- gcePATCH_COUNT,
-}
-gcePATCH_ID;
-
#if gcdLINK_QUEUE_SIZE
typedef struct _gckLINKDATA * gckLINKDATA;
struct _gckLINKDATA
{
gctUINT32 start;
gctUINT32 end;
- gctINT pid;
+ gctUINT32 pid;
};
typedef struct _gckLINKQUEUE * gckLINKQUEUE;
};
#endif
+#define gcdENTRY_QUEUE_SIZE 256
+typedef struct _gckENTRYDATA * gckENTRYDATA;
+struct _gckENTRYDATA
+{
+ gctUINT32 physical;
+ gctUINT32 bytes;
+};
+
+typedef struct _gckENTRYQUEUE * gckENTRYQUEUE;
+struct _gckENTRYQUEUE
+{
+ struct _gckENTRYDATA data[gcdENTRY_QUEUE_SIZE];
+ gctUINT32 rear;
+ gctUINT32 front;
+ gctUINT32 count;
+};
+
+typedef enum _gceTRACEMODE
+{
+ gcvTRACEMODE_NONE = 0,
+ gcvTRACEMODE_FULL = 1,
+ gcvTRACEMODE_LOGGER = 2,
+ gcvTRACEMODE_PRE = 3,
+ gcvTRACEMODE_POST = 4,
+ gcvTRACEMODE_SYSTRACE = 5,
+
+} gceTRACEMODE;
+
+
#ifdef __cplusplus
}
#endif
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#ifndef __gc_hal_version_h_
#define __gc_hal_version_h_
-#define gcvVERSION_MAJOR 4
+#define gcvVERSION_MAJOR 5
-#define gcvVERSION_MINOR 6
+#define gcvVERSION_MINOR 0
-#define gcvVERSION_PATCH 9
+#define gcvVERSION_PATCH 11
-#define gcvVERSION_BUILD 9754
+#define gcvVERSION_BUILD 25762
+
+#define gcvVERSION_STRING "5.0.11.p4.25762"
#define gcvVERSION_DATE __DATE__
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
/* Allocate linear video memory. */
gceSTATUS
-gckKERNEL_AllocateLinearMemory(
+gckVGKERNEL_AllocateLinearMemory(
IN gckKERNEL Kernel,
IN OUT gcePOOL * Pool,
IN gctSIZE_T Bytes,
- IN gctSIZE_T Alignment,
+ IN gctUINT32 Alignment,
IN gceSURF_TYPE Type,
OUT gcuVIDMEM_NODE_PTR * Node
);
OUT gcsCOMMAND_BUFFER_INFO_PTR Information
);
-#if gcdDYNAMIC_MAP_RESERVED_MEMORY
-gceSTATUS
-gckOS_MapReservedMemoryToKernel(
- IN gckOS Os,
- IN gctUINT32 Physical,
- IN gctINT Bytes,
- IN OUT gctPOINTER *Virtual
- );
-
-gceSTATUS
-gckOS_UnmapReservedMemoryFromKernel(
- IN gctPOINTER Virtual
- );
-#endif
-
/******************************************************************************\
******************************* gckVGHARDWARE Object ******************************
\******************************************************************************/
gckVGHARDWARE_Execute(
IN gckVGHARDWARE Hardware,
IN gctUINT32 Address,
- IN gctSIZE_T Count
+ IN gctUINT32 Count
);
/* Query the available memory. */
gckVGHARDWARE_ConvertLogical(
IN gckVGHARDWARE Hardware,
IN gctPOINTER Logical,
+ IN gctBOOL InUserSpace,
OUT gctUINT32 * Address
);
\******************************************************************************/
/* Vacant command buffer marker. */
-#define gcvVACANT_BUFFER ((gcsCOMPLETION_SIGNAL_PTR) (1))
+#define gcvVACANT_BUFFER ((gcsCOMPLETION_SIGNAL_PTR) ((gctSIZE_T)1))
/* Command buffer header. */
typedef struct _gcsCMDBUFFER * gcsCMDBUFFER_PTR;
/* The user sets this to the node of the container buffer whitin which
this particular command buffer resides. The kernel sets this to the
node of the internally allocated buffer. */
- gctUINT64 node;
+ gcuVIDMEM_NODE_PTR node;
/* Command buffer hardware address. */
gctUINT32 address;
/* Size of the area allocated for the data portion of this particular
command buffer (headers and tail reserves are excluded). */
- gctSIZE_T size;
+ gctUINT32 size;
/* Offset into the buffer [0..size]; reflects exactly how much data has
been put into the command buffer. */
/* The number of command units in the buffer for the hardware to
execute. */
- gctSIZE_T dataCount;
+ gctUINT32 dataCount;
/* MANAGED BY : user HAL (gcoBUFFER object).
USED BY : user HAL (gcoBUFFER object).
gctUINT32 currentPipe;
/* State map/mod buffer. */
- gctSIZE_T mapFirst;
- gctSIZE_T mapLast;
-#ifdef __QNXNTO__
- gctSIZE_T mapContainerSize;
-#endif
- gcsVGCONTEXT_MAP_PTR mapContainer;
- gcsVGCONTEXT_MAP_PTR mapPrev;
- gcsVGCONTEXT_MAP_PTR mapCurr;
- gcsVGCONTEXT_MAP_PTR firstPrevMap;
- gcsVGCONTEXT_MAP_PTR firstCurrMap;
+ gctUINT32 mapFirst;
+ gctUINT32 mapLast;
+ gcsVGCONTEXT_MAP_PTR mapContainer;
+ gcsVGCONTEXT_MAP_PTR mapPrev;
+ gcsVGCONTEXT_MAP_PTR mapCurr;
+ gcsVGCONTEXT_MAP_PTR firstPrevMap;
+ gcsVGCONTEXT_MAP_PTR firstCurrMap;
/* Main context buffer. */
gcsCMDBUFFER_PTR header;
gceSTATUS
gckVGMMU_Construct(
IN gckVGKERNEL Kernel,
- IN gctSIZE_T MmuSize,
+ IN gctUINT32 MmuSize,
OUT gckVGMMU * Mmu
);
--- /dev/null
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2014 by Vivante Corp.
+*
+* 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.
+*
+*****************************************************************************/
+
+
+extern gceSTATUS
+_DefaultAlloctorInit(
+ IN gckOS Os,
+ OUT gckALLOCATOR * Allocator
+ );
+
+gcsALLOCATOR_DESC allocatorArray[] =
+{
+ /* Default allocator. */
+ gcmkDEFINE_ALLOCATOR_DESC("default", _DefaultAlloctorInit),
+};
+
+
--- /dev/null
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2014 by Vivante Corp.
+*
+* 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.
+*
+*****************************************************************************/
+
+
+extern gceSTATUS
+_DefaultAlloctorInit(
+ IN gckOS Os,
+ OUT gckALLOCATOR * Allocator
+ );
+
+#if LINUX_CMA_FSL
+gceSTATUS
+_CMAFSLAlloctorInit(
+ IN gckOS Os,
+ OUT gckALLOCATOR * Allocator
+ );
+#endif
+
+gcsALLOCATOR_DESC allocatorArray[] =
+{
+#if LINUX_CMA_FSL
+ gcmkDEFINE_ALLOCATOR_DESC("cmafsl", _CMAFSLAlloctorInit),
+#endif
+ /* Default allocator. */
+ gcmkDEFINE_ALLOCATOR_DESC("default", _DefaultAlloctorInit),
+};
+
+
--- /dev/null
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2014 by Vivante Corp.
+*
+* 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.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+#include "gc_hal_kernel_allocator.h"
+
+#include <linux/pagemap.h>
+#include <linux/seq_file.h>
+#include <linux/mman.h>
+#include <asm/atomic.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+
+#define _GC_OBJ_ZONE gcvZONE_OS
+
+typedef struct _gcsCMA_PRIV * gcsCMA_PRIV_PTR;
+typedef struct _gcsCMA_PRIV {
+ gctUINT32 cmasize;
+}
+gcsCMA_PRIV;
+
+struct mdl_cma_priv {
+ gctPOINTER kvaddr;
+ dma_addr_t physical;
+};
+
+int gc_cma_usage_show(struct seq_file* m, void* data)
+{
+ gcsINFO_NODE *node = m->private;
+ gckALLOCATOR Allocator = node->device;
+ gcsCMA_PRIV_PTR priv = Allocator->privateData;
+
+ seq_printf(m, "cma: %u bytes\n", priv->cmasize);
+
+ return 0;
+}
+
+static gcsINFO InfoList[] =
+{
+ {"cmausage", gc_cma_usage_show},
+};
+
+static void
+_DefaultAllocatorDebugfsInit(
+ IN gckALLOCATOR Allocator,
+ IN gckDEBUGFS_DIR Root
+ )
+{
+ gcmkVERIFY_OK(
+ gckDEBUGFS_DIR_Init(&Allocator->debugfsDir, Root->root, "cma"));
+
+ gcmkVERIFY_OK(gckDEBUGFS_DIR_CreateFiles(
+ &Allocator->debugfsDir,
+ InfoList,
+ gcmCOUNTOF(InfoList),
+ Allocator
+ ));
+}
+
+static void
+_DefaultAllocatorDebugfsCleanup(
+ IN gckALLOCATOR Allocator
+ )
+{
+ gcmkVERIFY_OK(gckDEBUGFS_DIR_RemoveFiles(
+ &Allocator->debugfsDir,
+ InfoList,
+ gcmCOUNTOF(InfoList)
+ ));
+
+ gckDEBUGFS_DIR_Deinit(&Allocator->debugfsDir);
+}
+
+static gceSTATUS
+_CMAFSLAlloc(
+ IN gckALLOCATOR Allocator,
+ INOUT PLINUX_MDL Mdl,
+ IN gctSIZE_T NumPages,
+ IN gctUINT32 Flags
+ )
+{
+ gceSTATUS status;
+ gcsCMA_PRIV_PTR priv = (gcsCMA_PRIV_PTR)Allocator->privateData;
+
+ struct mdl_cma_priv *mdl_priv=gcvNULL;
+ gckOS os = Allocator->os;
+
+ gcmkHEADER_ARG("Mdl=%p NumPages=%d", Mdl, NumPages);
+
+ gcmkONERROR(gckOS_Allocate(os, sizeof(struct mdl_cma_priv), (gctPOINTER *)&mdl_priv));
+ mdl_priv->kvaddr = gcvNULL;
+
+ mdl_priv->kvaddr = dma_alloc_writecombine(gcvNULL,
+ NumPages * PAGE_SIZE,
+ &mdl_priv->physical,
+ GFP_KERNEL | gcdNOWARN);
+
+ if (mdl_priv->kvaddr == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ Mdl->priv = mdl_priv;
+ priv->cmasize += NumPages * PAGE_SIZE;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if(mdl_priv)
+ gckOS_Free(os, mdl_priv);
+ gcmkFOOTER();
+ return status;
+}
+
+static void
+_CMAFSLFree(
+ IN gckALLOCATOR Allocator,
+ IN OUT PLINUX_MDL Mdl
+ )
+{
+ gckOS os = Allocator->os;
+ struct mdl_cma_priv *mdl_priv=(struct mdl_cma_priv *)Mdl->priv;
+ gcsCMA_PRIV_PTR priv = (gcsCMA_PRIV_PTR)Allocator->privateData;
+ dma_free_writecombine(gcvNULL,
+ Mdl->numPages * PAGE_SIZE,
+ mdl_priv->kvaddr,
+ mdl_priv->physical);
+ gckOS_Free(os, mdl_priv);
+ priv->cmasize -= Mdl->numPages * PAGE_SIZE;
+}
+
+gctINT
+_CMAFSLMapUser(
+ gckALLOCATOR Allocator,
+ PLINUX_MDL Mdl,
+ PLINUX_MDL_MAP MdlMap,
+ gctBOOL Cacheable
+ )
+{
+
+ PLINUX_MDL mdl = Mdl;
+ PLINUX_MDL_MAP mdlMap = MdlMap;
+ struct mdl_cma_priv *mdl_priv=(struct mdl_cma_priv *)Mdl->priv;
+
+ gcmkHEADER_ARG("Allocator=%p Mdl=%p MdlMap=%p gctBOOL=%d", Allocator, Mdl, MdlMap, Cacheable);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
+ mdlMap->vmaAddr = (gctSTRING)vm_mmap(gcvNULL,
+ 0L,
+ mdl->numPages * PAGE_SIZE,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ 0);
+#else
+ down_write(¤t->mm->mmap_sem);
+
+ mdlMap->vmaAddr = (gctSTRING)do_mmap_pgoff(gcvNULL,
+ 0L,
+ mdl->numPages * PAGE_SIZE,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ 0);
+
+ up_write(¤t->mm->mmap_sem);
+#endif
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): vmaAddr->0x%X for phys_addr->0x%X",
+ __FUNCTION__, __LINE__,
+ (gctUINT32)(gctUINTPTR_T)mdlMap->vmaAddr,
+ (gctUINT32)(gctUINTPTR_T)mdl
+ );
+
+ if (IS_ERR(mdlMap->vmaAddr))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): do_mmap_pgoff error",
+ __FUNCTION__, __LINE__
+ );
+
+ mdlMap->vmaAddr = gcvNULL;
+
+ gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
+ return gcvSTATUS_OUT_OF_MEMORY;
+ }
+
+ down_write(¤t->mm->mmap_sem);
+
+ mdlMap->vma = find_vma(current->mm, (unsigned long)mdlMap->vmaAddr);
+
+ if (mdlMap->vma == gcvNULL)
+ {
+ up_write(¤t->mm->mmap_sem);
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): find_vma error",
+ __FUNCTION__, __LINE__
+ );
+
+ mdlMap->vmaAddr = gcvNULL;
+
+ gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_RESOURCES);
+ return gcvSTATUS_OUT_OF_RESOURCES;
+ }
+
+ /* Now map all the vmalloc pages to this user address. */
+ if (mdl->contiguous)
+ {
+ /* map kernel memory to user space.. */
+ if (dma_mmap_writecombine(gcvNULL,
+ mdlMap->vma,
+ mdl_priv->kvaddr,
+ mdl_priv->physical,
+ mdl->numPages * PAGE_SIZE) < 0)
+ {
+ up_write(¤t->mm->mmap_sem);
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_WARNING, gcvZONE_OS,
+ "%s(%d): dma_mmap_attrs error",
+ __FUNCTION__, __LINE__
+ );
+
+ mdlMap->vmaAddr = gcvNULL;
+
+ gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
+ return gcvSTATUS_OUT_OF_MEMORY;
+ }
+ }
+ else
+ {
+ gckOS_Print("incorrect mdl:conti%d\n",mdl->contiguous);
+ }
+
+ up_write(¤t->mm->mmap_sem);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+void
+_CMAUnmapUser(
+ IN gckALLOCATOR Allocator,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Size
+ )
+{
+ if (unlikely(current->mm == gcvNULL))
+ {
+ /* Do nothing if process is exiting. */
+ return;
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+ if (vm_munmap((unsigned long)Logical, Size) < 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_WARNING, gcvZONE_OS,
+ "%s(%d): vm_munmap failed",
+ __FUNCTION__, __LINE__
+ );
+ }
+#else
+ down_write(¤t->mm->mmap_sem);
+ if (do_munmap(current->mm, (unsigned long)Logical, Size) < 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_WARNING, gcvZONE_OS,
+ "%s(%d): do_munmap failed",
+ __FUNCTION__, __LINE__
+ );
+ }
+ up_write(¤t->mm->mmap_sem);
+#endif
+}
+
+gceSTATUS
+_CMAMapKernel(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ OUT gctPOINTER *Logical
+ )
+{
+ struct mdl_cma_priv *mdl_priv=(struct mdl_cma_priv *)Mdl->priv;
+ *Logical =mdl_priv->kvaddr;
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+_CMAUnmapKernel(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctPOINTER Logical
+ )
+{
+ return gcvSTATUS_OK;
+}
+
+extern gceSTATUS
+_DefaultLogicalToPhysical(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctPOINTER Logical,
+ IN gctUINT32 ProcessID,
+ OUT gctUINT32_PTR Physical
+ );
+
+extern gceSTATUS
+_DefaultCache(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Physical,
+ IN gctUINT32 Bytes,
+ IN gceCACHEOPERATION Operation
+ );
+
+gceSTATUS
+_CMAPhysical(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctUINT32 Offset,
+ OUT gctUINT32_PTR Physical
+ )
+{
+ struct mdl_cma_priv *mdl_priv=(struct mdl_cma_priv *)Mdl->priv;
+ gcmkASSERT(!Offset);
+ *Physical = mdl_priv->physical;
+
+ return gcvSTATUS_OK;
+}
+
+
+extern void
+_DefaultAllocatorDestructor(
+ IN void* PrivateData
+ );
+
+/* Default allocator operations. */
+gcsALLOCATOR_OPERATIONS CMAFSLAllocatorOperations = {
+ .Alloc = _CMAFSLAlloc,
+ .Free = _CMAFSLFree,
+ .MapUser = _CMAFSLMapUser,
+ .UnmapUser = _CMAUnmapUser,
+ .MapKernel = _CMAMapKernel,
+ .UnmapKernel = _CMAUnmapKernel,
+ .LogicalToPhysical = _DefaultLogicalToPhysical,
+ .Cache = _DefaultCache,
+ .Physical = _CMAPhysical,
+};
+
+/* Default allocator entry. */
+gceSTATUS
+_CMAFSLAlloctorInit(
+ IN gckOS Os,
+ OUT gckALLOCATOR * Allocator
+ )
+{
+ gceSTATUS status;
+ gckALLOCATOR allocator;
+ gcsCMA_PRIV_PTR priv = gcvNULL;
+
+ gcmkONERROR(
+ gckALLOCATOR_Construct(Os, &CMAFSLAllocatorOperations, &allocator));
+
+ priv = kzalloc(gcmSIZEOF(gcsCMA_PRIV), GFP_KERNEL | gcdNOWARN);
+
+ if (!priv)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ /* Register private data. */
+ allocator->privateData = priv;
+ allocator->privateDataDestructor = _DefaultAllocatorDestructor;
+
+ allocator->debugfsInit = _DefaultAllocatorDebugfsInit;
+ allocator->debugfsCleanup = _DefaultAllocatorDebugfsCleanup;
+
+ allocator->capability = gcvALLOC_FLAG_CONTIGUOUS;
+
+ *Allocator = allocator;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
--- /dev/null
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2014 by Vivante Corp.
+*
+* 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.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+#include "gc_hal_kernel_allocator.h"
+#include <linux/pagemap.h>
+#include <linux/seq_file.h>
+#include <linux/mman.h>
+#include <asm/atomic.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
+#include "gc_hal_kernel_allocator_array.h"
+#include "gc_hal_kernel_platform.h"
+
+#define _GC_OBJ_ZONE gcvZONE_OS
+
+typedef struct _gcsDEFAULT_PRIV * gcsDEFAULT_PRIV_PTR;
+typedef struct _gcsDEFAULT_PRIV {
+ gctUINT32 low;
+ gctUINT32 high;
+}
+gcsDEFAULT_PRIV;
+
+/******************************************************************************\
+************************** Default Allocator Debugfs ***************************
+\******************************************************************************/
+
+int gc_usage_show(struct seq_file* m, void* data)
+{
+ gcsINFO_NODE *node = m->private;
+ gckALLOCATOR Allocator = node->device;
+ gcsDEFAULT_PRIV_PTR priv = Allocator->privateData;
+
+ seq_printf(m, "low: %u bytes\n", priv->low);
+ seq_printf(m, "high: %u bytes\n", priv->high);
+
+ return 0;
+}
+
+static gcsINFO InfoList[] =
+{
+ {"lowHighUsage", gc_usage_show},
+};
+
+static void
+_DefaultAllocatorDebugfsInit(
+ IN gckALLOCATOR Allocator,
+ IN gckDEBUGFS_DIR Root
+ )
+{
+ gcmkVERIFY_OK(
+ gckDEBUGFS_DIR_Init(&Allocator->debugfsDir, Root->root, "default"));
+
+ gcmkVERIFY_OK(gckDEBUGFS_DIR_CreateFiles(
+ &Allocator->debugfsDir,
+ InfoList,
+ gcmCOUNTOF(InfoList),
+ Allocator
+ ));
+}
+
+static void
+_DefaultAllocatorDebugfsCleanup(
+ IN gckALLOCATOR Allocator
+ )
+{
+ gcmkVERIFY_OK(gckDEBUGFS_DIR_RemoveFiles(
+ &Allocator->debugfsDir,
+ InfoList,
+ gcmCOUNTOF(InfoList)
+ ));
+
+ gckDEBUGFS_DIR_Deinit(&Allocator->debugfsDir);
+}
+
+
+static void
+_NonContiguousFree(
+ IN struct page ** Pages,
+ IN gctUINT32 NumPages
+ )
+{
+ gctINT i;
+
+ gcmkHEADER_ARG("Pages=0x%X, NumPages=%d", Pages, NumPages);
+
+ gcmkASSERT(Pages != gcvNULL);
+
+ for (i = 0; i < NumPages; i++)
+ {
+ __free_page(Pages[i]);
+ }
+
+ if (is_vmalloc_addr(Pages))
+ {
+ vfree(Pages);
+ }
+ else
+ {
+ kfree(Pages);
+ }
+
+ gcmkFOOTER_NO();
+}
+
+static struct page **
+_NonContiguousAlloc(
+ IN gctUINT32 NumPages
+ )
+{
+ struct page ** pages;
+ struct page *p;
+ gctINT i, size;
+
+ gcmkHEADER_ARG("NumPages=%lu", NumPages);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
+ if (NumPages > totalram_pages)
+#else
+ if (NumPages > num_physpages)
+#endif
+ {
+ gcmkFOOTER_NO();
+ return gcvNULL;
+ }
+
+ size = NumPages * sizeof(struct page *);
+
+ pages = kmalloc(size, GFP_KERNEL | gcdNOWARN);
+
+ if (!pages)
+ {
+ pages = vmalloc(size);
+
+ if (!pages)
+ {
+ gcmkFOOTER_NO();
+ return gcvNULL;
+ }
+ }
+
+ for (i = 0; i < NumPages; i++)
+ {
+ p = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN);
+
+ if (!p)
+ {
+ _NonContiguousFree(pages, i);
+ gcmkFOOTER_NO();
+ return gcvNULL;
+ }
+
+ pages[i] = p;
+ }
+
+ gcmkFOOTER_ARG("pages=0x%X", pages);
+ return pages;
+}
+
+gctSTRING
+_CreateKernelVirtualMapping(
+ IN PLINUX_MDL Mdl
+ )
+{
+ gctSTRING addr = 0;
+ gctINT numPages = Mdl->numPages;
+
+#if gcdNONPAGED_MEMORY_CACHEABLE
+ if (Mdl->contiguous)
+ {
+ addr = page_address(Mdl->u.contiguousPages);
+ }
+ else
+ {
+ addr = vmap(Mdl->u.nonContiguousPages,
+ numPages,
+ 0,
+ PAGE_KERNEL);
+
+ /* Trigger a page fault. */
+ memset(addr, 0, numPages * PAGE_SIZE);
+ }
+#else
+ struct page ** pages;
+ gctBOOL free = gcvFALSE;
+ gctINT i;
+
+ if (Mdl->contiguous)
+ {
+ pages = kmalloc(sizeof(struct page *) * numPages, GFP_KERNEL | gcdNOWARN);
+
+ if (!pages)
+ {
+ return gcvNULL;
+ }
+
+ for (i = 0; i < numPages; i++)
+ {
+ pages[i] = nth_page(Mdl->u.contiguousPages, i);
+ }
+
+ free = gcvTRUE;
+ }
+ else
+ {
+ pages = Mdl->u.nonContiguousPages;
+ }
+
+ /* ioremap() can't work on system memory since 2.6.38. */
+ addr = vmap(pages, numPages, 0, gcmkNONPAGED_MEMROY_PROT(PAGE_KERNEL));
+
+ if (free)
+ {
+ kfree(pages);
+ }
+
+#endif
+
+ return addr;
+}
+
+void
+_DestoryKernelVirtualMapping(
+ IN gctSTRING Addr
+ )
+{
+#if !gcdNONPAGED_MEMORY_CACHEABLE
+ vunmap(Addr);
+#endif
+}
+
+void
+_UnmapUserLogical(
+ IN gctPOINTER Logical,
+ IN gctUINT32 Size
+)
+{
+ if (unlikely(current->mm == gcvNULL))
+ {
+ /* Do nothing if process is exiting. */
+ return;
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ if (vm_munmap((unsigned long)Logical, Size) < 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_WARNING, gcvZONE_OS,
+ "%s(%d): vm_munmap failed",
+ __FUNCTION__, __LINE__
+ );
+ }
+#else
+ down_write(¤t->mm->mmap_sem);
+ if (do_munmap(current->mm, (unsigned long)Logical, Size) < 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_WARNING, gcvZONE_OS,
+ "%s(%d): do_munmap failed",
+ __FUNCTION__, __LINE__
+ );
+ }
+ up_write(¤t->mm->mmap_sem);
+#endif
+}
+
+/***************************************************************************\
+************************ Default Allocator **********************************
+\***************************************************************************/
+#define C_MAX_PAGENUM (50*1024)
+static gceSTATUS
+_DefaultAlloc(
+ IN gckALLOCATOR Allocator,
+ INOUT PLINUX_MDL Mdl,
+ IN gctSIZE_T NumPages,
+ IN gctUINT32 Flags
+ )
+{
+ gceSTATUS status;
+ gctUINT32 order;
+ gctSIZE_T bytes;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+ gctPOINTER addr = gcvNULL;
+#endif
+ gctUINT32 numPages;
+ gctUINT i = 0;
+ gctBOOL contiguous = Flags & gcvALLOC_FLAG_CONTIGUOUS;
+ struct sysinfo temsysinfo;
+ gcsDEFAULT_PRIV_PTR priv = (gcsDEFAULT_PRIV_PTR)Allocator->privateData;
+
+ gcmkHEADER_ARG("Mdl=%p NumPages=%d", Mdl, NumPages);
+
+ numPages = NumPages;
+ bytes = NumPages * PAGE_SIZE;
+ order = get_order(bytes);
+
+ si_meminfo(&temsysinfo);
+
+ if (Flags & gcvALLOC_FLAG_MEMLIMIT)
+ {
+ if ( (temsysinfo.freeram < NumPages) || ((temsysinfo.freeram-NumPages) < C_MAX_PAGENUM) )
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+ }
+
+ if (contiguous)
+ {
+ if (order >= MAX_ORDER)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+ addr =
+ alloc_pages_exact(bytes, GFP_KERNEL | gcdNOWARN | __GFP_NORETRY);
+
+ Mdl->u.contiguousPages = addr
+ ? virt_to_page(addr)
+ : gcvNULL;
+
+ Mdl->exact = gcvTRUE;
+#else
+ Mdl->u.contiguousPages =
+ alloc_pages(GFP_KERNEL | gcdNOWARN | __GFP_NORETRY, order);
+#endif
+
+ if (Mdl->u.contiguousPages == gcvNULL)
+ {
+ Mdl->u.contiguousPages =
+ alloc_pages(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN, order);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+ Mdl->exact = gcvFALSE;
+#endif
+ }
+ }
+ else
+ {
+ Mdl->u.nonContiguousPages = _NonContiguousAlloc(numPages);
+ }
+
+ if (Mdl->u.contiguousPages == gcvNULL && Mdl->u.nonContiguousPages == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ for (i = 0; i < numPages; i++)
+ {
+ struct page *page;
+
+ if (contiguous)
+ {
+ page = nth_page(Mdl->u.contiguousPages, i);
+ }
+ else
+ {
+ page = _NonContiguousToPage(Mdl->u.nonContiguousPages, i);
+ }
+
+ SetPageReserved(page);
+
+ if (!PageHighMem(page) && page_to_phys(page))
+ {
+ gcmkVERIFY_OK(
+ gckOS_CacheFlush(Allocator->os, _GetProcessID(), gcvNULL,
+ page_to_phys(page),
+ page_address(page),
+ PAGE_SIZE));
+
+ priv->low += PAGE_SIZE;
+ }
+ else
+ {
+ flush_dcache_page(page);
+
+#if !gcdCACHE_FUNCTION_UNIMPLEMENTED && defined(CONFIG_OUTER_CACHE) && gcdENABLE_OUTER_CACHE_PATCH
+ if (page_to_phys(page))
+ {
+ _HandleOuterCache(
+ Allocator->os,
+ page_to_phys(page),
+ gcvNULL,
+ PAGE_SIZE,
+ gcvCACHE_FLUSH
+ );
+ }
+#endif
+
+ priv->high += PAGE_SIZE;
+ }
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+static void
+_DefaultFree(
+ IN gckALLOCATOR Allocator,
+ IN OUT PLINUX_MDL Mdl
+ )
+{
+ gctINT i;
+ struct page * page;
+ gcsDEFAULT_PRIV_PTR priv = (gcsDEFAULT_PRIV_PTR)Allocator->privateData;
+
+ for (i = 0; i < Mdl->numPages; i++)
+ {
+ if (Mdl->contiguous)
+ {
+ page = nth_page(Mdl->u.contiguousPages, i);
+ }
+ else
+ {
+ page = _NonContiguousToPage(Mdl->u.nonContiguousPages, i);
+ }
+
+ ClearPageReserved(page);
+
+ if (PageHighMem(page))
+ {
+ priv->high -= PAGE_SIZE;
+ }
+ else
+ {
+ priv->low -= PAGE_SIZE;
+ }
+ }
+
+ if (Mdl->contiguous)
+ {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+ if (Mdl->exact == gcvTRUE)
+ {
+ free_pages_exact(page_address(Mdl->u.contiguousPages), Mdl->numPages * PAGE_SIZE);
+ }
+ else
+#endif
+ {
+ __free_pages(Mdl->u.contiguousPages, get_order(Mdl->numPages * PAGE_SIZE));
+ }
+ }
+ else
+ {
+ _NonContiguousFree(Mdl->u.nonContiguousPages, Mdl->numPages);
+ }
+}
+
+gctINT
+_DefaultMapUser(
+ gckALLOCATOR Allocator,
+ PLINUX_MDL Mdl,
+ PLINUX_MDL_MAP MdlMap,
+ gctBOOL Cacheable
+ )
+{
+
+ gctSTRING addr;
+ unsigned long start;
+ unsigned long pfn;
+ gctINT i;
+ gckOS os = Allocator->os;
+ gcsPLATFORM * platform = os->device->platform;
+
+ PLINUX_MDL mdl = Mdl;
+ PLINUX_MDL_MAP mdlMap = MdlMap;
+
+ gcmkHEADER_ARG("Allocator=%p Mdl=%p MdlMap=%p gctBOOL=%d", Allocator, Mdl, MdlMap, Cacheable);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
+ mdlMap->vmaAddr = (gctSTRING)vm_mmap(gcvNULL,
+ 0L,
+ mdl->numPages * PAGE_SIZE,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ 0);
+#else
+ down_write(¤t->mm->mmap_sem);
+
+ mdlMap->vmaAddr = (gctSTRING)do_mmap_pgoff(gcvNULL,
+ 0L,
+ mdl->numPages * PAGE_SIZE,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ 0);
+
+ up_write(¤t->mm->mmap_sem);
+#endif
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): vmaAddr->0x%X for phys_addr->0x%X",
+ __FUNCTION__, __LINE__,
+ (gctUINT32)(gctUINTPTR_T)mdlMap->vmaAddr,
+ (gctUINT32)(gctUINTPTR_T)mdl
+ );
+
+ if (IS_ERR(mdlMap->vmaAddr))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): do_mmap_pgoff error",
+ __FUNCTION__, __LINE__
+ );
+
+ mdlMap->vmaAddr = gcvNULL;
+
+ gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
+ return gcvSTATUS_OUT_OF_MEMORY;
+ }
+
+ down_write(¤t->mm->mmap_sem);
+
+ mdlMap->vma = find_vma(current->mm, (unsigned long)mdlMap->vmaAddr);
+
+ if (mdlMap->vma == gcvNULL)
+ {
+ up_write(¤t->mm->mmap_sem);
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): find_vma error",
+ __FUNCTION__, __LINE__
+ );
+
+ mdlMap->vmaAddr = gcvNULL;
+
+ gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_RESOURCES);
+ return gcvSTATUS_OUT_OF_RESOURCES;
+ }
+
+ mdlMap->vma->vm_flags |= gcdVM_FLAGS;
+
+ if (Cacheable == gcvFALSE)
+ {
+ /* Make this mapping non-cached. */
+ mdlMap->vma->vm_page_prot = gcmkPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot);
+ }
+
+ if (platform && platform->ops->adjustProt)
+ {
+ platform->ops->adjustProt(mdlMap->vma);
+ }
+
+ addr = mdl->addr;
+
+ /* Now map all the vmalloc pages to this user address. */
+ if (mdl->contiguous)
+ {
+ /* map kernel memory to user space.. */
+ if (remap_pfn_range(mdlMap->vma,
+ mdlMap->vma->vm_start,
+ page_to_pfn(mdl->u.contiguousPages),
+ mdlMap->vma->vm_end - mdlMap->vma->vm_start,
+ mdlMap->vma->vm_page_prot) < 0)
+ {
+ up_write(¤t->mm->mmap_sem);
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): unable to mmap ret",
+ __FUNCTION__, __LINE__
+ );
+
+ mdlMap->vmaAddr = gcvNULL;
+
+ gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
+ return gcvSTATUS_OUT_OF_MEMORY;
+ }
+ }
+ else
+ {
+ start = mdlMap->vma->vm_start;
+
+ for (i = 0; i < mdl->numPages; i++)
+ {
+ pfn = _NonContiguousToPfn(mdl->u.nonContiguousPages, i);
+
+ if (remap_pfn_range(mdlMap->vma,
+ start,
+ pfn,
+ PAGE_SIZE,
+ mdlMap->vma->vm_page_prot) < 0)
+ {
+ up_write(¤t->mm->mmap_sem);
+
+ mdlMap->vmaAddr = gcvNULL;
+
+ gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
+ return gcvSTATUS_OUT_OF_MEMORY;
+ }
+
+ start += PAGE_SIZE;
+ addr += PAGE_SIZE;
+ }
+ }
+
+ up_write(¤t->mm->mmap_sem);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+void
+_DefaultUnmapUser(
+ IN gckALLOCATOR Allocator,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Size
+ )
+{
+ _UnmapUserLogical(Logical, Size);
+}
+
+gceSTATUS
+_DefaultMapKernel(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ OUT gctPOINTER *Logical
+ )
+{
+ *Logical = _CreateKernelVirtualMapping(Mdl);
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+_DefaultUnmapKernel(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctPOINTER Logical
+ )
+{
+ _DestoryKernelVirtualMapping(Logical);
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+_DefaultLogicalToPhysical(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctPOINTER Logical,
+ IN gctUINT32 ProcessID,
+ OUT gctUINT32_PTR Physical
+ )
+{
+ return _ConvertLogical2Physical(
+ Allocator->os, Logical, ProcessID, Mdl, Physical);
+}
+
+gceSTATUS
+_DefaultCache(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Physical,
+ IN gctUINT32 Bytes,
+ IN gceCACHEOPERATION Operation
+ )
+{
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+_DefaultPhysical(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctUINT32 Offset,
+ OUT gctUINT32_PTR Physical
+ )
+{
+ gcmkASSERT(Mdl->pagedMem && !Mdl->contiguous);
+ *Physical = _NonContiguousToPhys(Mdl->u.nonContiguousPages, Offset);
+
+ return gcvSTATUS_OK;
+}
+
+void
+_DefaultAllocatorDestructor(
+ IN void* PrivateData
+ )
+{
+ kfree(PrivateData);
+}
+
+/* Default allocator operations. */
+gcsALLOCATOR_OPERATIONS DefaultAllocatorOperations = {
+ .Alloc = _DefaultAlloc,
+ .Free = _DefaultFree,
+ .MapUser = _DefaultMapUser,
+ .UnmapUser = _DefaultUnmapUser,
+ .MapKernel = _DefaultMapKernel,
+ .UnmapKernel = _DefaultUnmapKernel,
+ .LogicalToPhysical = _DefaultLogicalToPhysical,
+ .Cache = _DefaultCache,
+ .Physical = _DefaultPhysical,
+};
+
+/* Default allocator entry. */
+gceSTATUS
+_DefaultAlloctorInit(
+ IN gckOS Os,
+ OUT gckALLOCATOR * Allocator
+ )
+{
+ gceSTATUS status;
+ gckALLOCATOR allocator;
+ gcsDEFAULT_PRIV_PTR priv = gcvNULL;
+
+ gcmkONERROR(
+ gckALLOCATOR_Construct(Os, &DefaultAllocatorOperations, &allocator));
+
+ priv = kzalloc(gcmSIZEOF(gcsDEFAULT_PRIV), GFP_KERNEL | gcdNOWARN);
+
+ if (!priv)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ /* Register private data. */
+ allocator->privateData = priv;
+ allocator->privateDataDestructor = _DefaultAllocatorDestructor;
+
+ allocator->debugfsInit = _DefaultAllocatorDebugfsInit;
+ allocator->debugfsCleanup = _DefaultAllocatorDebugfsCleanup;
+
+ *Allocator = allocator;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+/***************************************************************************\
+************************ Allocator helper ***********************************
+\***************************************************************************/
+
+gceSTATUS
+gckALLOCATOR_Construct(
+ IN gckOS Os,
+ IN gcsALLOCATOR_OPERATIONS * Operations,
+ OUT gckALLOCATOR * Allocator
+ )
+{
+ gceSTATUS status;
+ gckALLOCATOR allocator;
+
+ gcmkHEADER_ARG("Os=%p, Operations=%p, Allocator=%p",
+ Os, Operations, Allocator);
+
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Allocator != gcvNULL);
+ gcmkVERIFY_ARGUMENT
+ ( Operations
+ && Operations->Alloc
+ && Operations->Free
+ && Operations->MapUser
+ && Operations->UnmapUser
+ && Operations->MapKernel
+ && Operations->UnmapKernel
+ && Operations->LogicalToPhysical
+ && Operations->Cache
+ && Operations->Physical
+ );
+
+ gcmkONERROR(
+ gckOS_Allocate(Os, gcmSIZEOF(gcsALLOCATOR), (gctPOINTER *)&allocator));
+
+ gckOS_ZeroMemory(allocator, gcmSIZEOF(gcsALLOCATOR));
+
+ /* Record os. */
+ allocator->os = Os;
+
+ /* Set operations. */
+ allocator->ops = Operations;
+
+ allocator->capability = gcvALLOC_FLAG_CONTIGUOUS
+ | gcvALLOC_FLAG_NON_CONTIGUOUS
+ | gcvALLOC_FLAG_CACHEABLE
+ | gcvALLOC_FLAG_MEMLIMIT;
+ ;
+
+ *Allocator = allocator;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+/******************************************************************************\
+******************************** Debugfs Support *******************************
+\******************************************************************************/
+
+static gceSTATUS
+_AllocatorDebugfsInit(
+ IN gckOS Os
+ )
+{
+ gceSTATUS status;
+ gckGALDEVICE device = Os->device;
+
+ gckDEBUGFS_DIR dir = &Os->allocatorDebugfsDir;
+
+ gcmkONERROR(gckDEBUGFS_DIR_Init(dir, device->debugfsDir.root, "allocators"));
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+static void
+_AllocatorDebugfsCleanup(
+ IN gckOS Os
+ )
+{
+ gckDEBUGFS_DIR dir = &Os->allocatorDebugfsDir;
+
+ gckDEBUGFS_DIR_Deinit(dir);
+}
+
+/***************************************************************************\
+************************ Allocator management *******************************
+\***************************************************************************/
+
+gceSTATUS
+gckOS_ImportAllocators(
+ gckOS Os
+ )
+{
+ gceSTATUS status;
+ gctUINT i;
+ gckALLOCATOR allocator;
+
+ _AllocatorDebugfsInit(Os);
+
+ INIT_LIST_HEAD(&Os->allocatorList);
+
+ for (i = 0; i < gcmCOUNTOF(allocatorArray); i++)
+ {
+ if (allocatorArray[i].construct)
+ {
+ /* Construct allocator. */
+ status = allocatorArray[i].construct(Os, &allocator);
+
+ if (gcmIS_ERROR(status))
+ {
+ gcmkPRINT("["DEVICE_NAME"]: Can't construct allocator(%s)",
+ allocatorArray[i].name);
+
+ continue;
+ }
+
+ allocator->name = allocatorArray[i].name;
+
+ if (allocator->debugfsInit)
+ {
+ /* Init allocator's debugfs. */
+ allocator->debugfsInit(allocator, &Os->allocatorDebugfsDir);
+ }
+
+ list_add_tail(&allocator->head, &Os->allocatorList);
+ }
+ }
+
+#if gcdDEBUG
+ list_for_each_entry(allocator, &Os->allocatorList, head)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_WARNING, gcvZONE_OS,
+ "%s(%d) Allocator: %s",
+ __FUNCTION__, __LINE__,
+ allocator->name
+ );
+ }
+#endif
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_FreeAllocators(
+ gckOS Os
+ )
+{
+ gckALLOCATOR allocator;
+ gckALLOCATOR temp;
+
+ list_for_each_entry_safe(allocator, temp, &Os->allocatorList, head)
+ {
+ list_del(&allocator->head);
+
+ if (allocator->debugfsCleanup)
+ {
+ /* Clean up allocator's debugfs. */
+ allocator->debugfsCleanup(allocator);
+ }
+
+ /* Free private data. */
+ if (allocator->privateDataDestructor && allocator->privateData)
+ {
+ allocator->privateDataDestructor(allocator->privateData);
+ }
+
+ gckOS_Free(Os, allocator);
+ }
+
+ _AllocatorDebugfsCleanup(Os);
+
+ return gcvSTATUS_OK;
+}
+
--- /dev/null
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2014 by Vivante Corp.
+*
+* 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.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_allocator_h_
+#define __gc_hal_kernel_allocator_h_
+
+#include "gc_hal_kernel_linux.h"
+
+typedef struct _gcsALLOCATOR * gckALLOCATOR;
+
+typedef struct _gcsALLOCATOR_OPERATIONS
+{
+ /**************************************************************************
+ **
+ ** Alloc
+ **
+ ** Allocte memory, request size is page aligned.
+ **
+ ** INPUT:
+ **
+ ** gckALLOCATOR Allocator
+ ** Pointer to an gckALLOCATOER object.
+ **
+ ** PLINUX_Mdl
+ ** Pointer to Mdl whichs stores information
+ ** about allocated memory.
+ **
+ ** gctSIZE_T NumPages
+ ** Number of pages need to allocate.
+ **
+ ** gctUINT32 Flag
+ ** Allocation option.
+ **
+ ** OUTPUT:
+ **
+ ** Nothing.
+ **
+ */
+ gceSTATUS
+ (*Alloc)(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctSIZE_T NumPages,
+ IN gctUINT32 Flag
+ );
+
+ /**************************************************************************
+ **
+ ** Free
+ **
+ ** Free memory.
+ **
+ ** INPUT:
+ **
+ ** gckALLOCATOR Allocator
+ ** Pointer to an gckALLOCATOER object.
+ **
+ ** PLINUX_MDL Mdl
+ ** Mdl which stores information.
+ **
+ ** OUTPUT:
+ **
+ ** Nothing.
+ **
+ */
+ void
+ (*Free)(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl
+ );
+
+ /**************************************************************************
+ **
+ ** MapUser
+ **
+ ** Map memory to user space.
+ **
+ ** INPUT:
+ ** gckALLOCATOR Allocator
+ ** Pointer to an gckALLOCATOER object.
+ **
+ ** PLINUX_MDL Mdl
+ ** Pointer to a Mdl.
+ **
+ ** PLINUX_MDL_MAP MdlMap
+ ** Pointer to a MdlMap, mapped address is stored
+ ** in MdlMap->vmaAddr
+ **
+ ** gctBOOL Cacheable
+ ** Whether this mapping is cacheable.
+ **
+ ** OUTPUT:
+ **
+ ** Nothing.
+ **
+ */
+ gctINT
+ (*MapUser)(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN PLINUX_MDL_MAP MdlMap,
+ IN gctBOOL Cacheable
+ );
+
+ /**************************************************************************
+ **
+ ** UnmapUser
+ **
+ ** Unmap address from user address space.
+ **
+ ** INPUT:
+ ** gckALLOCATOR Allocator
+ ** Pointer to an gckALLOCATOER object.
+ **
+ ** gctPOINTER Logical
+ ** Address to be unmap
+ **
+ ** gctUINT32 Size
+ ** Size of address space
+ **
+ ** OUTPUT:
+ **
+ ** Nothing.
+ **
+ */
+ void
+ (*UnmapUser)(
+ IN gckALLOCATOR Allocator,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Size
+ );
+
+ /**************************************************************************
+ **
+ ** MapKernel
+ **
+ ** Map memory to kernel space.
+ **
+ ** INPUT:
+ ** gckALLOCATOR Allocator
+ ** Pointer to an gckALLOCATOER object.
+ **
+ ** PLINUX_MDL Mdl
+ ** Pointer to a Mdl object.
+ **
+ ** OUTPUT:
+ ** gctPOINTER * Logical
+ ** Mapped kernel address.
+ */
+ gceSTATUS
+ (*MapKernel)(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ OUT gctPOINTER *Logical
+ );
+
+ /**************************************************************************
+ **
+ ** UnmapKernel
+ **
+ ** Unmap memory from kernel space.
+ **
+ ** INPUT:
+ ** gckALLOCATOR Allocator
+ ** Pointer to an gckALLOCATOER object.
+ **
+ ** PLINUX_MDL Mdl
+ ** Pointer to a Mdl object.
+ **
+ ** gctPOINTER Logical
+ ** Mapped kernel address.
+ **
+ ** OUTPUT:
+ **
+ ** Nothing.
+ **
+ */
+ gceSTATUS
+ (*UnmapKernel)(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctPOINTER Logical
+ );
+
+ /**************************************************************************
+ **
+ ** LogicalToPhysical
+ **
+ ** Get physical address from logical address, logical
+ ** address could be user virtual address or kernel
+ ** virtual address.
+ **
+ ** INPUT:
+ ** gckALLOCATOR Allocator
+ ** Pointer to an gckALLOCATOER object.
+ **
+ ** PLINUX_MDL Mdl
+ ** Pointer to a Mdl object.
+ **
+ ** gctPOINTER Logical
+ ** Mapped kernel address.
+ **
+ ** gctUINT32 ProcessID
+ ** pid of current process.
+ ** OUTPUT:
+ **
+ ** gctUINT32_PTR Physical
+ ** Physical address.
+ **
+ */
+ gceSTATUS
+ (*LogicalToPhysical)(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctPOINTER Logical,
+ IN gctUINT32 ProcessID,
+ OUT gctUINT32_PTR Physical
+ );
+
+ /**************************************************************************
+ **
+ ** Cache
+ **
+ ** Maintain cache coherency.
+ **
+ ** INPUT:
+ ** gckALLOCATOR Allocator
+ ** Pointer to an gckALLOCATOER object.
+ **
+ ** PLINUX_MDL Mdl
+ ** Pointer to a Mdl object.
+ **
+ ** gctPOINTER Logical
+ ** Logical address, could be user address or kernel address
+ **
+ ** gctUINT32_PTR Physical
+ ** Physical address.
+ **
+ ** gctUINT32 Bytes
+ ** Size of memory region.
+ **
+ ** gceCACHEOPERATION Opertaion
+ ** Cache operation.
+ **
+ ** OUTPUT:
+ **
+ ** Nothing.
+ **
+ */
+ gceSTATUS (*Cache)(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Physical,
+ IN gctUINT32 Bytes,
+ IN gceCACHEOPERATION Operation
+ );
+
+ /**************************************************************************
+ **
+ ** Physical
+ **
+ ** Get physical address from a offset in memory region.
+ **
+ ** INPUT:
+ ** gckALLOCATOR Allocator
+ ** Pointer to an gckALLOCATOER object.
+ **
+ ** PLINUX_MDL Mdl
+ ** Pointer to a Mdl object.
+ **
+ ** gctUINT32 Offset
+ ** Offset in this memory region.
+ **
+ ** OUTPUT:
+ ** gctUINT32_PTR Physical
+ ** Physical address.
+ **
+ */
+ gceSTATUS (*Physical)(
+ IN gckALLOCATOR Allocator,
+ IN PLINUX_MDL Mdl,
+ IN gctUINT32 Offset,
+ OUT gctUINT32_PTR Physical
+ );
+}
+gcsALLOCATOR_OPERATIONS;
+
+typedef struct _gcsALLOCATOR
+{
+ /* Pointer to gckOS Object. */
+ gckOS os;
+
+ /* Name. */
+ gctSTRING name;
+
+ /* Operations. */
+ gcsALLOCATOR_OPERATIONS* ops;
+
+ /* Capability of this allocator. */
+ gctUINT32 capability;
+
+ struct list_head head;
+
+ /* Debugfs entry of this allocator. */
+ gcsDEBUGFS_DIR debugfsDir;
+
+ /* Init allocator debugfs. */
+ void (*debugfsInit)(gckALLOCATOR, gckDEBUGFS_DIR);
+
+ /* Cleanup allocator debugfs. */
+ void (*debugfsCleanup)(gckALLOCATOR);
+
+ /* Private data used by customer allocator. */
+ void * privateData;
+
+ /* Private data destructor. */
+ void (*privateDataDestructor)(void *);
+}
+gcsALLOCATOR;
+
+typedef struct _gcsALLOCATOR_DESC
+{
+ /* Name of a allocator. */
+ char * name;
+
+ /* Entry function to construct a allocator. */
+ gceSTATUS (*construct)(gckOS, gckALLOCATOR *);
+}
+gcsALLOCATOR_DESC;
+
+/*
+* Helpers
+*/
+
+/* Fill a gcsALLOCATOR_DESC structure. */
+#define gcmkDEFINE_ALLOCATOR_DESC(Name, Construct) \
+ { \
+ .name = Name, \
+ .construct = Construct, \
+ }
+
+/* Construct a allocator. */
+gceSTATUS
+gckALLOCATOR_Construct(
+ IN gckOS Os,
+ IN gcsALLOCATOR_OPERATIONS * Operations,
+ OUT gckALLOCATOR * Allocator
+ );
+
+/*
+ How to implement customer allocator
+
+ Build in customer alloctor
+
+ It is recommanded that customer allocator is implmented in independent
+ source file(s) which is specified by CUSOMTER_ALLOCATOR_OBJS in Kbuld.
+
+ Register gcsALLOCATOR
+
+ For each customer specified allocator, a desciption entry must be added
+ to allocatorArray defined in gc_hal_kernel_allocator_array.h.
+
+ An entry in allocatorArray is a gcsALLOCATOR_DESC structure which describes
+ name and constructor of a gckALLOCATOR object.
+
+
+ Implement gcsALLOCATOR_DESC.init()
+
+ In gcsALLOCATOR_DESC.init(), gckALLOCATOR_Construct should be called
+ to create a gckALLOCATOR object, customer specified private data can
+ be put in gcsALLOCATOR.privateData.
+
+
+ Implement gcsALLOCATOR_OPERATIONS
+
+ When call gckALLOCATOR_Construct to create a gckALLOCATOR object, a
+ gcsALLOCATOR_OPERATIONS structure must be provided whose all members
+ implemented.
+
+*/
+#endif
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#define gcmkARGUMENTS_END(Arguments) \
va_end(Arguments)
+#define gcmkARGUMENTS_ARG(Arguments, Type) \
+ va_arg(Arguments, Type)
+
#define gcmkDECLARE_LOCK(__spinLock__) \
- static DEFINE_SPINLOCK(__spinLock__);
+ static DEFINE_SPINLOCK(__spinLock__); \
+ unsigned long __spinLock__##flags = 0;
#define gcmkLOCKSECTION(__spinLock__) \
- spin_lock(&__spinLock__)
+ spin_lock_irqsave(&__spinLock__, __spinLock__##flags)
#define gcmkUNLOCKSECTION(__spinLock__) \
- spin_unlock(&__spinLock__)
+ spin_unlock_irqrestore(&__spinLock__, __spinLock__##flags)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
# define gcmkGETPROCESSID() \
#endif
#define gcmkOUTPUT_STRING(String) \
- if(gckDebugFileSystemIsEnabled()) \
- gckDebugFileSystemPrint(String);\
- else\
- printk(String); \
+ if(gckDEBUGFS_IsEnabled()) {\
+ while(-ERESTARTSYS == gckDEBUGFS_Print(String));\
+ }else{\
+ printk(String); \
+ }\
touch_softlockup_watchdog()
snprintf(Destination, Size, Message, Value1, Value2, Value3)
#define gcmkVSPRINTF(Destination, Size, Message, Arguments) \
- vsnprintf(Destination, Size, Message, *(va_list *) &Arguments)
+ vsnprintf(Destination, Size, Message, *((va_list*)Arguments))
#define gcmkSTRCAT(Destination, Size, String) \
strncat(Destination, String, Size)
+#define gcmkMEMCPY(Destination, Source, Size) \
+ memcpy(Destination, Source, Size)
+
+#define gcmkSTRLEN(String) \
+ strlen(String)
+
/* If not zero, forces data alignment in the variable argument list
by its individual size. */
#define gcdALIGNBYSIZE 1
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#include <linux/poll.h>
#include <asm/uaccess.h>
#include <linux/completion.h>
+#include <linux/seq_file.h>
#include "gc_hal_kernel_linux.h"
+#include "gc_hal_kernel.h"
/*
Prequsite:
2.a)If the debugfs is not mounted, you must do "mount -t debugfs none /sys/kernel/debug"
3) To read what is being printed in the debugfs file system:
- Ex : cat /sys/kernel/debug/gpu/galcore_trace
+ Ex : cat /sys/kernel/debug/gc/galcore_trace
4)To write into the debug file system from user side :
- Ex: echo "hello" > cat /sys/kernel/debug/gpu/galcore_trace
+ Ex: echo "hello" > cat /sys/kernel/debug/gc/galcore_trace
- 5)To write into debugfs from kernel side, Use the function called gckDebugFileSystemPrint
+ 5)To write into debugfs from kernel side, Use the function called gckDEBUGFS_Print
+ How to Get Video Memory Usage:
+ 1) Select a process whose video memory usage can be dump, no need to reset it until <pid> is needed to be change.
+ echo <pid> > /sys/kernel/debug/gc/vidmem
+
+ 2) Get video memory usage.
+ cat /sys/kernel/debug/gc/vidmem
USECASE Kernel Dump:
/**/
typedef va_list gctDBGARGS ;
#define gcmkARGS_START(argument, pointer) va_start(argument, pointer)
-#define gcmkARGS_END(argument) va_end(argument)
+#define gcmkARGS_END(argument) va_end(argument)
-#define gcmkDBGFSPRINT(ArgumentSize, Message) \
+#define gcmkDEBUGFS_PRINT(ArgumentSize, Message) \
{ \
- gctDBGARGS __arguments__; \
- gcmkARGS_START(__arguments__, Message); \
- _DebugFSPrint(ArgumentSize, Message, __arguments__);\
- gcmkARGS_END(__arguments__); \
+ gctDBGARGS __arguments__; \
+ gcmkARGS_START(__arguments__, Message); \
+ _debugfs_res = _DebugFSPrint(ArgumentSize, Message, &__arguments__);\
+ gcmkARGS_END(__arguments__); \
}
-/*Debug File System Node Struct*/
-struct _gcsDebugFileSystemNode
+/* Debug File System Node Struct. */
+struct _gcsDEBUGFS_Node
{
/*wait queues for read and write operations*/
#if defined(DECLARE_WAIT_QUEUE_HEAD)
#endif
struct dentry *parent ; /*parent directory*/
struct dentry *filen ; /*filename*/
+ struct dentry *vidmem;
struct semaphore sem ; /* mutual exclusion semaphore */
char *data ; /* The circular buffer data */
int size ; /* Size of the buffer pointed to by 'data' */
int read_point ; /* Offset in circ. buffer of oldest data */
int write_point ; /* Offset in circ. buffer of newest data */
int offset ; /* Byte number of read_point in the stream */
- struct _gcsDebugFileSystemNode *next ;
-} ;
+ struct _gcsDEBUGFS_Node *next ;
+};
/* amount of data in the queue */
#define gcmkNODE_QLEN(node) ( (node)->write_point >= (node)->read_point ? \
#define gcmkMIN(x, y) ((x) < (y) ? (x) : y)
/*Debug File System Struct*/
-typedef struct _gcsDebugFileSystem
+typedef struct _gcsDEBUGFS_
{
- gcsDebugFileSystemNode* linkedlist ;
- gcsDebugFileSystemNode* currentNode ;
+ gcsDEBUGFS_Node* linkedlist ;
+ gcsDEBUGFS_Node* currentNode ;
int isInited ;
-} gcsDebugFileSystem ;
-
+} gcsDEBUGFS_ ;
/*debug file system*/
-static gcsDebugFileSystem gc_dbgfs ;
+static gcsDEBUGFS_ gc_dbgfs ;
+
+static int gc_debugfs_open(struct inode *inode, struct file *file)
+{
+ gcsINFO_NODE *node = inode->i_private;
+
+ return single_open(file, node->info->show, node);
+}
+
+static const struct file_operations gc_debugfs_operations = {
+ .owner = THIS_MODULE,
+ .open = gc_debugfs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+gceSTATUS
+gckDEBUGFS_DIR_Init(
+ IN gckDEBUGFS_DIR Dir,
+ IN struct dentry *root,
+ IN gctCONST_STRING Name
+ )
+{
+ Dir->root = debugfs_create_dir(Name, root);
+
+ if (!Dir->root)
+ {
+ return gcvSTATUS_NOT_SUPPORTED;
+ }
+
+ INIT_LIST_HEAD(&Dir->nodeList);
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckDEBUGFS_DIR_CreateFiles(
+ IN gckDEBUGFS_DIR Dir,
+ IN gcsINFO * List,
+ IN int count,
+ IN gctPOINTER Data
+ )
+{
+ int i;
+ gcsINFO_NODE * node;
+ gceSTATUS status;
+
+ for (i = 0; i < count; i++)
+ {
+ /* Create a node. */
+ node = (gcsINFO_NODE *)kzalloc(sizeof(gcsINFO_NODE), GFP_KERNEL);
+
+ node->info = &List[i];
+ node->device = Data;
+ /* Bind to a file. TODO: clean up when fail. */
+ node->entry = debugfs_create_file(
+ List[i].name, S_IRUGO|S_IWUSR, Dir->root, node, &gc_debugfs_operations);
+ if (!node->entry)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ list_add(&(node->head), &(Dir->nodeList));
+ }
+
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkVERIFY_OK(gckDEBUGFS_DIR_RemoveFiles(Dir, List, count));
+ return status;
+}
+
+gceSTATUS
+gckDEBUGFS_DIR_RemoveFiles(
+ IN gckDEBUGFS_DIR Dir,
+ IN gcsINFO * List,
+ IN int count
+ )
+{
+ int i;
+ gcsINFO_NODE * node;
+ gcsINFO_NODE * temp;
+
+ for (i = 0; i < count; i++)
+ {
+ list_for_each_entry_safe(node, temp, &Dir->nodeList, head)
+ {
+ if (node->info == &List[i])
+ {
+ debugfs_remove(node->entry);
+ list_del(&node->head);
+ kfree(node);
+ }
+ }
+ }
+
+ return gcvSTATUS_OK;
+}
+
+void
+gckDEBUGFS_DIR_Deinit(
+ IN gckDEBUGFS_DIR Dir
+ )
+{
+ if (Dir->root != NULL)
+ {
+ debugfs_remove(Dir->root);
+ Dir->root = NULL;
+ }
+}
/*******************************************************************************
**
- ** READ & WRITE FUNCTIONS (START)
+ ** READ & WRITE FUNCTIONS (START)
**
*******************************************************************************/
**
** _ReadFromNode
**
- ** 1) reading bytes out of a circular buffer with wraparound.
- ** 2)returns caddr_t, pointer to data read, which the caller must free.
- ** 3) length is (a pointer to) the number of bytes to be read, which will be set by this function to
- ** be the number of bytes actually returned
+ ** 1) reading bytes out of a circular buffer with wraparound.
+ ** 2)returns caddr_t, pointer to data read, which the caller must free.
+ ** 3) length is (a pointer to) the number of bytes to be read, which will be set by this function to
+ ** be the number of bytes actually returned
**
*******************************************************************************/
static caddr_t
_ReadFromNode (
- gcsDebugFileSystemNode* Node ,
+ gcsDEBUGFS_Node* Node ,
size_t *Length ,
loff_t *Offset
)
*********************************************************************************/
static void
_WriteToNode (
- gcsDebugFileSystemNode* Node ,
+ gcsDEBUGFS_Node* Node ,
caddr_t Buf ,
int Length
)
/* in case of overflow, figure out where the new buffer will
* begin. we start by figuring out where the current buffer ENDS:
- * node->parent->offset + gcmkNODE_QLEN. we then advance the end-offset
+ * node->parent->offset + gcmkNODE_QLEN. we then advance the end-offset
* by the Length of the current write, and work backwards to
* figure out what the oldest unoverwritten data will be (i.e.,
* size of the buffer). */
}
}
-
/*******************************************************************************
**
- ** PRINTING UTILITY (START)
+ ** PRINTING UTILITY (START)
**
*******************************************************************************/
*******************************************************************************/
static ssize_t
_AppendString (
- IN gcsDebugFileSystemNode* Node ,
+ IN gcsDEBUGFS_Node* Node ,
IN gctCONST_STRING String ,
IN int Length
)
**
**
*******************************************************************************/
-static void
+static ssize_t
_DebugFSPrint (
IN unsigned int ArgumentSize ,
IN const char* Message ,
- IN gctDBGARGS Arguments
+ IN gctDBGARGS * Arguments
)
{
char buffer[MAX_LINE_SIZE] ;
int len ;
- down ( gcmkNODE_SEM ( gc_dbgfs.currentNode ) ) ;
- len = vsnprintf ( buffer , sizeof (buffer ) , Message , *( va_list * ) & Arguments ) ;
+ ssize_t res=0;
+
+ if(in_interrupt())
+ {
+ return - ERESTARTSYS ;
+ }
+
+ if(down_interruptible( gcmkNODE_SEM ( gc_dbgfs.currentNode ) ) )
+ {
+ return - ERESTARTSYS ;
+ }
+ len = vsnprintf ( buffer , sizeof (buffer ) , Message , *( va_list * ) Arguments ) ;
buffer[len] = '\0' ;
/* Add end-of-line if missing. */
buffer[len ++] = '\n' ;
buffer[len] = '\0' ;
}
- _AppendString ( gc_dbgfs.currentNode , buffer , len ) ;
+ res = _AppendString ( gc_dbgfs.currentNode , buffer , len ) ;
up ( gcmkNODE_SEM ( gc_dbgfs.currentNode ) ) ;
wake_up_interruptible ( gcmkNODE_READQ ( gc_dbgfs.currentNode ) ) ; /* blocked in read*/
+ return res;
}
/*******************************************************************************
/*******************************************************************************
**
** find the vivlog structure associated with an inode.
- ** returns a pointer to the structure if found, NULL if not found
+ ** returns a pointer to the structure if found, NULL if not found
**
*******************************************************************************/
-static gcsDebugFileSystemNode*
+static gcsDEBUGFS_Node*
_GetNodeInfo (
IN struct inode *Inode
)
{
- gcsDebugFileSystemNode* node ;
+ gcsDEBUGFS_Node* node ;
if ( Inode == NULL )
return NULL ;
{
int retval ;
caddr_t data_to_return ;
- gcsDebugFileSystemNode* node ;
+ gcsDEBUGFS_Node* node ;
/* get the metadata about this emlog */
if ( ( node = _GetNodeInfo ( file->f_dentry->d_inode ) ) == NULL )
{
{
caddr_t message = NULL ;
int n ;
- gcsDebugFileSystemNode*node ;
+ gcsDEBUGFS_Node*node ;
/* get the metadata about this log */
if ( ( node = _GetNodeInfo ( file->f_dentry->d_inode ) ) == NULL )
return - ENOMEM ;
}
+
/* copy into our temp buffer */
if ( copy_from_user ( message , buffer , n ) > 0 )
{
return n ;
}
+int dumpProcess = 0;
+
+void
+_PrintCounter(
+ struct seq_file *file,
+ gcsDATABASE_COUNTERS * counter,
+ gctCONST_STRING Name
+ )
+{
+ seq_printf(file,"Counter: %s\n", Name);
+
+ seq_printf(file,"%-9s%10s","", "All");
+
+ seq_printf(file, "\n");
+
+ seq_printf(file,"%-9s","Current");
+
+ seq_printf(file,"%10lld", counter->bytes);
+
+ seq_printf(file, "\n");
+
+ seq_printf(file,"%-9s","Maximum");
+
+ seq_printf(file,"%10lld", counter->maxBytes);
+
+ seq_printf(file, "\n");
+
+ seq_printf(file,"%-9s","Total");
+
+ seq_printf(file,"%10lld", counter->totalBytes);
+
+ seq_printf(file, "\n");
+}
+
+void
+_ShowCounters(
+ struct seq_file *file,
+ gcsDATABASE_PTR database
+ )
+{
+ gctUINT i = 0;
+ gcsDATABASE_COUNTERS * counter;
+ gcsDATABASE_COUNTERS * nonPaged;
+
+ static gctCONST_STRING surfaceTypes[] = {
+ "UNKNOWN",
+ "Index",
+ "Vertex",
+ "Texture",
+ "RT",
+ "Depth",
+ "Bitmap",
+ "TS",
+ "Image",
+ "Mask",
+ "Scissor",
+ "HZDepth",
+ };
+
+ /* Get pointer to counters. */
+ counter = &database->vidMem;
+
+ nonPaged = &database->nonPaged;
+
+ seq_printf(file,"Counter: vidMem (for each surface type)\n");
+
+ seq_printf(file,"%-9s%10s","", "All");
+
+ for (i = 1; i < gcvSURF_NUM_TYPES; i++)
+ {
+ counter = &database->vidMemType[i];
+
+ seq_printf(file, "%10s",surfaceTypes[i]);
+ }
+
+ seq_printf(file, "\n");
+
+ seq_printf(file,"%-9s","Current");
+
+ seq_printf(file,"%10lld", database->vidMem.bytes);
+
+ for (i = 1; i < gcvSURF_NUM_TYPES; i++)
+ {
+ counter = &database->vidMemType[i];
+
+ seq_printf(file,"%10lld", counter->bytes);
+ }
+
+ seq_printf(file, "\n");
+
+ seq_printf(file,"%-9s","Maximum");
+
+ seq_printf(file,"%10lld", database->vidMem.maxBytes);
+
+ for (i = 1; i < gcvSURF_NUM_TYPES; i++)
+ {
+ counter = &database->vidMemType[i];
+
+ seq_printf(file,"%10lld", counter->maxBytes);
+ }
+
+ seq_printf(file, "\n");
+
+ seq_printf(file,"%-9s","Total");
+
+ seq_printf(file,"%10lld", database->vidMem.totalBytes);
+
+ for (i = 1; i < gcvSURF_NUM_TYPES; i++)
+ {
+ counter = &database->vidMemType[i];
+
+ seq_printf(file,"%10lld", counter->totalBytes);
+ }
+
+ seq_printf(file, "\n");
+
+ seq_printf(file,"Counter: vidMem (for each pool)\n");
+
+ seq_printf(file,"%-9s%10s","", "All");
+
+ for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
+ {
+ seq_printf(file, "%10d", i);
+ }
+
+ seq_printf(file, "\n");
+
+ seq_printf(file,"%-9s","Current");
+
+ seq_printf(file,"%10lld", database->vidMem.bytes);
+
+ for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
+ {
+ counter = &database->vidMemPool[i];
+
+ seq_printf(file,"%10lld", counter->bytes);
+ }
+
+ seq_printf(file, "\n");
+
+ seq_printf(file,"%-9s","Maximum");
+
+ seq_printf(file,"%10lld", database->vidMem.maxBytes);
+
+ for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
+ {
+ counter = &database->vidMemPool[i];
+
+ seq_printf(file,"%10lld", counter->maxBytes);
+ }
+
+ seq_printf(file, "\n");
+
+ seq_printf(file,"%-9s","Total");
+
+ seq_printf(file,"%10lld", database->vidMem.totalBytes);
+
+ for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
+ {
+ counter = &database->vidMemPool[i];
+
+ seq_printf(file,"%10lld", counter->totalBytes);
+ }
+
+ seq_printf(file, "\n");
+
+ /* Print nonPaged. */
+ _PrintCounter(file, &database->nonPaged, "nonPaged");
+ _PrintCounter(file, &database->contiguous, "contiguous");
+ _PrintCounter(file, &database->mapUserMemory, "mapUserMemory");
+ _PrintCounter(file, &database->mapMemory, "mapMemory");
+}
+
+gckKERNEL
+_GetValidKernel(
+ gckGALDEVICE Device
+);
+static int vidmem_show(struct seq_file *file, void *unused)
+{
+ gceSTATUS status;
+ gcsDATABASE_PTR database;
+ gckGALDEVICE device = file->private;
+
+ gckKERNEL kernel = _GetValidKernel(device);
+ if(kernel == gcvNULL)
+ {
+ return 0;
+ }
+
+ /* Find the database. */
+ gcmkONERROR(
+ gckKERNEL_FindDatabase(kernel, dumpProcess, gcvFALSE, &database));
+
+ seq_printf(file, "VidMem Usage (Process %d):\n", dumpProcess);
+
+ _ShowCounters(file, database);
+
+ return 0;
+
+OnError:
+ return 0;
+}
+
+static int
+vidmem_open(
+ struct inode *inode,
+ struct file *file
+ )
+{
+ return single_open(file, vidmem_show, inode->i_private);
+}
+
+static ssize_t
+vidmem_write(
+ struct file *file,
+ const char __user *buf,
+ size_t count,
+ loff_t *pos
+ )
+{
+ dumpProcess = simple_strtol(buf, NULL, 0);
+ return count;
+}
+
/*******************************************************************************
**
** File Operations Table
.write = _DebugFSWrite ,
} ;
+static const struct file_operations vidmem_operations = {
+ .owner = THIS_MODULE ,
+ .open = vidmem_open,
+ .read = seq_read,
+ .write = vidmem_write,
+ .llseek = seq_lseek,
+} ;
+
/*******************************************************************************
**
** INTERFACE FUNCTIONS (START)
/*******************************************************************************
**
- ** gckDebugFileSystemIsEnabled
+ ** gckDEBUGFS_IsEnabled
**
**
** INPUT:
gctINT
-gckDebugFileSystemIsEnabled ( void )
+gckDEBUGFS_IsEnabled ( void )
{
return gc_dbgfs.isInited ;
}
/*******************************************************************************
**
- ** gckDebugFileSystemInitialize
+ ** gckDEBUGFS_Initialize
**
**
** INPUT:
*******************************************************************************/
gctINT
-gckDebugFileSystemInitialize ( void )
+gckDEBUGFS_Initialize ( void )
{
if ( ! gc_dbgfs.isInited )
{
}
/*******************************************************************************
**
- ** gckDebugFileSystemTerminate
+ ** gckDEBUGFS_Terminate
**
**
** INPUT:
*******************************************************************************/
gctINT
-gckDebugFileSystemTerminate ( void )
+gckDEBUGFS_Terminate ( void )
{
- gcsDebugFileSystemNode * next = gcvNULL ;
- gcsDebugFileSystemNode * temp = gcvNULL ;
+ gcsDEBUGFS_Node * next = gcvNULL ;
+ gcsDEBUGFS_Node * temp = gcvNULL ;
if ( gc_dbgfs.isInited )
{
temp = gc_dbgfs.linkedlist ;
while ( temp != gcvNULL )
{
next = temp->next ;
- gckDebugFileSystemFreeNode ( temp ) ;
+ gckDEBUGFS_FreeNode ( temp ) ;
kfree ( temp ) ;
temp = next ;
}
/*******************************************************************************
**
- ** gckDebugFileSystemCreateNode
+ ** gckDEBUGFS_CreateNode
**
**
** INPUT:
**
** OUTPUT:
**
- ** gckDebugFileSystemFreeNode * Device
- ** Pointer to a variable receiving the gcsDebugFileSystemNode object pointer on
- ** success.
+ ** gckDEBUGFS_FreeNode * Device
+ ** Pointer to a variable receiving the gcsDEBUGFS_Node object pointer on
+ ** success.
*********************************************************************************/
gctINT
-gckDebugFileSystemCreateNode (
- IN gctINT SizeInKB ,
- IN gctCONST_STRING ParentName ,
- IN gctCONST_STRING NodeName ,
- OUT gcsDebugFileSystemNode **Node
- )
+gckDEBUGFS_CreateNode (
+ IN gctPOINTER Device,
+ IN gctINT SizeInKB ,
+ IN struct dentry * Root ,
+ IN gctCONST_STRING NodeName ,
+ OUT gcsDEBUGFS_Node **Node
+ )
{
- gcsDebugFileSystemNode*node ;
+ gcsDEBUGFS_Node*node ;
/* allocate space for our metadata and initialize it */
- if ( ( node = kmalloc ( sizeof (gcsDebugFileSystemNode ) , GFP_KERNEL ) ) == NULL )
+ if ( ( node = kmalloc ( sizeof (gcsDEBUGFS_Node ) , GFP_KERNEL ) ) == NULL )
goto struct_malloc_failed ;
/*Zero it out*/
- memset ( node , 0 , sizeof (gcsDebugFileSystemNode ) ) ;
+ memset ( node , 0 , sizeof (gcsDEBUGFS_Node ) ) ;
/*Init the sync primitives*/
#if defined(DECLARE_WAIT_QUEUE_HEAD)
sema_init ( gcmkNODE_SEM ( node ) , 1 ) ;
/*End the sync primitives*/
-
- /* figure out how much of a buffer this should be and allocate the buffer */
- node->size = 1024 * SizeInKB ;
- if ( ( node->data = ( char * ) vmalloc ( sizeof (char ) * node->size ) ) == NULL )
- goto data_malloc_failed ;
-
/*creating the debug file system*/
- node->parent = debugfs_create_dir ( ParentName , NULL ) ;
+ node->parent = Root;
- /*creating the file*/
- node->filen = debugfs_create_file ( NodeName , S_IRUGO | S_IWUSR , node->parent , NULL ,
- &debugfs_operations ) ;
+ if (SizeInKB)
+ {
+ /* figure out how much of a buffer this should be and allocate the buffer */
+ node->size = 1024 * SizeInKB ;
+ if ( ( node->data = ( char * ) vmalloc ( sizeof (char ) * node->size ) ) == NULL )
+ goto data_malloc_failed ;
+
+ /*creating the file*/
+ node->filen = debugfs_create_file(NodeName, S_IRUGO|S_IWUSR, node->parent, NULL,
+ &debugfs_operations);
+ }
+
+ node->vidmem
+ = debugfs_create_file("vidmem", S_IRUGO|S_IWUSR, node->parent, Device, &vidmem_operations);
/* add it to our linked list */
node->next = gc_dbgfs.linkedlist ;
gc_dbgfs.linkedlist = node ;
+
/* pass the struct back */
*Node = node ;
return 0 ;
- vfree ( node->data ) ;
+
data_malloc_failed:
kfree ( node ) ;
struct_malloc_failed:
/*******************************************************************************
**
- ** gckDebugFileSystemFreeNode
+ ** gckDEBUGFS_FreeNode
**
**
** INPUT:
**
*******************************************************************************/
void
-gckDebugFileSystemFreeNode (
- IN gcsDebugFileSystemNode * Node
+gckDEBUGFS_FreeNode (
+ IN gcsDEBUGFS_Node * Node
)
{
- gcsDebugFileSystemNode **ptr ;
+ gcsDEBUGFS_Node **ptr ;
if ( Node == NULL )
{
vfree ( Node->data ) ;
/*Close Debug fs*/
- if ( Node->filen )
+ if (Node->vidmem)
{
- debugfs_remove ( Node->filen ) ;
+ debugfs_remove(Node->vidmem);
}
- if ( Node->parent )
+
+ if ( Node->filen )
{
- debugfs_remove ( Node->parent ) ;
+ debugfs_remove ( Node->filen ) ;
}
/* now delete the node from the linked list */
/*******************************************************************************
**
- ** gckDebugFileSystemSetCurrentNode
+ ** gckDEBUGFS_SetCurrentNode
**
**
** INPUT:
**
*******************************************************************************/
void
-gckDebugFileSystemSetCurrentNode (
- IN gcsDebugFileSystemNode * Node
+gckDEBUGFS_SetCurrentNode (
+ IN gcsDEBUGFS_Node * Node
)
{
gc_dbgfs.currentNode = Node ;
/*******************************************************************************
**
- ** gckDebugFileSystemGetCurrentNode
+ ** gckDEBUGFS_GetCurrentNode
**
**
** INPUT:
**
*******************************************************************************/
void
-gckDebugFileSystemGetCurrentNode (
- OUT gcsDebugFileSystemNode ** Node
+gckDEBUGFS_GetCurrentNode (
+ OUT gcsDEBUGFS_Node ** Node
)
{
*Node = gc_dbgfs.currentNode ;
/*******************************************************************************
**
- ** gckDebugFileSystemPrint
+ ** gckDEBUGFS_Print
**
**
** INPUT:
** OUTPUT:
**
*******************************************************************************/
-void
-gckDebugFileSystemPrint (
+ssize_t
+gckDEBUGFS_Print (
IN gctCONST_STRING Message ,
...
)
{
- gcmkDBGFSPRINT ( _GetArgumentSize ( Message ) , Message ) ;
+ ssize_t _debugfs_res;
+ gcmkDEBUGFS_PRINT ( _GetArgumentSize ( Message ) , Message ) ;
+ return _debugfs_res;
}
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#ifndef __gc_hal_kernel_debugfs_h_
#define __gc_hal_kernel_debugfs_h_
- #define MAX_LINE_SIZE 768 /* Max bytes for a line of debug info */
-
-
- typedef struct _gcsDebugFileSystemNode gcsDebugFileSystemNode ;
-
+ #define MAX_LINE_SIZE 768 /* Max bytes for a line of debug info */
+
+
+ typedef struct _gcsDEBUGFS_Node gcsDEBUGFS_Node;
+
+typedef struct _gcsDEBUGFS_DIR *gckDEBUGFS_DIR;
+typedef struct _gcsDEBUGFS_DIR
+{
+ struct dentry * root;
+ struct list_head nodeList;
+}
+gcsDEBUGFS_DIR;
+
+typedef struct _gcsINFO
+{
+ const char * name;
+ int (*show)(struct seq_file*, void*);
+}
+gcsINFO;
+
+typedef struct _gcsINFO_NODE
+{
+ gcsINFO * info;
+ gctPOINTER device;
+ struct dentry * entry;
+ struct list_head head;
+}
+gcsINFO_NODE;
+
+gceSTATUS
+gckDEBUGFS_DIR_Init(
+ IN gckDEBUGFS_DIR Dir,
+ IN struct dentry *root,
+ IN gctCONST_STRING Name
+ );
+
+gceSTATUS
+gckDEBUGFS_DIR_CreateFiles(
+ IN gckDEBUGFS_DIR Dir,
+ IN gcsINFO * List,
+ IN int count,
+ IN gctPOINTER Data
+ );
+
+gceSTATUS
+gckDEBUGFS_DIR_RemoveFiles(
+ IN gckDEBUGFS_DIR Dir,
+ IN gcsINFO * List,
+ IN int count
+ );
+
+void
+gckDEBUGFS_DIR_Deinit(
+ IN gckDEBUGFS_DIR Dir
+ );
/*******************************************************************************
**
**
*******************************************************************************/
-gctINT gckDebugFileSystemIsEnabled(void);
+gctINT gckDEBUGFS_IsEnabled(void);
-gctINT gckDebugFileSystemInitialize(void);
+gctINT gckDEBUGFS_Initialize(void);
-gctINT gckDebugFileSystemTerminate(void);
+gctINT gckDEBUGFS_Terminate(void);
/*******************************************************************************
**
*******************************************************************************/
-gctINT gckDebugFileSystemCreateNode(
- IN gctINT SizeInKB,
- IN gctCONST_STRING ParentName ,
- IN gctCONST_STRING NodeName,
- OUT gcsDebugFileSystemNode **Node
- );
-
+gctINT
+gckDEBUGFS_CreateNode(
+ IN gctPOINTER Device,
+ IN gctINT SizeInKB,
+ IN struct dentry * Root,
+ IN gctCONST_STRING NodeName,
+ OUT gcsDEBUGFS_Node **Node
+ );
-void gckDebugFileSystemFreeNode(
- IN gcsDebugFileSystemNode * Node
- );
+void gckDEBUGFS_FreeNode(
+ IN gcsDEBUGFS_Node * Node
+ );
-void gckDebugFileSystemSetCurrentNode(
- IN gcsDebugFileSystemNode * Node
- );
+void gckDEBUGFS_SetCurrentNode(
+ IN gcsDEBUGFS_Node * Node
+ );
-void gckDebugFileSystemGetCurrentNode(
- OUT gcsDebugFileSystemNode ** Node
- );
+void gckDEBUGFS_GetCurrentNode(
+ OUT gcsDEBUGFS_Node ** Node
+ );
-void gckDebugFileSystemPrint(
- IN gctCONST_STRING Message,
- ...
- );
+ssize_t gckDEBUGFS_Print(
+ IN gctCONST_STRING Message,
+ ...
+ );
#endif
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#include "gc_hal_kernel_linux.h"
#include <linux/pagemap.h>
#include <linux/seq_file.h>
-#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/slab.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
-#include <mach/hardware.h>
-#endif
-#include <linux/pm_runtime.h>
#define _GC_OBJ_ZONE gcvZONE_DEVICE
-#define DEBUG_FILE "galcore_trace"
-#define PARENT_FILE "gpu"
+#define DEBUG_FILE "galcore_trace"
+#define PARENT_FILE "gpu"
#ifdef FLAREON
static struct dove_gpio_irq_handler gc500_handle;
#endif
-#define gcmIS_CORE_PRESENT(Device, Core) (Device->irqLines[Core] > 0)
+gckKERNEL
+_GetValidKernel(
+ gckGALDEVICE Device
+ )
+{
+ if (Device->kernels[gcvCORE_MAJOR])
+ {
+ return Device->kernels[gcvCORE_MAJOR];
+ }
+ else
+ if (Device->kernels[gcvCORE_2D])
+ {
+ return Device->kernels[gcvCORE_2D];
+ }
+ else
+ if (Device->kernels[gcvCORE_VG])
+ {
+ return Device->kernels[gcvCORE_VG];
+ }
+ else
+ {
+ return gcvNULL;
+ }
+}
+
+/******************************************************************************\
+******************************** Debugfs Support *******************************
+\******************************************************************************/
+
+/******************************************************************************\
+***************************** DEBUG SHOW FUNCTIONS *****************************
+\******************************************************************************/
+
+int gc_info_show(struct seq_file* m, void* data)
+{
+ gcsINFO_NODE *node = m->private;
+ gckGALDEVICE device = node->device;
+ int i = 0;
+ gceCHIPMODEL chipModel;
+ gctUINT32 chipRevision;
+
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ if (device->irqLines[i] != -1)
+ {
+#if gcdENABLE_VG
+ if (i == gcvCORE_VG)
+ {
+ chipModel = device->kernels[i]->vg->hardware->chipModel;
+ chipRevision = device->kernels[i]->vg->hardware->chipRevision;
+ }
+ else
+#endif
+ {
+ chipModel = device->kernels[i]->hardware->identity.chipModel;
+ chipRevision = device->kernels[i]->hardware->identity.chipRevision;
+ }
+
+ seq_printf(m, "gpu : %d\n", i);
+ seq_printf(m, "model : %4x\n", chipModel);
+ seq_printf(m, "revision : %4x\n", chipRevision);
+ seq_printf(m, "\n");
+ }
+ }
+
+ return 0;
+}
+
+int gc_clients_show(struct seq_file* m, void* data)
+{
+ gcsINFO_NODE *node = m->private;
+ gckGALDEVICE device = node->device;
+
+ gckKERNEL kernel = _GetValidKernel(device);
+
+ gcsDATABASE_PTR database;
+ gctINT i, pid;
+ gctUINT8 name[24];
+
+ seq_printf(m, "%-8s%s\n", "PID", "NAME");
+ seq_printf(m, "------------------------\n");
+
+ /* Acquire the database mutex. */
+ gcmkVERIFY_OK(
+ gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));
+
+ /* Walk the databases. */
+ for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i)
+ {
+ for (database = kernel->db->db[i];
+ database != gcvNULL;
+ database = database->next)
+ {
+ pid = database->processID;
+
+ gcmkVERIFY_OK(gckOS_ZeroMemory(name, gcmSIZEOF(name)));
+
+ gcmkVERIFY_OK(gckOS_GetProcessNameByPid(pid, gcmSIZEOF(name), name));
+
+ seq_printf(m, "%-8d%s\n", pid, name);
+ }
+ }
+
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));
+
+ /* Success. */
+ return 0;
+}
+
+static void
+_CounterAdd(
+ gcsDATABASE_COUNTERS * Dest,
+ gcsDATABASE_COUNTERS * Src
+ )
+{
+ Dest->bytes += Src->bytes;
+ Dest->maxBytes += Src->maxBytes;
+ Dest->totalBytes += Src->totalBytes;
+}
+
+static void
+_CounterPrint(
+ gcsDATABASE_COUNTERS * Counter,
+ gctCONST_STRING Name,
+ struct seq_file* m
+ )
+{
+ seq_printf(m, " %s:\n", Name);
+ seq_printf(m, " Used : %10llu B\n", Counter->bytes);
+}
+
+int gc_meminfo_show(struct seq_file* m, void* data)
+{
+ gcsINFO_NODE *node = m->private;
+ gckGALDEVICE device = node->device;
+ gckKERNEL kernel = _GetValidKernel(device);
+ gckVIDMEM memory;
+ gceSTATUS status;
+ gcsDATABASE_PTR database;
+ gctUINT32 i;
+
+ gctUINT32 free = 0, used = 0, total = 0;
+
+ gcsDATABASE_COUNTERS contiguousCounter = {0, 0, 0};
+ gcsDATABASE_COUNTERS virtualCounter = {0, 0, 0};
+ gcsDATABASE_COUNTERS nonPagedCounter = {0, 0, 0};
+
+ status = gckKERNEL_GetVideoMemoryPool(kernel, gcvPOOL_SYSTEM, &memory);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ gcmkVERIFY_OK(
+ gckOS_AcquireMutex(memory->os, memory->mutex, gcvINFINITE));
+
+ free = memory->freeBytes;
+ used = memory->bytes - memory->freeBytes;
+ total = memory->bytes;
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(memory->os, memory->mutex));
+ }
+
+ seq_printf(m, "VIDEO MEMORY:\n");
+ seq_printf(m, " gcvPOOL_SYSTEM:\n");
+ seq_printf(m, " Free : %10u B\n", free);
+ seq_printf(m, " Used : %10u B\n", used);
+ seq_printf(m, " Total : %10u B\n", total);
+
+ /* Acquire the database mutex. */
+ gcmkVERIFY_OK(
+ gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));
+
+ /* Walk the databases. */
+ for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i)
+ {
+ for (database = kernel->db->db[i];
+ database != gcvNULL;
+ database = database->next)
+ {
+ gcsDATABASE_COUNTERS * counter = &database->vidMemPool[gcvPOOL_CONTIGUOUS];
+ _CounterAdd(&contiguousCounter, counter);
+
+ counter = &database->vidMemPool[gcvPOOL_VIRTUAL];
+ _CounterAdd(&virtualCounter, counter);
+
+
+ counter = &database->nonPaged;
+ _CounterAdd(&nonPagedCounter, counter);
+ }
+ }
+
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));
+
+ _CounterPrint(&contiguousCounter, "gcvPOOL_CONTIGUOUS", m);
+ _CounterPrint(&virtualCounter, "gcvPOOL_VIRTUAL", m);
+
+ seq_printf(m, "\n");
+
+ seq_printf(m, "NON PAGED MEMORY:\n");
+ seq_printf(m, " Used : %10llu B\n", nonPagedCounter.bytes);
+
+ return 0;
+}
+
+static int
+_ShowRecord(
+ IN struct seq_file *file,
+ IN gcsDATABASE_RECORD_PTR record
+ )
+{
+ seq_printf(file, "%4d%8d%16p%16p%16zu\n",
+ record->type,
+ record->kernel->core,
+ record->data,
+ record->physical,
+ record->bytes
+ );
+
+ return 0;
+}
+
+static int
+_ShowRecords(
+ IN struct seq_file *File,
+ IN gcsDATABASE_PTR Database
+ )
+{
+ gctUINT i;
+
+ seq_printf(File, "Records:\n");
+
+ seq_printf(File, "%s%8s%16s%16s%16s\n",
+ "Type", "GPU", "Data", "Physical", "Bytes");
+
+ for (i = 0; i < gcmCOUNTOF(Database->list); i++)
+ {
+ gcsDATABASE_RECORD_PTR record = Database->list[i];
+
+ while (record != NULL)
+ {
+ _ShowRecord(File, record);
+ record = record->next;
+ }
+ }
+
+ return 0;
+}
+
+void
+_ShowCounters(
+ struct seq_file *File,
+ gcsDATABASE_PTR Database
+ );
+
+static void
+_ShowProcess(
+ IN struct seq_file *File,
+ IN gcsDATABASE_PTR Database
+ )
+{
+ gctINT pid;
+ gctUINT8 name[24];
+
+ /* Process ID and name */
+ pid = Database->processID;
+ gcmkVERIFY_OK(gckOS_ZeroMemory(name, gcmSIZEOF(name)));
+ gcmkVERIFY_OK(gckOS_GetProcessNameByPid(pid, gcmSIZEOF(name), name));
+
+ seq_printf(File, "--------------------------------------------------------------------------------\n");
+ seq_printf(File, "Process: %-8d %s\n", pid, name);
+
+ /* Detailed records */
+ _ShowRecords(File, Database);
+
+ seq_printf(File, "Counters:\n");
+
+ _ShowCounters(File, Database);
+}
+
+static void
+_ShowProcesses(
+ IN struct seq_file * file,
+ IN gckKERNEL Kernel
+ )
+{
+ gcsDATABASE_PTR database;
+ gctINT i;
+
+ /* Acquire the database mutex. */
+ gcmkVERIFY_OK(
+ gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+
+ /* Idle time since last call */
+ seq_printf(file, "GPU Idle: %llu ns\n", Kernel->db->idleTime);
+ Kernel->db->idleTime = 0;
+
+ /* Walk the databases. */
+ for (i = 0; i < gcmCOUNTOF(Kernel->db->db); ++i)
+ {
+ for (database = Kernel->db->db[i];
+ database != gcvNULL;
+ database = database->next)
+ {
+ _ShowProcess(file, database);
+ }
+ }
+
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+}
+
+static int
+gc_db_show(struct seq_file *m, void *data)
+{
+ gcsINFO_NODE *node = m->private;
+ gckGALDEVICE device = node->device;
+ gckKERNEL kernel = _GetValidKernel(device);
+ _ShowProcesses(m, kernel);
+ return 0 ;
+}
+
+static int
+gc_version_show(struct seq_file *m, void *data)
+{
+ seq_printf(m, "%s\n", gcvVERSION_STRING);
+
+ return 0 ;
+}
+
+int gc_idle_show(struct seq_file* m, void* data)
+{
+ gcsINFO_NODE *node = m->private;
+ gckGALDEVICE device = node->device;
+ gckKERNEL kernel = _GetValidKernel(device);
+ gcuDATABASE_INFO info;
+
+ gckKERNEL_QueryProcessDB(kernel, 0, gcvFALSE, gcvDB_IDLE, &info);
+
+ seq_printf(m, "GPU idle time since last query: %llu ns\n", info.time);
+
+ return 0;
+}
+
+static gcsINFO InfoList[] =
+{
+ {"info", gc_info_show},
+ {"clients", gc_clients_show},
+ {"meminfo", gc_meminfo_show},
+ {"idle", gc_idle_show},
+ {"database", gc_db_show},
+ {"version", gc_version_show},
+};
+
+static gceSTATUS
+_DebugfsInit(
+ IN gckGALDEVICE Device
+ )
+{
+ gceSTATUS status;
+
+ gckDEBUGFS_DIR dir = &Device->debugfsDir;
+
+ gcmkONERROR(gckDEBUGFS_DIR_Init(dir, gcvNULL, "gc"));
+
+ gcmkONERROR(gckDEBUGFS_DIR_CreateFiles(dir, InfoList, gcmCOUNTOF(InfoList), Device));
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+static void
+_DebugfsCleanup(
+ IN gckGALDEVICE Device
+ )
+{
+ gckDEBUGFS_DIR dir = &Device->debugfsDir;
+
+ if (Device->debugfsDir.root)
+ {
+ gcmkVERIFY_OK(gckDEBUGFS_DIR_RemoveFiles(dir, InfoList, gcmCOUNTOF(InfoList)));
+
+ gckDEBUGFS_DIR_Deinit(dir);
+ }
+}
+
/******************************************************************************\
*************************** Memory Allocation Wrappers *************************
Device->os, gcvFALSE, &Bytes, Physical, Logical
));
- *PhysAddr = ((PLINUX_MDL)*Physical)->dmaHandle - Device->baseAddress;
+ *PhysAddr = ((PLINUX_MDL)*Physical)->dmaHandle;
/* Success. */
gcmkFOOTER_ARG(
return gcvSTATUS_OK;
-OnError:
- gcmkFOOTER();
- return status;
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+static gceSTATUS
+_FreeMemory(
+ IN gckGALDEVICE Device,
+ IN gctPOINTER Logical,
+ IN gctPHYS_ADDR Physical)
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Device=0x%x Logical=0x%x Physical=0x%x",
+ Device, Logical, Physical);
+
+ gcmkVERIFY_ARGUMENT(Device != NULL);
+
+ status = gckOS_FreeContiguous(
+ Device->os, Physical, Logical,
+ ((PLINUX_MDL) Physical)->numPages * PAGE_SIZE
+ );
+
+ gcmkFOOTER();
+ return status;
+}
+
+
+
+/******************************************************************************\
+******************************* Interrupt Handler ******************************
+\******************************************************************************/
+#if gcdMULTI_GPU
+static irqreturn_t isrRoutine3D0(int irq, void *ctxt)
+{
+ gceSTATUS status;
+ gckGALDEVICE device;
+
+ device = (gckGALDEVICE) ctxt;
+
+ /* Call kernel interrupt notification. */
+ status = gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR],
+ gcvCORE_3D_0_ID,
+ gcvNOTIFY_INTERRUPT,
+ gcvTRUE);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ /* Wake up the threadRoutine to process events. */
+ device->dataReady3D[gcvCORE_3D_0_ID] = gcvTRUE;
+ wake_up_interruptible(&device->intrWaitQueue3D[gcvCORE_3D_0_ID]);
+
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static int threadRoutine3D0(void *ctxt)
+{
+ gckGALDEVICE device = (gckGALDEVICE) ctxt;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
+ "Starting isr Thread with extension=%p",
+ device);
+
+ for (;;)
+ {
+ /* Sleep until being awaken by the interrupt handler. */
+ wait_event_interruptible(device->intrWaitQueue3D[gcvCORE_3D_0_ID],
+ device->dataReady3D[gcvCORE_3D_0_ID] == gcvTRUE);
+ device->dataReady3D[gcvCORE_3D_0_ID] = gcvFALSE;
+
+ if (device->killThread == gcvTRUE)
+ {
+ /* The daemon exits. */
+ while (!kthread_should_stop())
+ {
+ gckOS_Delay(device->os, 1);
+ }
+
+ return 0;
+ }
+
+ gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR],
+ gcvCORE_3D_0_ID,
+ gcvNOTIFY_INTERRUPT,
+ gcvFALSE);
+ }
+}
+
+#if gcdMULTI_GPU > 1
+static irqreturn_t isrRoutine3D1(int irq, void *ctxt)
+{
+ gceSTATUS status;
+ gckGALDEVICE device;
+
+ device = (gckGALDEVICE) ctxt;
+
+ /* Call kernel interrupt notification. */
+ status = gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR],
+ gcvCORE_3D_1_ID,
+ gcvNOTIFY_INTERRUPT,
+ gcvTRUE);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ /* Wake up the worker thread to process events. */
+ device->dataReady3D[gcvCORE_3D_1_ID] = gcvTRUE;
+ wake_up_interruptible(&device->intrWaitQueue3D[gcvCORE_3D_1_ID]);
+
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static int threadRoutine3D1(void *ctxt)
+{
+ gckGALDEVICE device = (gckGALDEVICE) ctxt;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
+ "Starting isr Thread with extension=%p",
+ device);
+
+ for (;;)
+ {
+ /* Sleep until being awaken by the interrupt handler. */
+ wait_event_interruptible(device->intrWaitQueue3D[gcvCORE_3D_1_ID],
+ device->dataReady3D[gcvCORE_3D_1_ID] == gcvTRUE);
+ device->dataReady3D[gcvCORE_3D_1_ID] = gcvFALSE;
+
+ if (device->killThread == gcvTRUE)
+ {
+ /* The daemon exits. */
+ while (!kthread_should_stop())
+ {
+ gckOS_Delay(device->os, 1);
+ }
+
+ return 0;
+ }
+
+ gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR],
+ gcvCORE_3D_1_ID,
+ gcvNOTIFY_INTERRUPT,
+ gcvFALSE);
+ }
+}
+#endif
+#elif gcdMULTI_GPU_AFFINITY
+static irqreturn_t isrRoutine3D0(int irq, void *ctxt)
+{
+ gceSTATUS status;
+ gckGALDEVICE device;
+
+ device = (gckGALDEVICE) ctxt;
+
+ /* Call kernel interrupt notification. */
+ status = gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR], gcvNOTIFY_INTERRUPT, gcvTRUE);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ up(&device->semas[gcvCORE_MAJOR]);
+
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static int threadRoutine3D0(void *ctxt)
+{
+ gckGALDEVICE device = (gckGALDEVICE) ctxt;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
+ "Starting isr Thread with extension=%p",
+ device);
+
+ for (;;)
+ {
+ static int down;
+
+ down = down_interruptible(&device->semas[gcvCORE_MAJOR]);
+ if (down); /*To make gcc 4.6 happye*/
+
+ if (device->killThread == gcvTRUE)
+ {
+ /* The daemon exits. */
+ while (!kthread_should_stop())
+ {
+ gckOS_Delay(device->os, 1);
+ }
+
+ return 0;
+ }
+
+ gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR],
+ gcvNOTIFY_INTERRUPT,
+ gcvFALSE);
+ }
+}
+
+static irqreturn_t isrRoutine3D1(int irq, void *ctxt)
+{
+ gceSTATUS status;
+ gckGALDEVICE device;
+
+ device = (gckGALDEVICE) ctxt;
+
+ /* Call kernel interrupt notification. */
+ status = gckKERNEL_Notify(device->kernels[gcvCORE_OCL], gcvNOTIFY_INTERRUPT, gcvTRUE);
+
+ if (gcmIS_SUCCESS(status))
+ {
+ up(&device->semas[gcvCORE_OCL]);
+
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
}
-static gceSTATUS
-_FreeMemory(
- IN gckGALDEVICE Device,
- IN gctPOINTER Logical,
- IN gctPHYS_ADDR Physical)
+static int threadRoutine3D1(void *ctxt)
{
- gceSTATUS status;
-
- gcmkHEADER_ARG("Device=0x%x Logical=0x%x Physical=0x%x",
- Device, Logical, Physical);
+ gckGALDEVICE device = (gckGALDEVICE) ctxt;
- gcmkVERIFY_ARGUMENT(Device != NULL);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
+ "Starting isr Thread with extension=%p",
+ device);
- status = gckOS_FreeContiguous(
- Device->os, Physical, Logical,
- ((PLINUX_MDL) Physical)->numPages * PAGE_SIZE
- );
+ for (;;)
+ {
+ static int down;
- gcmkFOOTER();
- return status;
-}
+ down = down_interruptible(&device->semas[gcvCORE_OCL]);
+ if (down); /*To make gcc 4.6 happye*/
+ if (device->killThread == gcvTRUE)
+ {
+ /* The daemon exits. */
+ while (!kthread_should_stop())
+ {
+ gckOS_Delay(device->os, 1);
+ }
+ return 0;
+ }
-/******************************************************************************\
-******************************* Interrupt Handler ******************************
-\******************************************************************************/
+ gckKERNEL_Notify(device->kernels[gcvCORE_OCL],
+ gcvNOTIFY_INTERRUPT,
+ gcvFALSE);
+ }
+}
+#else
static irqreturn_t isrRoutine(int irq, void *ctxt)
{
gceSTATUS status;
if (gcmIS_SUCCESS(status))
{
- device->dataReadys[gcvCORE_MAJOR] = gcvTRUE;
-
up(&device->semas[gcvCORE_MAJOR]);
return IRQ_HANDLED;
down = down_interruptible(&device->semas[gcvCORE_MAJOR]);
if (down); /*To make gcc 4.6 happye*/
- device->dataReadys[gcvCORE_MAJOR] = gcvFALSE;
if (device->killThread == gcvTRUE)
{
return 0;
}
- gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR], gcvNOTIFY_INTERRUPT, gcvFALSE);
+ gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR],
+ gcvNOTIFY_INTERRUPT,
+ gcvFALSE);
}
}
+#endif
static irqreturn_t isrRoutine2D(int irq, void *ctxt)
{
device = (gckGALDEVICE) ctxt;
/* Call kernel interrupt notification. */
- status = gckKERNEL_Notify(device->kernels[gcvCORE_2D], gcvNOTIFY_INTERRUPT, gcvTRUE);
-
+ status = gckKERNEL_Notify(device->kernels[gcvCORE_2D],
+#if gcdMULTI_GPU
+ 0,
+#endif
+ gcvNOTIFY_INTERRUPT,
+ gcvTRUE);
if (gcmIS_SUCCESS(status))
{
- device->dataReadys[gcvCORE_2D] = gcvTRUE;
-
up(&device->semas[gcvCORE_2D]);
return IRQ_HANDLED;
down = down_interruptible(&device->semas[gcvCORE_2D]);
if (down); /*To make gcc 4.6 happye*/
- device->dataReadys[gcvCORE_2D] = gcvFALSE;
if (device->killThread == gcvTRUE)
{
return 0;
}
-
- gckKERNEL_Notify(device->kernels[gcvCORE_2D], gcvNOTIFY_INTERRUPT, gcvFALSE);
+ gckKERNEL_Notify(device->kernels[gcvCORE_2D],
+#if gcdMULTI_GPU
+ 0,
+#endif
+ gcvNOTIFY_INTERRUPT,
+ gcvFALSE);
}
}
device = (gckGALDEVICE) ctxt;
- /* Serve the interrupt. */
- status = gckVGINTERRUPT_Enque(device->kernels[gcvCORE_VG]->vg->interrupt);
+ /* Serve the interrupt. */
+ status = gckVGINTERRUPT_Enque(device->kernels[gcvCORE_VG]->vg->interrupt);
- /* Determine the return value. */
- return (status == gcvSTATUS_NOT_OUR_INTERRUPT)
- ? IRQ_RETVAL(0)
- : IRQ_RETVAL(1);
+ /* Determine the return value. */
+ return (status == gcvSTATUS_NOT_OUR_INTERRUPT)
+ ? IRQ_RETVAL(0)
+ : IRQ_RETVAL(1);
#else
return IRQ_NONE;
#endif
down = down_interruptible(&device->semas[gcvCORE_VG]);
if (down); /*To make gcc 4.6 happye*/
- device->dataReadys[gcvCORE_VG] = gcvFALSE;
if (device->killThread == gcvTRUE)
{
return 0;
}
-
- gckKERNEL_Notify(device->kernels[gcvCORE_VG], gcvNOTIFY_INTERRUPT, gcvFALSE);
+ gckKERNEL_Notify(device->kernels[gcvCORE_VG],
+#if gcdMULTI_GPU
+ 0,
+#endif
+ gcvNOTIFY_INTERRUPT,
+ gcvFALSE);
}
}
*/
gceSTATUS
gckGALDEVICE_Construct(
+#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY
+ IN gctINT IrqLine3D0,
+ IN gctUINT32 RegisterMemBase3D0,
+ IN gctSIZE_T RegisterMemSize3D0,
+ IN gctINT IrqLine3D1,
+ IN gctUINT32 RegisterMemBase3D1,
+ IN gctSIZE_T RegisterMemSize3D1,
+#else
IN gctINT IrqLine,
IN gctUINT32 RegisterMemBase,
IN gctSIZE_T RegisterMemSize,
+#endif
IN gctINT IrqLine2D,
IN gctUINT32 RegisterMemBase2D,
IN gctSIZE_T RegisterMemSize2D,
IN gctUINT32 PhysSize,
IN gctINT Signal,
IN gctUINT LogFileSize,
- IN struct device *pdev,
IN gctINT PowerManagement,
IN gctINT GpuProfiler,
+ IN gcsDEVICE_CONSTRUCT_ARGS * Args,
OUT gckGALDEVICE *Device
)
{
gckGALDEVICE device;
gceSTATUS status;
gctINT32 i;
+#if gcdMULTI_GPU
+ gctINT32 j;
+#endif
gceHARDWARE_TYPE type;
gckDB sharedDB = gcvNULL;
gckKERNEL kernel = gcvNULL;
+#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY
+ gcmkHEADER_ARG("IrqLine3D0=%d RegisterMemBase3D0=0x%08x RegisterMemSize3D0=%u "
+ "IrqLine2D=%d RegisterMemBase2D=0x%08x RegisterMemSize2D=%u "
+ "IrqLineVG=%d RegisterMemBaseVG=0x%08x RegisterMemSizeVG=%u "
+ "ContiguousBase=0x%08x ContiguousSize=%lu BankSize=%lu "
+ "FastClear=%d Compression=%d PhysBaseAddr=0x%x PhysSize=%d Signal=%d",
+ IrqLine3D0, RegisterMemBase3D0, RegisterMemSize3D0,
+ IrqLine2D, RegisterMemBase2D, RegisterMemSize2D,
+ IrqLineVG, RegisterMemBaseVG, RegisterMemSizeVG,
+ ContiguousBase, ContiguousSize, BankSize, FastClear, Compression,
+ PhysBaseAddr, PhysSize, Signal);
+#else
gcmkHEADER_ARG("IrqLine=%d RegisterMemBase=0x%08x RegisterMemSize=%u "
"IrqLine2D=%d RegisterMemBase2D=0x%08x RegisterMemSize2D=%u "
"IrqLineVG=%d RegisterMemBaseVG=0x%08x RegisterMemSizeVG=%u "
IrqLineVG, RegisterMemBaseVG, RegisterMemSizeVG,
ContiguousBase, ContiguousSize, BankSize, FastClear, Compression,
PhysBaseAddr, PhysSize, Signal);
+#endif
+
+#if gcdDISABLE_CORES_2D3D
+ IrqLine = -1;
+ IrqLine2D = -1;
+#endif
/* Allocate device structure. */
- device = kmalloc(sizeof(struct _gckGALDEVICE), GFP_KERNEL);
+ device = kmalloc(sizeof(struct _gckGALDEVICE), GFP_KERNEL | __GFP_NOWARN);
if (!device)
{
memset(device, 0, sizeof(struct _gckGALDEVICE));
- device->dbgnode = gcvNULL;
- if(LogFileSize != 0)
- {
- if(gckDebugFileSystemCreateNode(LogFileSize,PARENT_FILE,DEBUG_FILE,&(device->dbgnode)) != 0)
- {
- gcmkTRACE_ZONE(
- gcvLEVEL_ERROR, gcvZONE_DRIVER,
- "%s(%d): Failed to create the debug file system %s/%s \n",
- __FUNCTION__, __LINE__,
- PARENT_FILE, DEBUG_FILE
- );
- }
- else
- {
- /*Everything is OK*/
- gckDebugFileSystemSetCurrentNode(device->dbgnode);
- }
- }
-#ifdef CONFIG_PM
- /*Init runtime pm for gpu*/
- pm_runtime_enable(pdev);
- device->pmdev = pdev;
-#endif
+ device->dbgNode = gcvNULL;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
- /*get gpu regulator*/
- device->gpu_regulator = regulator_get(pdev, "cpu_vddgpu");
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
- device->gpu_regulator = devm_regulator_get(pdev, "pu");
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
- if (IS_ERR(device->gpu_regulator)) {
- gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DRIVER,
- "%s(%d): Failed to get gpu regulator %s/%s \n",
- __FUNCTION__, __LINE__,
- PARENT_FILE, DEBUG_FILE);
- gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ device->platform = Args->platform;
+
+ gcmkONERROR(_DebugfsInit(device));
+
+ if (gckDEBUGFS_CreateNode(
+ device, LogFileSize, device->debugfsDir.root ,DEBUG_FILE, &(device->dbgNode)))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Failed to create the debug file system %s/%s \n",
+ __FUNCTION__, __LINE__,
+ PARENT_FILE, DEBUG_FILE
+ );
}
-#endif
- /*Initialize the clock structure*/
- if (IrqLine != -1) {
- device->clk_3d_core = clk_get(pdev, "gpu3d_clk");
- if (!IS_ERR(device->clk_3d_core)) {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
- if (cpu_is_mx6q()) {
- device->clk_3d_shader = clk_get(pdev, "gpu3d_shader_clk");
- if (IS_ERR(device->clk_3d_shader)) {
- IrqLine = -1;
- clk_put(device->clk_3d_core);
- device->clk_3d_core = NULL;
- device->clk_3d_shader = NULL;
- gckOS_Print("galcore: clk_get gpu3d_shader_clk failed, disable 3d!\n");
- }
- }
-#else
- device->clk_3d_axi = clk_get(pdev, "gpu3d_axi_clk");
- device->clk_3d_shader = clk_get(pdev, "gpu3d_shader_clk");
- if (IS_ERR(device->clk_3d_shader)) {
- IrqLine = -1;
- clk_put(device->clk_3d_core);
- device->clk_3d_core = NULL;
- device->clk_3d_shader = NULL;
- gckOS_Print("galcore: clk_get gpu3d_shader_clk failed, disable 3d!\n");
- }
-#endif
- } else {
- IrqLine = -1;
- device->clk_3d_core = NULL;
- gckOS_Print("galcore: clk_get gpu3d_clk failed, disable 3d!\n");
- }
- }
- if ((IrqLine2D != -1) || (IrqLineVG != -1)) {
- device->clk_2d_core = clk_get(pdev, "gpu2d_clk");
- if (IS_ERR(device->clk_2d_core)) {
- IrqLine2D = -1;
- IrqLineVG = -1;
- device->clk_2d_core = NULL;
- gckOS_Print("galcore: clk_get 2d core clock failed, disable 2d/vg!\n");
- } else {
- if (IrqLine2D != -1) {
- device->clk_2d_axi = clk_get(pdev, "gpu2d_axi_clk");
- if (IS_ERR(device->clk_2d_axi)) {
- device->clk_2d_axi = NULL;
- IrqLine2D = -1;
- gckOS_Print("galcore: clk_get 2d axi clock failed, disable 2d\n");
- }
- }
- if (IrqLineVG != -1) {
- device->clk_vg_axi = clk_get(pdev, "openvg_axi_clk");
- if (IS_ERR(device->clk_vg_axi)) {
- IrqLineVG = -1;
- device->clk_vg_axi = NULL;
- gckOS_Print("galcore: clk_get vg clock failed, disable vg!\n");
- }
- }
- }
+ else if (LogFileSize)
+ {
+ gckDEBUGFS_SetCurrentNode(device->dbgNode);
+ }
+
+#if gcdMULTI_GPU
+ if (IrqLine3D0 != -1)
+ {
+ device->requestedRegisterMemBase3D[gcvCORE_3D_0_ID] = RegisterMemBase3D0;
+ device->requestedRegisterMemSize3D[gcvCORE_3D_0_ID] = RegisterMemSize3D0;
+ }
+
+ if (IrqLine3D1 != -1)
+ {
+ device->requestedRegisterMemBase3D[gcvCORE_3D_1_ID] = RegisterMemBase3D1;
+ device->requestedRegisterMemSize3D[gcvCORE_3D_1_ID] = RegisterMemSize3D1;
+ }
+#elif gcdMULTI_GPU_AFFINITY
+ if (IrqLine3D0 != -1)
+ {
+ device->requestedRegisterMemBases[gcvCORE_MAJOR] = RegisterMemBase3D0;
+ device->requestedRegisterMemSizes[gcvCORE_MAJOR] = RegisterMemSize3D0;
}
+ if (IrqLine3D1 != -1)
+ {
+ device->requestedRegisterMemBases[gcvCORE_OCL] = RegisterMemBase3D1;
+ device->requestedRegisterMemSizes[gcvCORE_OCL] = RegisterMemSize3D1;
+ }
+#else
if (IrqLine != -1)
{
- device->requestedRegisterMemBases[gcvCORE_MAJOR] = RegisterMemBase;
- device->requestedRegisterMemSizes[gcvCORE_MAJOR] = RegisterMemSize;
+ device->requestedRegisterMemBases[gcvCORE_MAJOR] = RegisterMemBase;
+ device->requestedRegisterMemSizes[gcvCORE_MAJOR] = RegisterMemSize;
}
+#endif
if (IrqLine2D != -1)
{
- device->requestedRegisterMemBases[gcvCORE_2D] = RegisterMemBase2D;
- device->requestedRegisterMemSizes[gcvCORE_2D] = RegisterMemSize2D;
+ device->requestedRegisterMemBases[gcvCORE_2D] = RegisterMemBase2D;
+ device->requestedRegisterMemSizes[gcvCORE_2D] = RegisterMemSize2D;
}
if (IrqLineVG != -1)
{
- device->requestedRegisterMemBases[gcvCORE_VG] = RegisterMemBaseVG;
- device->requestedRegisterMemSizes[gcvCORE_VG] = RegisterMemSizeVG;
+ device->requestedRegisterMemBases[gcvCORE_VG] = RegisterMemBaseVG;
+ device->requestedRegisterMemSizes[gcvCORE_VG] = RegisterMemSizeVG;
}
device->requestedContiguousBase = 0;
device->requestedContiguousSize = 0;
-
for (i = 0; i < gcdMAX_GPU_COUNT; i++)
{
- physical = device->requestedRegisterMemBases[i];
+#if gcdMULTI_GPU
+ if (i == gcvCORE_MAJOR)
+ {
+ for (j = 0; j < gcdMULTI_GPU; j++)
+ {
+ physical = device->requestedRegisterMemBase3D[j];
+
+ /* Set up register memory region. */
+ if (physical != 0)
+ {
+ mem_region = request_mem_region(physical,
+ device->requestedRegisterMemSize3D[j],
+ "galcore register region");
+
+ if (mem_region == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Failed to claim %lu bytes @ 0x%08X\n",
+ __FUNCTION__, __LINE__,
+ physical, device->requestedRegisterMemSize3D[j]
+ );
+
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ device->registerBase3D[j] = (gctPOINTER) ioremap_nocache(
+ physical, device->requestedRegisterMemSize3D[j]);
+
+ if (device->registerBase3D[j] == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Unable to map %ld bytes @ 0x%08X\n",
+ __FUNCTION__, __LINE__,
+ physical, device->requestedRegisterMemSize3D[j]
+ );
+
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
- /* Set up register memory region. */
- if (physical != 0)
+ physical += device->requestedRegisterMemSize3D[j];
+ }
+ else
+ {
+ device->registerBase3D[j] = gcvNULL;
+ }
+ }
+ }
+ else
+#endif
{
- mem_region = request_mem_region(
- physical, device->requestedRegisterMemSizes[i], "galcore register region"
- );
+ physical = device->requestedRegisterMemBases[i];
- if (mem_region == gcvNULL)
+ /* Set up register memory region. */
+ if (physical != 0)
{
- gcmkTRACE_ZONE(
- gcvLEVEL_ERROR, gcvZONE_DRIVER,
- "%s(%d): Failed to claim %lu bytes @ 0x%08X\n",
- __FUNCTION__, __LINE__,
- physical, device->requestedRegisterMemSizes[i]
+ mem_region = request_mem_region(physical,
+ device->requestedRegisterMemSizes[i],
+ "galcore register region");
+
+ if (mem_region == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Failed to claim %lu bytes @ 0x%08X\n",
+ __FUNCTION__, __LINE__,
+ physical, device->requestedRegisterMemSizes[i]
);
- gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
- }
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
- device->registerBases[i] = (gctPOINTER) ioremap_nocache(
- physical, device->requestedRegisterMemSizes[i]);
+ device->registerBases[i] = (gctPOINTER) ioremap_nocache(
+ physical, device->requestedRegisterMemSizes[i]);
- if (device->registerBases[i] == gcvNULL)
- {
- gcmkTRACE_ZONE(
- gcvLEVEL_ERROR, gcvZONE_DRIVER,
- "%s(%d): Unable to map %ld bytes @ 0x%08X\n",
- __FUNCTION__, __LINE__,
- physical, device->requestedRegisterMemSizes[i]
+ if (device->registerBases[i] == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Unable to map %ld bytes @ 0x%08X\n",
+ __FUNCTION__, __LINE__,
+ physical, device->requestedRegisterMemSizes[i]
);
- gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
- }
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
- physical += device->requestedRegisterMemSizes[i];
- }
- else
- {
- device->registerBases[i] = gcvNULL;
+ physical += device->requestedRegisterMemSizes[i];
+ }
}
}
/* Set the base address */
- device->baseAddress = PhysBaseAddr;
+ device->baseAddress = device->physBase = PhysBaseAddr;
+ device->physSize = PhysSize;
+ device->mmu = Args->mmu;
/* Construct the gckOS object. */
gcmkONERROR(gckOS_Construct(device, &device->os));
+#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY
+ if (IrqLine3D0 != -1)
+#else
if (IrqLine != -1)
+#endif
{
/* Construct the gckKERNEL object. */
gcmkONERROR(gckKERNEL_Construct(
device->kernels[gcvCORE_MAJOR]->hardware, FastClear, Compression
));
- gcmkONERROR(gckHARDWARE_SetPowerManagement(
- device->kernels[gcvCORE_MAJOR]->hardware, PowerManagement
+ if(PowerManagement != -1)
+ {
+ gcmkONERROR(gckHARDWARE_SetPowerManagementLock(
+ device->kernels[gcvCORE_MAJOR]->hardware, gcvFALSE
+ ));
+ gcmkONERROR(gckHARDWARE_SetPowerManagement(
+ device->kernels[gcvCORE_MAJOR]->hardware, PowerManagement
+ ));
+ gcmkONERROR(gckHARDWARE_SetPowerManagementLock(
+ device->kernels[gcvCORE_MAJOR]->hardware, gcvTRUE
+ ));
+ }
+ else
+ {
+ gcmkONERROR(gckHARDWARE_SetPowerManagementLock(
+ device->kernels[gcvCORE_MAJOR]->hardware, gcvFALSE
+ ));
+ gcmkONERROR(gckHARDWARE_SetPowerManagement(
+ device->kernels[gcvCORE_MAJOR]->hardware, gcvTRUE
+ ));
+ }
+
+#if gcdENABLE_FSCALE_VAL_ADJUST
+ gcmkONERROR(gckHARDWARE_SetMinFscaleValue(
+ device->kernels[gcvCORE_MAJOR]->hardware, Args->gpu3DMinClock
));
+#endif
gcmkONERROR(gckHARDWARE_SetGpuProfiler(
device->kernels[gcvCORE_MAJOR]->hardware, GpuProfiler
));
+ gcmkVERIFY_OK(gckKERNEL_SetRecovery(
+ device->kernels[gcvCORE_MAJOR], Args->recovery, Args->stuckDump
+ ));
+
#if COMMAND_PROCESSOR_VERSION == 1
/* Start the command queue. */
gcmkONERROR(gckCOMMAND_Start(device->kernels[gcvCORE_MAJOR]->command));
device->kernels[gcvCORE_MAJOR] = gcvNULL;
}
+#if gcdMULTI_GPU_AFFINITY
+ if (IrqLine3D1 != -1)
+ {
+ /* Construct the gckKERNEL object. */
+ gcmkONERROR(gckKERNEL_Construct(
+ device->os, gcvCORE_OCL, device,
+ gcvNULL, &device->kernels[gcvCORE_OCL]));
+
+ if (sharedDB == gcvNULL) sharedDB = device->kernels[gcvCORE_OCL]->db;
+
+ /* Initialize core mapping */
+ if (device->kernels[gcvCORE_MAJOR] == gcvNULL)
+ {
+ for (i = 0; i < 8; i++)
+ {
+ device->coreMapping[i] = gcvCORE_OCL;
+ }
+ }
+ else
+ {
+ device->coreMapping[gcvHARDWARE_OCL] = gcvCORE_OCL;
+ }
+
+ /* Setup the ISR manager. */
+ gcmkONERROR(gckHARDWARE_SetIsrManager(
+ device->kernels[gcvCORE_OCL]->hardware,
+ (gctISRMANAGERFUNC) gckGALDEVICE_Setup_ISR,
+ (gctISRMANAGERFUNC) gckGALDEVICE_Release_ISR,
+ device
+ ));
+
+ gcmkONERROR(gckHARDWARE_SetFastClear(
+ device->kernels[gcvCORE_OCL]->hardware, FastClear, Compression
+ ));
+
+#if gcdENABLE_FSCALE_VAL_ADJUST
+ gcmkONERROR(gckHARDWARE_SetMinFscaleValue(
+ device->kernels[gcvCORE_OCL]->hardware, Args->gpu3DMinClock
+ ));
+#endif
+ if(PowerManagement != -1)
+ {
+ gcmkONERROR(gckHARDWARE_SetPowerManagementLock(
+ device->kernels[gcvCORE_OCL]->hardware, gcvFALSE
+ ));
+ gcmkONERROR(gckHARDWARE_SetPowerManagement(
+ device->kernels[gcvCORE_OCL]->hardware, PowerManagement
+ ));
+ gcmkONERROR(gckHARDWARE_SetPowerManagementLock(
+ device->kernels[gcvCORE_OCL]->hardware, gcvTRUE
+ ));
+ }
+ else
+ {
+ gcmkONERROR(gckHARDWARE_SetPowerManagementLock(
+ device->kernels[gcvCORE_OCL]->hardware, gcvFALSE
+ ));
+ gcmkONERROR(gckHARDWARE_SetPowerManagement(
+ device->kernels[gcvCORE_OCL]->hardware, gcvTRUE
+ ));
+ }
+
+#if COMMAND_PROCESSOR_VERSION == 1
+ /* Start the command queue. */
+ gcmkONERROR(gckCOMMAND_Start(device->kernels[gcvCORE_OCL]->command));
+#endif
+ }
+ else
+ {
+ device->kernels[gcvCORE_OCL] = gcvNULL;
+ }
+#endif
+
if (IrqLine2D != -1)
{
gcmkONERROR(gckKERNEL_Construct(
}
/* Initialize core mapping */
- if (device->kernels[gcvCORE_MAJOR] == gcvNULL)
+ if (device->kernels[gcvCORE_MAJOR] == gcvNULL
+#if gcdMULTI_GPU_AFFINITY
+ && device->kernels[gcvCORE_OCL] == gcvNULL
+#endif
+ )
{
for (i = 0; i < 8; i++)
{
device
));
- gcmkONERROR(gckHARDWARE_SetPowerManagement(
- device->kernels[gcvCORE_2D]->hardware, PowerManagement
+ if(PowerManagement != -1)
+ {
+ gcmkONERROR(gckHARDWARE_SetPowerManagementLock(
+ device->kernels[gcvCORE_2D]->hardware, gcvFALSE
+ ));
+ gcmkONERROR(gckHARDWARE_SetPowerManagement(
+ device->kernels[gcvCORE_2D]->hardware, PowerManagement
+ ));
+ gcmkONERROR(gckHARDWARE_SetPowerManagementLock(
+ device->kernels[gcvCORE_2D]->hardware, gcvTRUE
+ ));
+ }
+ else
+ {
+ gcmkONERROR(gckHARDWARE_SetPowerManagementLock(
+ device->kernels[gcvCORE_2D]->hardware, gcvFALSE
+ ));
+ gcmkONERROR(gckHARDWARE_SetPowerManagement(
+ device->kernels[gcvCORE_2D]->hardware, gcvTRUE
+ ));
+ }
+
+#if gcdENABLE_FSCALE_VAL_ADJUST
+ gcmkONERROR(gckHARDWARE_SetMinFscaleValue(
+ device->kernels[gcvCORE_2D]->hardware, 1
));
+#endif
+ gcmkVERIFY_OK(gckKERNEL_SetRecovery(
+ device->kernels[gcvCORE_2D], Args->recovery, Args->stuckDump
+ ));
#if COMMAND_PROCESSOR_VERSION == 1
/* Start the command queue. */
/* Initialize core mapping */
if (device->kernels[gcvCORE_MAJOR] == gcvNULL
&& device->kernels[gcvCORE_2D] == gcvNULL
+#if gcdMULTI_GPU_AFFINITY
+ && device->kernels[gcvCORE_OCL] == gcvNULL
+#endif
)
{
for (i = 0; i < 8; i++)
device->coreMapping[gcvHARDWARE_VG] = gcvCORE_VG;
}
+ if(PowerManagement != -1)
+ {
+ gcmkONERROR(gckVGHARDWARE_SetPowerManagement(
+ device->kernels[gcvCORE_VG]->vg->hardware,
+ PowerManagement
+ ));
+ }
+ else
+ {
+ gcmkONERROR(gckVGHARDWARE_SetPowerManagement(
+ device->kernels[gcvCORE_VG]->vg->hardware,
+ gcvTRUE
+ ));
+ }
- gcmkONERROR(gckVGHARDWARE_SetPowerManagement(
- device->kernels[gcvCORE_VG]->vg->hardware,
- PowerManagement
- ));
#endif
}
}
/* Initialize the ISR. */
+#if gcdMULTI_GPU
+ device->irqLine3D[gcvCORE_3D_0_ID] = IrqLine3D0;
+#if gcdMULTI_GPU > 1
+ device->irqLine3D[gcvCORE_3D_1_ID] = IrqLine3D1;
+#endif
+#elif gcdMULTI_GPU_AFFINITY
+ device->irqLines[gcvCORE_MAJOR] = IrqLine3D0;
+ device->irqLines[gcvCORE_OCL] = IrqLine3D1;
+#else
device->irqLines[gcvCORE_MAJOR] = IrqLine;
- device->irqLines[gcvCORE_2D] = IrqLine2D;
- device->irqLines[gcvCORE_VG] = IrqLineVG;
+#endif
+ device->irqLines[gcvCORE_2D] = IrqLine2D;
+ device->irqLines[gcvCORE_VG] = IrqLineVG;
/* Initialize the kernel thread semaphores. */
for (i = 0; i < gcdMAX_GPU_COUNT; i++)
{
- if (device->irqLines[i] != -1) sema_init(&device->semas[i], 0);
+#if gcdMULTI_GPU
+ if (i == gcvCORE_MAJOR)
+ {
+ for (j = 0; j < gcdMULTI_GPU; j++)
+ {
+ if (device->irqLine3D[j] != -1) init_waitqueue_head(&device->intrWaitQueue3D[j]);
+ }
+ }
+ else
+#endif
+ {
+ if (device->irqLines[i] != -1) sema_init(&device->semas[i], 0);
+ }
}
device->signal = Signal;
}
if (i == gcdMAX_GPU_COUNT)
- {
- gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
- }
+ {
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
#if gcdENABLE_VG
if (i == gcvCORE_VG)
/* Grab the first availiable kernel */
for (i = 0; i < gcdMAX_GPU_COUNT; i++)
{
- if (device->irqLines[i] != -1)
+#if gcdMULTI_GPU
+ if (i == gcvCORE_MAJOR)
+ {
+ for (j = 0; j < gcdMULTI_GPU; j++)
+ {
+ if (device->irqLine3D[j] != -1)
+ {
+ kernel = device->kernels[i];
+ break;
+ }
+ }
+ }
+ else
+#endif
{
- kernel = device->kernels[i];
- break;
+ if (device->irqLines[i] != -1)
+ {
+ kernel = device->kernels[i];
+ break;
+ }
}
}
}
else
{
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
- mem_region = request_mem_region(
- ContiguousBase, ContiguousSize, "galcore managed memory"
- );
-
- if (mem_region == gcvNULL)
+ if (Args->contiguousRequested == gcvFALSE)
{
- gcmkTRACE_ZONE(
- gcvLEVEL_ERROR, gcvZONE_DRIVER,
- "%s(%d): Failed to claim %ld bytes @ 0x%08X\n",
- __FUNCTION__, __LINE__,
- ContiguousSize, ContiguousBase
+ mem_region = request_mem_region(
+ ContiguousBase, ContiguousSize, "galcore managed memory"
);
- gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
- }
-#endif
-
- device->requestedContiguousBase = ContiguousBase;
- device->requestedContiguousSize = ContiguousSize;
-
-#if !gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
- if (gcmIS_CORE_PRESENT(device, gcvCORE_VG))
- {
- device->contiguousBase
-#if gcdPAGED_MEMORY_CACHEABLE
- = (gctPOINTER) ioremap_cached(ContiguousBase, ContiguousSize);
-#else
- = (gctPOINTER) ioremap_nocache(ContiguousBase, ContiguousSize);
-#endif
- if (device->contiguousBase == gcvNULL)
+ if (mem_region == gcvNULL)
{
- device->contiguousVidMem = gcvNULL;
- device->contiguousSize = 0;
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Failed to claim %ld bytes @ 0x%08X\n",
+ __FUNCTION__, __LINE__,
+ ContiguousSize, ContiguousBase
+ );
gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
}
}
-#endif
+
+ device->requestedContiguousBase = ContiguousBase;
+ device->requestedContiguousSize = ContiguousSize;
+ device->contiguousRequested = Args->contiguousRequested;
device->contiguousPhysical = gcvNULL;
device->contiguousPhysicalName = 0;
}
/* Return pointer to the device. */
- * Device = device;
+ *Device = device;
gcmkFOOTER_ARG("*Device=0x%x", * Device);
return gcvSTATUS_OK;
gckGALDEVICE Device)
{
gctINT i;
- gceSTATUS status = gcvSTATUS_OK;
+#if gcdMULTI_GPU
+ gctINT j;
+#endif
gckKERNEL kernel = gcvNULL;
gcmkHEADER_ARG("Device=0x%x", Device);
/* Grab the first availiable kernel */
for (i = 0; i < gcdMAX_GPU_COUNT; i++)
{
- if (Device->irqLines[i] != -1)
+#if gcdMULTI_GPU
+ if (i == gcvCORE_MAJOR)
{
- kernel = Device->kernels[i];
- break;
+ for (j = 0; j < gcdMULTI_GPU; j++)
+ {
+ if (Device->irqLine3D[j] != -1)
+ {
+ kernel = Device->kernels[i];
+ break;
+ }
+ }
+ }
+ else
+#endif
+ {
+ if (Device->irqLines[i] != -1)
+ {
+ kernel = Device->kernels[i];
+ break;
+ }
}
}
+
if (Device->internalPhysicalName != 0)
{
gcmRELEASE_NAME(Device->internalPhysicalName);
}
}
+ if (Device->internalLogical != gcvNULL)
{
- if (Device->internalLogical != gcvNULL)
- {
- /* Unmap the internal memory. */
- iounmap(Device->internalLogical);
- Device->internalLogical = gcvNULL;
- }
+ /* Unmap the internal memory. */
+ iounmap(Device->internalLogical);
+ Device->internalLogical = gcvNULL;
+ }
- if (Device->internalVidMem != gcvNULL)
- {
- /* Destroy the internal heap. */
- gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->internalVidMem));
- Device->internalVidMem = gcvNULL;
- }
+ if (Device->internalVidMem != gcvNULL)
+ {
+ /* Destroy the internal heap. */
+ gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->internalVidMem));
+ Device->internalVidMem = gcvNULL;
}
+ if (Device->externalLogical != gcvNULL)
{
- if (Device->externalLogical != gcvNULL)
- {
- /* Unmap the external memory. */
- iounmap(Device->externalLogical);
- Device->externalLogical = gcvNULL;
- }
+ /* Unmap the external memory. */
+ iounmap(Device->externalLogical);
+ Device->externalLogical = gcvNULL;
+ }
- if (Device->externalVidMem != gcvNULL)
+ if (Device->externalVidMem != gcvNULL)
+ {
+ /* destroy the external heap */
+ gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->externalVidMem));
+ Device->externalVidMem = gcvNULL;
+ }
+
+ if (Device->contiguousBase != gcvNULL)
+ {
+ if (Device->contiguousMapped == gcvFALSE)
{
- /* destroy the external heap */
- gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->externalVidMem));
- Device->externalVidMem = gcvNULL;
+ gcmkVERIFY_OK(_FreeMemory(
+ Device,
+ Device->contiguousBase,
+ Device->contiguousPhysical
+ ));
}
+
+ Device->contiguousBase = gcvNULL;
+ Device->contiguousPhysical = gcvNULL;
}
+ if (Device->requestedContiguousBase != 0
+ && Device->contiguousRequested == gcvFALSE
+ )
{
- if (Device->contiguousBase != gcvNULL)
- {
- if (Device->contiguousMapped)
- {
-#if !gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
- if (Device->contiguousBase)
- {
- /* Unmap the contiguous memory. */
- iounmap(Device->contiguousBase);
- }
-#endif
- }
- else
- {
- gcmkONERROR(_FreeMemory(
- Device,
- Device->contiguousBase,
- Device->contiguousPhysical
- ));
- }
+ release_mem_region(Device->requestedContiguousBase, Device->requestedContiguousSize);
+ Device->requestedContiguousBase = 0;
+ Device->requestedContiguousSize = 0;
+ }
- Device->contiguousBase = gcvNULL;
- Device->contiguousPhysical = gcvNULL;
- }
+ if (Device->contiguousVidMem != gcvNULL)
+ {
+ /* Destroy the contiguous heap. */
+ gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->contiguousVidMem));
+ Device->contiguousVidMem = gcvNULL;
+ }
- if (Device->requestedContiguousBase != 0)
- {
- release_mem_region(Device->requestedContiguousBase, Device->requestedContiguousSize);
- Device->requestedContiguousBase = 0;
- Device->requestedContiguousSize = 0;
- }
+ if (Device->dbgNode)
+ {
+ gckDEBUGFS_FreeNode(Device->dbgNode);
- if (Device->contiguousVidMem != gcvNULL)
+ if(Device->dbgNode != gcvNULL)
{
- /* Destroy the contiguous heap. */
- gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->contiguousVidMem));
- Device->contiguousVidMem = gcvNULL;
+ kfree(Device->dbgNode);
+ Device->dbgNode = gcvNULL;
}
}
- {
- if(gckDebugFileSystemIsEnabled())
- {
- gckDebugFileSystemFreeNode(Device->dbgnode);
- kfree(Device->dbgnode);
- Device->dbgnode = gcvNULL;
- }
- }
-
for (i = 0; i < gcdMAX_GPU_COUNT; i++)
{
- if (Device->registerBases[i] != gcvNULL)
+#if gcdMULTI_GPU
+ if (i == gcvCORE_MAJOR)
{
- /* Unmap register memory. */
- iounmap(Device->registerBases[i]);
- if (Device->requestedRegisterMemBases[i] != 0)
- {
- release_mem_region(Device->requestedRegisterMemBases[i], Device->requestedRegisterMemSizes[i]);
- }
-
- Device->registerBases[i] = gcvNULL;
- Device->requestedRegisterMemBases[i] = 0;
- Device->requestedRegisterMemSizes[i] = 0;
+ for (j = 0; j < gcdMULTI_GPU; j++)
+ {
+ if (Device->registerBase3D[j] != gcvNULL)
+ {
+ /* Unmap register memory. */
+ iounmap(Device->registerBase3D[j]);
+ if (Device->requestedRegisterMemBase3D[j] != 0)
+ {
+ release_mem_region(Device->requestedRegisterMemBase3D[j],
+ Device->requestedRegisterMemSize3D[j]);
+ }
+
+ Device->registerBase3D[j] = gcvNULL;
+ Device->requestedRegisterMemBase3D[j] = 0;
+ Device->requestedRegisterMemSize3D[j] = 0;
+ }
+ }
}
- }
-
- /*Disable clock*/
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
- if (Device->clk_3d_axi) {
- clk_put(Device->clk_3d_axi);
- Device->clk_3d_axi = NULL;
- }
-#endif
- if (Device->clk_3d_core) {
- clk_put(Device->clk_3d_core);
- Device->clk_3d_core = NULL;
- }
- if (Device->clk_3d_shader) {
- clk_put(Device->clk_3d_shader);
- Device->clk_3d_shader = NULL;
- }
- if (Device->clk_2d_core) {
- clk_put(Device->clk_2d_core);
- Device->clk_2d_core = NULL;
- }
- if (Device->clk_2d_axi) {
- clk_put(Device->clk_2d_axi);
- Device->clk_2d_axi = NULL;
- }
- if (Device->clk_vg_axi) {
- clk_put(Device->clk_vg_axi);
- Device->clk_vg_axi = NULL;
- }
-
-#ifdef CONFIG_PM
- if(Device->pmdev)
- pm_runtime_disable(Device->pmdev);
+ else
#endif
+ {
+ if (Device->registerBases[i] != gcvNULL)
+ {
+ /* Unmap register memory. */
+ iounmap(Device->registerBases[i]);
+ if (Device->requestedRegisterMemBases[i] != 0)
+ {
+ release_mem_region(Device->requestedRegisterMemBases[i],
+ Device->requestedRegisterMemSizes[i]);
+ }
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
- if (Device->gpu_regulator) {
- regulator_put(Device->gpu_regulator);
- Device->gpu_regulator = NULL;
+ Device->registerBases[i] = gcvNULL;
+ Device->requestedRegisterMemBases[i] = 0;
+ Device->requestedRegisterMemSizes[i] = 0;
+ }
+ }
}
-#endif
/* Destroy the gckOS object. */
if (Device->os != gcvNULL)
Device->os = gcvNULL;
}
+ _DebugfsCleanup(Device);
+
/* Free the device. */
kfree(Device);
}
gcmkFOOTER_NO();
return gcvSTATUS_OK;
-
-OnError:
- gcmkFOOTER();
- return status;
}
/*******************************************************************************
)
{
gceSTATUS status;
- gctINT ret;
+ gctINT ret = 0;
gcmkHEADER_ARG("Device=0x%x", Device);
ret = dove_gpio_request(
DOVE_GPIO0_7, &gc500_handle
);
+#else
+#if gcdMULTI_GPU
+ ret = request_irq(
+ Device->irqLine3D[gcvCORE_3D_0_ID], isrRoutine3D0, IRQF_DISABLED,
+ "galcore_3d_0", Device
+ );
+
+ if (ret != 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Could not register irq line %d (error=%d)\n",
+ __FUNCTION__, __LINE__,
+ Device->irqLine3D[gcvCORE_3D_0_ID], ret
+ );
+
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ /* Mark ISR as initialized. */
+ Device->isrInitialized3D[gcvCORE_3D_0_ID] = gcvTRUE;
+
+#if gcdMULTI_GPU > 1
+ ret = request_irq(
+ Device->irqLine3D[gcvCORE_3D_1_ID], isrRoutine3D1, IRQF_DISABLED,
+ "galcore_3d_1", Device
+ );
+
+ if (ret != 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Could not register irq line %d (error=%d)\n",
+ __FUNCTION__, __LINE__,
+ Device->irqLine3D[gcvCORE_3D_1_ID], ret
+ );
+
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ /* Mark ISR as initialized. */
+ Device->isrInitialized3D[gcvCORE_3D_1_ID] = gcvTRUE;
+#endif
+#elif gcdMULTI_GPU_AFFINITY
+ ret = request_irq(
+ Device->irqLines[gcvCORE_MAJOR], isrRoutine3D0, IRQF_DISABLED,
+ "galcore_3d_0", Device
+ );
+
+ if (ret != 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Could not register irq line %d (error=%d)\n",
+ __FUNCTION__, __LINE__,
+ Device->irqLines[gcvCORE_MAJOR], ret
+ );
+
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ /* Mark ISR as initialized. */
+ Device->isrInitializeds[gcvCORE_MAJOR] = gcvTRUE;
+
+ ret = request_irq(
+ Device->irqLines[gcvCORE_OCL], isrRoutine3D1, IRQF_DISABLED,
+ "galcore_3d_1", Device
+ );
+
+ if (ret != 0)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Could not register irq line %d (error=%d)\n",
+ __FUNCTION__, __LINE__,
+ Device->irqLines[gcvCORE_OCL], ret
+ );
+
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ /* Mark ISR as initialized. */
+ Device->isrInitializeds[gcvCORE_OCL] = gcvTRUE;
#else
ret = request_irq(
Device->irqLines[gcvCORE_MAJOR], isrRoutine, IRQF_DISABLED,
"galcore interrupt service", Device
);
-#endif
if (ret != 0)
{
/* Mark ISR as initialized. */
Device->isrInitializeds[gcvCORE_MAJOR] = gcvTRUE;
+#endif
+#endif
gcmkFOOTER_NO();
return gcvSTATUS_OK;
gcmkVERIFY_ARGUMENT(Device != NULL);
+#if gcdMULTI_GPU
+ /* release the irq */
+ if (Device->isrInitialized3D[gcvCORE_3D_0_ID])
+ {
+ free_irq(Device->irqLine3D[gcvCORE_3D_0_ID], Device);
+ Device->isrInitialized3D[gcvCORE_3D_0_ID] = gcvFALSE;
+ }
+#if gcdMULTI_GPU > 1
+ /* release the irq */
+ if (Device->isrInitialized3D[gcvCORE_3D_1_ID])
+ {
+ free_irq(Device->irqLine3D[gcvCORE_3D_1_ID], Device);
+ Device->isrInitialized3D[gcvCORE_3D_1_ID] = gcvFALSE;
+ }
+#endif
+#else
/* release the irq */
if (Device->isrInitializeds[gcvCORE_MAJOR])
{
#else
free_irq(Device->irqLines[gcvCORE_MAJOR], Device);
#endif
-
- Device->isrInitializeds[gcvCORE_MAJOR] = gcvFALSE;
+ Device->isrInitializeds[gcvCORE_MAJOR] = gcvFALSE;
}
+#endif
gcmkFOOTER_NO();
return gcvSTATUS_OK;
free_irq(Device->irqLines[gcvCORE_2D], Device);
#endif
- Device->isrInitializeds[gcvCORE_2D] = gcvFALSE;
+ Device->isrInitializeds[gcvCORE_2D] = gcvFALSE;
}
gcmkFOOTER_NO();
free_irq(Device->irqLines[gcvCORE_VG], Device);
#endif
- Device->isrInitializeds[gcvCORE_VG] = gcvFALSE;
+ Device->isrInitializeds[gcvCORE_VG] = gcvFALSE;
}
gcmkFOOTER_NO();
gcmkVERIFY_ARGUMENT(Device != NULL);
+#if gcdMULTI_GPU
+ if (Device->kernels[gcvCORE_MAJOR] != gcvNULL)
+ {
+ /* Start the kernel thread. */
+ task = kthread_run(threadRoutine3D0, Device, "galcore_3d_0");
+
+ if (IS_ERR(task))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Could not start the kernel thread.\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ Device->threadCtxt3D[gcvCORE_3D_0_ID] = task;
+ Device->threadInitialized3D[gcvCORE_3D_0_ID] = gcvTRUE;
+
+#if gcdMULTI_GPU > 1
+ /* Start the kernel thread. */
+ task = kthread_run(threadRoutine3D1, Device, "galcore_3d_1");
+
+ if (IS_ERR(task))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Could not start the kernel thread.\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ Device->threadCtxt3D[gcvCORE_3D_1_ID] = task;
+ Device->threadInitialized3D[gcvCORE_3D_1_ID] = gcvTRUE;
+#endif
+ }
+#elif gcdMULTI_GPU_AFFINITY
+ if (Device->kernels[gcvCORE_MAJOR] != gcvNULL)
+ {
+ /* Start the kernel thread. */
+ task = kthread_run(threadRoutine3D0, Device, "galcore_3d_0");
+
+ if (IS_ERR(task))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Could not start the kernel thread.\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ Device->threadCtxts[gcvCORE_MAJOR] = task;
+ Device->threadInitializeds[gcvCORE_MAJOR] = gcvTRUE;
+ }
+
+ if (Device->kernels[gcvCORE_OCL] != gcvNULL)
+ {
+ /* Start the kernel thread. */
+ task = kthread_run(threadRoutine3D1, Device, "galcore_3d_1");
+
+ if (IS_ERR(task))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Could not start the kernel thread.\n",
+ __FUNCTION__, __LINE__
+ );
+
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ Device->threadCtxts[gcvCORE_OCL] = task;
+ Device->threadInitializeds[gcvCORE_OCL] = gcvTRUE;
+ }
+#else
if (Device->kernels[gcvCORE_MAJOR] != gcvNULL)
{
/* Start the kernel thread. */
Device->threadCtxts[gcvCORE_MAJOR] = task;
Device->threadInitializeds[gcvCORE_MAJOR] = gcvTRUE;
}
+#endif
if (Device->kernels[gcvCORE_2D] != gcvNULL)
{
)
{
gctINT i;
+#if gcdMULTI_GPU
+ gctINT j;
+#endif
gcmkHEADER_ARG("Device=0x%x", Device);
for (i = 0; i < gcdMAX_GPU_COUNT; i++)
{
- /* Stop the kernel threads. */
- if (Device->threadInitializeds[i])
+#if gcdMULTI_GPU
+ if (i == gcvCORE_MAJOR)
+ {
+ for (j = 0; j < gcdMULTI_GPU; j++)
+ {
+ /* Stop the kernel threads. */
+ if (Device->threadInitialized3D[j])
+ {
+ Device->killThread = gcvTRUE;
+ Device->dataReady3D[j] = gcvTRUE;
+ wake_up_interruptible(&Device->intrWaitQueue3D[j]);
+
+ kthread_stop(Device->threadCtxt3D[j]);
+ Device->threadCtxt3D[j] = gcvNULL;
+ Device->threadInitialized3D[j] = gcvFALSE;
+ }
+ }
+ }
+ else
+#endif
{
- Device->killThread = gcvTRUE;
- up(&Device->semas[i]);
+ /* Stop the kernel threads. */
+ if (Device->threadInitializeds[i])
+ {
+ Device->killThread = gcvTRUE;
+ up(&Device->semas[i]);
- kthread_stop(Device->threadCtxts[i]);
- Device->threadCtxts[i] = gcvNULL;
- Device->threadInitializeds[i] = gcvFALSE;
+ kthread_stop(Device->threadCtxts[i]);
+ Device->threadCtxts[i] = gcvNULL;
+ Device->threadInitializeds[i] = gcvFALSE;
+ }
}
}
/* Setup the ISR routine. */
gcmkONERROR(gckGALDEVICE_Setup_ISR_VG(Device));
+#if gcdENABLE_VG
/* Switch to SUSPEND power state. */
gcmkONERROR(gckVGHARDWARE_SetPowerManagementState(
Device->kernels[gcvCORE_VG]->vg->hardware, gcvPOWER_OFF_BROADCAST
));
+#endif
}
gcmkFOOTER_NO();
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#ifndef __gc_hal_kernel_device_h_
#define __gc_hal_kernel_device_h_
+#include "gc_hal_kernel_debugfs.h"
+
/******************************************************************************\
******************************* gckGALDEVICE Structure *******************************
\******************************************************************************/
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
-struct contiguous_mem_pool {
- struct dma_attrs attrs;
- dma_addr_t phys;
- void *virt;
- size_t size;
-};
-#endif
-
typedef struct _gckGALDEVICE
{
/* Objects. */
gckOS os;
gckKERNEL kernels[gcdMAX_GPU_COUNT];
+ gcsPLATFORM* platform;
+
/* Attributes. */
gctSIZE_T internalSize;
gctPHYS_ADDR internalPhysical;
gctSIZE_T contiguousSize;
gctBOOL contiguousMapped;
gctPOINTER contiguousMappedUser;
+ gctBOOL contiguousRequested;
gctSIZE_T systemMemorySize;
gctUINT32 systemMemoryBaseAddress;
+#if gcdMULTI_GPU
+ gctPOINTER registerBase3D[gcdMULTI_GPU];
+ gctSIZE_T registerSize3D[gcdMULTI_GPU];
+#endif
gctPOINTER registerBases[gcdMAX_GPU_COUNT];
gctSIZE_T registerSizes[gcdMAX_GPU_COUNT];
gctUINT32 baseAddress;
+ gctUINT32 physBase;
+ gctUINT32 physSize;
+ gctBOOL mmu;
+#if gcdMULTI_GPU
+ gctUINT32 requestedRegisterMemBase3D[gcdMULTI_GPU];
+ gctSIZE_T requestedRegisterMemSize3D[gcdMULTI_GPU];
+#endif
gctUINT32 requestedRegisterMemBases[gcdMAX_GPU_COUNT];
gctSIZE_T requestedRegisterMemSizes[gcdMAX_GPU_COUNT];
gctUINT32 requestedContiguousBase;
gctSIZE_T requestedContiguousSize;
/* IRQ management. */
+#if gcdMULTI_GPU
+ gctINT irqLine3D[gcdMULTI_GPU];
+ gctBOOL isrInitialized3D[gcdMULTI_GPU];
+ gctBOOL dataReady3D[gcdMULTI_GPU];
+#endif
gctINT irqLines[gcdMAX_GPU_COUNT];
gctBOOL isrInitializeds[gcdMAX_GPU_COUNT];
- gctBOOL dataReadys[gcdMAX_GPU_COUNT];
/* Thread management. */
+#if gcdMULTI_GPU
+ struct task_struct *threadCtxt3D[gcdMULTI_GPU];
+ wait_queue_head_t intrWaitQueue3D[gcdMULTI_GPU];
+ gctBOOL threadInitialized3D[gcdMULTI_GPU];
+#endif
struct task_struct *threadCtxts[gcdMAX_GPU_COUNT];
struct semaphore semas[gcdMAX_GPU_COUNT];
gctBOOL threadInitializeds[gcdMAX_GPU_COUNT];
/* States before suspend. */
gceCHIPPOWERSTATE statesStored[gcdMAX_GPU_COUNT];
- /*Device Debug File System Entry in Kernel*/
- struct _gcsDebugFileSystemNode * dbgnode;
+ /* Device Debug File System Entry in kernel. */
+ struct _gcsDEBUGFS_Node * dbgNode;
- /* Clock management.*/
- struct clk *clk_3d_core;
- struct clk *clk_3d_shader;
- struct clk *clk_3d_axi;
- struct clk *clk_2d_core;
- struct clk *clk_2d_axi;
- struct clk *clk_vg_axi;
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
- /*Power management.*/
- struct regulator *gpu_regulator;
-#endif
- /*Run time pm*/
- struct device *pmdev;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
- struct contiguous_mem_pool *pool;
- struct reset_control *rstc[gcdMAX_GPU_COUNT];
-#endif
+ gcsDEBUGFS_DIR debugfsDir;
}
* gckGALDEVICE;
}
gcsHAL_PRIVATE_DATA, * gcsHAL_PRIVATE_DATA_PTR;
+typedef struct _gcsDEVICE_CONSTRUCT_ARGS
+{
+ gctBOOL recovery;
+ gctUINT stuckDump;
+ gctUINT gpu3DMinClock;
+
+ gctBOOL contiguousRequested;
+ gcsPLATFORM* platform;
+ gctBOOL mmu;
+}
+gcsDEVICE_CONSTRUCT_ARGS;
+
gceSTATUS gckGALDEVICE_Setup_ISR(
IN gckGALDEVICE Device
);
);
gceSTATUS gckGALDEVICE_Construct(
+#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY
+ IN gctINT IrqLine3D0,
+ IN gctUINT32 RegisterMemBase3D0,
+ IN gctSIZE_T RegisterMemSize3D0,
+ IN gctINT IrqLine3D1,
+ IN gctUINT32 RegisterMemBase3D1,
+ IN gctSIZE_T RegisterMemSize3D1,
+#else
IN gctINT IrqLine,
IN gctUINT32 RegisterMemBase,
IN gctSIZE_T RegisterMemSize,
+#endif
IN gctINT IrqLine2D,
IN gctUINT32 RegisterMemBase2D,
IN gctSIZE_T RegisterMemSize2D,
IN gctUINT32 PhysSize,
IN gctINT Signal,
IN gctUINT LogFileSize,
- IN struct device *pdev,
IN gctINT PowerManagement,
IN gctINT GpuProfiler,
+ IN gcsDEVICE_CONSTRUCT_ARGS * Args,
OUT gckGALDEVICE *Device
);
--- /dev/null
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2014 by Vivante Corp.
+*
+* 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.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+#include "gc_hal_kernel_device.h"
+
+#include <linux/iommu.h>
+#include <linux/platform_device.h>
+
+#define _GC_OBJ_ZONE gcvZONE_OS
+
+typedef struct _gcsIOMMU
+{
+ struct iommu_domain * domain;
+ struct device * device;
+}
+gcsIOMMU;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+static int
+_IOMMU_Fault_Handler(
+ struct iommu_domain * Domain,
+ struct device * Dev,
+ unsigned long DomainAddress,
+ int flags,
+ void * args
+ )
+#else
+static int
+_IOMMU_Fault_Handler(
+ struct iommu_domain * Domain,
+ struct device * Dev,
+ unsigned long DomainAddress,
+ int flags
+ )
+#endif
+{
+ return 0;
+}
+
+static int
+_FlatMapping(
+ IN gckIOMMU Iommu
+ )
+{
+ gceSTATUS status;
+ gctUINT32 physical;
+
+ for (physical = 0; physical < 0x80000000; physical += PAGE_SIZE)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "Map %x => %x bytes = %d",
+ physical, physical, PAGE_SIZE
+ );
+
+ gcmkONERROR(gckIOMMU_Map(Iommu, physical, physical, PAGE_SIZE));
+ }
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+void
+gckIOMMU_Destory(
+ IN gckOS Os,
+ IN gckIOMMU Iommu
+ )
+{
+ gcmkHEADER();
+
+ if (Iommu->domain && Iommu->device)
+ {
+ iommu_attach_device(Iommu->domain, Iommu->device);
+ }
+
+ if (Iommu->domain)
+ {
+ iommu_domain_free(Iommu->domain);
+ }
+
+ if (Iommu)
+ {
+ gcmkOS_SAFE_FREE(Os, Iommu);
+ }
+
+ gcmkFOOTER_NO();
+}
+
+gceSTATUS
+gckIOMMU_Construct(
+ IN gckOS Os,
+ OUT gckIOMMU * Iommu
+ )
+{
+ gceSTATUS status;
+ gckIOMMU iommu = gcvNULL;
+ struct device *dev;
+ int ret;
+
+ gcmkHEADER();
+
+ dev = &Os->device->platform->device->dev;
+
+ gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsIOMMU), (gctPOINTER *)&iommu));
+
+ gckOS_ZeroMemory(iommu, gcmSIZEOF(gcsIOMMU));
+
+ iommu->domain = iommu_domain_alloc(&platform_bus_type);
+
+ if (!iommu->domain)
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "iommu_domain_alloc() fail");
+
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ iommu_set_fault_handler(iommu->domain, _IOMMU_Fault_Handler, dev);
+#else
+ iommu_set_fault_handler(iommu->domain, _IOMMU_Fault_Handler);
+#endif
+
+ ret = iommu_attach_device(iommu->domain, dev);
+
+ if (ret)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS, "iommu_attach_device() fail %d", ret);
+
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ iommu->device = dev;
+
+ _FlatMapping(iommu);
+
+ *Iommu = iommu;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+
+ gckIOMMU_Destory(Os, iommu);
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckIOMMU_Map(
+ IN gckIOMMU Iommu,
+ IN gctUINT32 DomainAddress,
+ IN gctUINT32 Physical,
+ IN gctUINT32 Bytes
+ )
+{
+ gceSTATUS status;
+ int ret;
+
+ gcmkHEADER_ARG("DomainAddress=%#X, Physical=%#X, Bytes=%d",
+ DomainAddress, Physical, Bytes);
+
+ ret = iommu_map(Iommu->domain, DomainAddress, Physical, Bytes, 0);
+
+ if (ret)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+
+ gcmkFOOTER();
+ return status;
+
+}
+
+gceSTATUS
+gckIOMMU_Unmap(
+ IN gckIOMMU Iommu,
+ IN gctUINT32 DomainAddress,
+ IN gctUINT32 Bytes
+ )
+{
+ gcmkHEADER();
+
+ iommu_unmap(Iommu->domain, DomainAddress, Bytes);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
OUT gctPOINTER * Logical
)
{
- gckGALDEVICE device;
- PLINUX_MDL mdl;
- PLINUX_MDL_MAP mdlMap;
- gcePOOL pool;
- gctUINT32 offset, base;
+ gckGALDEVICE device = gcvNULL;
+ PLINUX_MDL mdl = gcvNULL;
+ PLINUX_MDL_MAP mdlMap = gcvNULL;
+ gcePOOL pool = gcvPOOL_UNKNOWN;
+ gctUINT32 offset = 0;
+ gctUINT32 base = 0;
gceSTATUS status;
- gctPOINTER logical;
+ gctPOINTER logical = gcvNULL;
+ gctUINT32 baseAddress;
gcmkHEADER_ARG("Kernel=%p InUserSpace=%d Address=%08x",
Kernel, InUserSpace, Address);
else
#endif
{
- gctUINT32 baseAddress = 0;
+ gctUINT32 systemBaseAddress = 0;
if (Kernel->hardware->mmuVersion == 0)
{
- gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress));
+ gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &systemBaseAddress));
}
+ gcmkVERIFY_OK(
+ gckOS_CPUPhysicalToGPUPhysical(
+ Kernel->os,
+ device->contiguousVidMem->baseAddress - systemBaseAddress,
+ &baseAddress
+ ));
+
gcmkVERIFY_OK(
gckHARDWARE_SplitMemory(Kernel->hardware,
- device->contiguousVidMem->baseAddress - baseAddress,
+ baseAddress,
&pool,
&base));
}
gceSTATUS
gckKERNEL_Notify(
IN gckKERNEL Kernel,
+#if gcdMULTI_GPU
+ IN gctUINT CoreId,
+#endif
IN gceNOTIFY Notification,
IN gctBOOL Data
)
#if COMMAND_PROCESSOR_VERSION > 1
status = gckINTERRUPT_Notify(Kernel->interrupt, Data);
#else
- status = gckHARDWARE_Interrupt(Kernel->hardware, Data);
+ status = gckHARDWARE_Interrupt(Kernel->hardware,
+#if gcdMULTI_GPU
+ CoreId,
+#endif
+ Data);
#endif
break;
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#include <linux/dma-mapping.h>
#include <linux/kthread.h>
+#include <linux/idr.h>
+
#ifdef MODVERSIONS
# include <linux/modversions.h>
#endif
#if ENABLE_GPU_CLOCK_BY_DRIVER && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
#include <linux/clk.h>
-#include <linux/regulator/consumer.h>
#endif
#define NTSTRSAFE_NO_CCH_FUNCTIONS
#include "gc_hal.h"
#include "gc_hal_driver.h"
#include "gc_hal_kernel.h"
+#include "gc_hal_kernel_platform.h"
#include "gc_hal_kernel_device.h"
#include "gc_hal_kernel_os.h"
#include "gc_hal_kernel_debugfs.h"
+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
#define FIND_TASK_BY_PID(x) pid_task(find_vpid(x), PIDTYPE_PID)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
#define FIND_TASK_BY_PID(x) find_task_by_pid(x)
#endif
-#define _WIDE(string) L##string
-#define WIDE(string) _WIDE(string)
+#define _WIDE(string) L##string
+#define WIDE(string) _WIDE(string)
-#define countof(a) (sizeof(a) / sizeof(a[0]))
+#define countof(a) (sizeof(a) / sizeof(a[0]))
-#define DRV_NAME "galcore"
+#ifndef DEVICE_NAME
+#ifdef CONFIG_DOVE_GPU
+# define DEVICE_NAME "dove_gpu"
+#else
+# define DEVICE_NAME "galcore"
+#endif
+#endif
-#define GetPageCount(size, offset) ((((size) + ((offset) & ~PAGE_CACHE_MASK)) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT)
+#define GetPageCount(size, offset) ((((size) + ((offset) & ~PAGE_CACHE_MASK)) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT)
#if LINUX_VERSION_CODE >= KERNEL_VERSION (3,7,0)
#define gcdVM_FLAGS (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP)
#define gcdVM_FLAGS (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED)
#endif
+/* Protection bit when mapping memroy to user sapce */
+#define gcmkPAGED_MEMROY_PROT(x) pgprot_writecombine(x)
+
+#if gcdNONPAGED_MEMORY_BUFFERABLE
+#define gcmkIOREMAP ioremap_wc
+#define gcmkNONPAGED_MEMROY_PROT(x) pgprot_writecombine(x)
+#elif !gcdNONPAGED_MEMORY_CACHEABLE
+#define gcmkIOREMAP ioremap_nocache
+#define gcmkNONPAGED_MEMROY_PROT(x) pgprot_noncached(x)
+#endif
+
+#define gcdSUPPRESS_OOM_MESSAGE 1
+
+#if gcdSUPPRESS_OOM_MESSAGE
+#define gcdNOWARN __GFP_NOWARN
+#else
+#define gcdNOWARN 0
+#endif
+
+/******************************************************************************\
+********************************** Structures **********************************
+\******************************************************************************/
+typedef struct _gcsIOMMU * gckIOMMU;
+
+typedef struct _gcsUSER_MAPPING * gcsUSER_MAPPING_PTR;
+typedef struct _gcsUSER_MAPPING
+{
+ /* Pointer to next mapping structure. */
+ gcsUSER_MAPPING_PTR next;
+
+ /* Physical address of this mapping. */
+ gctUINT32 physical;
+
+ /* Logical address of this mapping. */
+ gctPOINTER logical;
+
+ /* Number of bytes of this mapping. */
+ gctSIZE_T bytes;
+
+ /* Starting address of this mapping. */
+ gctINT8_PTR start;
+
+ /* Ending address of this mapping. */
+ gctINT8_PTR end;
+}
+gcsUSER_MAPPING;
+
+typedef struct _gcsINTEGER_DB * gcsINTEGER_DB_PTR;
+typedef struct _gcsINTEGER_DB
+{
+ struct idr idr;
+ spinlock_t lock;
+ gctINT curr;
+}
+gcsINTEGER_DB;
+
+struct _gckOS
+{
+ /* Object. */
+ gcsOBJECT object;
+
+ /* Pointer to device */
+ gckGALDEVICE device;
+
+ /* Memory management */
+ gctPOINTER memoryLock;
+ gctPOINTER memoryMapLock;
+
+ struct _LINUX_MDL *mdlHead;
+ struct _LINUX_MDL *mdlTail;
+
+ /* Kernel process ID. */
+ gctUINT32 kernelProcessID;
+
+ /* Signal management. */
+
+ /* Lock. */
+ gctPOINTER signalMutex;
+
+ /* signal id database. */
+ gcsINTEGER_DB signalDB;
+
+#if gcdANDROID_NATIVE_FENCE_SYNC
+ /* Lock. */
+ gctPOINTER syncPointMutex;
+
+ /* sync point id database. */
+ gcsINTEGER_DB syncPointDB;
+#endif
+
+ gcsUSER_MAPPING_PTR userMap;
+ gctPOINTER debugLock;
+
+ /* workqueue for os timer. */
+ struct workqueue_struct * workqueue;
+
+ /* Allocate extra page to avoid cache overflow */
+ struct page* paddingPage;
+
+ /* Detect unfreed allocation. */
+ atomic_t allocateCount;
+
+ struct list_head allocatorList;
+
+ gcsDEBUGFS_DIR allocatorDebugfsDir;
+
+ /* Lock for register access check. */
+ struct mutex registerAccessLocks[gcdMAX_GPU_COUNT];
+
+ /* External power states. */
+ gctBOOL powerStates[gcdMAX_GPU_COUNT];
+
+ /* External clock states. */
+ gctBOOL clockStates[gcdMAX_GPU_COUNT];
+
+ /* IOMMU. */
+ gckIOMMU iommu;
+};
+
+typedef struct _gcsSIGNAL * gcsSIGNAL_PTR;
+typedef struct _gcsSIGNAL
+{
+ /* Kernel sync primitive. */
+ struct completion obj;
+
+ /* Manual reset flag. */
+ gctBOOL manualReset;
+
+ /* The reference counter. */
+ atomic_t ref;
+
+ /* The owner of the signal. */
+ gctHANDLE process;
+
+ gckHARDWARE hardware;
+
+ /* ID. */
+ gctUINT32 id;
+}
+gcsSIGNAL;
+
+#if gcdANDROID_NATIVE_FENCE_SYNC
+typedef struct _gcsSYNC_POINT * gcsSYNC_POINT_PTR;
+typedef struct _gcsSYNC_POINT
+{
+ /* The reference counter. */
+ atomic_t ref;
+
+ /* State. */
+ atomic_t state;
+
+ /* timeline. */
+ struct sync_timeline * timeline;
+
+ /* ID. */
+ gctUINT32 id;
+}
+gcsSYNC_POINT;
+#endif
+
+typedef struct _gcsPageInfo * gcsPageInfo_PTR;
+typedef struct _gcsPageInfo
+{
+ struct page **pages;
+ gctUINT32_PTR pageTable;
+ gctUINT32 extraPage;
+ gctUINT32 address;
+#if gcdPROCESS_ADDRESS_SPACE
+ gckMMU mmu;
+#endif
+}
+gcsPageInfo;
+
+typedef struct _gcsOSTIMER * gcsOSTIMER_PTR;
+typedef struct _gcsOSTIMER
+{
+ struct delayed_work work;
+ gctTIMERFUNCTION function;
+ gctPOINTER data;
+} gcsOSTIMER;
+
+gceSTATUS
+gckOS_ImportAllocators(
+ gckOS Os
+ );
+
+gceSTATUS
+gckOS_FreeAllocators(
+ gckOS Os
+ );
+
+gceSTATUS
+_HandleOuterCache(
+ IN gckOS Os,
+ IN gctUINT32 Physical,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes,
+ IN gceCACHEOPERATION Type
+ );
+
+gceSTATUS
+_ConvertLogical2Physical(
+ IN gckOS Os,
+ IN gctPOINTER Logical,
+ IN gctUINT32 ProcessID,
+ IN PLINUX_MDL Mdl,
+ OUT gctUINT32_PTR Physical
+ );
+
+gctSTRING
+_CreateKernelVirtualMapping(
+ IN PLINUX_MDL Mdl
+ );
+
+void
+_DestoryKernelVirtualMapping(
+ IN gctSTRING Addr
+ );
+
+void
+_UnmapUserLogical(
+ IN gctPOINTER Logical,
+ IN gctUINT32 Size
+ );
+
static inline gctINT
-GetOrder(
- IN gctINT numPages
- )
+_GetProcessID(
+ void
+ )
{
- gctINT order = 0;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+ return task_tgid_vnr(current);
+#else
+ return current->tgid;
+#endif
+}
- while ((1 << order) < numPages) order++;
+static inline struct page *
+_NonContiguousToPage(
+ IN struct page ** Pages,
+ IN gctUINT32 Index
+ )
+{
+ gcmkASSERT(Pages != gcvNULL);
+ return Pages[Index];
+}
- return order;
+static inline unsigned long
+_NonContiguousToPfn(
+ IN struct page ** Pages,
+ IN gctUINT32 Index
+ )
+{
+ gcmkASSERT(Pages != gcvNULL);
+ return page_to_pfn(_NonContiguousToPage(Pages, Index));
}
+static inline unsigned long
+_NonContiguousToPhys(
+ IN struct page ** Pages,
+ IN gctUINT32 Index
+ )
+{
+ gcmkASSERT(Pages != gcvNULL);
+ return page_to_phys(_NonContiguousToPage(Pages, Index));
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
+static inline int
+is_vmalloc_addr(
+ void *Addr
+ )
+{
+ unsigned long addr = (unsigned long)Addr;
+
+ return addr >= VMALLOC_START && addr < VMALLOC_END;
+}
+#endif
+
+#ifdef CONFIG_IOMMU_SUPPORT
+void
+gckIOMMU_Destory(
+ IN gckOS Os,
+ IN gckIOMMU Iommu
+ );
+
+gceSTATUS
+gckIOMMU_Construct(
+ IN gckOS Os,
+ OUT gckIOMMU * Iommu
+ );
+
+gceSTATUS
+gckIOMMU_Map(
+ IN gckIOMMU Iommu,
+ IN gctUINT32 DomainAddress,
+ IN gctUINT32 Physical,
+ IN gctUINT32 Bytes
+ );
+
+gceSTATUS
+gckIOMMU_Unmap(
+ IN gckIOMMU Iommu,
+ IN gctUINT32 DomainAddress,
+ IN gctUINT32 Bytes
+ );
+#endif
+
#endif /* __gc_hal_kernel_linux_h_ */
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#include <linux/pagemap.h>
#include <linux/seq_file.h>
-#include <linux/mm.h>
#include <linux/mman.h>
-#include <linux/sched.h>
#include <asm/atomic.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
-#include <linux/idr.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
-#include <mach/hardware.h>
-#endif
#include <linux/workqueue.h>
-#include <linux/idr.h>
+#include <linux/irqflags.h>
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
#include <linux/math64.h>
#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
-#include <linux/reset.h>
-static inline void imx_gpc_power_up_pu(bool flag) {}
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
-#include <mach/common.h>
-#endif
#include <linux/delay.h>
-#include <linux/pm_runtime.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+#include <linux/anon_inodes.h>
+#endif
#if gcdANDROID_NATIVE_FENCE_SYNC
#include <linux/file.h>
#include "gc_hal_kernel_sync.h"
#endif
-
#define _GC_OBJ_ZONE gcvZONE_OS
-/*******************************************************************************
-***** Version Signature *******************************************************/
-
-#ifdef ANDROID
-const char * _PLATFORM = "\n\0$PLATFORM$Android$\n";
-#else
-const char * _PLATFORM = "\n\0$PLATFORM$Linux$\n";
-#endif
-
-#define USER_SIGNAL_TABLE_LEN_INIT 64
-#define gcdSUPPRESS_OOM_MESSAGE 1
+#include "gc_hal_kernel_allocator.h"
#define MEMORY_LOCK(os) \
gcmkVERIFY_OK(gckOS_AcquireMutex( \
#define MEMORY_MAP_UNLOCK(os) \
gcmkVERIFY_OK(gckOS_ReleaseMutex((os), (os)->memoryMapLock))
-/* Protection bit when mapping memroy to user sapce */
-#define gcmkPAGED_MEMROY_PROT(x) pgprot_writecombine(x)
-
-#if gcdNONPAGED_MEMORY_BUFFERABLE
-#define gcmkIOREMAP ioremap_wc
-#define gcmkNONPAGED_MEMROY_PROT(x) pgprot_writecombine(x)
-#elif !gcdNONPAGED_MEMORY_CACHEABLE
-#define gcmkIOREMAP ioremap_nocache
-#define gcmkNONPAGED_MEMROY_PROT(x) pgprot_noncached(x)
-#endif
-
-#if gcdSUPPRESS_OOM_MESSAGE
-#define gcdNOWARN __GFP_NOWARN
-#else
-#define gcdNOWARN 0
-#endif
-
-#define gcdINFINITE_TIMEOUT (60 * 1000)
-#define gcdDETECT_TIMEOUT 0
-#define gcdDETECT_DMA_ADDRESS 1
-#define gcdDETECT_DMA_STATE 1
-
-#define gcdUSE_NON_PAGED_MEMORY_CACHE 10
-
-/******************************************************************************\
-********************************** Structures **********************************
-\******************************************************************************/
-#if gcdUSE_NON_PAGED_MEMORY_CACHE
-typedef struct _gcsNonPagedMemoryCache
-{
-#ifndef NO_DMA_COHERENT
- gctINT size;
- gctSTRING addr;
- dma_addr_t dmaHandle;
-#else
- long order;
- struct page * page;
-#endif
-
- struct _gcsNonPagedMemoryCache * prev;
- struct _gcsNonPagedMemoryCache * next;
-}
-gcsNonPagedMemoryCache;
-#endif /* gcdUSE_NON_PAGED_MEMORY_CACHE */
-
-typedef struct _gcsUSER_MAPPING * gcsUSER_MAPPING_PTR;
-typedef struct _gcsUSER_MAPPING
-{
- /* Pointer to next mapping structure. */
- gcsUSER_MAPPING_PTR next;
-
- /* Physical address of this mapping. */
- gctUINT32 physical;
-
- /* Logical address of this mapping. */
- gctPOINTER logical;
-
- /* Number of bytes of this mapping. */
- gctSIZE_T bytes;
-
- /* Starting address of this mapping. */
- gctINT8_PTR start;
-
- /* Ending address of this mapping. */
- gctINT8_PTR end;
-}
-gcsUSER_MAPPING;
-
-typedef struct _gcsINTEGER_DB * gcsINTEGER_DB_PTR;
-typedef struct _gcsINTEGER_DB
-{
- struct idr idr;
- spinlock_t lock;
- gctINT curr;
-}
-gcsINTEGER_DB;
-
-struct _gckOS
-{
- /* Object. */
- gcsOBJECT object;
-
- /* Heap. */
- gckHEAP heap;
-
- /* Pointer to device */
- gckGALDEVICE device;
-
- /* Memory management */
- gctPOINTER memoryLock;
- gctPOINTER memoryMapLock;
-
- struct _LINUX_MDL *mdlHead;
- struct _LINUX_MDL *mdlTail;
-
- /* Kernel process ID. */
- gctUINT32 kernelProcessID;
-
- /* Signal management. */
-
- /* Lock. */
- gctPOINTER signalMutex;
-
- /* signal id database. */
- gcsINTEGER_DB signalDB;
-
-#if gcdANDROID_NATIVE_FENCE_SYNC
- /* Lock. */
- gctPOINTER syncPointMutex;
-
- /* sync point id database. */
- gcsINTEGER_DB syncPointDB;
-#endif
-
- gcsUSER_MAPPING_PTR userMap;
- gctPOINTER debugLock;
-
-#if gcdUSE_NON_PAGED_MEMORY_CACHE
- gctUINT cacheSize;
- gcsNonPagedMemoryCache * cacheHead;
- gcsNonPagedMemoryCache * cacheTail;
-#endif
-
- /* workqueue for os timer. */
- struct workqueue_struct * workqueue;
-};
-
-typedef struct _gcsSIGNAL * gcsSIGNAL_PTR;
-typedef struct _gcsSIGNAL
-{
- /* Kernel sync primitive. */
- struct completion obj;
-
- /* Manual reset flag. */
- gctBOOL manualReset;
-
- /* The reference counter. */
- atomic_t ref;
-
- /* The owner of the signal. */
- gctHANDLE process;
-
- gckHARDWARE hardware;
-
- /* ID. */
- gctUINT32 id;
-}
-gcsSIGNAL;
-
-#if gcdANDROID_NATIVE_FENCE_SYNC
-typedef struct _gcsSYNC_POINT * gcsSYNC_POINT_PTR;
-typedef struct _gcsSYNC_POINT
-{
- /* The reference counter. */
- atomic_t ref;
-
- /* State. */
- atomic_t state;
-
- /* timeline. */
- struct sync_timeline * timeline;
-
- /* ID. */
- gctUINT32 id;
-}
-gcsSYNC_POINT;
-#endif
-
-typedef struct _gcsPageInfo * gcsPageInfo_PTR;
-typedef struct _gcsPageInfo
-{
- struct page **pages;
- gctUINT32_PTR pageTable;
-}
-gcsPageInfo;
-
-typedef struct _gcsOSTIMER * gcsOSTIMER_PTR;
-typedef struct _gcsOSTIMER
-{
- struct delayed_work work;
- gctTIMERFUNCTION function;
- gctPOINTER data;
-} gcsOSTIMER;
/******************************************************************************\
******************************* Private Functions ******************************
\******************************************************************************/
-
-static gctINT
-_GetProcessID(
- void
- )
-{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
- return task_tgid_vnr(current);
-#else
- return current->tgid;
-#endif
-}
-
static gctINT
_GetThreadID(
void
static PLINUX_MDL
_CreateMdl(
- IN gctINT ProcessID
+ void
)
{
PLINUX_MDL mdl;
- gcmkHEADER_ARG("ProcessID=%d", ProcessID);
+ gcmkHEADER();
mdl = (PLINUX_MDL)kzalloc(sizeof(struct _LINUX_MDL), GFP_KERNEL | gcdNOWARN);
- if (mdl == gcvNULL)
- {
- gcmkFOOTER_NO();
- return gcvNULL;
- }
-
- mdl->pid = ProcessID;
- mdl->maps = gcvNULL;
- mdl->prev = gcvNULL;
- mdl->next = gcvNULL;
gcmkFOOTER_ARG("0x%X", mdl);
return mdl;
return gcvNULL;
}
-void
-OnProcessExit(
- IN gckOS Os,
- IN gckKERNEL Kernel
- )
-{
-}
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
-static inline int
-is_vmalloc_addr(
- void *Addr
- )
-{
- unsigned long addr = (unsigned long)Addr;
-
- return addr >= VMALLOC_START && addr < VMALLOC_END;
-}
-#endif
-
-static void
-_NonContiguousFree(
- IN struct page ** Pages,
- IN gctUINT32 NumPages
- )
-{
- gctINT i;
-
- gcmkHEADER_ARG("Pages=0x%X, NumPages=%d", Pages, NumPages);
-
- gcmkASSERT(Pages != gcvNULL);
-
- for (i = 0; i < NumPages; i++)
- {
- __free_page(Pages[i]);
- }
-
- if (is_vmalloc_addr(Pages))
- {
- vfree(Pages);
- }
- else
- {
- kfree(Pages);
- }
-
- gcmkFOOTER_NO();
-}
-
-static struct page **
-_NonContiguousAlloc(
- IN gctUINT32 NumPages
- )
-{
- struct page ** pages;
- struct page *p;
- gctINT i, size;
-
- gcmkHEADER_ARG("NumPages=%lu", NumPages);
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
- if (NumPages > totalram_pages)
-#else
- if (NumPages > num_physpages)
-#endif
- {
- gcmkFOOTER_NO();
- return gcvNULL;
- }
-
- size = NumPages * sizeof(struct page *);
-
- pages = kmalloc(size, GFP_KERNEL | gcdNOWARN);
-
- if (!pages)
- {
- pages = vmalloc(size);
-
- if (!pages)
- {
- gcmkFOOTER_NO();
- return gcvNULL;
- }
- }
-
- for (i = 0; i < NumPages; i++)
- {
- p = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN);
-
- if (!p)
- {
- _NonContiguousFree(pages, i);
- gcmkFOOTER_NO();
- return gcvNULL;
- }
-
- pages[i] = p;
- }
-
- gcmkFOOTER_ARG("pages=0x%X", pages);
- return pages;
-}
-
-static inline struct page *
-_NonContiguousToPage(
- IN struct page ** Pages,
- IN gctUINT32 Index
- )
-{
- gcmkASSERT(Pages != gcvNULL);
- return Pages[Index];
-}
-
-static inline unsigned long
-_NonContiguousToPfn(
- IN struct page ** Pages,
- IN gctUINT32 Index
- )
-{
- gcmkASSERT(Pages != gcvNULL);
- return page_to_pfn(_NonContiguousToPage(Pages, Index));
-}
-
-static inline unsigned long
-_NonContiguousToPhys(
- IN struct page ** Pages,
- IN gctUINT32 Index
- )
-{
- gcmkASSERT(Pages != gcvNULL);
- return page_to_phys(_NonContiguousToPage(Pages, Index));
-}
-
-
-#if gcdUSE_NON_PAGED_MEMORY_CACHE
-
-static gctBOOL
-_AddNonPagedMemoryCache(
- gckOS Os,
-#ifndef NO_DMA_COHERENT
- gctINT Size,
- gctSTRING Addr,
- dma_addr_t DmaHandle
-#else
- long Order,
- struct page * Page
-#endif
- )
-{
- gcsNonPagedMemoryCache *cache;
-
- if (Os->cacheSize >= gcdUSE_NON_PAGED_MEMORY_CACHE)
- {
- return gcvFALSE;
- }
-
- /* Allocate the cache record */
- cache = (gcsNonPagedMemoryCache *)kmalloc(sizeof(gcsNonPagedMemoryCache), GFP_ATOMIC);
-
- if (cache == gcvNULL) return gcvFALSE;
-
-#ifndef NO_DMA_COHERENT
- cache->size = Size;
- cache->addr = Addr;
- cache->dmaHandle = DmaHandle;
-#else
- cache->order = Order;
- cache->page = Page;
-#endif
-
- /* Add to list */
- if (Os->cacheHead == gcvNULL)
- {
- cache->prev = gcvNULL;
- cache->next = gcvNULL;
- Os->cacheHead =
- Os->cacheTail = cache;
- }
- else
- {
- /* Add to the tail. */
- cache->prev = Os->cacheTail;
- cache->next = gcvNULL;
- Os->cacheTail->next = cache;
- Os->cacheTail = cache;
- }
-
- Os->cacheSize++;
-
- return gcvTRUE;
-}
-
-#ifndef NO_DMA_COHERENT
-static gctSTRING
-_GetNonPagedMemoryCache(
- gckOS Os,
- gctINT Size,
- dma_addr_t * DmaHandle
- )
-#else
-static struct page *
-_GetNonPagedMemoryCache(
- gckOS Os,
- long Order
- )
-#endif
-{
- gcsNonPagedMemoryCache *cache;
-#ifndef NO_DMA_COHERENT
- gctSTRING addr;
-#else
- struct page * page;
-#endif
-
- if (Os->cacheHead == gcvNULL) return gcvNULL;
-
- /* Find the right cache */
- cache = Os->cacheHead;
-
- while (cache != gcvNULL)
- {
-#ifndef NO_DMA_COHERENT
- if (cache->size == Size) break;
-#else
- if (cache->order == Order) break;
-#endif
-
- cache = cache->next;
- }
-
- if (cache == gcvNULL) return gcvNULL;
-
- /* Remove the cache from list */
- if (cache == Os->cacheHead)
- {
- Os->cacheHead = cache->next;
-
- if (Os->cacheHead == gcvNULL)
- {
- Os->cacheTail = gcvNULL;
- }
- }
- else
- {
- cache->prev->next = cache->next;
-
- if (cache == Os->cacheTail)
- {
- Os->cacheTail = cache->prev;
- }
- else
- {
- cache->next->prev = cache->prev;
- }
- }
-
- /* Destroy cache */
-#ifndef NO_DMA_COHERENT
- addr = cache->addr;
- *DmaHandle = cache->dmaHandle;
-#else
- page = cache->page;
-#endif
-
- kfree(cache);
-
- Os->cacheSize--;
-
-#ifndef NO_DMA_COHERENT
- return addr;
-#else
- return page;
-#endif
-}
-
-static void
-_FreeAllNonPagedMemoryCache(
- gckOS Os
- )
-{
- gcsNonPagedMemoryCache *cache, *nextCache;
-
- MEMORY_LOCK(Os);
-
- cache = Os->cacheHead;
-
- while (cache != gcvNULL)
- {
- if (cache != Os->cacheTail)
- {
- nextCache = cache->next;
- }
- else
- {
- nextCache = gcvNULL;
- }
-
- /* Remove the cache from list */
- if (cache == Os->cacheHead)
- {
- Os->cacheHead = cache->next;
-
- if (Os->cacheHead == gcvNULL)
- {
- Os->cacheTail = gcvNULL;
- }
- }
- else
- {
- cache->prev->next = cache->next;
-
- if (cache == Os->cacheTail)
- {
- Os->cacheTail = cache->prev;
- }
- else
- {
- cache->next->prev = cache->prev;
- }
- }
-
-#ifndef NO_DMA_COHERENT
- dma_free_coherent(gcvNULL,
- cache->size,
- cache->addr,
- cache->dmaHandle);
-#else
- free_pages((unsigned long)page_address(cache->page), cache->order);
-#endif
-
- kfree(cache);
-
- cache = nextCache;
- }
-
- MEMORY_UNLOCK(Os);
-}
-
-#endif /* gcdUSE_NON_PAGED_MEMORY_CACHE */
-
/*******************************************************************************
** Integer Id Management.
*/
spin_lock(&Database->lock);
next = (Database->curr + 1 <= 0) ? 1 : Database->curr + 1;
+
result = idr_alloc(&Database->idr, KernelPointer, next, 0, GFP_ATOMIC);
- if (!result)
+ /* ID allocated should not be 0. */
+ gcmkASSERT(result != 0);
+
+ if (result > 0)
{
- Database->curr = *Id;
+ Database->curr = *Id = result;
}
spin_unlock(&Database->lock);
{
return gcvSTATUS_OUT_OF_RESOURCES;
}
-
- *Id = result;
#else
again:
if (idr_pre_get(&Database->idr, GFP_KERNEL | gcdNOWARN) == 0)
next = (Database->curr + 1 <= 0) ? 1 : Database->curr + 1;
- /* Try to get a id greater than current id. */
+ /* Try to get a id greater than 0. */
result = idr_get_new_above(&Database->idr, KernelPointer, next, Id);
if (!result)
return gcvSTATUS_OK;
}
-static void
-_UnmapUserLogical(
- IN gctINT Pid,
+gceSTATUS
+_QueryProcessPageTable(
IN gctPOINTER Logical,
- IN gctUINT32 Size
-)
+ OUT gctUINT32 * Address
+ )
{
- if (unlikely(current->mm == gcvNULL))
+ spinlock_t *lock;
+ gctUINTPTR_T logical = (gctUINTPTR_T)Logical;
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+
+ if (!current->mm)
{
- /* Do nothing if process is exiting. */
- return;
+ return gcvSTATUS_NOT_FOUND;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
- if (vm_munmap((unsigned long)Logical, Size) < 0)
+ pgd = pgd_offset(current->mm, logical);
+ if (pgd_none(*pgd) || pgd_bad(*pgd))
{
- gcmkTRACE_ZONE(
- gcvLEVEL_WARNING, gcvZONE_OS,
- "%s(%d): vm_munmap failed",
- __FUNCTION__, __LINE__
- );
+ return gcvSTATUS_NOT_FOUND;
}
-#else
- down_write(¤t->mm->mmap_sem);
- if (do_munmap(current->mm, (unsigned long)Logical, Size) < 0)
+
+ pud = pud_offset(pgd, logical);
+ if (pud_none(*pud) || pud_bad(*pud))
{
- gcmkTRACE_ZONE(
- gcvLEVEL_WARNING, gcvZONE_OS,
- "%s(%d): do_munmap failed",
- __FUNCTION__, __LINE__
- );
+ return gcvSTATUS_NOT_FOUND;
}
- up_write(¤t->mm->mmap_sem);
-#endif
+
+ pmd = pmd_offset(pud, logical);
+ if (pmd_none(*pmd) || pmd_bad(*pmd))
+ {
+ return gcvSTATUS_NOT_FOUND;
+ }
+
+ pte = pte_offset_map_lock(current->mm, pmd, logical, &lock);
+ if (!pte)
+ {
+ return gcvSTATUS_NOT_FOUND;
+ }
+
+ if (!pte_present(*pte))
+ {
+ pte_unmap_unlock(pte, lock);
+ return gcvSTATUS_NOT_FOUND;
+ }
+
+ *Address = (pte_pfn(*pte) << PAGE_SHIFT) | (logical & ~PAGE_MASK);
+ pte_unmap_unlock(pte, lock);
+
+ return gcvSTATUS_OK;
+}
+
+#if !gcdCACHE_FUNCTION_UNIMPLEMENTED && defined(CONFIG_OUTER_CACHE)
+static inline gceSTATUS
+outer_func(
+ gceCACHEOPERATION Type,
+ unsigned long Start,
+ unsigned long End
+ )
+{
+ switch (Type)
+ {
+ case gcvCACHE_CLEAN:
+ outer_clean_range(Start, End);
+ break;
+ case gcvCACHE_INVALIDATE:
+ outer_inv_range(Start, End);
+ break;
+ case gcvCACHE_FLUSH:
+ outer_flush_range(Start, End);
+ break;
+ default:
+ return gcvSTATUS_INVALID_ARGUMENT;
+ break;
+ }
+ return gcvSTATUS_OK;
+}
+
+#if gcdENABLE_OUTER_CACHE_PATCH
+/*******************************************************************************
+** _HandleOuterCache
+**
+** Handle the outer cache for the specified addresses.
+**
+** ARGUMENTS:
+**
+** gckOS Os
+** Pointer to gckOS object.
+**
+** gctPOINTER Physical
+** Physical address to flush.
+**
+** gctPOINTER Logical
+** Logical address to flush.
+**
+** gctSIZE_T Bytes
+** Size of the address range in bytes to flush.
+**
+** gceOUTERCACHE_OPERATION Type
+** Operation need to be execute.
+*/
+gceSTATUS
+_HandleOuterCache(
+ IN gckOS Os,
+ IN gctUINT32 Physical,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes,
+ IN gceCACHEOPERATION Type
+ )
+{
+ gceSTATUS status;
+ unsigned long paddr;
+ gctPOINTER vaddr;
+ gctUINT32 offset, bytes, left;
+
+ gcmkHEADER_ARG("Os=0x%X Logical=0x%X Bytes=%lu",
+ Os, Logical, Bytes);
+
+ if (Physical != gcvINVALID_ADDRESS)
+ {
+ /* Non paged memory or gcvPOOL_USER surface */
+ paddr = (unsigned long) Physical;
+ gcmkONERROR(outer_func(Type, paddr, paddr + Bytes));
+ }
+ else
+ {
+ /* Non contiguous virtual memory */
+ vaddr = Logical;
+ left = Bytes;
+
+ while (left)
+ {
+ /* Handle (part of) current page. */
+ offset = (gctUINTPTR_T)vaddr & ~PAGE_MASK;
+
+ bytes = gcmMIN(left, PAGE_SIZE - offset);
+
+ gcmkONERROR(_QueryProcessPageTable(vaddr, (gctUINT32*)&paddr));
+ gcmkONERROR(outer_func(Type, paddr, paddr + bytes));
+
+ vaddr = (gctUINT8_PTR)vaddr + bytes;
+ left -= bytes;
+ }
+ }
+
+ mb();
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
}
+#endif
+#endif
-gceSTATUS
-_QueryProcessPageTable(
- IN gctPOINTER Logical,
- OUT gctUINT32 * Address
+gctBOOL
+_AllowAccess(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctUINT32 Address
)
{
- spinlock_t *lock;
- gctUINTPTR_T logical = (gctUINTPTR_T)Logical;
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *pte;
+ gctUINT32 data;
- if (!current->mm)
+ /* Check external clock state. */
+ if (Os->clockStates[Core] == gcvFALSE)
{
- return gcvSTATUS_NOT_FOUND;
+ gcmkPRINT("[galcore]: %s(%d) External clock off", __FUNCTION__, __LINE__);
+ return gcvFALSE;
}
- pgd = pgd_offset(current->mm, logical);
- if (pgd_none(*pgd) || pgd_bad(*pgd))
+ /* Check internal clock state. */
+ if (Address == 0)
{
- return gcvSTATUS_NOT_FOUND;
+ return gcvTRUE;
}
- pud = pud_offset(pgd, logical);
- if (pud_none(*pud) || pud_bad(*pud))
+#if gcdMULTI_GPU
+ if (Core == gcvCORE_MAJOR)
{
- return gcvSTATUS_NOT_FOUND;
+ data = readl((gctUINT8 *)Os->device->registerBases[gcvCORE_3D_0_ID] + 0x0);
}
-
- pmd = pmd_offset(pud, logical);
- if (pmd_none(*pmd) || pmd_bad(*pmd))
+ else
+#endif
{
- return gcvSTATUS_NOT_FOUND;
+ data = readl((gctUINT8 *)Os->device->registerBases[Core] + 0x0);
}
- pte = pte_offset_map_lock(current->mm, pmd, logical, &lock);
- if (!pte)
+ if ((data & 0x3) == 0x3)
{
- return gcvSTATUS_NOT_FOUND;
+ gcmkPRINT("[galcore]: %s(%d) Internal clock off", __FUNCTION__, __LINE__);
+ return gcvFALSE;
}
- if (!pte_present(*pte))
+ return gcvTRUE;
+}
+
+static gceSTATUS
+_ShrinkMemory(
+ IN gckOS Os
+ )
+{
+ gcsPLATFORM * platform;
+
+ gcmkHEADER_ARG("Os=0x%X", Os);
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+
+ platform = Os->device->platform;
+
+ if (platform && platform->ops->shrinkMemory)
{
- pte_unmap_unlock(pte, lock);
- return gcvSTATUS_NOT_FOUND;
+ platform->ops->shrinkMemory(platform);
+ }
+ else
+ {
+ gcmkFOOTER_NO();
+ return gcvSTATUS_NOT_SUPPORTED;
}
- *Address = (pte_pfn(*pte) << PAGE_SHIFT) | (logical & ~PAGE_MASK);
- pte_unmap_unlock(pte, lock);
-
+ gcmkFOOTER_NO();
return gcvSTATUS_OK;
}
{
gckOS os;
gceSTATUS status;
+ gctINT i;
gcmkHEADER_ARG("Context=0x%X", Context);
/* Set device device. */
os->device = Context;
- /* IMPORTANT! No heap yet. */
- os->heap = gcvNULL;
+ /* Set allocateCount to 0, gckOS_Allocate has not been used yet. */
+ atomic_set(&os->allocateCount, 0);
/* Initialize the memory lock. */
gcmkONERROR(gckOS_CreateMutex(os, &os->memoryLock));
/* Create debug lock mutex. */
gcmkONERROR(gckOS_CreateMutex(os, &os->debugLock));
-
os->mdlHead = os->mdlTail = gcvNULL;
/* Get the kernel process ID. */
idr_init(&os->syncPointDB.idr);
#endif
-#if gcdUSE_NON_PAGED_MEMORY_CACHE
- os->cacheSize = 0;
- os->cacheHead = gcvNULL;
- os->cacheTail = gcvNULL;
-#endif
-
/* Create a workqueue for os timer. */
os->workqueue = create_singlethread_workqueue("galcore workqueue");
gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
}
+ os->paddingPage = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN);
+ if (os->paddingPage == gcvNULL)
+ {
+ /* Out of memory. */
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+ else
+ {
+ SetPageReserved(os->paddingPage);
+ }
+
+ for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+ {
+ mutex_init(&os->registerAccessLocks[i]);
+ }
+
+ gckOS_ImportAllocators(os);
+
+#ifdef CONFIG_IOMMU_SUPPORT
+ if (((gckGALDEVICE)(os->device))->mmu == gcvFALSE)
+ {
+ /* Only use IOMMU when internal MMU is not enabled. */
+ status = gckIOMMU_Construct(os, &os->iommu);
+
+ if (gcmIS_ERROR(status))
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): Fail to setup IOMMU",
+ __FUNCTION__, __LINE__
+ );
+ }
+ }
+#endif
+
/* Return pointer to the gckOS object. */
*Os = os;
gckOS_DeleteMutex(os, os->signalMutex));
}
- if (os->heap != gcvNULL)
- {
- gcmkVERIFY_OK(
- gckHEAP_Destroy(os->heap));
- }
-
if (os->memoryMapLock != gcvNULL)
{
gcmkVERIFY_OK(
IN gckOS Os
)
{
- gckHEAP heap;
-
gcmkHEADER_ARG("Os=0x%X", Os);
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
-#if gcdUSE_NON_PAGED_MEMORY_CACHE
- _FreeAllNonPagedMemoryCache(Os);
-#endif
+ if (Os->paddingPage != gcvNULL)
+ {
+ ClearPageReserved(Os->paddingPage);
+ __free_page(Os->paddingPage);
+ Os->paddingPage = gcvNULL;
+ }
#if gcdANDROID_NATIVE_FENCE_SYNC
/*
/* Destroy the mutex. */
gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->signalMutex));
- if (Os->heap != gcvNULL)
- {
- /* Mark gckHEAP as gone. */
- heap = Os->heap;
- Os->heap = gcvNULL;
-
- /* Destroy the gckHEAP object. */
- gcmkVERIFY_OK(gckHEAP_Destroy(heap));
- }
-
/* Destroy the memory lock. */
gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->memoryMapLock));
gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->memoryLock));
/* Destory work queue. */
destroy_workqueue(Os->workqueue);
+ gckOS_FreeAllocators(Os);
+
+#ifdef CONFIG_IOMMU_SUPPORT
+ if (Os->iommu)
+ {
+ gckIOMMU_Destory(Os, Os->iommu);
+ }
+#endif
+
/* Flush the debug cache. */
gcmkDEBUGFLUSH(~0U);
/* Mark the gckOS object as unknown. */
Os->object.type = gcvOBJ_UNKNOWN;
+
/* Free the gckOS object. */
kfree(Os);
return gcvSTATUS_OK;
}
-static gctSTRING
-_CreateKernelVirtualMapping(
- IN PLINUX_MDL Mdl
+gceSTATUS
+gckOS_CreateKernelVirtualMapping(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Logical,
+ OUT gctSIZE_T * PageCount
)
{
- gctSTRING addr = 0;
- gctINT numPages = Mdl->numPages;
-
-#if gcdNONPAGED_MEMORY_CACHEABLE
- if (Mdl->contiguous)
- {
- addr = page_address(Mdl->u.contiguousPages);
- }
- else
- {
- addr = vmap(Mdl->u.nonContiguousPages,
- numPages,
- 0,
- PAGE_KERNEL);
-
- /* Trigger a page fault. */
- memset(addr, 0, numPages * PAGE_SIZE);
- }
-#else
- struct page ** pages;
- gctBOOL free = gcvFALSE;
- gctINT i;
-
- if (Mdl->contiguous)
- {
- pages = kmalloc(sizeof(struct page *) * numPages, GFP_KERNEL | gcdNOWARN);
-
- if (!pages)
- {
- return gcvNULL;
- }
-
- for (i = 0; i < numPages; i++)
- {
- pages[i] = nth_page(Mdl->u.contiguousPages, i);
- }
-
- free = gcvTRUE;
- }
- else
- {
- pages = Mdl->u.nonContiguousPages;
- }
+ gceSTATUS status;
+ PLINUX_MDL mdl = (PLINUX_MDL)Physical;
+ gckALLOCATOR allocator = mdl->allocator;
- /* ioremap() can't work on system memory since 2.6.38. */
- addr = vmap(pages, numPages, 0, gcmkNONPAGED_MEMROY_PROT(PAGE_KERNEL));
+ gcmkHEADER();
- /* Trigger a page fault. */
- memset(addr, 0, numPages * PAGE_SIZE);
+ *PageCount = mdl->numPages;
- if (free)
- {
- kfree(pages);
- }
+ gcmkONERROR(allocator->ops->MapKernel(allocator, mdl, Logical));
-#endif
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
- return addr;
+OnError:
+ gcmkFOOTER();
+ return status;
}
-static void
-_DestoryKernelVirtualMapping(
- IN gctSTRING Addr
+gceSTATUS
+gckOS_DestroyKernelVirtualMapping(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical
)
{
-#if !gcdNONPAGED_MEMORY_CACHEABLE
- vunmap(Addr);
-#endif
+ PLINUX_MDL mdl = (PLINUX_MDL)Physical;
+ gckALLOCATOR allocator = mdl->allocator;
+
+ gcmkHEADER();
+
+ allocator->ops->UnmapKernel(allocator, mdl, Logical);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
}
gceSTATUS
-gckOS_CreateKernelVirtualMapping(
+gckOS_CreateUserVirtualMapping(
+ IN gckOS Os,
IN gctPHYS_ADDR Physical,
- OUT gctSIZE_T * PageCount,
- OUT gctPOINTER * Logical
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Logical,
+ OUT gctSIZE_T * PageCount
)
{
- *PageCount = ((PLINUX_MDL)Physical)->numPages;
- *Logical = _CreateKernelVirtualMapping((PLINUX_MDL)Physical);
-
- return gcvSTATUS_OK;
+ return gckOS_LockPages(Os, Physical, Bytes, gcvFALSE, Logical, PageCount);
}
gceSTATUS
-gckOS_DestroyKernelVirtualMapping(
+gckOS_DestroyUserVirtualMapping(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
IN gctPOINTER Logical
)
{
- _DestoryKernelVirtualMapping((gctSTRING)Logical);
- return gcvSTATUS_OK;
+ return gckOS_UnlockPages(Os, Physical, Bytes, Logical);
}
/*******************************************************************************
gcmkVERIFY_ARGUMENT(Bytes > 0);
gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
- /* Do we have a heap? */
- if (Os->heap != gcvNULL)
- {
- /* Allocate from the heap. */
- gcmkONERROR(gckHEAP_Allocate(Os->heap, Bytes, Memory));
- }
- else
- {
- gcmkONERROR(gckOS_AllocateMemory(Os, Bytes, Memory));
- }
+ gcmkONERROR(gckOS_AllocateMemory(Os, Bytes, Memory));
/* Success. */
gcmkFOOTER_ARG("*Memory=0x%X", *Memory);
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
- /* Do we have a heap? */
- if (Os->heap != gcvNULL)
- {
- /* Free from the heap. */
- gcmkONERROR(gckHEAP_Free(Os->heap, Memory));
- }
- else
- {
- gcmkONERROR(gckOS_FreeMemory(Os, Memory));
- }
+ gcmkONERROR(gckOS_FreeMemory(Os, Memory));
/* Success. */
gcmkFOOTER_NO();
gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
}
+ /* Increase count. */
+ atomic_inc(&Os->allocateCount);
+
/* Return pointer to the memory allocation. */
*Memory = memory;
kfree(Memory);
}
+ /* Decrease count. */
+ atomic_dec(&Os->allocateCount);
+
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
}
#ifndef NO_DMA_COHERENT
- if (dma_mmap_coherent(gcvNULL,
+ if (dma_mmap_writecombine(gcvNULL,
mdlMap->vma,
mdl->addr,
mdl->dmaHandle,
return gcvSTATUS_INVALID_ARGUMENT;
}
- _UnmapUserLogical(PID, mdlMap->vmaAddr, mdl->numPages * PAGE_SIZE);
+ _UnmapUserLogical(mdlMap->vmaAddr, mdl->numPages * PAGE_SIZE);
gcmkVERIFY_OK(_DestroyMdlMap(mdl, mdlMap));
}
PLINUX_MDL mdl = gcvNULL;
PLINUX_MDL_MAP mdlMap = gcvNULL;
gctSTRING addr;
+ gckKERNEL kernel;
#ifdef NO_DMA_COHERENT
struct page * page;
long size, order;
numPages = GetPageCount(bytes, 0);
/* Allocate mdl+vector structure */
- mdl = _CreateMdl(_GetProcessID());
+ mdl = _CreateMdl();
if (mdl == gcvNULL)
{
gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
locked = gcvTRUE;
#ifndef NO_DMA_COHERENT
-#if gcdUSE_NON_PAGED_MEMORY_CACHE
- addr = _GetNonPagedMemoryCache(Os,
- mdl->numPages * PAGE_SIZE,
- &mdl->dmaHandle);
-
- if (addr == gcvNULL)
-#endif
- {
- addr = dma_alloc_coherent(gcvNULL,
- mdl->numPages * PAGE_SIZE,
- &mdl->dmaHandle,
- GFP_KERNEL | gcdNOWARN);
- }
-#if gcdUSE_NON_PAGED_MEMORY_CACHE
- if(addr == gcvNULL)
- {
- MEMORY_UNLOCK(Os);
- locked = gcvFALSE;
- /*Free all cache and try again*/
- _FreeAllNonPagedMemoryCache(Os);
- MEMORY_LOCK(Os);
- locked = gcvTRUE;
- addr = dma_alloc_coherent(gcvNULL,
- mdl->numPages * PAGE_SIZE,
- &mdl->dmaHandle,
- GFP_KERNEL | gcdNOWARN);
- }
+#ifdef CONFIG_ARM64
+ addr = dma_alloc_coherent(gcvNULL,
+#else
+ addr = dma_alloc_writecombine(gcvNULL,
#endif
+ mdl->numPages * PAGE_SIZE,
+ &mdl->dmaHandle,
+ GFP_KERNEL | gcdNOWARN);
#else
size = mdl->numPages * PAGE_SIZE;
order = get_order(size);
-#if gcdUSE_NON_PAGED_MEMORY_CACHE
- page = _GetNonPagedMemoryCache(Os, order);
- if (page == gcvNULL)
-#endif
- {
- page = alloc_pages(GFP_KERNEL | gcdNOWARN, order);
- }
+ page = alloc_pages(GFP_KERNEL | gcdNOWARN, order);
if (page == gcvNULL)
{
addr = _CreateKernelVirtualMapping(mdl);
mdl->dmaHandle = virt_to_phys(vaddr);
mdl->kaddr = vaddr;
- mdl->u.contiguousPages = page;
+
+ /* Trigger a page fault. */
+ memset(addr, 0, numPages * PAGE_SIZE);
#if !defined(CONFIG_PPC)
/* Cache invalidate. */
gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
}
+ kernel = Os->device->kernels[gcvCORE_MAJOR] != gcvNULL ?
+ Os->device->kernels[gcvCORE_MAJOR] : Os->device->kernels[gcvCORE_2D];
+ if (((Os->device->baseAddress & 0x80000000) != (mdl->dmaHandle & 0x80000000)) &&
+ kernel->hardware->mmuVersion == 0)
+ {
+ mdl->dmaHandle = (mdl->dmaHandle & ~0x80000000)
+ | (Os->device->baseAddress & 0x80000000);
+ }
+
mdl->addr = addr;
/* Return allocated memory. */
gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
}
#else
+#if !gcdSECURITY
mdlMap->vma->vm_page_prot = gcmkNONPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot);
+#endif
mdlMap->vma->vm_flags |= gcdVM_FLAGS;
mdlMap->vma->vm_pgoff = 0;
}
else
{
+#if gcdSECURITY
+ *Logical = (gctPOINTER)mdl->kaddr;
+#else
*Logical = (gctPOINTER)mdl->addr;
+#endif
}
/*
/* Free LINUX_MDL. */
gcmkVERIFY_OK(_DestroyMdl(mdl));
}
+ *Physical = gcvNULL;
+ *Bytes = 0;
if (locked)
{
MEMORY_LOCK(Os);
#ifndef NO_DMA_COHERENT
-#if gcdUSE_NON_PAGED_MEMORY_CACHE
- if (!_AddNonPagedMemoryCache(Os,
- mdl->numPages * PAGE_SIZE,
- mdl->addr,
- mdl->dmaHandle))
+#ifdef CONFIG_ARM64
+ dma_free_coherent(gcvNULL,
+#else
+ dma_free_writecombine(gcvNULL,
#endif
- {
- dma_free_coherent(gcvNULL,
- mdl->numPages * PAGE_SIZE,
- mdl->addr,
- mdl->dmaHandle);
- }
+ mdl->numPages * PAGE_SIZE,
+ mdl->addr,
+ mdl->dmaHandle);
#else
size = mdl->numPages * PAGE_SIZE;
vaddr = mdl->kaddr;
size -= PAGE_SIZE;
}
-#if gcdUSE_NON_PAGED_MEMORY_CACHE
- if (!_AddNonPagedMemoryCache(Os,
- get_order(mdl->numPages * PAGE_SIZE),
- virt_to_page(mdl->kaddr)))
-#endif
- {
- free_pages((unsigned long)mdl->kaddr, get_order(mdl->numPages * PAGE_SIZE));
- }
+ free_pages((unsigned long)mdl->kaddr, get_order(mdl->numPages * PAGE_SIZE));
_DestoryKernelVirtualMapping(mdl->addr);
#endif /* NO_DMA_COHERENT */
while (mdlMap != gcvNULL)
{
- if (mdlMap->vmaAddr != gcvNULL)
- {
- /* No mapped memory exists when free nonpaged memory */
- gcmkASSERT(0);
- }
+ /* No mapped memory exists when free nonpaged memory */
+ gcmkASSERT(mdlMap->vmaAddr == gcvNULL);
mdlMap = mdlMap->next;
}
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+#if !gcdMULTI_GPU
gcmkVERIFY_ARGUMENT(Address < Os->device->requestedRegisterMemSizes[Core]);
+#endif
+ gcmkVERIFY_ARGUMENT(Data != gcvNULL);
+
+ if (!in_interrupt())
+ {
+ mutex_lock(&Os->registerAccessLocks[Core]);
+ }
+
+ BUG_ON(!_AllowAccess(Os, Core, Address));
+
+#if gcdMULTI_GPU
+ if (Core == gcvCORE_MAJOR)
+ {
+ *Data = readl((gctUINT8 *)Os->device->registerBase3D[gcvCORE_3D_0_ID] + Address);
+ }
+ else
+#endif
+ {
+ *Data = readl((gctUINT8 *)Os->device->registerBases[Core] + Address);
+ }
+
+ if (!in_interrupt())
+ {
+ mutex_unlock(&Os->registerAccessLocks[Core]);
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Data=0x%08x", *Data);
+ return gcvSTATUS_OK;
+}
+
+#if gcdMULTI_GPU
+gceSTATUS
+gckOS_ReadRegisterByCoreId(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctUINT32 CoreId,
+ IN gctUINT32 Address,
+ OUT gctUINT32 * Data
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X Core=%d CoreId=%d Address=0x%X",
+ Os, Core, CoreId, Address);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
gcmkVERIFY_ARGUMENT(Data != gcvNULL);
- *Data = readl((gctUINT8 *)Os->device->registerBases[Core] + Address);
+ *Data = readl((gctUINT8 *)Os->device->registerBase3D[CoreId] + Address);
/* Success. */
gcmkFOOTER_ARG("*Data=0x%08x", *Data);
return gcvSTATUS_OK;
}
+#endif
/*******************************************************************************
**
{
gcmkHEADER_ARG("Os=0x%X Core=%d Address=0x%X Data=0x%08x", Os, Core, Address, Data);
+#if !gcdMULTI_GPU
gcmkVERIFY_ARGUMENT(Address < Os->device->requestedRegisterMemSizes[Core]);
+#endif
+
+ if (!in_interrupt())
+ {
+ mutex_lock(&Os->registerAccessLocks[Core]);
+ }
+
+ BUG_ON(!_AllowAccess(Os, Core, Address));
+
+#if gcdMULTI_GPU
+ if (Core == gcvCORE_MAJOR)
+ {
+ writel(Data, (gctUINT8 *)Os->device->registerBase3D[gcvCORE_3D_0_ID] + Address);
+#if gcdMULTI_GPU > 1
+ writel(Data, (gctUINT8 *)Os->device->registerBase3D[gcvCORE_3D_1_ID] + Address);
+#endif
+ }
+ else
+#endif
+ {
+ writel(Data, (gctUINT8 *)Os->device->registerBases[Core] + Address);
+ }
+
+ if (!in_interrupt())
+ {
+ mutex_unlock(&Os->registerAccessLocks[Core]);
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+#if gcdMULTI_GPU
+gceSTATUS
+gckOS_WriteRegisterByCoreId(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gctUINT32 CoreId,
+ IN gctUINT32 Address,
+ IN gctUINT32 Data
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X Core=%d CoreId=%d Address=0x%X Data=0x%08x",
+ Os, Core, CoreId, Address, Data);
- writel(Data, (gctUINT8 *)Os->device->registerBases[Core] + Address);
+ writel(Data, (gctUINT8 *)Os->device->registerBase3D[CoreId] + Address);
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
}
+#endif
/*******************************************************************************
**
gckOS_GetPhysicalAddressProcess(Os, Logical, processID, Address));
}
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Os, *Address, Address));
+
/* Success. */
gcmkFOOTER_ARG("*Address=0x%08x", *Address);
return gcvSTATUS_OK;
return status;
}
+/*******************************************************************************
+**
+** gckOS_UserLogicalToPhysical
+**
+** Get the physical system address of a corresponding user virtual address.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPOINTER Logical
+** Logical address.
+**
+** OUTPUT:
+**
+** gctUINT32 * Address
+** Pointer to a variable that receives the 32-bit physical address.
+*/
+gceSTATUS gckOS_UserLogicalToPhysical(
+ IN gckOS Os,
+ IN gctPOINTER Logical,
+ OUT gctUINT32 * Address
+ )
+{
+ return gckOS_GetPhysicalAddress(Os, Logical, Address);
+}
+
#if gcdSECURE_USER
static gceSTATUS
gckOS_AddMapping(
}
#endif
-static gceSTATUS
+gceSTATUS
_ConvertLogical2Physical(
IN gckOS Os,
IN gctPOINTER Logical,
PLINUX_MDL_MAP map;
gcsUSER_MAPPING_PTR userMap;
+#if gcdSECURITY
+ base = (Mdl == gcvNULL) ? gcvNULL : (gctINT8_PTR) Mdl->kaddr;
+#else
base = (Mdl == gcvNULL) ? gcvNULL : (gctINT8_PTR) Mdl->addr;
+#endif
/* Check for the logical address match. */
if ((base != gcvNULL)
}
else
{
- *Physical = gcmPTR2INT(virt_to_phys(base)) + offset;
+ *Physical = gcmPTR2INT32(virt_to_phys(base)) + offset;
}
return gcvSTATUS_OK;
{
PLINUX_MDL mdl;
gctINT8_PTR base;
+ gckALLOCATOR allocator = gcvNULL;
gceSTATUS status = gcvSTATUS_INVALID_ADDRESS;
gcmkHEADER_ARG("Os=0x%X Logical=0x%X ProcessID=%d", Os, Logical, ProcessID);
for (mdl = Os->mdlHead; mdl != gcvNULL; mdl = mdl->next)
{
/* Try this MDL. */
- status = _ConvertLogical2Physical(Os,
- Logical,
- ProcessID,
- mdl,
- Address);
+ allocator = mdl->allocator;
+
+ if (allocator)
+ {
+ status = allocator->ops->LogicalToPhysical(
+ allocator,
+ mdl,
+ Logical,
+ ProcessID,
+ Address
+ );
+ }
+ else
+ {
+ status = _ConvertLogical2Physical(Os,
+ Logical,
+ ProcessID,
+ mdl,
+ Address);
+ }
+
if (gcmIS_SUCCESS(status))
{
break;
mdl = mdl->next;
}
+ MEMORY_UNLOCK(Os);
+
if (mdl == gcvNULL)
{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
- struct contiguous_mem_pool *pool = Os->device->pool;
+ struct page * page = pfn_to_page(physical >> PAGE_SHIFT);
- if (Physical >= pool->phys && Physical < pool->phys + pool->size)
- logical = (gctPOINTER)(Physical - pool->phys + pool->virt);
- else
- logical = gcvNULL;
-#else
- /* Map memory as cached memory. */
- request_mem_region(physical, Bytes, "MapRegion");
- logical = (gctPOINTER) ioremap_nocache(physical, Bytes);
-#endif
+ if (pfn_valid(page_to_pfn(page)))
+ {
+ gctUINT32 offset = physical & ~PAGE_MASK;
+ struct page ** pages;
+ gctUINT numPages;
+ gctINT i;
+
+ numPages = GetPageCount(PAGE_ALIGN(offset + Bytes), 0);
+
+ pages = kmalloc(sizeof(struct page *) * numPages, GFP_KERNEL | gcdNOWARN);
+
+ if (!pages)
+ {
+ gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_MEMORY);
+ return gcvSTATUS_OUT_OF_MEMORY;
+ }
+
+ for (i = 0; i < numPages; i++)
+ {
+ pages[i] = nth_page(page, i);
+ }
- if (logical == gcvNULL)
+ logical = vmap(pages, numPages, 0, gcmkNONPAGED_MEMROY_PROT(PAGE_KERNEL));
+
+ kfree(pages);
+
+ if (logical == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): Failed to vmap",
+ __FUNCTION__, __LINE__
+ );
+
+ /* Out of resources. */
+ gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES);
+ return gcvSTATUS_OUT_OF_RESOURCES;
+ }
+
+ logical += offset;
+ }
+ else
{
- gcmkTRACE_ZONE(
- gcvLEVEL_INFO, gcvZONE_OS,
- "%s(%d): Failed to map physical address 0x%08x",
- __FUNCTION__, __LINE__, Physical
- );
+ /* Map memory as cached memory. */
+ request_mem_region(physical, Bytes, "MapRegion");
+ logical = (gctPOINTER) ioremap_nocache(physical, Bytes);
- MEMORY_UNLOCK(Os);
+ if (logical == gcvNULL)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): Failed to ioremap",
+ __FUNCTION__, __LINE__
+ );
- /* Out of resources. */
- gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES);
- return gcvSTATUS_OUT_OF_RESOURCES;
+ /* Out of resources. */
+ gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES);
+ return gcvSTATUS_OUT_OF_RESOURCES;
+ }
}
/* Return pointer to mapped memory. */
*Logical = logical;
}
- MEMORY_UNLOCK(Os);
/* Success. */
gcmkFOOTER_ARG("*Logical=0x%X", *Logical);
if (mdl == gcvNULL)
{
/* Unmap the memory. */
- iounmap(Logical);
+ vunmap((void *)((unsigned long)Logical & PAGE_MASK));
}
MEMORY_UNLOCK(Os);
gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
/* Destroy the mutex. */
- mutex_destroy(Mutex);
+ mutex_destroy((struct mutex *)Mutex);
/* Free the mutex structure. */
gcmkONERROR(gckOS_Free(Os, Mutex));
IN gctUINT32 Timeout
)
{
-#if gcdDETECT_TIMEOUT
- gctUINT32 timeout;
-#endif
-
gcmkHEADER_ARG("Os=0x%X Mutex=0x%0x Timeout=%u", Os, Mutex, Timeout);
/* Validate the arguments. */
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
-#if gcdDETECT_TIMEOUT
- timeout = 0;
-
- for (;;)
- {
- /* Try to acquire the mutex. */
- if (mutex_trylock(Mutex))
- {
- /* Success. */
- gcmkFOOTER_NO();
- return gcvSTATUS_OK;
- }
-
- /* Advance the timeout. */
- timeout += 1;
-
- if (Timeout == gcvINFINITE)
- {
- if (timeout == gcdINFINITE_TIMEOUT)
- {
- gctUINT32 dmaAddress1, dmaAddress2;
- gctUINT32 dmaState1, dmaState2;
-
- dmaState1 = dmaState2 =
- dmaAddress1 = dmaAddress2 = 0;
-
- /* Verify whether DMA is running. */
- gcmkVERIFY_OK(_VerifyDMA(
- Os, &dmaAddress1, &dmaAddress2, &dmaState1, &dmaState2
- ));
-
-#if gcdDETECT_DMA_ADDRESS
- /* Dump only if DMA appears stuck. */
- if (
- (dmaAddress1 == dmaAddress2)
-#if gcdDETECT_DMA_STATE
- && (dmaState1 == dmaState2)
-# endif
- )
-# endif
- {
- gcmkVERIFY_OK(_DumpGPUState(Os, gcvCORE_MAJOR));
-
- gcmkPRINT(
- "%s(%d): mutex 0x%X; forced message flush.",
- __FUNCTION__, __LINE__, Mutex
- );
-
- /* Flush the debug cache. */
- gcmkDEBUGFLUSH(dmaAddress2);
- }
-
- timeout = 0;
- }
- }
- else
- {
- /* Timedout? */
- if (timeout >= Timeout)
- {
- break;
- }
- }
-
- /* Wait for 1 millisecond. */
- gcmkVERIFY_OK(gckOS_Delay(Os, 1));
- }
-#else
if (Timeout == gcvINFINITE)
{
/* Lock the mutex. */
/* Wait for 1 millisecond. */
gcmkVERIFY_OK(gckOS_Delay(Os, 1));
}
-#endif
/* Timeout. */
gcmkFOOTER_ARG("status=%d", gcvSTATUS_TIMEOUT);
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(OldValue != gcvNULL);
/* Exchange the pair of 32-bit values. */
*OldValue = (gctUINT32) atomic_xchg((atomic_t *) Target, (int) NewValue);
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(OldValue != gcvNULL);
/* Exchange the pair of pointers. */
*OldValue = (gctPOINTER)(gctUINTPTR_T) atomic_xchg((atomic_t *) Target, (int)(gctUINTPTR_T) NewValue);
return gcvSTATUS_OK;
}
-#if gcdSMP
/*******************************************************************************
**
** gckOS_AtomicSetMask
gcmkFOOTER_NO();
return gcvSTATUS_OK;
}
-#endif
/*******************************************************************************
**
if (Delay > 0)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
- ktime_t delay = ktime_set(Delay/1000, (Delay%1000) * NSEC_PER_MSEC);
+ ktime_t delay = ktime_set((Delay / MSEC_PER_SEC), (Delay % MSEC_PER_SEC) * NSEC_PER_MSEC);
__set_current_state(TASK_UNINTERRUPTIBLE);
schedule_hrtimeout(&delay, HRTIMER_MODE_REL);
#else
msleep(Delay);
#endif
-
}
/* Success. */
OUT gctUINT64_PTR Time
)
{
+ struct timeval tv;
gcmkHEADER();
- *Time = 0;
+ /* Return the time of day in microseconds. */
+ do_gettimeofday(&tv);
+ *Time = (tv.tv_sec * 1000000ULL) + tv.tv_usec;
gcmkFOOTER_NO();
return gcvSTATUS_OK;
gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
/* Allocate the memory. */
- gcmkONERROR(gckOS_AllocatePagedMemoryEx(Os, gcvFALSE, Bytes, Physical));
+ gcmkONERROR(gckOS_AllocatePagedMemoryEx(Os, gcvALLOC_FLAG_NONE, Bytes, gcvNULL, Physical));
/* Success. */
gcmkFOOTER_ARG("*Physical=0x%X", *Physical);
** gckOS Os
** Pointer to an gckOS object.
**
-** gctBOOL Contiguous
-** Need contiguous memory or not.
+** gctUINT32 Flag
+** Allocation attribute.
**
** gctSIZE_T Bytes
** Number of bytes to allocate.
**
** OUTPUT:
**
+** gctUINT32 * Gid
+** Save the global ID for the piece of allocated memory.
+**
** gctPHYS_ADDR * Physical
** Pointer to a variable that receives the physical address of the
** memory allocation.
gceSTATUS
gckOS_AllocatePagedMemoryEx(
IN gckOS Os,
- IN gctBOOL Contiguous,
+ IN gctUINT32 Flag,
IN gctSIZE_T Bytes,
+ OUT gctUINT32 * Gid,
OUT gctPHYS_ADDR * Physical
)
{
gctINT numPages;
- gctINT i;
PLINUX_MDL mdl = gcvNULL;
gctSIZE_T bytes;
- gctBOOL locked = gcvFALSE;
- gceSTATUS status;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
- gctPOINTER addr = gcvNULL;
-#endif
+ gceSTATUS status = gcvSTATUS_OUT_OF_MEMORY;
+ gckALLOCATOR allocator;
- gcmkHEADER_ARG("Os=0x%X Contiguous=%d Bytes=%lu", Os, Contiguous, Bytes);
+ gcmkHEADER_ARG("Os=0x%X Flag=%x Bytes=%lu", Os, Flag, Bytes);
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
numPages = GetPageCount(bytes, 0);
- MEMORY_LOCK(Os);
- locked = gcvTRUE;
-
- mdl = _CreateMdl(_GetProcessID());
+ mdl = _CreateMdl();
if (mdl == gcvNULL)
{
gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
}
- if (Contiguous)
+ /* Walk all allocators. */
+ list_for_each_entry(allocator, &Os->allocatorList, head)
{
- gctUINT32 order = get_order(bytes);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d) flag = %x allocator->capability = %x",
+ __FUNCTION__, __LINE__, Flag, allocator->capability);
- if (order >= MAX_ORDER)
+ if ((Flag & allocator->capability) != Flag)
{
- gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ continue;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
- addr =
- alloc_pages_exact(numPages * PAGE_SIZE, GFP_KERNEL | gcdNOWARN | __GFP_NORETRY);
+ status = allocator->ops->Alloc(allocator, mdl, numPages, Flag);
- mdl->u.contiguousPages = addr
- ? virt_to_page(addr)
- : gcvNULL;
-
- mdl->exact = gcvTRUE;
-#else
- mdl->u.contiguousPages =
- alloc_pages(GFP_KERNEL | gcdNOWARN | __GFP_NORETRY, order);
-#endif
- if (mdl->u.contiguousPages == gcvNULL)
+ if (gcmIS_SUCCESS(status))
{
- mdl->u.contiguousPages =
- alloc_pages(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN, order);
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
- mdl->exact = gcvFALSE;
-#endif
+ mdl->allocator = allocator;
+ break;
}
}
- else
- {
- mdl->u.nonContiguousPages = _NonContiguousAlloc(numPages);
- }
- if (mdl->u.contiguousPages == gcvNULL && mdl->u.nonContiguousPages == gcvNULL)
- {
- gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
- }
+ /* Check status. */
+ gcmkONERROR(status);
mdl->dmaHandle = 0;
mdl->addr = 0;
mdl->numPages = numPages;
mdl->pagedMem = 1;
- mdl->contiguous = Contiguous;
-
- for (i = 0; i < mdl->numPages; i++)
- {
- struct page *page;
-
- if (mdl->contiguous)
- {
- page = nth_page(mdl->u.contiguousPages, i);
- }
- else
- {
- page = _NonContiguousToPage(mdl->u.nonContiguousPages, i);
- }
+ mdl->contiguous = Flag & gcvALLOC_FLAG_CONTIGUOUS;
- SetPageReserved(page);
+ /* Return physical address. */
+ *Physical = (gctPHYS_ADDR) mdl;
- if (!PageHighMem(page) && page_to_phys(page))
- {
- gcmkVERIFY_OK(
- gckOS_CacheFlush(Os, _GetProcessID(), gcvNULL,
- (gctPOINTER)(gctUINTPTR_T)page_to_phys(page),
- page_address(page),
- PAGE_SIZE));
- }
+ if (Gid != gcvNULL)
+ {
+ *Gid = mdl->gid;
}
- /* Return physical address. */
- *Physical = (gctPHYS_ADDR) mdl;
+ MEMORY_LOCK(Os);
/*
* Add this to a global list.
/* Free the memory. */
_DestroyMdl(mdl);
}
-
- if (locked)
- {
- /* Unlock the memory. */
- MEMORY_UNLOCK(Os);
- }
+ *Physical = gcvNULL;
/* Return the status. */
- gcmkFOOTER();
+ gcmkFOOTER_ARG("Os=0x%X Flag=%x Bytes=%lu", Os, Flag, Bytes);
return status;
}
)
{
PLINUX_MDL mdl = (PLINUX_MDL) Physical;
- gctINT i;
+ gckALLOCATOR allocator = (gckALLOCATOR)mdl->allocator;
gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Bytes);
gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
gcmkVERIFY_ARGUMENT(Bytes > 0);
- /*addr = mdl->addr;*/
-
MEMORY_LOCK(Os);
- for (i = 0; i < mdl->numPages; i++)
- {
- if (mdl->contiguous)
- {
- ClearPageReserved(nth_page(mdl->u.contiguousPages, i));
- }
- else
- {
- ClearPageReserved(_NonContiguousToPage(mdl->u.nonContiguousPages, i));
- }
- }
-
- if (mdl->contiguous)
- {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
- if (mdl->exact == gcvTRUE)
- {
- free_pages_exact(page_address(mdl->u.contiguousPages), mdl->numPages * PAGE_SIZE);
- }
- else
-#endif
- {
- __free_pages(mdl->u.contiguousPages, GetOrder(mdl->numPages));
- }
- }
- else
- {
- _NonContiguousFree(mdl->u.nonContiguousPages, mdl->numPages);
- }
-
/* Remove the node from global list. */
if (mdl == Os->mdlHead)
{
MEMORY_UNLOCK(Os);
+ allocator->ops->Free(allocator, mdl);
+
/* Free the structure... */
gcmkVERIFY_OK(_DestroyMdl(mdl));
OUT gctSIZE_T * PageCount
)
{
- PLINUX_MDL mdl;
- PLINUX_MDL_MAP mdlMap;
- gctSTRING addr;
- unsigned long start;
- unsigned long pfn;
- gctINT i;
-
- gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Logical);
-
- /* Verify the arguments. */
- gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
- gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
- gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
- gcmkVERIFY_ARGUMENT(PageCount != gcvNULL);
-
- mdl = (PLINUX_MDL) Physical;
-
- MEMORY_LOCK(Os);
-
- mdlMap = FindMdlMap(mdl, _GetProcessID());
-
- if (mdlMap == gcvNULL)
- {
- mdlMap = _CreateMdlMap(mdl, _GetProcessID());
-
- if (mdlMap == gcvNULL)
- {
- MEMORY_UNLOCK(Os);
-
- gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
- return gcvSTATUS_OUT_OF_MEMORY;
- }
- }
-
- if (mdlMap->vmaAddr == gcvNULL)
- {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
- mdlMap->vmaAddr = (gctSTRING)vm_mmap(gcvNULL,
- 0L,
- mdl->numPages * PAGE_SIZE,
- PROT_READ | PROT_WRITE,
- MAP_SHARED,
- 0);
-#else
- down_write(¤t->mm->mmap_sem);
-
- mdlMap->vmaAddr = (gctSTRING)do_mmap_pgoff(gcvNULL,
- 0L,
- mdl->numPages * PAGE_SIZE,
- PROT_READ | PROT_WRITE,
- MAP_SHARED,
- 0);
-
- up_write(¤t->mm->mmap_sem);
-#endif
-
- gcmkTRACE_ZONE(
- gcvLEVEL_INFO, gcvZONE_OS,
- "%s(%d): vmaAddr->0x%X for phys_addr->0x%X",
- __FUNCTION__, __LINE__,
- (gctUINT32)(gctUINTPTR_T)mdlMap->vmaAddr,
- (gctUINT32)(gctUINTPTR_T)mdl
- );
+ gceSTATUS status;
+ PLINUX_MDL mdl;
+ PLINUX_MDL_MAP mdlMap;
+ gckALLOCATOR allocator;
- if (IS_ERR(mdlMap->vmaAddr))
- {
- gcmkTRACE_ZONE(
- gcvLEVEL_INFO, gcvZONE_OS,
- "%s(%d): do_mmap_pgoff error",
- __FUNCTION__, __LINE__
- );
+ gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Logical);
- mdlMap->vmaAddr = gcvNULL;
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(PageCount != gcvNULL);
- MEMORY_UNLOCK(Os);
+ mdl = (PLINUX_MDL) Physical;
+ allocator = mdl->allocator;
- gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
- return gcvSTATUS_OUT_OF_MEMORY;
- }
+ MEMORY_LOCK(Os);
- down_write(¤t->mm->mmap_sem);
+ mdlMap = FindMdlMap(mdl, _GetProcessID());
- mdlMap->vma = find_vma(current->mm, (unsigned long)mdlMap->vmaAddr);
+ if (mdlMap == gcvNULL)
+ {
+ mdlMap = _CreateMdlMap(mdl, _GetProcessID());
- if (mdlMap->vma == gcvNULL)
+ if (mdlMap == gcvNULL)
{
- up_write(¤t->mm->mmap_sem);
-
- gcmkTRACE_ZONE(
- gcvLEVEL_INFO, gcvZONE_OS,
- "%s(%d): find_vma error",
- __FUNCTION__, __LINE__
- );
-
- mdlMap->vmaAddr = gcvNULL;
-
MEMORY_UNLOCK(Os);
- gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_RESOURCES);
- return gcvSTATUS_OUT_OF_RESOURCES;
- }
-
- mdlMap->vma->vm_flags |= gcdVM_FLAGS;
-
- if (Cacheable == gcvFALSE)
- {
- /* Make this mapping non-cached. */
- mdlMap->vma->vm_page_prot = gcmkPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot);
+ gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
+ return gcvSTATUS_OUT_OF_MEMORY;
}
+ }
- addr = mdl->addr;
-
- /* Now map all the vmalloc pages to this user address. */
- if (mdl->contiguous)
- {
- /* map kernel memory to user space.. */
- if (remap_pfn_range(mdlMap->vma,
- mdlMap->vma->vm_start,
- page_to_pfn(mdl->u.contiguousPages),
- mdlMap->vma->vm_end - mdlMap->vma->vm_start,
- mdlMap->vma->vm_page_prot) < 0)
- {
- up_write(¤t->mm->mmap_sem);
-
- gcmkTRACE_ZONE(
- gcvLEVEL_INFO, gcvZONE_OS,
- "%s(%d): unable to mmap ret",
- __FUNCTION__, __LINE__
- );
-
- mdlMap->vmaAddr = gcvNULL;
-
- MEMORY_UNLOCK(Os);
+ if (mdlMap->vmaAddr == gcvNULL)
+ {
+ status = allocator->ops->MapUser(allocator, mdl, mdlMap, Cacheable);
- gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
- return gcvSTATUS_OUT_OF_MEMORY;
- }
- }
- else
+ if (gcmIS_ERROR(status))
{
- start = mdlMap->vma->vm_start;
-
- for (i = 0; i < mdl->numPages; i++)
- {
- pfn = _NonContiguousToPfn(mdl->u.nonContiguousPages, i);
-
- if (remap_pfn_range(mdlMap->vma,
- start,
- pfn,
- PAGE_SIZE,
- mdlMap->vma->vm_page_prot) < 0)
- {
- up_write(¤t->mm->mmap_sem);
-
- gcmkTRACE_ZONE(
- gcvLEVEL_INFO, gcvZONE_OS,
- "%s(%d): gctPHYS_ADDR->0x%X Logical->0x%X Unable to map addr->0x%X to start->0x%X",
- __FUNCTION__, __LINE__,
- (gctUINT32)(gctUINTPTR_T)Physical,
- (gctUINT32)(gctUINTPTR_T)*Logical,
- (gctUINT32)(gctUINTPTR_T)addr,
- (gctUINT32)(gctUINTPTR_T)start
- );
-
- mdlMap->vmaAddr = gcvNULL;
-
- MEMORY_UNLOCK(Os);
-
- gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
- return gcvSTATUS_OUT_OF_MEMORY;
- }
+ MEMORY_UNLOCK(Os);
- start += PAGE_SIZE;
- addr += PAGE_SIZE;
- }
+ gcmkFOOTER_ARG("*status=%d", status);
+ return status;
}
-
- up_write(¤t->mm->mmap_sem);
}
mdlMap->count++;
Os,
_GetProcessID(),
Physical,
- gcvNULL,
+ gcvINVALID_ADDRESS,
(gctPOINTER)mdlMap->vmaAddr,
mdl->numPages * PAGE_SIZE
));
gcvCORE_MAJOR,
Physical,
PageCount,
+ 0,
PageTable);
}
IN gceCORE Core,
IN gctPHYS_ADDR Physical,
IN gctSIZE_T PageCount,
+ IN gctUINT32 Address,
IN gctPOINTER PageTable
)
{
gctPHYS_ADDR pageTablePhysical;
#endif
+#if gcdPROCESS_ADDRESS_SPACE
+ gckKERNEL kernel = Os->device->kernels[Core];
+ gckMMU mmu;
+#endif
+ gckALLOCATOR allocator;
+
gcmkHEADER_ARG("Os=0x%X Core=%d Physical=0x%X PageCount=%u PageTable=0x%X",
Os, Core, Physical, PageCount, PageTable);
/* Convert pointer to MDL. */
mdl = (PLINUX_MDL)Physical;
+ allocator = mdl->allocator;
+
gcmkTRACE_ZONE(
gcvLEVEL_INFO, gcvZONE_OS,
"%s(%d): Physical->0x%X PageCount->0x%X PagedMemory->?%d",
mdl->pagedMem
);
- MEMORY_LOCK(Os);
+#if gcdPROCESS_ADDRESS_SPACE
+ gcmkONERROR(gckKERNEL_GetProcessMMU(kernel, &mmu));
+#endif
table = (gctUINT32 *)PageTable;
#if gcdNONPAGED_MEMORY_CACHEABLE
/* Get all the physical addresses and store them in the page table. */
offset = 0;
+ PageCount = PageCount / (PAGE_SIZE / 4096);
- if (mdl->pagedMem)
+ /* Try to get the user pages so DMA can happen. */
+ while (PageCount-- > 0)
{
- /* Try to get the user pages so DMA can happen. */
- while (PageCount-- > 0)
+ gctUINT i;
+ gctUINT32 phys = ~0;
+
+ if (mdl->pagedMem && !mdl->contiguous)
+ {
+ allocator->ops->Physical(allocator, mdl, offset, &phys);
+ }
+ else
+ {
+ if (!mdl->pagedMem)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): we should not get this call for Non Paged Memory!",
+ __FUNCTION__, __LINE__
+ );
+ }
+
+ phys = page_to_phys(nth_page(mdl->u.contiguousPages, offset));
+ }
+
+ gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Os, phys, &phys));
+
+#ifdef CONFIG_IOMMU_SUPPORT
+ if (Os->iommu)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): Setup mapping in IOMMU %x => %x",
+ __FUNCTION__, __LINE__,
+ Address + (offset * PAGE_SIZE), phys
+ );
+
+ /* When use IOMMU, GPU use system PAGE_SIZE. */
+ gcmkONERROR(gckIOMMU_Map(
+ Os->iommu, Address + (offset * PAGE_SIZE), phys, PAGE_SIZE));
+ }
+ else
+#endif
{
+
#if gcdENABLE_VG
if (Core == gcvCORE_VG)
{
- if (mdl->contiguous)
+ for (i = 0; i < (PAGE_SIZE / 4096); i++)
{
gcmkONERROR(
gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
- page_to_phys(nth_page(mdl->u.contiguousPages, offset)),
- table));
- }
- else
- {
- gcmkONERROR(
- gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
- _NonContiguousToPhys(mdl->u.nonContiguousPages, offset),
- table));
+ phys + (i * 4096),
+ table++));
}
}
else
#endif
{
- if (mdl->contiguous)
+ for (i = 0; i < (PAGE_SIZE / 4096); i++)
{
+#if gcdPROCESS_ADDRESS_SPACE
+ gctUINT32_PTR pageTableEntry;
+ gckMMU_GetPageEntry(mmu, Address + (offset * 4096), &pageTableEntry);
gcmkONERROR(
- gckMMU_SetPage(Os->device->kernels[Core]->mmu,
- page_to_phys(nth_page(mdl->u.contiguousPages, offset)),
- table));
- }
- else
- {
+ gckMMU_SetPage(mmu,
+ phys + (i * 4096),
+ pageTableEntry));
+#else
gcmkONERROR(
gckMMU_SetPage(Os->device->kernels[Core]->mmu,
- _NonContiguousToPhys(mdl->u.nonContiguousPages, offset),
- table));
+ phys + (i * 4096),
+ table++));
+#endif
}
}
-
- table++;
- offset += 1;
}
- }
- else
- {
- gcmkTRACE_ZONE(
- gcvLEVEL_INFO, gcvZONE_OS,
- "%s(%d): we should not get this call for Non Paged Memory!",
- __FUNCTION__, __LINE__
- );
- while (PageCount-- > 0)
- {
-#if gcdENABLE_VG
- if (Core == gcvCORE_VG)
- {
- gcmkONERROR(
- gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
- page_to_phys(nth_page(mdl->u.contiguousPages, offset)),
- table));
- }
- else
-#endif
- {
- gcmkONERROR(
- gckMMU_SetPage(Os->device->kernels[Core]->mmu,
- page_to_phys(nth_page(mdl->u.contiguousPages, offset)),
- table));
- }
- table++;
- offset += 1;
- }
+ offset += 1;
}
#if gcdNONPAGED_MEMORY_CACHEABLE
OnError:
- MEMORY_UNLOCK(Os);
-
/* Return the status. */
gcmkFOOTER();
return status;
}
+gceSTATUS
+gckOS_UnmapPages(
+ IN gckOS Os,
+ IN gctSIZE_T PageCount,
+ IN gctUINT32 Address
+ )
+{
+#ifdef CONFIG_IOMMU_SUPPORT
+ if (Os->iommu)
+ {
+ gcmkVERIFY_OK(gckIOMMU_Unmap(
+ Os->iommu, Address, PageCount * PAGE_SIZE));
+ }
+#endif
+
+ return gcvSTATUS_OK;
+}
+
/*******************************************************************************
**
** gckOS_UnlockPages
{
PLINUX_MDL_MAP mdlMap;
PLINUX_MDL mdl = (PLINUX_MDL)Physical;
+ gckALLOCATOR allocator = mdl->allocator;
gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%u Logical=0x%X",
Os, Physical, Bytes, Logical);
gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
- /* Make sure there is already a mapping...*/
- gcmkVERIFY_ARGUMENT(mdl->u.nonContiguousPages != gcvNULL
- || mdl->u.contiguousPages != gcvNULL);
-
MEMORY_LOCK(Os);
mdlMap = mdl->maps;
{
if (--mdlMap->count == 0)
{
- _UnmapUserLogical(mdlMap->pid, mdlMap->vmaAddr, mdl->numPages * PAGE_SIZE);
+ allocator->ops->UnmapUser(
+ allocator,
+ mdlMap->vmaAddr,
+ mdl->numPages * PAGE_SIZE);
+
mdlMap->vmaAddr = gcvNULL;
}
}
gctUINTPTR_T start, end, memory;
gctUINT32 offset;
gctINT result = 0;
+#if gcdPROCESS_ADDRESS_SPACE
+ gckMMU mmu;
+#endif
gcsPageInfo_PTR info = gcvNULL;
struct page **pages = gcvNULL;
do
{
+ gctSIZE_T extraPage;
+
memory = (gctUINTPTR_T) Memory;
/* Get the number of required pages. */
start = memory >> PAGE_SHIFT;
pageCount = end - start;
+ /* Allocate extra 64 bytes to avoid cache overflow */
+ extraPage = (((memory + gcmALIGN(Size + 64, 64) + PAGE_SIZE - 1) >> PAGE_SHIFT) > end) ? 1 : 0;
+
gcmkTRACE_ZONE(
gcvLEVEL_INFO, gcvZONE_OS,
"%s(%d): pageCount: %d.",
break;
}
+ info->extraPage = 0;
+
/* Allocate the array of page addresses. */
- pages = (struct page **)kmalloc(pageCount * sizeof(struct page *), GFP_KERNEL | gcdNOWARN);
+ pages = (struct page **)kmalloc((pageCount + extraPage) * sizeof(struct page *), GFP_KERNEL | gcdNOWARN);
if (pages == gcvNULL)
{
for (i = 0; i < pageCount; i++)
{
pages[i] = pfn_to_page((Physical >> PAGE_SHIFT) + i);
- get_page(pages[i]);
+
+ if (pfn_valid(page_to_pfn(pages[i])))
+ {
+ get_page(pages[i]);
+ }
}
}
else
*Address = physical - Os->device->baseAddress;
*Info = info;
+ gcmkVERIFY_OK(
+ gckOS_CPUPhysicalToGPUPhysical(Os, *Address, Address));
+
gcmkFOOTER_ARG("*Info=0x%X *Address=0x%08x",
*Info, *Address);
/* Reference pages. */
for (i = 0; i < pageCount; i++)
{
- get_page(pages[i]);
+ if (pfn_valid(page_to_pfn(pages[i])))
+ {
+ get_page(pages[i]);
+ }
}
}
}
/* Flush(clean) the data cache. */
gcmkONERROR(gckOS_CacheFlush(Os, _GetProcessID(), gcvNULL,
- (gctPOINTER)(gctUINTPTR_T)page_to_phys(pages[i]),
+ page_to_phys(pages[i]),
(gctPOINTER)(memory & PAGE_MASK) + i*PAGE_SIZE,
PAGE_SIZE));
}
+#if gcdPROCESS_ADDRESS_SPACE
+ gcmkONERROR(gckKERNEL_GetProcessMMU(Os->device->kernels[Core], &mmu));
+#endif
+
+ if (extraPage)
+ {
+ pages[pageCount++] = Os->paddingPage;
+ info->extraPage = 1;
+ }
+
+#if gcdSECURITY
+ {
+ gctPHYS_ADDR physicalArrayPhysical;
+ gctPOINTER physicalArrayLogical;
+ gctUINT32_PTR logical;
+ gctSIZE_T bytes = pageCount * gcmSIZEOF(gctUINT32);
+ pageTable = gcvNULL;
+
+ gcmkONERROR(gckOS_AllocateNonPagedMemory(
+ Os,
+ gcvFALSE,
+ &bytes,
+ &physicalArrayPhysical,
+ &physicalArrayLogical
+ ));
+
+ logical = physicalArrayLogical;
+
+ /* Fill the page table. */
+ for (i = 0; i < pageCount; i++)
+ {
+ gctUINT32 phys;
+ phys = page_to_phys(pages[i]);
+
+ logical[i] = phys;
+ }
+ j = 0;
+
+
+ gcmkONERROR(gckKERNEL_SecurityMapMemory(
+ Os->device->kernels[Core],
+ physicalArrayLogical,
+ pageCount,
+ &address
+ ));
+
+ gcmkONERROR(gckOS_FreeNonPagedMemory(
+ Os,
+ 1,
+ physicalArrayPhysical,
+ physicalArrayLogical
+ ));
+ }
+
+#else
#if gcdENABLE_VG
if (Core == gcvCORE_VG)
{
else
#endif
{
+#if gcdPROCESS_ADDRESS_SPACE
+ /* Allocate pages inside the page table. */
+ gcmkERR_BREAK(gckMMU_AllocatePages(mmu,
+ pageCount * (PAGE_SIZE/4096),
+ (gctPOINTER *) &pageTable,
+ &address));
+#else
/* Allocate pages inside the page table. */
gcmkERR_BREAK(gckMMU_AllocatePages(Os->device->kernels[Core]->mmu,
pageCount * (PAGE_SIZE/4096),
(gctPOINTER *) &pageTable,
&address));
+#endif
}
/* Fill the page table. */
gctUINT32 phys;
gctUINT32_PTR tab = pageTable + i * (PAGE_SIZE/4096);
+#if gcdPROCESS_ADDRESS_SPACE
+ gckMMU_GetPageEntry(mmu, address + i * 4096, &tab);
+#endif
phys = page_to_phys(pages[i]);
-#if gcdENABLE_VG
- if (Core == gcvCORE_VG)
+#ifdef CONFIG_IOMMU_SUPPORT
+ if (Os->iommu)
{
- /* Get the physical address from page struct. */
- gcmkONERROR(
- gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
- phys,
- tab));
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): Setup mapping in IOMMU %x => %x",
+ __FUNCTION__, __LINE__,
+ Address + (i * PAGE_SIZE), phys
+ );
+
+ gcmkONERROR(gckIOMMU_Map(
+ Os->iommu, address + i * PAGE_SIZE, phys, PAGE_SIZE));
}
else
#endif
{
- /* Get the physical address from page struct. */
- gcmkONERROR(
- gckMMU_SetPage(Os->device->kernels[Core]->mmu,
- phys,
- tab));
- }
- for (j = 1; j < (PAGE_SIZE/4096); j++)
- {
- pageTable[i * (PAGE_SIZE/4096) + j] = pageTable[i * (PAGE_SIZE/4096)] + 4096 * j;
+#if gcdENABLE_VG
+ if (Core == gcvCORE_VG)
+ {
+ gcmkVERIFY_OK(
+ gckOS_CPUPhysicalToGPUPhysical(Os, phys, &phys));
+
+ /* Get the physical address from page struct. */
+ gcmkONERROR(
+ gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
+ phys,
+ tab));
+ }
+ else
+#endif
+ {
+ /* Get the physical address from page struct. */
+ gcmkONERROR(
+ gckMMU_SetPage(Os->device->kernels[Core]->mmu,
+ phys,
+ tab));
+ }
+
+ for (j = 1; j < (PAGE_SIZE/4096); j++)
+ {
+ pageTable[i * (PAGE_SIZE/4096) + j] = pageTable[i * (PAGE_SIZE/4096)] + 4096 * j;
+ }
}
+#if !gcdPROCESS_ADDRESS_SPACE
gcmkTRACE_ZONE(
gcvLEVEL_INFO, gcvZONE_OS,
"%s(%d): pageTable[%d]: 0x%X 0x%X.",
__FUNCTION__, __LINE__,
i, phys, pageTable[i]);
+#endif
}
#if gcdENABLE_VG
else
#endif
{
- gcmkONERROR(gckMMU_Flush(Os->device->kernels[Core]->mmu));
+#if gcdPROCESS_ADDRESS_SPACE
+ info->mmu = mmu;
+ gcmkONERROR(gckMMU_Flush(mmu));
+#else
+ gcmkONERROR(gckMMU_Flush(Os->device->kernels[Core]->mmu, gcvSURF_TYPE_UNKNOWN));
+#endif
}
+#endif
+ info->address = address;
/* Save pointer to page table. */
info->pageTable = pageTable;
MEMORY_MAP_LOCK(Os);
+#if !gcdSECURITY
gcmkASSERT(info->pageTable != gcvNULL);
+#endif
+
+ if (info->extraPage)
+ {
+ pageCount += 1;
+ }
+#if gcdSECURITY
+ if (info->address > 0x80000000)
+ {
+ gckKERNEL_SecurityUnmapMemory(
+ Os->device->kernels[Core],
+ info->address,
+ pageCount
+ );
+ }
+ else
+ {
+ gcmkPRINT("Wrong address %s(%d) %x", __FUNCTION__, __LINE__, info->address);
+ }
+#else
#if gcdENABLE_VG
if (Core == gcvCORE_VG)
{
else
#endif
{
- /* Free the pages from the MMU. */
- gcmkERR_BREAK(gckMMU_FreePages(Os->device->kernels[Core]->mmu,
- info->pageTable,
- pageCount * (PAGE_SIZE/4096)
- ));
+ /* Free the pages from the MMU. */
+#if gcdPROCESS_ADDRESS_SPACE
+ gcmkERR_BREAK(gckMMU_FreePagesEx(info->mmu,
+ info->address,
+ pageCount * (PAGE_SIZE/4096)
+ ));
+
+#else
+ gcmkERR_BREAK(gckMMU_FreePages(Os->device->kernels[Core]->mmu,
+ info->pageTable,
+ pageCount * (PAGE_SIZE/4096)
+ ));
+#endif
+
+ gcmkERR_BREAK(gckOS_UnmapPages(
+ Os,
+ pageCount * (PAGE_SIZE/4096),
+ info->address
+ ));
+ }
+#endif
+
+ if (info->extraPage)
+ {
+ pageCount -= 1;
+ info->extraPage = 0;
}
/* Release the page cache. */
SetPageDirty(pages[i]);
}
- page_cache_release(pages[i]);
+ if (pfn_valid(page_to_pfn(pages[i])))
+ {
+ page_cache_release(pages[i]);
+ }
}
}
return gckOS_SuspendInterruptEx(Os, gcvCORE_MAJOR);
}
+#if gcdMULTI_GPU
+gceSTATUS
+gckOS_SuspendInterruptEx(
+ IN gckOS Os,
+ IN gceCORE Core
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+
+ if (Core == gcvCORE_MAJOR)
+ {
+ disable_irq(Os->device->irqLine3D[gcvCORE_3D_0_ID]);
+ disable_irq(Os->device->irqLine3D[gcvCORE_3D_1_ID]);
+ }
+ else
+ {
+ disable_irq(Os->device->irqLines[Core]);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+#else
gceSTATUS
gckOS_SuspendInterruptEx(
IN gckOS Os,
gcmkFOOTER_NO();
return gcvSTATUS_OK;
}
+#endif
gceSTATUS
gckOS_ResumeInterrupt(
return gckOS_ResumeInterruptEx(Os, gcvCORE_MAJOR);
}
+#if gcdMULTI_GPU
+gceSTATUS
+gckOS_ResumeInterruptEx(
+ IN gckOS Os,
+ IN gceCORE Core
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+
+ if (Core == gcvCORE_MAJOR)
+ {
+ enable_irq(Os->device->irqLine3D[gcvCORE_3D_0_ID]);
+ enable_irq(Os->device->irqLine3D[gcvCORE_3D_1_ID]);
+ }
+ else
+ {
+ enable_irq(Os->device->irqLines[Core]);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+#else
gceSTATUS
gckOS_ResumeInterruptEx(
IN gckOS Os,
gcmkFOOTER_NO();
return gcvSTATUS_OK;
}
+#endif
gceSTATUS
gckOS_MemCopy(
********************************* Cache Control ********************************
*******************************************************************************/
-#if !gcdCACHE_FUNCTION_UNIMPLEMENTED && defined(CONFIG_OUTER_CACHE)
-static inline gceSTATUS
-outer_func(
- gceCACHEOPERATION Type,
- unsigned long Start,
- unsigned long End
- )
-{
- switch (Type)
- {
- case gcvCACHE_CLEAN:
- outer_clean_range(Start, End);
- break;
- case gcvCACHE_INVALIDATE:
- outer_inv_range(Start, End);
- break;
- case gcvCACHE_FLUSH:
- outer_flush_range(Start, End);
- break;
- default:
- return gcvSTATUS_INVALID_ARGUMENT;
- break;
- }
- return gcvSTATUS_OK;
-}
-
-#if gcdENABLE_OUTER_CACHE_PATCH
-/*******************************************************************************
-** _HandleOuterCache
-**
-** Handle the outer cache for the specified addresses.
-**
-** ARGUMENTS:
-**
-** gckOS Os
-** Pointer to gckOS object.
-**
-** gctUINT32 ProcessID
-** Process ID Logical belongs.
-**
-** gctPHYS_ADDR Handle
-** Physical address handle. If gcvNULL it is video memory.
-**
-** gctPOINTER Physical
-** Physical address to flush.
-**
-** gctPOINTER Logical
-** Logical address to flush.
-**
-** gctSIZE_T Bytes
-** Size of the address range in bytes to flush.
-**
-** gceOUTERCACHE_OPERATION Type
-** Operation need to be execute.
-*/
-static gceSTATUS
-_HandleOuterCache(
- IN gckOS Os,
- IN gctUINT32 ProcessID,
- IN gctPHYS_ADDR Handle,
- IN gctPOINTER Physical,
- IN gctPOINTER Logical,
- IN gctSIZE_T Bytes,
- IN gceCACHEOPERATION Type
- )
-{
- gceSTATUS status;
- gctUINT32 i, pageNum;
- unsigned long paddr;
- gctPOINTER vaddr;
-
- gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=0x%X Bytes=%lu",
- Os, ProcessID, Handle, Logical, Bytes);
-
- if (Physical != gcvNULL)
- {
- /* Non paged memory or gcvPOOL_USER surface */
- paddr = (unsigned long) Physical;
- gcmkONERROR(outer_func(Type, paddr, paddr + Bytes));
- }
- else if ((Handle == gcvNULL)
- || (Handle != gcvNULL && ((PLINUX_MDL)Handle)->contiguous)
- )
- {
- /* Video Memory or contiguous virtual memory */
- gcmkONERROR(gckOS_GetPhysicalAddress(Os, Logical, (gctUINT32*)&paddr));
- gcmkONERROR(outer_func(Type, paddr, paddr + Bytes));
- }
- else
- {
- /* Non contiguous virtual memory */
- vaddr = (gctPOINTER)gcmALIGN_BASE((gctUINTPTR_T)Logical, PAGE_SIZE);
- pageNum = GetPageCount(Bytes, 0);
-
- for (i = 0; i < pageNum; i += 1)
- {
- gcmkONERROR(_ConvertLogical2Physical(
- Os,
- vaddr + PAGE_SIZE * i,
- ProcessID,
- (PLINUX_MDL)Handle,
- (gctUINT32*)&paddr
- ));
-
- gcmkONERROR(outer_func(Type, paddr, paddr + PAGE_SIZE));
- }
- }
-
- mb();
-
- /* Success. */
- gcmkFOOTER_NO();
- return gcvSTATUS_OK;
-
-OnError:
- /* Return the status. */
- gcmkFOOTER();
- return status;
-}
-#endif
-#endif
-
/*******************************************************************************
** gckOS_CacheClean
**
IN gckOS Os,
IN gctUINT32 ProcessID,
IN gctPHYS_ADDR Handle,
- IN gctPOINTER Physical,
+ IN gctUINT32 Physical,
IN gctPOINTER Logical,
IN gctSIZE_T Bytes
)
{
+ gcsPLATFORM * platform;
+
gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=0x%X Bytes=%lu",
Os, ProcessID, Handle, Logical, Bytes);
gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
gcmkVERIFY_ARGUMENT(Bytes > 0);
+ platform = Os->device->platform;
+
+ if (platform && platform->ops->cache)
+ {
+ platform->ops->cache(
+ platform,
+ ProcessID,
+ Handle,
+ Physical,
+ Logical,
+ Bytes,
+ gcvCACHE_CLEAN
+ );
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
#if !gcdCACHE_FUNCTION_UNIMPLEMENTED
#ifdef CONFIG_ARM
#if defined(CONFIG_OUTER_CACHE)
/* Outer cache. */
#if gcdENABLE_OUTER_CACHE_PATCH
- _HandleOuterCache(Os, ProcessID, Handle, Physical, Logical, Bytes, gcvCACHE_CLEAN);
+ _HandleOuterCache(Os, Physical, Logical, Bytes, gcvCACHE_CLEAN);
#else
outer_clean_range((unsigned long) Handle, (unsigned long) Handle + Bytes);
#endif
IN gckOS Os,
IN gctUINT32 ProcessID,
IN gctPHYS_ADDR Handle,
- IN gctPOINTER Physical,
+ IN gctUINT32 Physical,
IN gctPOINTER Logical,
IN gctSIZE_T Bytes
)
{
+ gcsPLATFORM * platform;
+
gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=0x%X Bytes=%lu",
Os, ProcessID, Handle, Logical, Bytes);
gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
gcmkVERIFY_ARGUMENT(Bytes > 0);
+ platform = Os->device->platform;
+
+ if (platform && platform->ops->cache)
+ {
+ platform->ops->cache(
+ platform,
+ ProcessID,
+ Handle,
+ Physical,
+ Logical,
+ Bytes,
+ gcvCACHE_INVALIDATE
+ );
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
#if !gcdCACHE_FUNCTION_UNIMPLEMENTED
#ifdef CONFIG_ARM
#if defined(CONFIG_OUTER_CACHE)
/* Outer cache. */
#if gcdENABLE_OUTER_CACHE_PATCH
- _HandleOuterCache(Os, ProcessID, Handle, Physical, Logical, Bytes, gcvCACHE_INVALIDATE);
+ _HandleOuterCache(Os, Physical, Logical, Bytes, gcvCACHE_INVALIDATE);
#else
outer_inv_range((unsigned long) Handle, (unsigned long) Handle + Bytes);
#endif
IN gckOS Os,
IN gctUINT32 ProcessID,
IN gctPHYS_ADDR Handle,
- IN gctPOINTER Physical,
+ IN gctUINT32 Physical,
IN gctPOINTER Logical,
IN gctSIZE_T Bytes
)
{
+ gcsPLATFORM * platform;
+
gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=0x%X Bytes=%lu",
Os, ProcessID, Handle, Logical, Bytes);
gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
gcmkVERIFY_ARGUMENT(Bytes > 0);
+ platform = Os->device->platform;
+
+ if (platform && platform->ops->cache)
+ {
+ platform->ops->cache(
+ platform,
+ ProcessID,
+ Handle,
+ Physical,
+ Logical,
+ Bytes,
+ gcvCACHE_FLUSH
+ );
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
#if !gcdCACHE_FUNCTION_UNIMPLEMENTED
#ifdef CONFIG_ARM
/* Inner cache. */
#if defined(CONFIG_OUTER_CACHE)
/* Outer cache. */
#if gcdENABLE_OUTER_CACHE_PATCH
- _HandleOuterCache(Os, ProcessID, Handle, Physical, Logical, Bytes, gcvCACHE_FLUSH);
+ _HandleOuterCache(Os, Physical, Logical, Bytes, gcvCACHE_FLUSH);
#else
outer_flush_range((unsigned long) Handle, (unsigned long) Handle + Bytes);
#endif
/* Put GPU IDLE. */
gcmkONERROR(
gckHARDWARE_SetPowerManagementState(Hardware,
-#if gcdPOWER_SUSNPEND_WHEN_IDLE
+#if gcdPOWER_SUSPEND_WHEN_IDLE
gcvPOWER_SUSPEND_BROADCAST));
#else
gcvPOWER_IDLE_BROADCAST));
case gcvBROADCAST_GPU_STUCK:
gcmkTRACE_N(gcvLEVEL_ERROR, 0, "gcvBROADCAST_GPU_STUCK\n");
-#if !gcdENABLE_RECOVERY
- gcmkONERROR(gckHARDWARE_DumpGPUState(Hardware));
-#endif
gcmkONERROR(gckKERNEL_Recovery(Hardware->kernel));
break;
gcmkONERROR(gckHARDWARE_DumpGPUState(Hardware));
gcmkONERROR(gckKERNEL_Recovery(Hardware->kernel));
break;
+
+ case gcvBROADCAST_OUT_OF_MEMORY:
+ gcmkTRACE_N(gcvLEVEL_INFO, 0, "gcvBROADCAST_OUT_OF_MEMORY\n");
+
+ status = _ShrinkMemory(Os);
+
+ if (status == gcvSTATUS_NOT_SUPPORTED)
+ {
+ goto OnError;
+ }
+
+ gcmkONERROR(status);
+
+ break;
+
+ default:
+ /* Skip unimplemented broadcast. */
+ break;
}
/* Success. */
** gckOS Os
** Pointer to a gckOS object.
**
-** gckCORE Core
+** gceCORE Core
** GPU whose power is set.
**
** gctBOOL Clock
IN gctBOOL Power
)
{
- struct clk *clk_3dcore = Os->device->clk_3d_core;
- struct clk *clk_3dshader = Os->device->clk_3d_shader;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
- struct clk *clk_3d_axi = Os->device->clk_3d_axi;
-#endif
- struct clk *clk_2dcore = Os->device->clk_2d_core;
- struct clk *clk_2d_axi = Os->device->clk_2d_axi;
- struct clk *clk_vg_axi = Os->device->clk_vg_axi;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
- int ret;
-#endif
+ gcsPLATFORM * platform;
- gctBOOL oldClockState = gcvFALSE;
- gctBOOL oldPowerState = gcvFALSE;
+ gctBOOL powerChange = gcvFALSE;
+ gctBOOL clockChange = gcvFALSE;
gcmkHEADER_ARG("Os=0x%X Core=%d Clock=%d Power=%d", Os, Core, Clock, Power);
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+
+ platform = Os->device->platform;
- if (Os->device->kernels[Core] != NULL)
+ powerChange = (Power != Os->powerStates[Core]);
+
+ clockChange = (Clock != Os->clockStates[Core]);
+
+ if (powerChange && (Power == gcvTRUE))
{
-#if gcdENABLE_VG
- if (Core == gcvCORE_VG)
+ if (platform && platform->ops->setPower)
{
- oldClockState = Os->device->kernels[Core]->vg->hardware->clockState;
- oldPowerState = Os->device->kernels[Core]->vg->hardware->powerState;
- }
- else
- {
-#endif
- oldClockState = Os->device->kernels[Core]->hardware->clockState;
- oldPowerState = Os->device->kernels[Core]->hardware->powerState;
-#if gcdENABLE_VG
- }
-#endif
- }
- if((Power == gcvTRUE) && (oldPowerState == gcvFALSE))
- {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
- if(!IS_ERR(Os->device->gpu_regulator)) {
- ret = regulator_enable(Os->device->gpu_regulator);
- if (ret != 0)
- gckOS_Print("%s(%d): fail to enable pu regulator %d!\n",
- __FUNCTION__, __LINE__, ret);
+ gcmkVERIFY_OK(platform->ops->setPower(platform, Core, Power));
}
-#else
- imx_gpc_power_up_pu(true);
-#endif
-#ifdef CONFIG_PM
- pm_runtime_get_sync(Os->device->pmdev);
-#endif
- }
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
- if (Clock == gcvTRUE) {
- if (oldClockState == gcvFALSE) {
- switch (Core) {
- case gcvCORE_MAJOR:
- clk_enable(clk_3dcore);
- if (cpu_is_mx6q())
- clk_enable(clk_3dshader);
- break;
- case gcvCORE_2D:
- clk_enable(clk_2dcore);
- clk_enable(clk_2d_axi);
- break;
- case gcvCORE_VG:
- clk_enable(clk_2dcore);
- clk_enable(clk_vg_axi);
- break;
- default:
- break;
- }
- }
- } else {
- if (oldClockState == gcvTRUE) {
- switch (Core) {
- case gcvCORE_MAJOR:
- if (cpu_is_mx6q())
- clk_disable(clk_3dshader);
- clk_disable(clk_3dcore);
- break;
- case gcvCORE_2D:
- clk_disable(clk_2dcore);
- clk_disable(clk_2d_axi);
- break;
- case gcvCORE_VG:
- clk_disable(clk_2dcore);
- clk_disable(clk_vg_axi);
- break;
- default:
- break;
- }
- }
+ Os->powerStates[Core] = Power;
}
-#else
- if (Clock == gcvTRUE) {
- if (oldClockState == gcvFALSE) {
- switch (Core) {
- case gcvCORE_MAJOR:
- clk_prepare(clk_3dcore);
- clk_enable(clk_3dcore);
- clk_prepare(clk_3dshader);
- clk_enable(clk_3dshader);
- clk_prepare(clk_3d_axi);
- clk_enable(clk_3d_axi);
- break;
- case gcvCORE_2D:
- clk_prepare(clk_2dcore);
- clk_enable(clk_2dcore);
- clk_prepare(clk_2d_axi);
- clk_enable(clk_2d_axi);
- break;
- case gcvCORE_VG:
- clk_prepare(clk_2dcore);
- clk_enable(clk_2dcore);
- clk_prepare(clk_vg_axi);
- clk_enable(clk_vg_axi);
- break;
- default:
- break;
- }
- }
- } else {
- if (oldClockState == gcvTRUE) {
- switch (Core) {
- case gcvCORE_MAJOR:
- clk_disable(clk_3dshader);
- clk_unprepare(clk_3dshader);
- clk_disable(clk_3dcore);
- clk_unprepare(clk_3dcore);
- clk_disable(clk_3d_axi);
- clk_unprepare(clk_3d_axi);
- break;
- case gcvCORE_2D:
- clk_disable(clk_2dcore);
- clk_unprepare(clk_2dcore);
- clk_disable(clk_2d_axi);
- clk_unprepare(clk_2d_axi);
- break;
- case gcvCORE_VG:
- clk_disable(clk_2dcore);
- clk_unprepare(clk_2dcore);
- clk_disable(clk_vg_axi);
- clk_unprepare(clk_vg_axi);
- break;
- default:
- break;
- }
+
+ if (clockChange)
+ {
+ mutex_lock(&Os->registerAccessLocks[Core]);
+
+ if (platform && platform->ops->setClock)
+ {
+ gcmkVERIFY_OK(platform->ops->setClock(platform, Core, Clock));
}
+
+ Os->clockStates[Core] = Clock;
+
+ mutex_unlock(&Os->registerAccessLocks[Core]);
}
-#endif
- if((Power == gcvFALSE) && (oldPowerState == gcvTRUE))
- {
-#ifdef CONFIG_PM
- pm_runtime_put_sync(Os->device->pmdev);
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
- if(!IS_ERR(Os->device->gpu_regulator))
- regulator_disable(Os->device->gpu_regulator);
-#else
- imx_gpc_power_up_pu(false);
-#endif
+ if (powerChange && (Power == gcvFALSE))
+ {
+ if (platform && platform->ops->setPower)
+ {
+ gcmkVERIFY_OK(platform->ops->setPower(platform, Core, Power));
+ }
+
+ Os->powerStates[Core] = Power;
+ }
- }
- /* TODO: Put your code here. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
}
IN gceCORE Core
)
{
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
-#define SRC_SCR_OFFSET 0
-#define BP_SRC_SCR_GPU3D_RST 1
-#define BP_SRC_SCR_GPU2D_RST 4
- void __iomem *src_base = IO_ADDRESS(SRC_BASE_ADDR);
- gctUINT32 bit_offset,val;
+ gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
+ gcsPLATFORM * platform;
gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core);
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
- if(Core == gcvCORE_MAJOR) {
- bit_offset = BP_SRC_SCR_GPU3D_RST;
- } else if((Core == gcvCORE_VG)
- ||(Core == gcvCORE_2D)) {
- bit_offset = BP_SRC_SCR_GPU2D_RST;
- } else {
- return gcvSTATUS_INVALID_CONFIG;
- }
- val = __raw_readl(src_base + SRC_SCR_OFFSET);
- val &= ~(1 << (bit_offset));
- val |= (1 << (bit_offset));
- __raw_writel(val, src_base + SRC_SCR_OFFSET);
+ platform = Os->device->platform;
- while ((__raw_readl(src_base + SRC_SCR_OFFSET) &
- (1 << (bit_offset))) != 0) {
+ if (platform && platform->ops->reset)
+ {
+ status = platform->ops->reset(platform, Core);
}
gcmkFOOTER_NO();
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
- struct reset_control *rstc = Os->device->rstc[Core];
- if (rstc)
- reset_control_reset(rstc);
-#else
- imx_src_reset_gpu((int)Core);
-#endif
- return gcvSTATUS_OK;
+ return status;
}
/*******************************************************************************
else
{
/* Set the event to an unsignaled state. */
- reinit_completion(&signal->obj);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0)
+ reinit_completion(&signal->obj);
+#else
+ INIT_COMPLETION(signal->obj);
+#endif
}
gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->signalMutex));
else
{
/* Convert wait to milliseconds. */
-#if gcdDETECT_TIMEOUT
- gctINT timeout = (Wait == gcvINFINITE)
- ? gcdINFINITE_TIMEOUT * HZ / 1000
- : Wait * HZ / 1000;
-
- gctUINT complained = 0;
-#else
- gctINT timeout = (Wait == gcvINFINITE)
+ long timeout = (Wait == gcvINFINITE)
? MAX_SCHEDULE_TIMEOUT
: Wait * HZ / 1000;
-#endif
DECLARE_WAITQUEUE(wait, current);
wait.flags |= WQ_FLAG_EXCLUSIVE;
break;
}
-#if gcdDETECT_TIMEOUT
- if ((Wait == gcvINFINITE) && (timeout == 0))
- {
- gctUINT32 dmaAddress1, dmaAddress2;
- gctUINT32 dmaState1, dmaState2;
-
- dmaState1 = dmaState2 =
- dmaAddress1 = dmaAddress2 = 0;
-
- /* Verify whether DMA is running. */
- gcmkVERIFY_OK(_VerifyDMA(
- Os, &dmaAddress1, &dmaAddress2, &dmaState1, &dmaState2
- ));
-
-#if gcdDETECT_DMA_ADDRESS
- /* Dump only if DMA appears stuck. */
- if (
- (dmaAddress1 == dmaAddress2)
-#if gcdDETECT_DMA_STATE
- && (dmaState1 == dmaState2)
-#endif
- )
-#endif
- {
- /* Increment complain count. */
- complained += 1;
-
- gcmkVERIFY_OK(_DumpGPUState(Os, gcvCORE_MAJOR));
-
- gcmkPRINT(
- "%s(%d): signal 0x%X; forced message flush (%d).",
- __FUNCTION__, __LINE__, Signal, complained
- );
-
- /* Flush the debug cache. */
- gcmkDEBUGFLUSH(dmaAddress2);
- }
-
- /* Reset timeout. */
- timeout = gcdINFINITE_TIMEOUT * HZ / 1000;
- }
-#endif
-
if (timeout == 0)
{
}
__remove_wait_queue(&signal->obj.wait, &wait);
-
-#if gcdDETECT_TIMEOUT
- if (complained)
- {
- gcmkPRINT(
- "%s(%d): signal=0x%X; waiting done; status=%d",
- __FUNCTION__, __LINE__, Signal, status
- );
- }
-#endif
}
spin_unlock_irq(&signal->obj.wait.lock);
/*******************************************************************************
**
-** gckOS_UnmapSignal
+** gckOS_UnmapSignal
**
-** Unmap a signal .
+** Unmap a signal .
**
-** INPUT:
+** INPUT:
**
-** gckOS Os
-** Pointer to an gckOS object.
+** gckOS Os
+** Pointer to an gckOS object.
**
-** gctSIGNAL Signal
-** Pointer to that gctSIGNAL mapped.
+** gctSIGNAL Signal
+** Pointer to that gctSIGNAL mapped.
*/
gceSTATUS
gckOS_UnmapSignal(
gctSIZE_T signal;
/* Create a new signal. */
- status = gckOS_CreateSignal(Os, ManualReset, (gctSIGNAL *) &signal);
+ gcmkONERROR(gckOS_CreateSignal(Os, ManualReset, (gctSIGNAL *) &signal));
*SignalID = (gctINT) signal;
+OnError:
return status;
}
do
{
/* Allocate the semaphore structure. */
- newSemaphore = (struct semaphore *)kmalloc(gcmSIZEOF(struct semaphore), GFP_KERNEL | gcdNOWARN);
- if (newSemaphore == gcvNULL)
- {
- gcmkERR_BREAK(gcvSTATUS_OUT_OF_MEMORY);
- }
+ newSemaphore = (struct semaphore *)kmalloc(gcmSIZEOF(struct semaphore), GFP_KERNEL | gcdNOWARN);
+ if (newSemaphore == gcvNULL)
+ {
+ gcmkERR_BREAK(gcvSTATUS_OUT_OF_MEMORY);
+ }
/* Initialize the semaphore. */
sema_init(newSemaphore, 0);
timer = (gcsOSTIMER_PTR)Timer;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
+ mod_delayed_work(Os->workqueue, &timer->work, msecs_to_jiffies(Delay));
+#else
if (unlikely(delayed_work_pending(&timer->work)))
{
- if (unlikely(!cancel_delayed_work(&timer->work)))
- {
- cancel_work_sync(&timer->work.work);
-
- if (unlikely(delayed_work_pending(&timer->work)))
- {
- gckOS_Print("gckOS_StartTimer error, the pending worker cannot complete!!!! \n");
-
- return gcvSTATUS_INVALID_REQUEST;
- }
- }
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
+ cancel_delayed_work_sync(&timer->work);
+#else
+ cancel_delayed_work(&timer->work);
+ flush_workqueue(Os->workqueue);
+#endif
}
queue_delayed_work(Os->workqueue, &timer->work, msecs_to_jiffies(Delay));
+#endif
gcmkFOOTER_NO();
return gcvSTATUS_OK;
return gcvSTATUS_OK;
}
-
-gceSTATUS
-gckOS_DumpCallStack(
- IN gckOS Os
- )
-{
- gcmkHEADER_ARG("Os=0x%X", Os);
-
- gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
-
- dump_stack();
-
- gcmkFOOTER_NO();
- return gcvSTATUS_OK;
-}
-
-
gceSTATUS
gckOS_GetProcessNameByPid(
IN gctINT Pid,
return gcvSTATUS_OK;
}
+gceSTATUS
+gckOS_DumpCallStack(
+ IN gckOS Os
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X", Os);
+
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+
+ dump_stack();
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckOS_DetectProcessByName
+**
+** task->comm maybe part of process name, so this function
+** can only be used for debugging.
+**
+** INPUT:
+**
+** gctCONST_POINTER Name
+** Pointer to a string to hold name to be check. If the length
+** of name is longer than TASK_COMM_LEN (16), use part of name
+** to detect.
+**
+** OUTPUT:
+**
+** gcvSTATUS_TRUE if name of current process matches Name.
+**
+*/
+gceSTATUS
+gckOS_DetectProcessByName(
+ IN gctCONST_POINTER Name
+ )
+{
+ char comm[sizeof(current->comm)];
+
+ memset(comm, 0, sizeof(comm));
+
+ gcmkVERIFY_OK(
+ gckOS_GetProcessNameByPid(_GetProcessID(), sizeof(current->comm), comm));
+
+ return strstr(comm, Name) ? gcvSTATUS_TRUE
+ : gcvSTATUS_FALSE;
+}
+
#if gcdANDROID_NATIVE_FENCE_SYNC
gceSTATUS
{
gceSTATUS status;
gcsSYNC_POINT_PTR syncPoint;
+ struct sync_timeline * timeline;
gctBOOL acquired = gcvFALSE;
gcmkHEADER_ARG("Os=0x%X SyncPoint=%d", Os, (gctUINT32)(gctUINTPTR_T)SyncPoint);
gcmkASSERT(syncPoint->id == (gctUINT32)(gctUINTPTR_T)SyncPoint);
- /* Get state. */
- atomic_set(&syncPoint->state, gcvTRUE);
+ /* Set signaled state. */
+ atomic_set(&syncPoint->state, 1);
- /* Signal timeline. */
- if (syncPoint->timeline)
- {
- sync_timeline_signal(syncPoint->timeline);
- }
+ /* Get parent timeline. */
+ timeline = syncPoint->timeline;
gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->syncPointMutex));
acquired = gcvFALSE;
+ /* Signal timeline. */
+ if (timeline)
+ {
+ sync_timeline_signal(timeline);
+ }
+
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
return status;
}
#endif
+
+#if gcdSECURITY
+gceSTATUS
+gckOS_AllocatePageArray(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T PageCount,
+ OUT gctPOINTER * PageArrayLogical,
+ OUT gctPHYS_ADDR * PageArrayPhysical
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ PLINUX_MDL mdl;
+ gctUINT32* table;
+ gctUINT32 offset;
+ gctSIZE_T bytes;
+ gckALLOCATOR allocator;
+
+ gcmkHEADER_ARG("Os=0x%X Physical=0x%X PageCount=%u",
+ Os, Physical, PageCount);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(PageCount > 0);
+
+ bytes = PageCount * gcmSIZEOF(gctUINT32);
+ gcmkONERROR(gckOS_AllocateNonPagedMemory(
+ Os,
+ gcvFALSE,
+ &bytes,
+ PageArrayPhysical,
+ PageArrayLogical
+ ));
+
+ table = *PageArrayLogical;
+
+ /* Convert pointer to MDL. */
+ mdl = (PLINUX_MDL)Physical;
+
+ allocator = mdl->allocator;
+
+ /* Get all the physical addresses and store them in the page table. */
+
+ offset = 0;
+ PageCount = PageCount / (PAGE_SIZE / 4096);
+
+ /* Try to get the user pages so DMA can happen. */
+ while (PageCount-- > 0)
+ {
+ unsigned long phys = ~0;
+
+ if (mdl->pagedMem && !mdl->contiguous)
+ {
+ if (allocator)
+ {
+ gctUINT32 phys_addr;
+ allocator->ops->Physical(allocator, mdl, offset, &phys_addr);
+ phys = (unsigned long)phys_addr;
+ }
+ }
+ else
+ {
+ if (!mdl->pagedMem)
+ {
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_OS,
+ "%s(%d): we should not get this call for Non Paged Memory!",
+ __FUNCTION__, __LINE__
+ );
+ }
+
+ phys = page_to_phys(nth_page(mdl->u.contiguousPages, offset));
+ }
+
+ table[offset] = phys;
+
+ offset += 1;
+ }
+
+OnError:
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
+gceSTATUS
+gckOS_CPUPhysicalToGPUPhysical(
+ IN gckOS Os,
+ IN gctUINT32 CPUPhysical,
+ IN gctUINT32_PTR GPUPhysical
+ )
+{
+ gcsPLATFORM * platform;
+ gcmkHEADER_ARG("CPUPhysical=0x%X", CPUPhysical);
+
+ platform = Os->device->platform;
+
+ if (platform && platform->ops->getGPUPhysical)
+ {
+ gcmkVERIFY_OK(
+ platform->ops->getGPUPhysical(platform, CPUPhysical, GPUPhysical));
+ }
+ else
+ {
+ *GPUPhysical = CPUPhysical;
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_GPUPhysicalToCPUPhysical(
+ IN gckOS Os,
+ IN gctUINT32 GPUPhysical,
+ IN gctUINT32_PTR CPUPhysical
+ )
+{
+ gcmkHEADER_ARG("GPUPhysical=0x%X", GPUPhysical);
+
+ *CPUPhysical = GPUPhysical;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_PhysicalToPhysicalAddress(
+ IN gckOS Os,
+ IN gctPOINTER Physical,
+ OUT gctUINT32 * PhysicalAddress
+ )
+{
+ PLINUX_MDL mdl = (PLINUX_MDL)Physical;
+ gckALLOCATOR allocator = mdl->allocator;
+
+ if (allocator)
+ {
+ return allocator->ops->Physical(allocator, mdl, 0, PhysicalAddress);
+ }
+
+ return gcvSTATUS_NOT_SUPPORTED;
+}
+
+gceSTATUS
+gckOS_QueryOption(
+ IN gckOS Os,
+ IN gctCONST_STRING Option,
+ OUT gctUINT32 * Value
+ )
+{
+ gckGALDEVICE device = Os->device;
+
+ if (!strcmp(Option, "physBase"))
+ {
+ *Value = device->physBase;
+ return gcvSTATUS_OK;
+ }
+ else if (!strcmp(Option, "physSize"))
+ {
+ *Value = device->physSize;
+ return gcvSTATUS_OK;
+ }
+ else if (!strcmp(Option, "mmu"))
+ {
+#if gcdSECURITY
+ *Value = 0;
+#else
+ *Value = device->mmu;
+#endif
+ return gcvSTATUS_OK;
+ }
+
+ return gcvSTATUS_NOT_SUPPORTED;
+}
+
+static int
+fd_release(
+ struct inode *inode,
+ struct file *file
+ )
+{
+ gcsFDPRIVATE_PTR private = (gcsFDPRIVATE_PTR)file->private_data;
+
+ if (private && private->release)
+ {
+ return private->release(private);
+ }
+
+ return 0;
+}
+
+static const struct file_operations fd_fops = {
+ .release = fd_release,
+};
+
+gceSTATUS
+gckOS_GetFd(
+ IN gctSTRING Name,
+ IN gcsFDPRIVATE_PTR Private,
+ OUT gctINT *Fd
+ )
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+ *Fd = anon_inode_getfd(Name, &fd_fops, Private, O_RDWR);
+
+ if (*Fd < 0)
+ {
+ return gcvSTATUS_OUT_OF_RESOURCES;
+ }
+
+ return gcvSTATUS_OK;
+#else
+ return gcvSTATUS_NOT_SUPPORTED;
+#endif
+}
+
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
typedef struct _LINUX_MDL
{
- gctINT pid;
char * addr;
union _pages
PLINUX_MDL_MAP maps;
struct _LINUX_MDL * prev;
struct _LINUX_MDL * next;
+
+ /* Pointer to allocator which allocates memory for this mdl. */
+ void * allocator;
+
+ /* Private data used by allocator. */
+ void * priv;
+
+ uint gid;
}
LINUX_MDL, *PLINUX_MDL;
--- /dev/null
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2014 by Vivante Corp.
+*
+* 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.
+*
+*****************************************************************************/
+
+
+#ifndef _gc_hal_kernel_platform_h_
+#define _gc_hal_kernel_platform_h_
+#include <linux/mm.h>
+
+typedef struct _gcsMODULE_PARAMETERS
+{
+#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY
+ gctINT irqLine3D0;
+ gctUINT registerMemBase3D0;
+ gctUINT registerMemSize3D0;
+ gctINT irqLine3D1;
+ gctUINT registerMemBase3D1;
+ gctUINT registerMemSize3D1;
+#else
+ gctINT irqLine;
+ gctUINT registerMemBase;
+ gctUINT registerMemSize;
+#endif
+ gctINT irqLine2D;
+ gctUINT registerMemBase2D;
+ gctUINT registerMemSize2D;
+ gctINT irqLineVG;
+ gctUINT registerMemBaseVG;
+ gctUINT registerMemSizeVG;
+ gctUINT contiguousSize;
+ gctUINT contiguousBase;
+ gctUINT contiguousRequested;
+ gctUINT bankSize;
+ gctINT fastClear;
+ gctINT compression;
+ gctINT powerManagement;
+ gctINT gpuProfiler;
+ gctINT signal;
+ gctUINT baseAddress;
+ gctUINT physSize;
+ gctUINT logFileSize;
+ gctUINT recovery;
+ gctUINT stuckDump;
+ gctUINT showArgs;
+ gctUINT gpu3DMinClock;
+}
+gcsMODULE_PARAMETERS;
+
+typedef struct _gcsPLATFORM * gckPLATFORM;
+
+typedef struct _gcsPLATFORM_OPERATIONS
+{
+ /*******************************************************************************
+ **
+ ** needAddDevice
+ **
+ ** Determine whether platform_device is created by initialization code.
+ ** If platform_device is created by BSP, return gcvFLASE here.
+ */
+ gctBOOL
+ (*needAddDevice)(
+ IN gckPLATFORM Platform
+ );
+
+ /*******************************************************************************
+ **
+ ** adjustParam
+ **
+ ** Override content of arguments, if a argument is not changed here, it will
+ ** keep as default value or value set by insmod command line.
+ */
+ gceSTATUS
+ (*adjustParam)(
+ IN gckPLATFORM Platform,
+ OUT gcsMODULE_PARAMETERS *Args
+ );
+
+ /*******************************************************************************
+ **
+ ** adjustDriver
+ **
+ ** Override content of platform_driver which will be registered.
+ */
+ gceSTATUS
+ (*adjustDriver)(
+ IN gckPLATFORM Platform
+ );
+
+ /*******************************************************************************
+ **
+ ** getPower
+ **
+ ** Prepare power and clock operation.
+ */
+ gceSTATUS
+ (*getPower)(
+ IN gckPLATFORM Platform
+ );
+
+ /*******************************************************************************
+ **
+ ** putPower
+ **
+ ** Finish power and clock operation.
+ */
+ gceSTATUS
+ (*putPower)(
+ IN gckPLATFORM Platform
+ );
+
+ /*******************************************************************************
+ **
+ ** allocPriv
+ **
+ ** Construct platform private data.
+ */
+ gceSTATUS
+ (*allocPriv)(
+ IN gckPLATFORM Platform
+ );
+
+ /*******************************************************************************
+ **
+ ** freePriv
+ **
+ ** free platform private data.
+ */
+ gceSTATUS
+ (*freePriv)(
+ IN gckPLATFORM Platform
+ );
+
+ /*******************************************************************************
+ **
+ ** setPower
+ **
+ ** Set power state of specified GPU.
+ **
+ ** INPUT:
+ **
+ ** gceCORE GPU
+ ** GPU neeed to config.
+ **
+ ** gceBOOL Enable
+ ** Enable or disable power.
+ */
+ gceSTATUS
+ (*setPower)(
+ IN gckPLATFORM Platform,
+ IN gceCORE GPU,
+ IN gctBOOL Enable
+ );
+
+ /*******************************************************************************
+ **
+ ** setClock
+ **
+ ** Set clock state of specified GPU.
+ **
+ ** INPUT:
+ **
+ ** gceCORE GPU
+ ** GPU neeed to config.
+ **
+ ** gceBOOL Enable
+ ** Enable or disable clock.
+ */
+ gceSTATUS
+ (*setClock)(
+ IN gckPLATFORM Platform,
+ IN gceCORE GPU,
+ IN gctBOOL Enable
+ );
+
+ /*******************************************************************************
+ **
+ ** reset
+ **
+ ** Reset GPU outside.
+ **
+ ** INPUT:
+ **
+ ** gceCORE GPU
+ ** GPU neeed to reset.
+ */
+ gceSTATUS
+ (*reset)(
+ IN gckPLATFORM Platform,
+ IN gceCORE GPU
+ );
+
+ /*******************************************************************************
+ **
+ ** getGPUPhysical
+ **
+ ** Convert CPU physical address to GPU physical address if they are
+ ** different.
+ */
+ gceSTATUS
+ (*getGPUPhysical)(
+ IN gckPLATFORM Platform,
+ IN gctUINT32 CPUPhysical,
+ OUT gctUINT32_PTR GPUPhysical
+ );
+
+ /*******************************************************************************
+ **
+ ** adjustProt
+ **
+ ** Override Prot flag when mapping paged memory to userspace.
+ */
+ gceSTATUS
+ (*adjustProt)(
+ IN struct vm_area_struct * vma
+ );
+
+ /*******************************************************************************
+ **
+ ** shrinkMemory
+ **
+ ** Do something to collect memory, eg, act as oom killer.
+ */
+ gceSTATUS
+ (*shrinkMemory)(
+ IN gckPLATFORM Platform
+ );
+
+ /*******************************************************************************
+ **
+ ** cache
+ **
+ ** Cache operation.
+ */
+ gceSTATUS
+ (*cache)(
+ IN gckPLATFORM Platform,
+ IN gctUINT32 ProcessID,
+ IN gctPHYS_ADDR Handle,
+ IN gctUINT32 Physical,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes,
+ IN gceCACHEOPERATION Operation
+ );
+}
+gcsPLATFORM_OPERATIONS;
+
+typedef struct _gcsPLATFORM
+{
+ struct platform_device* device;
+ struct platform_driver* driver;
+
+ gcsPLATFORM_OPERATIONS* ops;
+
+ void* priv;
+}
+gcsPLATFORM;
+
+void
+gckPLATFORM_QueryOperations(
+ IN gcsPLATFORM_OPERATIONS ** Operations
+ );
+
+#endif
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
-* Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
*
*****************************************************************************/
+
#include <linux/device.h>
#include <linux/slab.h>
-#include <linux/notifier.h>
+
#include "gc_hal_kernel_linux.h"
#include "gc_hal_driver.h"
#endif
-#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
-# include <linux/resmem_account.h>
-# include <linux/kernel.h>
-# include <linux/mm.h>
-# include <linux/oom.h>
-# include <linux/sched.h>
-# include <linux/notifier.h>
-
-struct task_struct *lowmem_deathpending;
-
-static int
-task_notify_func(struct notifier_block *self, unsigned long val, void *data);
-
-static struct notifier_block task_nb = {
- .notifier_call = task_notify_func,
-};
-
-static int
-task_notify_func(struct notifier_block *self, unsigned long val, void *data)
-{
- struct task_struct *task = data;
-
- if (task == lowmem_deathpending)
- lowmem_deathpending = NULL;
-
- return NOTIFY_OK;
-}
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
-#include <mach/viv_gpu.h>
-#else
-#include <linux/pm_runtime.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
-#include <mach/busfreq.h>
-#else
-#include <linux/reset.h>
-#endif
-#endif
/* Zone used for header/footer. */
#define _GC_OBJ_ZONE gcvZONE_DRIVER
-#if gcdENABLE_FSCALE_VAL_ADJUST
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
-#include <linux/device_cooling.h>
-#define REG_THERMAL_NOTIFIER(a) register_devfreq_cooling_notifier(a);
-#define UNREG_THERMAL_NOTIFIER(a) unregister_devfreq_cooling_notifier(a);
-#else
-extern int register_thermal_notifier(struct notifier_block *nb);
-extern int unregister_thermal_notifier(struct notifier_block *nb);
-#define REG_THERMAL_NOTIFIER(a) register_thermal_notifier(a);
-#define UNREG_THERMAL_NOTIFIER(a) unregister_thermal_notifier(a);
-#endif
-#endif
-
MODULE_DESCRIPTION("Vivante Graphics Driver");
MODULE_LICENSE("GPL");
static struct class* gpuClass;
+static gcsPLATFORM platform;
+
static gckGALDEVICE galDevice;
static uint major = 199;
module_param(major, uint, 0644);
+#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY
+static int irqLine3D0 = -1;
+module_param(irqLine3D0, int, 0644);
+
+static ulong registerMemBase3D0 = 0;
+module_param(registerMemBase3D0, ulong, 0644);
+
+static ulong registerMemSize3D0 = 2 << 10;
+module_param(registerMemSize3D0, ulong, 0644);
+
+static int irqLine3D1 = -1;
+module_param(irqLine3D1, int, 0644);
+
+static ulong registerMemBase3D1 = 0;
+module_param(registerMemBase3D1, ulong, 0644);
+
+static ulong registerMemSize3D1 = 2 << 10;
+module_param(registerMemSize3D1, ulong, 0644);
+#else
static int irqLine = -1;
module_param(irqLine, int, 0644);
static ulong registerMemSize = 2 << 10;
module_param(registerMemSize, ulong, 0644);
+#endif
static int irqLine2D = -1;
module_param(irqLine2D, int, 0644);
static ulong registerMemSizeVG = 2 << 10;
module_param(registerMemSizeVG, ulong, 0644);
-#if gcdENABLE_FSCALE_VAL_ADJUST
-static ulong contiguousSize = 128 << 20;
-#else
-static ulong contiguousSize = 4 << 20;
+#ifndef gcdDEFAULT_CONTIGUOUS_SIZE
+#define gcdDEFAULT_CONTIGUOUS_SIZE (4 << 20)
#endif
+static ulong contiguousSize = gcdDEFAULT_CONTIGUOUS_SIZE;
module_param(contiguousSize, ulong, 0644);
static ulong contiguousBase = 0;
static int compression = -1;
module_param(compression, int, 0644);
-static int powerManagement = 1;
+static int powerManagement = -1;
module_param(powerManagement, int, 0644);
static int gpuProfiler = 0;
static ulong physSize = 0;
module_param(physSize, ulong, 0644);
-static uint logFileSize=0;
+static uint logFileSize = 0;
module_param(logFileSize,uint, 0644);
+static uint recovery = 1;
+module_param(recovery, uint, 0644);
+MODULE_PARM_DESC(recovery, "Recover GPU from stuck (1: Enable, 0: Disable)");
+
+/* Middle needs about 40KB buffer, Maximal may need more than 200KB buffer. */
+static uint stuckDump = 1;
+module_param(stuckDump, uint, 0644);
+MODULE_PARM_DESC(stuckDump, "Level of stuck dump content (1: Minimal, 2: Middle, 3: Maximal)");
+
static int showArgs = 0;
module_param(showArgs, int, 0644);
-int gpu3DMinClock = 0;
-module_param(gpu3DMinClock, int, 0644);
+static int mmu = 1;
+module_param(mmu, int, 0644);
-#if ENABLE_GPU_CLOCK_BY_DRIVER
- unsigned long coreClock = 156000000;
- module_param(coreClock, ulong, 0644);
-#endif
+static int gpu3DMinClock = 1;
+
+static int contiguousRequested = 0;
static int drv_open(
struct inode* inode,
.mmap = drv_mmap,
};
-#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
-static size_t viv_gpu_resmem_query(struct task_struct *p, struct reserved_memory_account *m);
-static struct reserved_memory_account viv_gpu_resmem_handler = {
- .name = "viv_gpu",
- .get_page_used_by_process = viv_gpu_resmem_query,
-};
+void
+_UpdateModuleParam(
+ gcsMODULE_PARAMETERS *Param
+ )
+{
+#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY
+#else
+ irqLine = Param->irqLine ;
+ registerMemBase = Param->registerMemBase;
+ registerMemSize = Param->registerMemSize;
+#endif
+ irqLine2D = Param->irqLine2D ;
+ registerMemBase2D = Param->registerMemBase2D;
+ registerMemSize2D = Param->registerMemSize2D;
+ irqLineVG = Param->irqLineVG;
+ registerMemBaseVG = Param->registerMemBaseVG;
+ registerMemSizeVG = Param->registerMemSizeVG;
+ contiguousSize = Param->contiguousSize;
+ contiguousBase = Param->contiguousBase;
+ bankSize = Param->bankSize;
+ fastClear = Param->fastClear;
+ compression = Param->compression;
+ powerManagement = Param->powerManagement;
+ gpuProfiler = Param->gpuProfiler;
+ signal = Param->signal;
+ baseAddress = Param->baseAddress;
+ physSize = Param->physSize;
+ logFileSize = Param->logFileSize;
+ recovery = Param->recovery;
+ stuckDump = Param->stuckDump;
+ showArgs = Param->showArgs;
+ contiguousRequested = Param->contiguousRequested;
+ gpu3DMinClock = Param->gpu3DMinClock;
+}
-size_t viv_gpu_resmem_query(struct task_struct *p, struct reserved_memory_account *m)
+void
+gckOS_DumpParam(
+ void
+ )
{
- gcuDATABASE_INFO info;
- unsigned int processid = p->pid;
- gckKERNEL gpukernel = m->data;
+ printk("Galcore options:\n");
+#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY
+ printk(" irqLine3D0 = %d\n", irqLine3D0);
+ printk(" registerMemBase3D0 = 0x%08lX\n", registerMemBase3D0);
+ printk(" registerMemSize3D0 = 0x%08lX\n", registerMemSize3D0);
- /* ignore error happens in this api. */
- if (gckKERNEL_QueryProcessDB(gpukernel, processid, false, gcvDB_VIDEO_MEMORY, &info) != gcvSTATUS_OK)
- return 0;
+ if (irqLine3D1 != -1)
+ {
+ printk(" irqLine3D1 = %d\n", irqLine3D1);
+ printk(" registerMemBase3D1 = 0x%08lX\n", registerMemBase3D1);
+ printk(" registerMemSize3D1 = 0x%08lX\n", registerMemSize3D1);
+ }
+#else
+ printk(" irqLine = %d\n", irqLine);
+ printk(" registerMemBase = 0x%08lX\n", registerMemBase);
+ printk(" registerMemSize = 0x%08lX\n", registerMemSize);
+#endif
- /* we return pages. */
- if (info.counters.bytes > 0)
- return info.counters.bytes / PAGE_SIZE;
- return 0;
+ if (irqLine2D != -1)
+ {
+ printk(" irqLine2D = %d\n", irqLine2D);
+ printk(" registerMemBase2D = 0x%08lX\n", registerMemBase2D);
+ printk(" registerMemSize2D = 0x%08lX\n", registerMemSize2D);
+ }
+
+ if (irqLineVG != -1)
+ {
+ printk(" irqLineVG = %d\n", irqLineVG);
+ printk(" registerMemBaseVG = 0x%08lX\n", registerMemBaseVG);
+ printk(" registerMemSizeVG = 0x%08lX\n", registerMemSizeVG);
+ }
+
+ printk(" contiguousSize = %ld\n", contiguousSize);
+ printk(" contiguousBase = 0x%08lX\n", contiguousBase);
+ printk(" bankSize = 0x%08lX\n", bankSize);
+ printk(" fastClear = %d\n", fastClear);
+ printk(" compression = %d\n", compression);
+ printk(" signal = %d\n", signal);
+ printk(" powerManagement = %d\n", powerManagement);
+ printk(" baseAddress = 0x%08lX\n", baseAddress);
+ printk(" physSize = 0x%08lX\n", physSize);
+ printk(" logFileSize = %d KB \n", logFileSize);
+ printk(" recovery = %d\n", recovery);
+ printk(" stuckDump = %d\n", stuckDump);
+ printk(" gpuProfiler = %d\n", gpuProfiler);
}
-#endif
int drv_open(
struct inode* inode,
gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
}
- data = kmalloc(sizeof(gcsHAL_PRIVATE_DATA), GFP_KERNEL);
+ data = kmalloc(sizeof(gcsHAL_PRIVATE_DATA), GFP_KERNEL | __GFP_NOWARN);
if (data == gcvNULL)
{
if (!galDevice->contiguousMapped)
{
- gcmkONERROR(gckOS_MapMemory(
- galDevice->os,
- galDevice->contiguousPhysical,
- galDevice->contiguousSize,
- &data->contiguousLogical
- ));
+ if (galDevice->contiguousPhysical != gcvNULL)
+ {
+ gcmkONERROR(gckOS_MapMemory(
+ galDevice->os,
+ galDevice->contiguousPhysical,
+ galDevice->contiguousSize,
+ &data->contiguousLogical
+ ));
+ }
}
filp->private_data = data;
gckGALDEVICE device;
gcsHAL_PRIVATE_DATA_PTR data;
gctINT32 i, count;
+ gckVIDMEM_NODE nodeObject;
gcmkHEADER_ARG(
"filp=0x%08X ioctlCode=0x%08X arg=0x%08X",
}
else
{
- if (iface.hardwareType < 0 || iface.hardwareType > 7)
+ if (iface.hardwareType > 7)
{
gcmkTRACE_ZONE(
gcvLEVEL_ERROR, gcvZONE_DRIVER,
if (gcmIS_SUCCESS(status) && (iface.command == gcvHAL_LOCK_VIDEO_MEMORY))
{
- gcuVIDMEM_NODE_PTR node = gcmUINT64_TO_PTR(iface.u.LockVideoMemory.node);
+ gcuVIDMEM_NODE_PTR node;
+ gctUINT32 processID;
+
+ gckOS_GetProcessID(&processID);
+
+ gcmkONERROR(gckVIDMEM_HANDLE_Lookup(device->kernels[device->coreMapping[iface.hardwareType]],
+ processID,
+ (gctUINT32)iface.u.LockVideoMemory.node,
+ &nodeObject));
+ node = nodeObject->node;
+
/* Special case for mapped memory. */
if ((data->mappedMemory != gcvNULL)
&& (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
return 0;
}
-
OnError:
gcmkFOOTER();
return -ENOTTY;
#if !USE_PLATFORM_DRIVER
static int __init drv_init(void)
#else
-static int drv_init(struct device *pdev)
+static int drv_init(void)
#endif
{
int ret;
gckGALDEVICE device = gcvNULL;
struct class* device_class = gcvNULL;
- gcmkHEADER();
-
-#if ENABLE_GPU_CLOCK_BY_DRIVER && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
- {
-# if 0
- struct clk * clk;
-
- clk = clk_get(NULL, "GCCLK");
-
- if (IS_ERR(clk))
- {
- gcmkTRACE_ZONE(
- gcvLEVEL_ERROR, gcvZONE_DRIVER,
- "%s(%d): clk get error: %d\n",
- __FUNCTION__, __LINE__,
- PTR_ERR(clk)
- );
-
- result = -ENODEV;
- gcmkONERROR(gcvSTATUS_GENERIC_IO);
- }
-
- /*
- * APMU_GC_156M, APMU_GC_312M, APMU_GC_PLL2, APMU_GC_PLL2_DIV2 currently.
- * Use the 2X clock.
- */
- if (clk_set_rate(clk, coreClock * 2))
- {
- gcmkTRACE_ZONE(
- gcvLEVEL_ERROR, gcvZONE_DRIVER,
- "%s(%d): Failed to set core clock.\n",
- __FUNCTION__, __LINE__
- );
-
- result = -EAGAIN;
- gcmkONERROR(gcvSTATUS_GENERIC_IO);
- }
-
- clk_enable(clk);
+ gcsDEVICE_CONSTRUCT_ARGS args = {
+ .recovery = recovery,
+ .stuckDump = stuckDump,
+ .gpu3DMinClock = gpu3DMinClock,
+ .contiguousRequested = contiguousRequested,
+ .platform = &platform,
+ .mmu = mmu,
+ };
-#if defined(CONFIG_PXA_DVFM) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
- gc_pwr(1);
-# endif
-# endif
- }
-#endif
+ gcmkHEADER();
printk(KERN_INFO "Galcore version %d.%d.%d.%d\n",
gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH, gcvVERSION_BUILD);
+
+#if !VIVANTE_PROFILER_PM
/* when enable gpu profiler, we need to turn off gpu powerMangement */
- if(gpuProfiler)
+ if (gpuProfiler)
+ {
powerManagement = 0;
+ }
+#endif
+
if (showArgs)
{
- printk("galcore options:\n");
- printk(" irqLine = %d\n", irqLine);
- printk(" registerMemBase = 0x%08lX\n", registerMemBase);
- printk(" registerMemSize = 0x%08lX\n", registerMemSize);
-
- if (irqLine2D != -1)
- {
- printk(" irqLine2D = %d\n", irqLine2D);
- printk(" registerMemBase2D = 0x%08lX\n", registerMemBase2D);
- printk(" registerMemSize2D = 0x%08lX\n", registerMemSize2D);
- }
-
- if (irqLineVG != -1)
- {
- printk(" irqLineVG = %d\n", irqLineVG);
- printk(" registerMemBaseVG = 0x%08lX\n", registerMemBaseVG);
- printk(" registerMemSizeVG = 0x%08lX\n", registerMemSizeVG);
- }
-
- printk(" contiguousSize = %ld\n", contiguousSize);
- printk(" contiguousBase = 0x%08lX\n", contiguousBase);
- printk(" bankSize = 0x%08lX\n", bankSize);
- printk(" fastClear = %d\n", fastClear);
- printk(" compression = %d\n", compression);
- printk(" signal = %d\n", signal);
- printk(" baseAddress = 0x%08lX\n", baseAddress);
- printk(" physSize = 0x%08lX\n", physSize);
- printk(" logFileSize = %d KB \n", logFileSize);
- printk(" powerManagement = %d\n", powerManagement);
- printk(" gpuProfiler = %d\n", gpuProfiler);
-#if ENABLE_GPU_CLOCK_BY_DRIVER
- printk(" coreClock = %lu\n", coreClock);
-#endif
+ gckOS_DumpParam();
}
- if(logFileSize != 0)
+ if (logFileSize != 0)
{
- gckDebugFileSystemInitialize();
+ gckDEBUGFS_Initialize();
}
/* Create the GAL device. */
- gcmkONERROR(gckGALDEVICE_Construct(
+ status = gckGALDEVICE_Construct(
+#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY
+ irqLine3D0,
+ registerMemBase3D0, registerMemSize3D0,
+ irqLine3D1,
+ registerMemBase3D1, registerMemSize3D1,
+#else
irqLine,
registerMemBase, registerMemSize,
+#endif
irqLine2D,
registerMemBase2D, registerMemSize2D,
irqLineVG,
contiguousBase, contiguousSize,
bankSize, fastClear, compression, baseAddress, physSize, signal,
logFileSize,
- pdev,
powerManagement,
gpuProfiler,
+ &args,
&device
- ));
+ );
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
- device->pool = dev_get_drvdata(pdev);
-#endif
+ if (gcmIS_ERROR(status))
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Failed to create the GAL device: status=%d\n",
+ __FUNCTION__, __LINE__, status);
+
+ goto OnError;
+ }
/* Start the GAL device. */
gcmkONERROR(gckGALDEVICE_Start(device));
&& (device->kernels[gcvCORE_MAJOR] != gcvNULL)
&& (device->kernels[gcvCORE_MAJOR]->hardware->mmuVersion != 0))
{
- status = gckMMU_Enable(device->kernels[gcvCORE_MAJOR]->mmu, baseAddress, physSize);
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
- "Enable new MMU: status=%d\n", status);
-
- if ((device->kernels[gcvCORE_2D] != gcvNULL)
- && (device->kernels[gcvCORE_2D]->hardware->mmuVersion != 0))
- {
- status = gckMMU_Enable(device->kernels[gcvCORE_2D]->mmu, baseAddress, physSize);
- gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
- "Enable new MMU for 2D: status=%d\n", status);
- }
-
/* Reset the base address */
device->baseAddress = 0;
}
-#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
- task_free_register(&task_nb);
- viv_gpu_resmem_handler.data = device->kernels[gcvCORE_MAJOR];
- register_reserved_memory_account(&viv_gpu_resmem_handler);
-#endif
-
-
/* Register the character device. */
- ret = register_chrdev(major, DRV_NAME, &driver_fops);
+ ret = register_chrdev(major, DEVICE_NAME, &driver_fops);
if (ret < 0)
{
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
- device_create(device_class, NULL, MKDEV(major, 0), NULL, "galcore");
+ device_create(device_class, NULL, MKDEV(major, 0), NULL, DEVICE_NAME);
#else
- device_create(device_class, NULL, MKDEV(major, 0), "galcore");
+ device_create(device_class, NULL, MKDEV(major, 0), DEVICE_NAME);
#endif
galDevice = device;
gpuClass = device_class;
+#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_DRIVER,
+ "%s(%d): irqLine3D0=%d, contiguousSize=%lu, memBase3D0=0x%lX\n",
+ __FUNCTION__, __LINE__,
+ irqLine3D0, contiguousSize, registerMemBase3D0
+ );
+#else
gcmkTRACE_ZONE(
gcvLEVEL_INFO, gcvZONE_DRIVER,
"%s(%d): irqLine=%d, contiguousSize=%lu, memBase=0x%lX\n",
__FUNCTION__, __LINE__,
irqLine, contiguousSize, registerMemBase
);
+#endif
/* Success. */
gcmkFOOTER_NO();
{
gcmkHEADER();
-#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
- task_free_unregister(&task_nb);
- unregister_reserved_memory_account(&viv_gpu_resmem_handler);
-#endif
-
gcmkASSERT(gpuClass != gcvNULL);
device_destroy(gpuClass, MKDEV(major, 0));
class_destroy(gpuClass);
- unregister_chrdev(major, DRV_NAME);
+ unregister_chrdev(major, DEVICE_NAME);
gcmkVERIFY_OK(gckGALDEVICE_Stop(galDevice));
gcmkVERIFY_OK(gckGALDEVICE_Destroy(galDevice));
- if(gckDebugFileSystemIsEnabled())
- {
- gckDebugFileSystemTerminate();
- }
-
-#if ENABLE_GPU_CLOCK_BY_DRIVER && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+ if(gckDEBUGFS_IsEnabled())
{
-# if 0
- struct clk * clk = NULL;
-
-#if defined(CONFIG_PXA_DVFM) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
- gc_pwr(0);
-#endif
- clk = clk_get(NULL, "GCCLK");
- clk_disable(clk);
-# endif
+ gckDEBUGFS_Terminate();
}
-#endif
gcmkFOOTER_NO();
}
module_exit(drv_exit);
#else
-#ifdef CONFIG_DOVE_GPU
-# define DEVICE_NAME "dove_gpu"
-#else
-# define DEVICE_NAME "galcore"
-#endif
-
-#if gcdENABLE_FSCALE_VAL_ADJUST
-static int thermal_hot_pm_notify(struct notifier_block *nb, unsigned long event,
- void *dummy)
-{
- static gctUINT orgFscale, minFscale, maxFscale;
- static gctBOOL bAlreadyTooHot = gcvFALSE;
- gckHARDWARE hardware = galDevice->kernels[gcvCORE_MAJOR]->hardware;
-
- if (event && !bAlreadyTooHot) {
- gckHARDWARE_GetFscaleValue(hardware,&orgFscale,&minFscale, &maxFscale);
- gckHARDWARE_SetFscaleValue(hardware, minFscale);
- bAlreadyTooHot = gcvTRUE;
- gckOS_Print("System is too hot. GPU3D will work at %d/64 clock.\n", minFscale);
- } else if (!event && bAlreadyTooHot) {
- gckHARDWARE_SetFscaleValue(hardware, orgFscale);
- gckOS_Print("Hot alarm is canceled. GPU3D clock will return to %d/64\n", orgFscale);
- bAlreadyTooHot = gcvFALSE;
- }
- return NOTIFY_OK;
-}
-
-static struct notifier_block thermal_hot_pm_notifier = {
- .notifier_call = thermal_hot_pm_notify,
- };
-#endif
-
-
-
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
static int gpu_probe(struct platform_device *pdev)
#else
#endif
{
int ret = -ENODEV;
- struct resource* res;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
- struct contiguous_mem_pool *pool;
- struct reset_control *rstc;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
- struct device_node *dn =pdev->dev.of_node;
- const u32 *prop;
+ gcsMODULE_PARAMETERS moduleParam = {
+#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY
#else
- struct viv_gpu_platform_data *pdata;
+ .irqLine = irqLine,
+ .registerMemBase = registerMemBase,
+ .registerMemSize = registerMemSize,
#endif
- gcmkHEADER();
+ .irqLine2D = irqLine2D,
+ .registerMemBase2D = registerMemBase2D,
+ .registerMemSize2D = registerMemSize2D,
+ .irqLineVG = irqLineVG,
+ .registerMemBaseVG = registerMemBaseVG,
+ .registerMemSizeVG = registerMemSizeVG,
+ .contiguousSize = contiguousSize,
+ .contiguousBase = contiguousBase,
+ .bankSize = bankSize,
+ .fastClear = fastClear,
+ .compression = compression,
+ .powerManagement = powerManagement,
+ .gpuProfiler = gpuProfiler,
+ .signal = signal,
+ .baseAddress = baseAddress,
+ .physSize = physSize,
+ .logFileSize = logFileSize,
+ .recovery = recovery,
+ .stuckDump = stuckDump,
+ .showArgs = showArgs,
+ .gpu3DMinClock = gpu3DMinClock,
+ };
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phys_baseaddr");
- if (res)
- baseAddress = res->start;
+ gcmkHEADER();
- res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_3d");
- if (res)
- irqLine = res->start;
+ platform.device = pdev;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_3d");
- if (res)
+ if (platform.ops->getPower)
{
- registerMemBase = res->start;
- registerMemSize = res->end - res->start + 1;
+ if (gcmIS_ERROR(platform.ops->getPower(&platform)))
+ {
+ gcmkFOOTER_NO();
+ return ret;
+ }
}
- res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_2d");
- if (res)
- irqLine2D = res->start;
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_2d");
- if (res)
+ if (platform.ops->adjustParam)
{
- registerMemBase2D = res->start;
- registerMemSize2D = res->end - res->start + 1;
- }
-
- res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_vg");
- if (res)
- irqLineVG = res->start;
+ /* Override default module param. */
+ platform.ops->adjustParam(&platform, &moduleParam);
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_vg");
- if (res)
- {
- registerMemBaseVG = res->start;
- registerMemSizeVG = res->end - res->start + 1;
+ /* Update module param because drv_init() uses them directly. */
+ _UpdateModuleParam(&moduleParam);
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
- pool = devm_kzalloc(&pdev->dev, sizeof(*pool), GFP_KERNEL);
- if (!pool)
- return -ENOMEM;
- pool->size = contiguousSize;
- init_dma_attrs(&pool->attrs);
- dma_set_attr(DMA_ATTR_WRITE_COMBINE, &pool->attrs);
- pool->virt = dma_alloc_attrs(&pdev->dev, pool->size, &pool->phys,
- GFP_KERNEL, &pool->attrs);
- if (!pool->virt) {
- dev_err(&pdev->dev, "Failed to allocate contiguous memory\n");
- return -ENOMEM;
- }
- contiguousBase = pool->phys;
- dev_set_drvdata(&pdev->dev, pool);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
- prop = of_get_property(dn, "contiguousbase", NULL);
- if(prop)
- contiguousBase = *prop;
- of_property_read_u32(dn,"contiguoussize", (u32 *)&contiguousSize);
-#else
- pdata = pdev->dev.platform_data;
- if (pdata) {
- contiguousBase = pdata->reserved_mem_base;
- contiguousSize = pdata->reserved_mem_size;
- }
-#endif
- if (contiguousSize == 0)
- gckOS_Print("Warning: No contiguous memory is reserverd for gpu.!\n ");
- ret = drv_init(&pdev->dev);
+ ret = drv_init();
if (!ret)
{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
- rstc = devm_reset_control_get(&pdev->dev, "gpu3d");
- galDevice->rstc[gcvCORE_MAJOR] = IS_ERR(rstc) ? NULL : rstc;
-
- rstc = devm_reset_control_get(&pdev->dev, "gpu2d");
- galDevice->rstc[gcvCORE_2D] = IS_ERR(rstc) ? NULL : rstc;
-
- rstc = devm_reset_control_get(&pdev->dev, "gpuvg");
- galDevice->rstc[gcvCORE_VG] = IS_ERR(rstc) ? NULL : rstc;
-#endif
platform_set_drvdata(pdev, galDevice);
-#if gcdENABLE_FSCALE_VAL_ADJUST
- if (galDevice->kernels[gcvCORE_MAJOR])
- REG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier);
-#endif
gcmkFOOTER_NO();
return ret;
}
-#if gcdENABLE_FSCALE_VAL_ADJUST
- UNREG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier);
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
- dma_free_attrs(&pdev->dev, pool->size, pool->virt, pool->phys,
- &pool->attrs);
-#endif
+
gcmkFOOTER_ARG(KERN_INFO "Failed to register gpu driver: %d\n", ret);
return ret;
}
static int __devexit gpu_remove(struct platform_device *pdev)
#endif
{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
- gckGALDEVICE device = platform_get_drvdata(pdev);
- struct contiguous_mem_pool *pool = device->pool;
-#endif
gcmkHEADER();
-#if gcdENABLE_FSCALE_VAL_ADJUST
- if(galDevice->kernels[gcvCORE_MAJOR])
- UNREG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier);
-#endif
+
drv_exit();
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
- dma_free_attrs(&pdev->dev, pool->size, pool->virt, pool->phys,
- &pool->attrs);
-#endif
+
+ if (platform.ops->putPower)
+ {
+ platform.ops->putPower(&platform);
+ }
+
gcmkFOOTER_NO();
return 0;
}
device = platform_get_drvdata(dev);
+ if (!device)
+ {
+ return -1;
+ }
+
for (i = 0; i < gcdMAX_GPU_COUNT; i++)
{
if (device->kernels[i] != gcvNULL)
{
status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, gcvPOWER_OFF);
}
+
if (gcmIS_ERROR(status))
{
return -1;
device = platform_get_drvdata(dev);
+ if (!device)
+ {
+ return -1;
+ }
+
for (i = 0; i < gcdMAX_GPU_COUNT; i++)
{
if (device->kernels[i] != gcvNULL)
default:
statesStored = device->statesStored[i];
break;
- }
+ }
/* Restore states. */
#if gcdENABLE_VG
if (i == gcvCORE_VG)
{
status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, statesStored);
- }
+ }
else
#endif
{
return 0;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
-static const struct of_device_id mxs_gpu_dt_ids[] = {
- { .compatible = "fsl,imx6q-gpu", },
- {/* sentinel */}
-};
-MODULE_DEVICE_TABLE(of, mxs_gpu_dt_ids);
-
-#ifdef CONFIG_PM
-static int gpu_runtime_suspend(struct device *dev)
-{
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
- release_bus_freq(BUS_FREQ_HIGH);
-#endif
- return 0;
-}
-
-static int gpu_runtime_resume(struct device *dev)
-{
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
- request_bus_freq(BUS_FREQ_HIGH);
-#endif
- return 0;
-}
-
+#if defined(CONFIG_PM) && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
+#ifdef CONFIG_PM_SLEEP
static int gpu_system_suspend(struct device *dev)
{
- pm_message_t state={0};
- return gpu_suspend(to_platform_device(dev), state);
+ pm_message_t state={0};
+ return gpu_suspend(to_platform_device(dev), state);
}
static int gpu_system_resume(struct device *dev)
{
- return gpu_resume(to_platform_device(dev));
+ return gpu_resume(to_platform_device(dev));
}
+#endif
static const struct dev_pm_ops gpu_pm_ops = {
- SET_RUNTIME_PM_OPS(gpu_runtime_suspend, gpu_runtime_resume, NULL)
- SET_SYSTEM_SLEEP_PM_OPS(gpu_system_suspend, gpu_system_resume)
+ SET_SYSTEM_SLEEP_PM_OPS(gpu_system_suspend, gpu_system_resume)
};
#endif
-#endif
static struct platform_driver gpu_driver = {
.probe = gpu_probe,
.driver = {
.name = DEVICE_NAME,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
- .of_match_table = mxs_gpu_dt_ids,
-#if CONFIG_PM
- .pm = &gpu_pm_ops,
-#endif
+#if defined(CONFIG_PM) && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
+ .pm = &gpu_pm_ops,
#endif
}
};
-#if 0 /*CONFIG_DOVE_GPU*/
-static struct resource gpu_resources[] = {
- {
- .name = "gpu_irq",
- .flags = IORESOURCE_IRQ,
- },
- {
- .name = "gpu_base",
- .flags = IORESOURCE_MEM,
- },
- {
- .name = "gpu_mem",
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct platform_device * gpu_device;
-#endif
-
static int __init gpu_init(void)
{
int ret = 0;
-#if 0 /*ndef CONFIG_DOVE_GPU*/
- gpu_resources[0].start = gpu_resources[0].end = irqLine;
-
- gpu_resources[1].start = registerMemBase;
- gpu_resources[1].end = registerMemBase + registerMemSize - 1;
+ memset(&platform, 0, sizeof(gcsPLATFORM));
- gpu_resources[2].start = contiguousBase;
- gpu_resources[2].end = contiguousBase + contiguousSize - 1;
+ gckPLATFORM_QueryOperations(&platform.ops);
- /* Allocate device */
- gpu_device = platform_device_alloc(DEVICE_NAME, -1);
- if (!gpu_device)
+ if (platform.ops == gcvNULL)
{
- printk(KERN_ERR "galcore: platform_device_alloc failed.\n");
- ret = -ENOMEM;
+ printk(KERN_ERR "galcore: No platform specific operations.\n");
+ ret = -ENODEV;
goto out;
}
- /* Insert resource */
- ret = platform_device_add_resources(gpu_device, gpu_resources, 3);
- if (ret)
+ if (platform.ops->allocPriv)
{
- printk(KERN_ERR "galcore: platform_device_add_resources failed.\n");
- goto put_dev;
+ /* Allocate platform private data. */
+ if (gcmIS_ERROR(platform.ops->allocPriv(&platform)))
+ {
+ ret = -ENOMEM;
+ goto out;
+ }
}
- /* Add device */
- ret = platform_device_add(gpu_device);
- if (ret)
+ if (platform.ops->needAddDevice
+ && platform.ops->needAddDevice(&platform))
{
- printk(KERN_ERR "galcore: platform_device_add failed.\n");
- goto put_dev;
+ /* Allocate device */
+ platform.device = platform_device_alloc(DEVICE_NAME, -1);
+ if (!platform.device)
+ {
+ printk(KERN_ERR "galcore: platform_device_alloc failed.\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* Add device */
+ ret = platform_device_add(platform.device);
+ if (ret)
+ {
+ printk(KERN_ERR "galcore: platform_device_add failed.\n");
+ goto put_dev;
+ }
+ }
+
+ platform.driver = &gpu_driver;
+
+ if (platform.ops->adjustDriver)
+ {
+ /* Override default platform_driver struct. */
+ platform.ops->adjustDriver(&platform);
}
-#endif
ret = platform_driver_register(&gpu_driver);
if (!ret)
goto out;
}
-#if 0 /*ndef CONFIG_DOVE_GPU*/
- platform_device_del(gpu_device);
+ platform_device_del(platform.device);
put_dev:
- platform_device_put(gpu_device);
-#endif
+ platform_device_put(platform.device);
out:
return ret;
static void __exit gpu_exit(void)
{
platform_driver_unregister(&gpu_driver);
-#if 0 /*ndef CONFIG_DOVE_GPU*/
- platform_device_unregister(gpu_device);
-#endif
+
+ if (platform.ops->needAddDevice
+ && platform.ops->needAddDevice(&platform))
+ {
+ platform_device_unregister(platform.device);
+ }
+
+ if (platform.priv)
+ {
+ /* Free platform private data. */
+ platform.ops->freePriv(&platform);
+ }
}
module_init(gpu_init);
--- /dev/null
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2014 by Vivante Corp.
+*
+* 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.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+#include <linux/slab.h>
+
+#include "tee_client_api.h"
+
+#define _GC_OBJ_ZONE gcvZONE_OS
+
+#define GPU3D_UUID { 0xcc9f80ea, 0xa836, 0x11e3, { 0x9b, 0x07, 0x78, 0x2b, 0xcb, 0x5c, 0xf3, 0xe3 } }
+
+static const TEEC_UUID gpu3d_uuid = GPU3D_UUID;
+TEEC_Context teecContext;
+
+typedef struct _gcsSecurityChannel {
+ gckOS os;
+ TEEC_Session session;
+ int * virtual;
+ TEEC_SharedMemory inputBuffer;
+ gctUINT32 bytes;
+ gctPOINTER mutex;
+} gcsSecurityChannel;
+
+TEEC_SharedMemory *
+gpu3d_allocate_secure_mem(
+ gckOS Os,
+ unsigned int size
+ )
+{
+ TEEC_Result result;
+ TEEC_Context *context = &teecContext;
+ TEEC_SharedMemory *shm = NULL;
+ void *handle = NULL;
+ unsigned int phyAddr = 0xFFFFFFFF;
+ gceSTATUS status;
+ gctSIZE_T bytes = size;
+
+ shm = kmalloc(sizeof(TEEC_SharedMemory), GFP_KERNEL);
+
+ if (NULL == shm)
+ {
+ return NULL;
+ }
+
+ memset(shm, 0, sizeof(TEEC_SharedMemory));
+
+ status = gckOS_AllocatePagedMemoryEx(
+ Os,
+ gcvALLOC_FLAG_SECURITY,
+ bytes,
+ gcvNULL,
+ (gctPHYS_ADDR *)&handle);
+
+ if (gcmIS_ERROR(status))
+ {
+ kfree(shm);
+ return NULL;
+ }
+
+ status = gckOS_PhysicalToPhysicalAddress(
+ Os,
+ handle,
+ &phyAddr);
+
+ if (gcmIS_ERROR(status))
+ {
+ kfree(shm);
+ return NULL;
+ }
+
+ /* record the handle into shm->user_data */
+ shm->userdata = handle;
+
+ /* [b] Bulk input buffer. */
+ shm->size = size;
+ shm->flags = TEEC_MEM_INPUT;
+
+ /* Use TEE Client API to register the underlying memory buffer. */
+ shm->phyAddr = (void *)phyAddr;
+
+ result = TEEC_RegisterSharedMemory(
+ context,
+ shm);
+
+ if (result != TEEC_SUCCESS)
+ {
+ gckOS_FreePagedMemory(Os, (gctPHYS_ADDR)handle, shm->size);
+ kfree(shm);
+ return NULL;
+ }
+
+ return shm;
+}
+
+void gpu3d_release_secure_mem(
+ gckOS Os,
+ void *shm_handle
+ )
+{
+ TEEC_SharedMemory *shm = shm_handle;
+ void * handle;
+
+ if (!shm)
+ {
+ return;
+ }
+
+ handle = shm->userdata;
+
+ TEEC_ReleaseSharedMemory(shm);
+ gckOS_FreePagedMemory(Os, (gctPHYS_ADDR)handle, shm->size);
+
+ kfree(shm);
+
+ return;
+}
+
+static TEEC_Result gpu3d_session_callback(
+ TEEC_Session* session,
+ uint32_t commandID,
+ TEEC_Operation* operation,
+ void* userdata
+ )
+{
+ gcsSecurityChannel *channel = userdata;
+
+ if (channel == gcvNULL)
+ {
+ return TEEC_ERROR_BAD_PARAMETERS;
+ }
+
+ switch(commandID)
+ {
+ case gcvTA_CALLBACK_ALLOC_SECURE_MEM:
+ {
+ uint32_t size = operation->params[0].value.a;
+ TEEC_SharedMemory *shm = NULL;
+
+ shm = gpu3d_allocate_secure_mem(channel->os, size);
+
+ /* use the value to save the pointer in client side */
+ operation->params[0].value.a = (uint32_t)shm;
+ operation->params[0].value.b = (uint32_t)shm->phyAddr;
+
+ break;
+ }
+ case gcvTA_CALLBACK_FREE_SECURE_MEM:
+ {
+ TEEC_SharedMemory *shm = (TEEC_SharedMemory *)operation->params[0].value.a;
+
+ gpu3d_release_secure_mem(channel->os, shm);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return TEEC_SUCCESS;
+}
+
+gceSTATUS
+gckOS_OpenSecurityChannel(
+ IN gckOS Os,
+ IN gceCORE GPU,
+ OUT gctUINT32 *Channel
+ )
+{
+ gceSTATUS status;
+ TEEC_Result result;
+ static bool initialized = gcvFALSE;
+ gcsSecurityChannel *channel = gcvNULL;
+
+ TEEC_Operation operation = {0};
+
+ /* Connect to TEE. */
+ if (initialized == gcvFALSE)
+ {
+ result = TEEC_InitializeContext(NULL, &teecContext);
+
+ if (result != TEEC_SUCCESS) {
+ gcmkONERROR(gcvSTATUS_CHIP_NOT_READY);
+ }
+
+ initialized = gcvTRUE;
+ }
+
+ /* Construct channel. */
+ gcmkONERROR(
+ gckOS_Allocate(Os, gcmSIZEOF(*channel), (gctPOINTER *)&channel));
+
+ gckOS_ZeroMemory(channel, gcmSIZEOF(gcsSecurityChannel));
+
+ channel->os = Os;
+
+ gcmkONERROR(gckOS_CreateMutex(Os, &channel->mutex));
+
+ /* Allocate shared memory for passing gcTA_INTERFACE. */
+ channel->bytes = gcmSIZEOF(gcsTA_INTERFACE);
+ channel->virtual = kmalloc(channel->bytes, GFP_KERNEL | __GFP_NOWARN);
+
+ if (!channel->virtual)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ channel->inputBuffer.size = channel->bytes;
+ channel->inputBuffer.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
+ channel->inputBuffer.phyAddr = (void *)virt_to_phys(channel->virtual);
+
+ result = TEEC_RegisterSharedMemory(&teecContext, &channel->inputBuffer);
+
+ if (result != TEEC_SUCCESS)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ operation.paramTypes = TEEC_PARAM_TYPES(
+ TEEC_VALUE_INPUT,
+ TEEC_NONE,
+ TEEC_NONE,
+ TEEC_NONE);
+
+ operation.params[0].value.a = GPU;
+
+ /* Open session with TEE application. */
+ result = TEEC_OpenSession(
+ &teecContext,
+ &channel->session,
+ &gpu3d_uuid,
+ TEEC_LOGIN_USER,
+ NULL,
+ &operation,
+ NULL);
+
+ /* Prepare callback. */
+ TEEC_RegisterCallback(&channel->session, gpu3d_session_callback, channel);
+
+ *Channel = (gctUINT32)channel;
+
+ return gcvSTATUS_OK;
+
+OnError:
+ if (channel)
+ {
+ if (channel->virtual)
+ {
+ }
+
+ if (channel->mutex)
+ {
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Os, channel->mutex));
+ }
+
+ gcmkVERIFY_OK(gckOS_Free(Os, channel));
+ }
+
+ return status;
+}
+
+gceSTATUS
+gckOS_CloseSecurityChannel(
+ IN gctUINT32 Channel
+ )
+{
+ /* TODO . */
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_CallSecurityService(
+ IN gctUINT32 Channel,
+ IN gcsTA_INTERFACE *Interface
+ )
+{
+ gceSTATUS status;
+ TEEC_Result result;
+ gcsSecurityChannel *channel = (gcsSecurityChannel *)Channel;
+ TEEC_Operation operation = {0};
+
+ gcmkHEADER();
+ gcmkVERIFY_ARGUMENT(Channel != 0);
+
+ gckOS_AcquireMutex(channel->os, channel->mutex, gcvINFINITE);
+
+ gckOS_MemCopy(channel->virtual, Interface, channel->bytes);
+
+ operation.paramTypes = TEEC_PARAM_TYPES(
+ TEEC_MEMREF_PARTIAL_INPUT,
+ TEEC_NONE,
+ TEEC_NONE,
+ TEEC_NONE);
+
+ /* Note: we use the updated size in the MemRef output by the encryption. */
+ operation.params[0].memref.parent = &channel->inputBuffer;
+ operation.params[0].memref.offset = 0;
+ operation.params[0].memref.size = sizeof(gcsTA_INTERFACE);
+ operation.started = true;
+
+ /* Start the commit command within the TEE application. */
+ result = TEEC_InvokeCommand(
+ &channel->session,
+ gcvTA_COMMAND_DISPATCH,
+ &operation,
+ NULL);
+
+ gckOS_MemCopy(Interface, channel->virtual, channel->bytes);
+
+ gckOS_ReleaseMutex(channel->os, channel->mutex);
+
+ if (result != TEEC_SUCCESS)
+ {
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckOS_InitSecurityChannel(
+ IN gctUINT32 Channel
+ )
+{
+ gceSTATUS status;
+ TEEC_Result result;
+ gcsSecurityChannel *channel = (gcsSecurityChannel *)Channel;
+ TEEC_Operation operation = {0};
+
+ gcmkHEADER();
+ gcmkVERIFY_ARGUMENT(Channel != 0);
+
+ operation.paramTypes = TEEC_PARAM_TYPES(
+ TEEC_MEMREF_PARTIAL_INPUT,
+ TEEC_NONE,
+ TEEC_NONE,
+ TEEC_NONE);
+
+ /* Note: we use the updated size in the MemRef output by the encryption. */
+ operation.params[0].memref.parent = &channel->inputBuffer;
+ operation.params[0].memref.offset = 0;
+ operation.params[0].memref.size = gcmSIZEOF(gcsTA_INTERFACE);
+ operation.started = true;
+
+ /* Start the commit command within the TEE application. */
+ result = TEEC_InvokeCommand(
+ &channel->session,
+ gcvTA_COMMAND_INIT,
+ &operation,
+ NULL);
+
+ if (result != TEEC_SUCCESS)
+ {
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
*****************************************************************************/
+#include <gc_hal.h>
+#include <gc_hal_base.h>
+
+#if gcdANDROID_NATIVE_FENCE_SYNC
+
#include <linux/kernel.h>
#include <linux/file.h>
#include <linux/fs.h>
#include "gc_hal_kernel_sync.h"
-#if gcdANDROID_NATIVE_FENCE_SYNC
-
static struct sync_pt *
viv_sync_pt_dup(
struct sync_pt * sync_pt
/****************************************************************************
*
-* Copyright (C) 2005 - 2013 by Vivante Corp.
+* Copyright (C) 2005 - 2014 by Vivante Corp.
*
* 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
#include <linux/types.h>
-#include <linux/sync.h>
+/* sync.h is in drivers/staging/android/ for now. */
+#include <sync.h>
#include <gc_hal.h>
#include <gc_hal_base.h>
--- /dev/null
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2014 by Vivante Corp.
+*
+* 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.
+*
+*****************************************************************************/
+
+
+#include "gc_hal_kernel_linux.h"
+#include "gc_hal_kernel_platform.h"
+#include "gc_hal_kernel_device.h"
+#include "gc_hal_driver.h"
+#include <linux/slab.h>
+
+#if USE_PLATFORM_DRIVER
+# include <linux/platform_device.h>
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
+#include <mach/viv_gpu.h>
+#else
+#include <linux/pm_runtime.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
+#include <mach/busfreq.h>
+#else
+#include <linux/reset.h>
+#endif
+#endif
+
+#include <linux/clk.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
+#include <mach/hardware.h>
+#endif
+#include <linux/pm_runtime.h>
+
+#include <linux/regulator/consumer.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+#include <linux/device_cooling.h>
+#define REG_THERMAL_NOTIFIER(a) register_devfreq_cooling_notifier(a);
+#define UNREG_THERMAL_NOTIFIER(a) unregister_devfreq_cooling_notifier(a);
+#else
+extern int register_thermal_notifier(struct notifier_block *nb);
+extern int unregister_thermal_notifier(struct notifier_block *nb);
+#define REG_THERMAL_NOTIFIER(a) register_thermal_notifier(a);
+#define UNREG_THERMAL_NOTIFIER(a) unregister_thermal_notifier(a);
+#endif
+
+static int initgpu3DMinClock = 1;
+module_param(initgpu3DMinClock, int, 0644);
+
+struct platform_device *pdevice;
+
+#ifdef CONFIG_GPU_LOW_MEMORY_KILLER
+# include <linux/kernel.h>
+# include <linux/mm.h>
+# include <linux/oom.h>
+# include <linux/sched.h>
+
+struct task_struct *lowmem_deathpending;
+
+static int
+task_notify_func(struct notifier_block *self, unsigned long val, void *data);
+
+static struct notifier_block task_nb = {
+ .notifier_call = task_notify_func,
+};
+
+static int
+task_notify_func(struct notifier_block *self, unsigned long val, void *data)
+{
+ struct task_struct *task = data;
+
+ if (task == lowmem_deathpending)
+ lowmem_deathpending = NULL;
+
+ return NOTIFY_OK;
+}
+
+extern struct task_struct *lowmem_deathpending;
+static unsigned long lowmem_deathpending_timeout;
+
+static int force_contiguous_lowmem_shrink(IN gckKERNEL Kernel)
+{
+ struct task_struct *p;
+ struct task_struct *selected = NULL;
+ int tasksize;
+ int ret = -1;
+ int min_adj = 0;
+ int selected_tasksize = 0;
+ int selected_oom_adj;
+ /*
+ * If we already have a death outstanding, then
+ * bail out right away; indicating to vmscan
+ * that we have nothing further to offer on
+ * this pass.
+ *
+ */
+ if (lowmem_deathpending &&
+ time_before_eq(jiffies, lowmem_deathpending_timeout))
+ return 0;
+ selected_oom_adj = min_adj;
+
+ rcu_read_lock();
+ for_each_process(p) {
+ struct mm_struct *mm;
+ struct signal_struct *sig;
+ gcuDATABASE_INFO info;
+ int oom_adj;
+
+ task_lock(p);
+ mm = p->mm;
+ sig = p->signal;
+ if (!mm || !sig) {
+ task_unlock(p);
+ continue;
+ }
+ oom_adj = sig->oom_score_adj;
+ if (oom_adj < min_adj) {
+ task_unlock(p);
+ continue;
+ }
+
+ tasksize = 0;
+ task_unlock(p);
+ rcu_read_unlock();
+
+ if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_VIDEO_MEMORY, &info) == gcvSTATUS_OK){
+ tasksize += info.counters.bytes / PAGE_SIZE;
+ }
+ if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_CONTIGUOUS, &info) == gcvSTATUS_OK){
+ tasksize += info.counters.bytes / PAGE_SIZE;
+ }
+
+ rcu_read_lock();
+
+ if (tasksize <= 0)
+ continue;
+
+ gckOS_Print("<gpu> pid %d (%s), adj %d, size %d \n", p->pid, p->comm, oom_adj, tasksize);
+
+ if (selected) {
+ if (oom_adj < selected_oom_adj)
+ continue;
+ if (oom_adj == selected_oom_adj &&
+ tasksize <= selected_tasksize)
+ continue;
+ }
+ selected = p;
+ selected_tasksize = tasksize;
+ selected_oom_adj = oom_adj;
+ }
+ if (selected) {
+ gckOS_Print("<gpu> send sigkill to %d (%s), adj %d, size %d\n",
+ selected->pid, selected->comm,
+ selected_oom_adj, selected_tasksize);
+ lowmem_deathpending = selected;
+ lowmem_deathpending_timeout = jiffies + HZ;
+ force_sig(SIGKILL, selected);
+ ret = 0;
+ }
+ rcu_read_unlock();
+ return ret;
+}
+
+
+gceSTATUS
+_ShrinkMemory(
+ IN gckPLATFORM Platform
+ )
+{
+ struct platform_device *pdev;
+ gckGALDEVICE galDevice;
+ gckKERNEL kernel;
+
+ pdev = Platform->device;
+
+ galDevice = platform_get_drvdata(pdev);
+
+ kernel = galDevice->kernels[gcvCORE_MAJOR];
+
+ if (kernel != gcvNULL)
+ {
+ force_contiguous_lowmem_shrink(kernel);
+ }
+ else
+ {
+ gcmkPRINT("%s(%d) can't find kernel! ", __FUNCTION__, __LINE__);
+ }
+
+ return gcvSTATUS_OK;
+}
+#endif
+
+#if gcdENABLE_FSCALE_VAL_ADJUST
+static int thermal_hot_pm_notify(struct notifier_block *nb, unsigned long event,
+ void *dummy)
+{
+ static gctUINT orgFscale, minFscale, maxFscale;
+ static gctBOOL bAlreadyTooHot = gcvFALSE;
+ gckHARDWARE hardware;
+ gckGALDEVICE galDevice;
+
+ galDevice = platform_get_drvdata(pdevice);
+ if (!galDevice)
+ {
+ /* GPU is not ready, so it is meaningless to change GPU freq. */
+ return NOTIFY_OK;
+ }
+
+ if (!galDevice->kernels[gcvCORE_MAJOR])
+ {
+ return NOTIFY_OK;
+ }
+
+ hardware = galDevice->kernels[gcvCORE_MAJOR]->hardware;
+
+ if (!hardware)
+ {
+ return NOTIFY_OK;
+ }
+
+ if (event && !bAlreadyTooHot) {
+ gckHARDWARE_GetFscaleValue(hardware,&orgFscale,&minFscale, &maxFscale);
+ gckHARDWARE_SetFscaleValue(hardware, minFscale);
+ bAlreadyTooHot = gcvTRUE;
+ gckOS_Print("System is too hot. GPU3D will work at %d/64 clock.\n", minFscale);
+ } else if (!event && bAlreadyTooHot) {
+ gckHARDWARE_SetFscaleValue(hardware, orgFscale);
+ gckOS_Print("Hot alarm is canceled. GPU3D clock will return to %d/64\n", orgFscale);
+ bAlreadyTooHot = gcvFALSE;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block thermal_hot_pm_notifier = {
+ .notifier_call = thermal_hot_pm_notify,
+ };
+
+static ssize_t show_gpu3DMinClock(struct device_driver *dev, char *buf)
+{
+ gctUINT currentf,minf,maxf;
+ gckGALDEVICE galDevice;
+
+ galDevice = platform_get_drvdata(pdevice);
+ if(galDevice->kernels[gcvCORE_MAJOR])
+ {
+ gckHARDWARE_GetFscaleValue(galDevice->kernels[gcvCORE_MAJOR]->hardware,
+ ¤tf, &minf, &maxf);
+ }
+ snprintf(buf, PAGE_SIZE, "%d\n", minf);
+ return strlen(buf);
+}
+
+static ssize_t update_gpu3DMinClock(struct device_driver *dev, const char *buf, size_t count)
+{
+
+ gctINT fields;
+ gctUINT MinFscaleValue;
+ gckGALDEVICE galDevice;
+
+ galDevice = platform_get_drvdata(pdevice);
+ if(galDevice->kernels[gcvCORE_MAJOR])
+ {
+ fields = sscanf(buf, "%d", &MinFscaleValue);
+ if (fields < 1)
+ return -EINVAL;
+
+ gckHARDWARE_SetMinFscaleValue(galDevice->kernels[gcvCORE_MAJOR]->hardware,MinFscaleValue);
+ }
+
+ return count;
+}
+
+static DRIVER_ATTR(gpu3DMinClock, S_IRUGO | S_IWUSR, show_gpu3DMinClock, update_gpu3DMinClock);
+#endif
+
+
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+static const struct of_device_id mxs_gpu_dt_ids[] = {
+ { .compatible = "fsl,imx6q-gpu", },
+ {/* sentinel */}
+};
+MODULE_DEVICE_TABLE(of, mxs_gpu_dt_ids);
+#endif
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+struct contiguous_mem_pool {
+ struct dma_attrs attrs;
+ dma_addr_t phys;
+ void *virt;
+ size_t size;
+};
+#endif
+
+struct imx_priv {
+ /* Clock management.*/
+ struct clk *clk_3d_core;
+ struct clk *clk_3d_shader;
+ struct clk *clk_3d_axi;
+ struct clk *clk_2d_core;
+ struct clk *clk_2d_axi;
+ struct clk *clk_vg_axi;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ /*Power management.*/
+ struct regulator *gpu_regulator;
+#endif
+#endif
+ /*Run time pm*/
+ struct device *pmdev;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ struct contiguous_mem_pool *pool;
+ struct reset_control *rstc[gcdMAX_GPU_COUNT];
+#endif
+};
+
+static struct imx_priv imxPriv;
+
+gceSTATUS
+gckPLATFORM_AdjustParam(
+ IN gckPLATFORM Platform,
+ OUT gcsMODULE_PARAMETERS *Args
+ )
+{
+ struct resource* res;
+ struct platform_device* pdev = Platform->device;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ struct device_node *dn =pdev->dev.of_node;
+ const u32 *prop;
+#else
+ struct viv_gpu_platform_data *pdata;
+#endif
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phys_baseaddr");
+ if (res)
+ Args->baseAddress = res->start;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_3d");
+ if (res)
+ Args->irqLine = res->start;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_3d");
+ if (res)
+ {
+ Args->registerMemBase = res->start;
+ Args->registerMemSize = res->end - res->start + 1;
+ }
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_2d");
+ if (res)
+ Args->irqLine2D = res->start;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_2d");
+ if (res)
+ {
+ Args->registerMemBase2D = res->start;
+ Args->registerMemSize2D = res->end - res->start + 1;
+ }
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_vg");
+ if (res)
+ Args->irqLineVG = res->start;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_vg");
+ if (res)
+ {
+ Args->registerMemBaseVG = res->start;
+ Args->registerMemSizeVG = res->end - res->start + 1;
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ Args->contiguousBase = 0;
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ prop = of_get_property(dn, "contiguousbase", NULL);
+ if(prop)
+ Args->contiguousBase = *prop;
+ of_property_read_u32(dn,"contiguoussize", (u32 *)&contiguousSize);
+#else
+ pdata = pdev->dev.platform_data;
+ if (pdata) {
+ Args->contiguousBase = pdata->reserved_mem_base;
+ Args->contiguousSize = pdata->reserved_mem_size;
+ }
+#endif
+ if (Args->contiguousSize == 0)
+ gckOS_Print("Warning: No contiguous memory is reserverd for gpu.!\n ");
+
+ Args->gpu3DMinClock = initgpu3DMinClock;
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+_AllocPriv(
+ IN gckPLATFORM Platform
+ )
+{
+ Platform->priv = &imxPriv;
+
+#ifdef CONFIG_GPU_LOW_MEMORY_KILLER
+ task_free_register(&task_nb);
+#endif
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+_FreePriv(
+ IN gckPLATFORM Platform
+ )
+{
+#ifdef CONFIG_GPU_LOW_MEMORY_KILLER
+ task_free_unregister(&task_nb);
+#endif
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+_GetPower(
+ IN gckPLATFORM Platform
+ )
+{
+ struct device* pdev = &Platform->device->dev;
+ struct imx_priv *priv = Platform->priv;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ struct reset_control *rstc;
+#endif
+
+#ifdef CONFIG_PM
+ /*Init runtime pm for gpu*/
+ pm_runtime_enable(pdev);
+ priv->pmdev = pdev;
+#endif
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ rstc = devm_reset_control_get(pdev, "gpu3d");
+ priv->rstc[gcvCORE_MAJOR] = IS_ERR(rstc) ? NULL : rstc;
+ rstc = devm_reset_control_get(pdev, "gpu2d");
+ priv->rstc[gcvCORE_2D] = IS_ERR(rstc) ? NULL : rstc;
+ rstc = devm_reset_control_get(pdev, "gpuvg");
+ priv->rstc[gcvCORE_VG] = IS_ERR(rstc) ? NULL : rstc;
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
+ /*get gpu regulator*/
+ priv->gpu_regulator = regulator_get(pdev, "cpu_vddgpu");
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ priv->gpu_regulator = devm_regulator_get(pdev, "pu");
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ if (IS_ERR(priv->gpu_regulator)) {
+ gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Failed to get gpu regulator \n",
+ __FUNCTION__, __LINE__);
+ return gcvSTATUS_NOT_FOUND;
+ }
+#endif
+#endif
+
+ /*Initialize the clock structure*/
+ priv->clk_3d_core = clk_get(pdev, "gpu3d_clk");
+ if (!IS_ERR(priv->clk_3d_core)) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
+ if (cpu_is_mx6q()) {
+ priv->clk_3d_shader = clk_get(pdev, "gpu3d_shader_clk");
+ if (IS_ERR(priv->clk_3d_shader)) {
+ clk_put(priv->clk_3d_core);
+ priv->clk_3d_core = NULL;
+ priv->clk_3d_shader = NULL;
+ gckOS_Print("galcore: clk_get gpu3d_shader_clk failed, disable 3d!\n");
+ }
+ }
+#else
+ priv->clk_3d_axi = clk_get(pdev, "gpu3d_axi_clk");
+ priv->clk_3d_shader = clk_get(pdev, "gpu3d_shader_clk");
+ if (IS_ERR(priv->clk_3d_shader)) {
+ clk_put(priv->clk_3d_core);
+ priv->clk_3d_core = NULL;
+ priv->clk_3d_shader = NULL;
+ gckOS_Print("galcore: clk_get gpu3d_shader_clk failed, disable 3d!\n");
+ }
+#endif
+ } else {
+ priv->clk_3d_core = NULL;
+ gckOS_Print("galcore: clk_get gpu3d_clk failed, disable 3d!\n");
+ }
+
+ priv->clk_2d_core = clk_get(pdev, "gpu2d_clk");
+ if (IS_ERR(priv->clk_2d_core)) {
+ priv->clk_2d_core = NULL;
+ gckOS_Print("galcore: clk_get 2d core clock failed, disable 2d/vg!\n");
+ } else {
+ priv->clk_2d_axi = clk_get(pdev, "gpu2d_axi_clk");
+ if (IS_ERR(priv->clk_2d_axi)) {
+ priv->clk_2d_axi = NULL;
+ gckOS_Print("galcore: clk_get 2d axi clock failed, disable 2d\n");
+ }
+
+ priv->clk_vg_axi = clk_get(pdev, "openvg_axi_clk");
+ if (IS_ERR(priv->clk_vg_axi)) {
+ priv->clk_vg_axi = NULL;
+ gckOS_Print("galcore: clk_get vg clock failed, disable vg!\n");
+ }
+ }
+
+
+#if gcdENABLE_FSCALE_VAL_ADJUST
+ pdevice = Platform->device;
+ REG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier);
+ {
+ int ret = 0;
+ ret = driver_create_file(pdevice->dev.driver, &driver_attr_gpu3DMinClock);
+ if(ret)
+ dev_err(&pdevice->dev, "create gpu3DMinClock attr failed (%d)\n", ret);
+ }
+#endif
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+_PutPower(
+ IN gckPLATFORM Platform
+ )
+{
+ struct imx_priv *priv = Platform->priv;
+
+ /*Disable clock*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ if (priv->clk_3d_axi) {
+ clk_put(priv->clk_3d_axi);
+ priv->clk_3d_axi = NULL;
+ }
+#endif
+ if (priv->clk_3d_core) {
+ clk_put(priv->clk_3d_core);
+ priv->clk_3d_core = NULL;
+ }
+ if (priv->clk_3d_shader) {
+ clk_put(priv->clk_3d_shader);
+ priv->clk_3d_shader = NULL;
+ }
+ if (priv->clk_2d_core) {
+ clk_put(priv->clk_2d_core);
+ priv->clk_2d_core = NULL;
+ }
+ if (priv->clk_2d_axi) {
+ clk_put(priv->clk_2d_axi);
+ priv->clk_2d_axi = NULL;
+ }
+ if (priv->clk_vg_axi) {
+ clk_put(priv->clk_vg_axi);
+ priv->clk_vg_axi = NULL;
+ }
+
+#ifdef CONFIG_PM
+ if(priv->pmdev)
+ pm_runtime_disable(priv->pmdev);
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
+ if (priv->gpu_regulator) {
+ regulator_put(priv->gpu_regulator);
+ priv->gpu_regulator = NULL;
+ }
+#endif
+
+#if gcdENABLE_FSCALE_VAL_ADJUST
+ UNREG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier);
+
+ driver_remove_file(pdevice->dev.driver, &driver_attr_gpu3DMinClock);
+#endif
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+_SetPower(
+ IN gckPLATFORM Platform,
+ IN gceCORE GPU,
+ IN gctBOOL Enable
+ )
+{
+ struct imx_priv* priv = Platform->priv;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ int ret;
+#endif
+#endif
+
+ if (Enable)
+ {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ if(!IS_ERR(priv->gpu_regulator)) {
+ ret = regulator_enable(priv->gpu_regulator);
+ if (ret != 0)
+ gckOS_Print("%s(%d): fail to enable pu regulator %d!\n",
+ __FUNCTION__, __LINE__, ret);
+ }
+#else
+ imx_gpc_power_up_pu(true);
+#endif
+#endif
+
+#ifdef CONFIG_PM
+ pm_runtime_get_sync(priv->pmdev);
+#endif
+ }
+ else
+ {
+#ifdef CONFIG_PM
+ pm_runtime_put_sync(priv->pmdev);
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ if(!IS_ERR(priv->gpu_regulator))
+ regulator_disable(priv->gpu_regulator);
+#else
+ imx_gpc_power_up_pu(false);
+#endif
+#endif
+
+ }
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+_SetClock(
+ IN gckPLATFORM Platform,
+ IN gceCORE GPU,
+ IN gctBOOL Enable
+ )
+{
+ struct imx_priv* priv = Platform->priv;
+ struct clk *clk_3dcore = priv->clk_3d_core;
+ struct clk *clk_3dshader = priv->clk_3d_shader;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ struct clk *clk_3d_axi = priv->clk_3d_axi;
+#endif
+ struct clk *clk_2dcore = priv->clk_2d_core;
+ struct clk *clk_2d_axi = priv->clk_2d_axi;
+ struct clk *clk_vg_axi = priv->clk_vg_axi;
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
+ if (Enable) {
+ switch (GPU) {
+ case gcvCORE_MAJOR:
+ clk_enable(clk_3dcore);
+ if (cpu_is_mx6q())
+ clk_enable(clk_3dshader);
+ break;
+ case gcvCORE_2D:
+ clk_enable(clk_2dcore);
+ clk_enable(clk_2d_axi);
+ break;
+ case gcvCORE_VG:
+ clk_enable(clk_2dcore);
+ clk_enable(clk_vg_axi);
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (GPU) {
+ case gcvCORE_MAJOR:
+ if (cpu_is_mx6q())
+ clk_disable(clk_3dshader);
+ clk_disable(clk_3dcore);
+ break;
+ case gcvCORE_2D:
+ clk_disable(clk_2dcore);
+ clk_disable(clk_2d_axi);
+ break;
+ case gcvCORE_VG:
+ clk_disable(clk_2dcore);
+ clk_disable(clk_vg_axi);
+ break;
+ default:
+ break;
+ }
+ }
+#else
+ if (Enable) {
+ switch (GPU) {
+ case gcvCORE_MAJOR:
+ clk_prepare(clk_3dcore);
+ clk_enable(clk_3dcore);
+ clk_prepare(clk_3dshader);
+ clk_enable(clk_3dshader);
+ clk_prepare(clk_3d_axi);
+ clk_enable(clk_3d_axi);
+ break;
+ case gcvCORE_2D:
+ clk_prepare(clk_2dcore);
+ clk_enable(clk_2dcore);
+ clk_prepare(clk_2d_axi);
+ clk_enable(clk_2d_axi);
+ break;
+ case gcvCORE_VG:
+ clk_prepare(clk_2dcore);
+ clk_enable(clk_2dcore);
+ clk_prepare(clk_vg_axi);
+ clk_enable(clk_vg_axi);
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (GPU) {
+ case gcvCORE_MAJOR:
+ clk_disable(clk_3dshader);
+ clk_unprepare(clk_3dshader);
+ clk_disable(clk_3dcore);
+ clk_unprepare(clk_3dcore);
+ clk_disable(clk_3d_axi);
+ clk_unprepare(clk_3d_axi);
+ break;
+ case gcvCORE_2D:
+ clk_disable(clk_2dcore);
+ clk_unprepare(clk_2dcore);
+ clk_disable(clk_2d_axi);
+ clk_unprepare(clk_2d_axi);
+ break;
+ case gcvCORE_VG:
+ clk_disable(clk_2dcore);
+ clk_unprepare(clk_2dcore);
+ clk_disable(clk_vg_axi);
+ clk_unprepare(clk_vg_axi);
+ break;
+ default:
+ break;
+ }
+ }
+#endif
+
+ return gcvSTATUS_OK;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+#ifdef CONFIG_PM
+static int gpu_runtime_suspend(struct device *dev)
+{
+ return 0;
+}
+
+static int gpu_runtime_resume(struct device *dev)
+{
+ return 0;
+}
+
+static struct dev_pm_ops gpu_pm_ops;
+#endif
+#endif
+
+gceSTATUS
+_AdjustDriver(
+ IN gckPLATFORM Platform
+ )
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ struct platform_driver * driver = Platform->driver;
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ driver->driver.of_match_table = mxs_gpu_dt_ids;
+#endif
+
+ /* Override PM callbacks to add runtime PM callbacks. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ /* Fill local structure with original value. */
+ memcpy(&gpu_pm_ops, driver->driver.pm, sizeof(struct dev_pm_ops));
+
+ /* Add runtime PM callback. */
+#ifdef CONFIG_PM_RUNTIME
+ gpu_pm_ops.runtime_suspend = gpu_runtime_suspend;
+ gpu_pm_ops.runtime_resume = gpu_runtime_resume;
+ gpu_pm_ops.runtime_idle = NULL;
+#endif
+
+ /* Replace callbacks. */
+ driver->driver.pm = &gpu_pm_ops;
+#endif
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+_Reset(
+ IN gckPLATFORM Platform,
+ gceCORE GPU
+ )
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
+#define SRC_SCR_OFFSET 0
+#define BP_SRC_SCR_GPU3D_RST 1
+#define BP_SRC_SCR_GPU2D_RST 4
+ void __iomem *src_base = IO_ADDRESS(SRC_BASE_ADDR);
+ gctUINT32 bit_offset,val;
+
+ if(GPU == gcvCORE_MAJOR) {
+ bit_offset = BP_SRC_SCR_GPU3D_RST;
+ } else if((GPU == gcvCORE_VG)
+ ||(GPU == gcvCORE_2D)) {
+ bit_offset = BP_SRC_SCR_GPU2D_RST;
+ } else {
+ return gcvSTATUS_INVALID_CONFIG;
+ }
+ val = __raw_readl(src_base + SRC_SCR_OFFSET);
+ val &= ~(1 << (bit_offset));
+ val |= (1 << (bit_offset));
+ __raw_writel(val, src_base + SRC_SCR_OFFSET);
+
+ while ((__raw_readl(src_base + SRC_SCR_OFFSET) &
+ (1 << (bit_offset))) != 0) {
+ }
+
+ return gcvSTATUS_NOT_SUPPORTED;
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ struct imx_priv* priv = Platform->priv;
+ struct reset_control *rstc = priv->rstc[GPU];
+ if (rstc)
+ reset_control_reset(rstc);
+#else
+ imx_src_reset_gpu((int)GPU);
+#endif
+ return gcvSTATUS_OK;
+}
+
+gcsPLATFORM_OPERATIONS platformOperations = {
+ .adjustParam = gckPLATFORM_AdjustParam,
+ .allocPriv = _AllocPriv,
+ .freePriv = _FreePriv,
+ .getPower = _GetPower,
+ .putPower = _PutPower,
+ .setPower = _SetPower,
+ .setClock = _SetClock,
+ .adjustDriver = _AdjustDriver,
+ .reset = _Reset,
+#ifdef CONFIG_GPU_LOW_MEMORY_KILLER
+ .shrinkMemory = _ShrinkMemory,
+#endif
+};
+
+void
+gckPLATFORM_QueryOperations(
+ IN gcsPLATFORM_OPERATIONS ** Operations
+ )
+{
+ *Operations = &platformOperations;
+}
+
--- /dev/null
+EXTRA_CFLAGS += -DgcdDEFAULT_CONTIGUOUS_SIZE=134217728
+
+ifneq ($(CONFIG_ANDROID),)
+# build for android
+EXTRA_CFLAGS += -DgcdANDROID_NATIVE_FENCE_SYNC=3
+
+ifeq ($(CONFIG_SYNC),)
+$(warn CONFIG_SYNC is not set in kernel config)
+$(warn Android native fence sync needs CONFIG_SYNC)
+endif
+endif
+
+EXTRA_CFLAGS += -DLINUX_CMA_FSL=1
+ALLOCATOR_ARRAY_H_LOCATION := $(OS_KERNEL_DIR)/allocator/freescale
+CUSTOMER_ALLOCATOR_OBJS := $(ALLOCATOR_ARRAY_H_LOCATION)/gc_hal_kernel_allocator_cma.o