gceSTATUS
gcfDump(
    IN gcoOS Os,
    IN gctCONST_STRING Message,
    ...
    )
{

    gctUINT offset = 0;
    gctARGUMENTS args;
    char buffer[80];

    if (!setDumpFlag)
        return gcvSTATUS_OK;

#if gcdDUMP_IN_KERNEL
    gcsHAL_INTERFACE ioctl;

    gcmARGUMENTS_START(args, Message);
    gcmVERIFY_OK(gcoOS_PrintStrVSafe(ioctl.u.Debug.message,
                                     gcmSIZEOF(ioctl.u.Debug.message),
                                     &offset,
                                     Message, args));
    gcmARGUMENTS_END(args);

    ioctl.command     = gcvHAL_DEBUG;
    ioctl.u.Debug.set = gcvFALSE;
#if gcdDUMP
    ioctl.u.Debug.type = gcvMESSAGE_TEXT;
#else
    ioctl.u.Debug.type = gcvMESSAGE_DUMP;
#endif
    ioctl.u.Debug.messageSize = (gctUINT32)gcmSIZEOF(ioctl.u.Debug.message);

    gcmVERIFY_OK(gcoOS_DeviceControl(Os,
                                     IOCTL_GCHAL_INTERFACE,
                                     &ioctl, gcmSIZEOF(ioctl),
                                     &ioctl, gcmSIZEOF(ioctl)));
#else

    gcmARGUMENTS_START(args, Message);
    gcmVERIFY_OK(gcoOS_PrintStrVSafe(buffer, gcmSIZEOF(buffer),
                                     &offset,
                                     Message, args));
    gcmARGUMENTS_END(args);

    gcoOS_Print("%s", buffer);
#endif

    return gcvSTATUS_OK;
}
gceSTATUS
gcoQUEUE_Commit(
    IN gcoQUEUE Queue
    )
{
    gceSTATUS status = gcvSTATUS_OK;
    gcsHAL_INTERFACE iface;

    gcmHEADER_ARG("Queue=0x%x", Queue);

    /* Verify the arguments. */
    gcmVERIFY_OBJECT(Queue, gcvOBJ_QUEUE);

    if (Queue->head != gcvNULL)
    {
        /* Initialize event commit command. */
        iface.command       = gcvHAL_EVENT_COMMIT;
        iface.u.Event.queue = Queue->head;

        /* Send command to kernel. */
        gcmONERROR(
            gcoOS_DeviceControl(gcvNULL,
                                IOCTL_GCHAL_INTERFACE,
                                &iface, gcmSIZEOF(iface),
                                &iface, gcmSIZEOF(iface)));

        /* Test for error. */
        gcmONERROR(iface.status);

        /* Free any records in the queue. */
        gcmONERROR(gcoQUEUE_Free(Queue));
    }

    /* Success. */
    gcmFOOTER_NO();
    return gcvSTATUS_OK;

OnError:
    /* Return the status. */
    gcmFOOTER();
    return status;
}
/**
 *
 * @param Hal
 * @param Node
 * @return
 */
static gceSTATUS UnlockVideoNode(
	IN gcoHAL Hal,
	IN gcuVIDMEM_NODE_PTR Node,
	IN gceSURF_TYPE surftype) {

	gcsHAL_INTERFACE iface;
	gceSTATUS status;

	gcmASSERT(Node != gcvNULL);

	iface.command = gcvHAL_UNLOCK_VIDEO_MEMORY;
	iface.u.UnlockVideoMemory.node = Node;
	iface.u.UnlockVideoMemory.type = surftype;
	iface.u.UnlockVideoMemory.asynchroneous = gcvTRUE;

	/* Call the kernel. */
	gcmONERROR(gcoOS_DeviceControl(
				gcvNULL,
				IOCTL_GCHAL_INTERFACE,
				&iface, gcmSIZEOF(iface),
				&iface, gcmSIZEOF(iface)
	));

	/* Success? */
	gcmONERROR(iface.status);

	/* Do we need to schedule an event for the unlock? */
	if (iface.u.UnlockVideoMemory.asynchroneous)
	{
		iface.u.UnlockVideoMemory.asynchroneous = gcvFALSE;
		gcmONERROR(gcoHAL_ScheduleEvent(Hal, &iface));
	}

OnError:
    /* Call kernel API. */
    return gcvSTATUS_FALSE;

}
/*#endif*/

    gcmFOOTER_NO();
    return gcvSTATUS_OK;
}

#endif /* vivante_no_3d */
gceSTATUS
gcoPROFILER_EndFrame(
    IN gcoHAL Hal
    )
{
/*#if	(PROFILE_HAL_COUNTERS || PROFILE_HW_COUNTERS)*/
	gcsHAL_INTERFACE iface;
    gceSTATUS status;
/*#endif*/

    gcmHEADER();

	if (!gcPLS.hal->profiler.enable)
	{
        gcmFOOTER_NO();
		return gcvSTATUS_OK;
	}

/*#if PROFILE_HAL_COUNTERS*/
    if (gcPLS.hal->profiler.enableHal)
    {
#if gcdNEW_PROFILER_FILE
        gcmWRITE_CONST(VPG_HAL);

        gcmWRITE_COUNTER(VPC_HALVERTBUFNEWBYTEALLOC, gcPLS.hal->profiler.vertexBufferNewBytesAlloc);
        gcmWRITE_COUNTER(VPC_HALVERTBUFTOTALBYTEALLOC, gcPLS.hal->profiler.vertexBufferTotalBytesAlloc);
        gcmWRITE_COUNTER(VPC_HALVERTBUFNEWOBJALLOC, gcPLS.hal->profiler.vertexBufferNewObjectsAlloc);
        gcmWRITE_COUNTER(VPC_HALVERTBUFTOTALOBJALLOC, gcPLS.hal->profiler.vertexBufferTotalObjectsAlloc);

        gcmWRITE_COUNTER(VPC_HALINDBUFNEWBYTEALLOC, gcPLS.hal->profiler.indexBufferNewBytesAlloc);
        gcmWRITE_COUNTER(VPC_HALINDBUFTOTALBYTEALLOC, gcPLS.hal->profiler.indexBufferTotalBytesAlloc);
        gcmWRITE_COUNTER(VPC_HALINDBUFNEWOBJALLOC, gcPLS.hal->profiler.indexBufferNewObjectsAlloc);
        gcmWRITE_COUNTER(VPC_HALINDBUFTOTALOBJALLOC, gcPLS.hal->profiler.indexBufferTotalObjectsAlloc);

        gcmWRITE_COUNTER(VPC_HALTEXBUFNEWBYTEALLOC, gcPLS.hal->profiler.textureBufferNewBytesAlloc);
        gcmWRITE_COUNTER(VPC_HALTEXBUFTOTALBYTEALLOC, gcPLS.hal->profiler.textureBufferTotalBytesAlloc);
        gcmWRITE_COUNTER(VPC_HALTEXBUFNEWOBJALLOC, gcPLS.hal->profiler.textureBufferNewObjectsAlloc);
        gcmWRITE_COUNTER(VPC_HALTEXBUFTOTALOBJALLOC, gcPLS.hal->profiler.textureBufferTotalObjectsAlloc);

        gcmWRITE_CONST(VPG_END);
#else
    	gcmWRITE_STRING("<HALCounters>\n");

	    gcmPRINT_XML_COUNTER(vertexBufferNewBytesAlloc);
    	gcmPRINT_XML_COUNTER(vertexBufferTotalBytesAlloc);
	    gcmPRINT_XML_COUNTER(vertexBufferNewObjectsAlloc);
    	gcmPRINT_XML_COUNTER(vertexBufferTotalObjectsAlloc);

	    gcmPRINT_XML_COUNTER(indexBufferNewBytesAlloc);
    	gcmPRINT_XML_COUNTER(indexBufferTotalBytesAlloc);
	    gcmPRINT_XML_COUNTER(indexBufferNewObjectsAlloc);
    	gcmPRINT_XML_COUNTER(indexBufferTotalObjectsAlloc);

	    gcmPRINT_XML_COUNTER(textureBufferNewBytesAlloc);
    	gcmPRINT_XML_COUNTER(textureBufferTotalBytesAlloc);
	    gcmPRINT_XML_COUNTER(textureBufferNewObjectsAlloc);
    	gcmPRINT_XML_COUNTER(textureBufferTotalObjectsAlloc);

	    gcmWRITE_STRING("</HALCounters>\n");
#endif

	    /* Reset per-frame counters. */
    	gcPLS.hal->profiler.vertexBufferNewBytesAlloc   = 0;
	    gcPLS.hal->profiler.vertexBufferNewObjectsAlloc = 0;

	    gcPLS.hal->profiler.indexBufferNewBytesAlloc   = 0;
    	gcPLS.hal->profiler.indexBufferNewObjectsAlloc = 0;

	    gcPLS.hal->profiler.textureBufferNewBytesAlloc   = 0;
  		gcPLS.hal->profiler.textureBufferNewObjectsAlloc = 0;
	}
/*#endif*/

/*#if PROFILE_HW_COUNTERS*/
    /* gcvHAL_READ_ALL_PROFILE_REGISTERS. */
    if (gcPLS.hal->profiler.enableHW)
    {
		iface.command = gcvHAL_READ_ALL_PROFILE_REGISTERS;

		/* Call the kernel. */
		status = gcoOS_DeviceControl(gcvNULL,
									 IOCTL_GCHAL_INTERFACE,
									 &iface, gcmSIZEOF(iface),
									 &iface, gcmSIZEOF(iface));

		/* Verify result. */
		if (gcmNO_ERROR(status))
		{
        #define gcmCOUNTER(name)    iface.u.RegisterProfileData.counters.name

#if gcdNEW_PROFILER_FILE
            gcmWRITE_CONST(VPG_HW);
            gcmWRITE_CONST(VPG_GPU);
            gcmWRITE_COUNTER(VPC_GPUREAD64BYTE, gcmCOUNTER(gpuTotalRead64BytesPerFrame));
            gcmWRITE_COUNTER(VPC_GPUWRITE64BYTE, gcmCOUNTER(gpuTotalWrite64BytesPerFrame));
            gcmWRITE_COUNTER(VPC_GPUCYCLES, gcmCOUNTER(gpuCyclesCounter));
            gcmWRITE_CONST(VPG_END);

            gcmWRITE_CONST(VPG_VS);
            gcmWRITE_COUNTER(VPC_VSINSTCOUNT, gcmCOUNTER(vs_inst_counter) - gcPLS.hal->profiler.prevVSInstCount);
            gcmWRITE_COUNTER(VPC_VSBRANCHINSTCOUNT, gcmCOUNTER(vtx_branch_inst_counter) - gcPLS.hal->profiler.prevVSBranchInstCount);
            gcmWRITE_COUNTER(VPC_VSTEXLDINSTCOUNT, gcmCOUNTER(vtx_texld_inst_counter) - gcPLS.hal->profiler.prevVSTexInstCount);
			gcmWRITE_COUNTER(VPC_VSRENDEREDVERTCOUNT, gcmCOUNTER(rendered_vertice_counter) - gcPLS.hal->profiler.prevVSVertexCount);
            gcmWRITE_CONST(VPG_END);

			gcPLS.hal->profiler.prevVSInstCount = gcmCOUNTER(vs_inst_counter);
			gcPLS.hal->profiler.prevVSBranchInstCount = gcmCOUNTER(vtx_branch_inst_counter);
			gcPLS.hal->profiler.prevVSTexInstCount = gcmCOUNTER(vtx_texld_inst_counter);
			gcPLS.hal->profiler.prevVSVertexCount = gcmCOUNTER(rendered_vertice_counter);

            gcmWRITE_CONST(VPG_PA);
            gcmWRITE_COUNTER(VPC_PAINVERTCOUNT, gcmCOUNTER(pa_input_vtx_counter));
            gcmWRITE_COUNTER(VPC_PAINPRIMCOUNT, gcmCOUNTER(pa_input_prim_counter));
            gcmWRITE_COUNTER(VPC_PAOUTPRIMCOUNT, gcmCOUNTER(pa_output_prim_counter));
            gcmWRITE_COUNTER(VPC_PADEPTHCLIPCOUNT, gcmCOUNTER(pa_depth_clipped_counter));
            gcmWRITE_COUNTER(VPC_PATRIVIALREJCOUNT, gcmCOUNTER(pa_trivial_rejected_counter));
            gcmWRITE_COUNTER(VPC_PACULLCOUNT, gcmCOUNTER(pa_culled_counter));
            gcmWRITE_CONST(VPG_END);

            gcmWRITE_CONST(VPG_SETUP);
            gcmWRITE_COUNTER(VPC_SETRIANGLECOUNT, gcmCOUNTER(se_culled_triangle_count));
            gcmWRITE_COUNTER(VPC_SELINECOUNT, gcmCOUNTER(se_culled_lines_count));
            gcmWRITE_CONST(VPG_END);

            gcmWRITE_CONST(VPG_RA);
            gcmWRITE_COUNTER(VPC_RAVALIDPIXCOUNT, gcmCOUNTER(ra_valid_pixel_count));
            gcmWRITE_COUNTER(VPC_RATOTALQUADCOUNT, gcmCOUNTER(ra_total_quad_count));
            gcmWRITE_COUNTER(VPC_RAVALIDQUADCOUNTEZ, gcmCOUNTER(ra_valid_quad_count_after_early_z));
            gcmWRITE_COUNTER(VPC_RATOTALPRIMCOUNT, gcmCOUNTER(ra_total_primitive_count));
            gcmWRITE_COUNTER(VPC_RAPIPECACHEMISSCOUNT, gcmCOUNTER(ra_pipe_cache_miss_counter));
            gcmWRITE_COUNTER(VPC_RAPREFCACHEMISSCOUNT, gcmCOUNTER(ra_prefetch_cache_miss_counter));
            gcmWRITE_COUNTER(VPC_RAEEZCULLCOUNT, gcmCOUNTER(ra_eez_culled_counter));
            gcmWRITE_CONST(VPG_END);

            gcmWRITE_CONST(VPG_TX);
            gcmWRITE_COUNTER(VPC_TXTOTBILINEARREQ, gcmCOUNTER(tx_total_bilinear_requests));
            gcmWRITE_COUNTER(VPC_TXTOTTRILINEARREQ, gcmCOUNTER(tx_total_trilinear_requests));
            gcmWRITE_COUNTER(VPC_TXTOTTEXREQ, gcmCOUNTER(tx_total_texture_requests));
            gcmWRITE_COUNTER(VPC_TXMEMREADCOUNT, gcmCOUNTER(tx_mem_read_count));
            gcmWRITE_COUNTER(VPC_TXMEMREADIN8BCOUNT, gcmCOUNTER(tx_mem_read_in_8B_count));
            gcmWRITE_COUNTER(VPC_TXCACHEMISSCOUNT, gcmCOUNTER(tx_cache_miss_count));
            gcmWRITE_COUNTER(VPC_TXCACHEHITTEXELCOUNT, gcmCOUNTER(tx_cache_hit_texel_count));
            gcmWRITE_COUNTER(VPC_TXCACHEMISSTEXELCOUNT, gcmCOUNTER(tx_cache_miss_texel_count));
            gcmWRITE_CONST(VPG_END);

            gcmWRITE_CONST(VPG_PS);
            gcmWRITE_COUNTER(VPC_PSINSTCOUNT, gcmCOUNTER(ps_inst_counter) - gcPLS.hal->profiler.prevPSInstCount);
            gcmWRITE_COUNTER(VPC_PSBRANCHINSTCOUNT, gcmCOUNTER(pxl_branch_inst_counter) - gcPLS.hal->profiler.prevPSBranchInstCount);
            gcmWRITE_COUNTER(VPC_PSTEXLDINSTCOUNT, gcmCOUNTER(pxl_texld_inst_counter) - gcPLS.hal->profiler.prevPSTexInstCount);
			gcmWRITE_COUNTER(VPC_PSRENDEREDPIXCOUNT, gcmCOUNTER(rendered_pixel_counter) - gcPLS.hal->profiler.prevPSPixelCount);
            gcmWRITE_CONST(VPG_END);

			gcPLS.hal->profiler.prevPSInstCount = gcmCOUNTER(ps_inst_counter);
			gcPLS.hal->profiler.prevPSBranchInstCount = gcmCOUNTER(pxl_branch_inst_counter);
			gcPLS.hal->profiler.prevPSTexInstCount = gcmCOUNTER(pxl_texld_inst_counter);
			gcPLS.hal->profiler.prevPSPixelCount = gcmCOUNTER(rendered_pixel_counter);

            gcmWRITE_CONST(VPG_PE);
            gcmWRITE_COUNTER(VPC_PEKILLEDBYCOLOR, gcmCOUNTER(pe_pixel_count_killed_by_color_pipe));
            gcmWRITE_COUNTER(VPC_PEKILLEDBYDEPTH, gcmCOUNTER(pe_pixel_count_killed_by_depth_pipe));
            gcmWRITE_COUNTER(VPC_PEDRAWNBYCOLOR, gcmCOUNTER(pe_pixel_count_drawn_by_color_pipe));
            gcmWRITE_COUNTER(VPC_PEDRAWNBYDEPTH, gcmCOUNTER(pe_pixel_count_drawn_by_depth_pipe));
            gcmWRITE_CONST(VPG_END);

            gcmWRITE_CONST(VPG_MC);
            gcmWRITE_COUNTER(VPC_MCREADREQ8BPIPE, gcmCOUNTER(mc_total_read_req_8B_from_pipeline));
            gcmWRITE_COUNTER(VPC_MCREADREQ8BIP, gcmCOUNTER(mc_total_read_req_8B_from_IP));
            gcmWRITE_COUNTER(VPC_MCWRITEREQ8BPIPE, gcmCOUNTER(mc_total_write_req_8B_from_pipeline));
            gcmWRITE_CONST(VPG_END);

            gcmWRITE_CONST(VPG_AXI);
            gcmWRITE_COUNTER(VPC_AXIREADREQSTALLED, gcmCOUNTER(hi_axi_cycles_read_request_stalled));
            gcmWRITE_COUNTER(VPC_AXIWRITEREQSTALLED, gcmCOUNTER(hi_axi_cycles_write_request_stalled));
            gcmWRITE_COUNTER(VPC_AXIWRITEDATASTALLED, gcmCOUNTER(hi_axi_cycles_write_data_stalled));
            gcmWRITE_CONST(VPG_END);

            gcmWRITE_CONST(VPG_END);
#else
		    gcmWRITE_STRING("<HWCounters>\n");

	        gcmPRINT_XML("<read_64Byte value=\"%u\"/>\n",
    	    			 gcmCOUNTER(gpuTotalRead64BytesPerFrame));
        	gcmPRINT_XML("<write_64Byte value=\"%u\"/>\n",
	        			 gcmCOUNTER(gpuTotalWrite64BytesPerFrame));
	        gcmPRINT_XML("<gpu_cycles value=\"%u\"/>\n",
    	    			 gcmCOUNTER(gpuCyclesCounter));
        	gcmPRINT_XML("<pe_pixel_count_killed_by_color_pipe value=\"%u\"/>\n",
        				 gcmCOUNTER(pe_pixel_count_killed_by_color_pipe));
	        gcmPRINT_XML("<pe_pixel_count_killed_by_depth_pipe value=\"%u\"/>\n",
    	    			 gcmCOUNTER(pe_pixel_count_killed_by_depth_pipe));
        	gcmPRINT_XML("<pe_pixel_count_drawn_by_color_pipe value=\"%u\"/>\n",
						 gcmCOUNTER(pe_pixel_count_drawn_by_color_pipe));
	        gcmPRINT_XML("<pe_pixel_count_drawn_by_depth_pipe value=\"%u\"/>\n",
						 gcmCOUNTER(pe_pixel_count_drawn_by_depth_pipe));
        	gcmPRINT_XML("<ps_inst_counter value=\"%u\"/>\n",
						 gcmCOUNTER(ps_inst_counter));
	        gcmPRINT_XML("<rendered_pixel_counter value=\"%u\"/>\n",
						 gcmCOUNTER(rendered_pixel_counter));
        	gcmPRINT_XML("<vs_inst_counter value=\"%u\"/>\n",
						 gcmCOUNTER(vs_inst_counter));
	        gcmPRINT_XML("<rendered_vertice_counter value=\"%u\"/>\n",
						 gcmCOUNTER(rendered_vertice_counter));
        	gcmPRINT_XML("<vtx_branch_inst_counter value=\"%u\"/>\n",
					 gcmCOUNTER(vtx_branch_inst_counter));
	        gcmPRINT_XML("<vtx_texld_inst_counter value=\"%u\"/>\n",
						 gcmCOUNTER(vtx_texld_inst_counter));
        	gcmPRINT_XML("<pxl_branch_inst_counter value=\"%u\"/>\n",
						 gcmCOUNTER(pxl_branch_inst_counter));
	        gcmPRINT_XML("<pxl_texld_inst_counter value=\"%u\"/>\n",
						 gcmCOUNTER(pxl_texld_inst_counter));
        	gcmPRINT_XML("<pa_input_vtx_counter value=\"%u\"/>\n",
					 gcmCOUNTER(pa_input_vtx_counter));
	        gcmPRINT_XML("<pa_input_prim_counter value=\"%u\"/>\n",
						 gcmCOUNTER(pa_input_prim_counter));
        	gcmPRINT_XML("<pa_output_prim_counter value=\"%u\"/>\n",
					 gcmCOUNTER(pa_output_prim_counter));
	        gcmPRINT_XML("<pa_depth_clipped_counter value=\"%u\"/>\n",
						 gcmCOUNTER(pa_depth_clipped_counter));
        	gcmPRINT_XML("<pa_trivial_rejected_counter value=\"%u\"/>\n",
					 gcmCOUNTER(pa_trivial_rejected_counter));
	        gcmPRINT_XML("<pa_culled_counter value=\"%u\"/>\n",
						 gcmCOUNTER(pa_culled_counter));
        	gcmPRINT_XML("<se_culled_triangle_count value=\"%u\"/>\n",
						 gcmCOUNTER(se_culled_triangle_count));
	        gcmPRINT_XML("<se_culled_lines_count value=\"%u\"/>\n",
						 gcmCOUNTER(se_culled_lines_count));
        	gcmPRINT_XML("<ra_valid_pixel_count value=\"%u\"/>\n",
					 gcmCOUNTER(ra_valid_pixel_count));
	        gcmPRINT_XML("<ra_total_quad_count value=\"%u\"/>\n",
						 gcmCOUNTER(ra_total_quad_count));
        	gcmPRINT_XML("<ra_valid_quad_count_after_early_z value=\"%u\"/>\n",
					 gcmCOUNTER(ra_valid_quad_count_after_early_z));
	        gcmPRINT_XML("<ra_total_primitive_count value=\"%u\"/>\n",
						 gcmCOUNTER(ra_total_primitive_count));
        	gcmPRINT_XML("<ra_pipe_cache_miss_counter value=\"%u\"/>\n",
						 gcmCOUNTER(ra_pipe_cache_miss_counter));
	        gcmPRINT_XML("<ra_prefetch_cache_miss_counter value=\"%u\"/>\n",
						 gcmCOUNTER(ra_prefetch_cache_miss_counter));
        	gcmPRINT_XML("<ra_eez_culled_counter value=\"%u\"/>\n",
					 gcmCOUNTER(ra_eez_culled_counter));
	        gcmPRINT_XML("<tx_total_bilinear_requests value=\"%u\"/>\n",
						 gcmCOUNTER(tx_total_bilinear_requests));
        	gcmPRINT_XML("<tx_total_trilinear_requests value=\"%u\"/>\n",
					 gcmCOUNTER(tx_total_trilinear_requests));
	        gcmPRINT_XML("<tx_total_discarded_texture_requests value=\"%u\"/>\n",
						 gcmCOUNTER(tx_total_discarded_texture_requests));
        	gcmPRINT_XML("<tx_total_texture_requests value=\"%u\"/>\n",
						 gcmCOUNTER(tx_total_texture_requests));
    	    gcmPRINT_XML("<tx_mem_read_count value=\"%u\"/>\n",
						 gcmCOUNTER(tx_mem_read_count));
	        gcmPRINT_XML("<tx_mem_read_in_8B_count value=\"%u\"/>\n",
						 gcmCOUNTER(tx_mem_read_in_8B_count));
        	gcmPRINT_XML("<tx_cache_miss_count value=\"%u\"/>\n",
						 gcmCOUNTER(tx_cache_miss_count));
    	    gcmPRINT_XML("<tx_cache_hit_texel_count value=\"%u\"/>\n",
						 gcmCOUNTER(tx_cache_hit_texel_count));
	        gcmPRINT_XML("<tx_cache_miss_texel_count value=\"%u\"/>\n",
						 gcmCOUNTER(tx_cache_miss_texel_count));
        	gcmPRINT_XML("<mc_total_read_req_8B_from_pipeline value=\"%u\"/>\n",
						 gcmCOUNTER(mc_total_read_req_8B_from_pipeline));
    	    gcmPRINT_XML("<mc_total_read_req_8B_from_IP value=\"%u\"/>\n",
						 gcmCOUNTER(mc_total_read_req_8B_from_IP));
	        gcmPRINT_XML("<mc_total_write_req_8B_from_pipeline value=\"%u\"/>\n",
						 gcmCOUNTER(mc_total_write_req_8B_from_pipeline));
	        gcmPRINT_XML("<hi_axi_cycles_read_request_stalled value=\"%u\"/>\n",
						 gcmCOUNTER(hi_axi_cycles_read_request_stalled));
	        gcmPRINT_XML("<hi_axi_cycles_write_request_stalled value=\"%u\"/>\n",
						 gcmCOUNTER(hi_axi_cycles_write_request_stalled));
        	gcmPRINT_XML("<hi_axi_cycles_write_data_stalled value=\"%u\"/>\n",
						 gcmCOUNTER(hi_axi_cycles_write_data_stalled));

	    	gcmWRITE_STRING("</HWCounters>\n");
#endif
		}
	}
/*#endif*/

	/* Success. */
    gcmFOOTER_NO();
    return gcvSTATUS_OK;
}
gceSTATUS
gcoPROFILER_Initialize(
	IN gcoHAL Hal
	)
{
    gceSTATUS status = gcvSTATUS_OK;
    char* fileName;
    char* filter = gcvNULL;
    gctSTRING portName;
    gctINT port;
	gcsHAL_INTERFACE iface;

    gcmHEADER();

    /* Check if already initialized. */
   	if (gcPLS.hal->profiler.enable)
    {
        gcPLS.hal->profiler.enable++;
        gcmFOOTER();
        return status;
    }

	/* Get profile setting. */
	iface.command = gcvHAL_GET_PROFILE_SETTING;

	/* Call the kernel. */
	status = gcoOS_DeviceControl(gcvNULL,
								 IOCTL_GCHAL_INTERFACE,
								 &iface, gcmSIZEOF(iface),
								 &iface, gcmSIZEOF(iface));

	if (gcmIS_ERROR(status) || !iface.u.GetProfileSetting.enable)
	{
    	gcPLS.hal->profiler.enable = 0;
        status = gcvSTATUS_GENERIC_IO;

        gcmFOOTER();
        return status;
	}

	gcmVERIFY_OK(gcoOS_ZeroMemory(&gcPLS.hal->profiler, gcmSIZEOF(gcPLS.hal->profiler)));

    gcoOS_GetEnv(gcvNULL,
                 "VP_COUNTER_FILTER",
                 &filter);

    /* Enable/Disable specific counters. */
    if ((filter != gcvNULL))
    {
        gctSIZE_T bitsLen;
        gcoOS_StrLen(filter, &bitsLen);
        if (bitsLen > 2)
        {
            gcPLS.hal->profiler.enableHal = (filter[2] == '1');
        }
        else
        {
            gcPLS.hal->profiler.enableHal = gcvTRUE;
        }

        if (bitsLen > 3)
        {
            gcPLS.hal->profiler.enableHW = (filter[3] == '1');
        }
        else
        {
            gcPLS.hal->profiler.enableHW = gcvTRUE;
        }

        if (bitsLen > 8)
        {
            gcPLS.hal->profiler.enableSH = (filter[8] == '1');
        }
        else
        {
            gcPLS.hal->profiler.enableSH = gcvTRUE;
        }
    }
    else
    {
        gcPLS.hal->profiler.enableHal = gcvTRUE;
        gcPLS.hal->profiler.enableHW = gcvTRUE;
        gcPLS.hal->profiler.enableSH = gcvTRUE;
    }

	gcoOS_GetEnv(gcvNULL,
				 "VPROFILER_OUTPUT",
				 &fileName);

    gcPLS.hal->profiler.useSocket = gcvFALSE;
	if (fileName && *fileName != '\0' && *fileName != ' ')
	{
        /* Extract port info. */
        gcoOS_StrFindReverse(fileName, ':', &portName);

        if (portName)
        {
            gcoOS_StrToInt(portName + 1, &port);

            if (port > 0)
            {
                /*status = gcoOS_Socket(gcvNULL, AF_INET, SOCK_STREAM, 0, &gcPLS.hal->profiler.sockFd);*/
                status = gcoOS_Socket(gcvNULL, 2, 1, 0, &gcPLS.hal->profiler.sockFd);

                if (gcmIS_SUCCESS(status))
                {
                    *portName = '\0';
                    status = gcoOS_Connect(gcvNULL,
                            gcPLS.hal->profiler.sockFd, fileName, port);
                    *portName = ':';

                    if (gcmIS_SUCCESS(status))
	                {
                        gcPLS.hal->profiler.useSocket = gcvTRUE;
                    }
                }
            }
        }
	}
    else
    {
		fileName = iface.u.GetProfileSetting.fileName;
    }

    if (! gcPLS.hal->profiler.useSocket)
	{
		status = gcoOS_Open(gcvNULL,
							fileName,
#ifdef gcdNEW_PROFILER_FILE
							gcvFILE_CREATE,
#else
							gcvFILE_CREATETEXT,
#endif
							&gcPLS.hal->profiler.file);
	}

    if (gcmIS_ERROR(status))
	{
    	gcPLS.hal->profiler.enable = 0;
        status = gcvSTATUS_GENERIC_IO;

        gcmFOOTER();
        return status;
	}

    gcPLS.hal->profiler.enable = 1;
	gcoOS_GetTime(&gcPLS.hal->profiler.frameStart);
	gcPLS.hal->profiler.frameStartTimeusec = gcPLS.hal->profiler.frameStart;
	gcPLS.hal->profiler.prevVSInstCount = 0;
	gcPLS.hal->profiler.prevVSBranchInstCount = 0;
	gcPLS.hal->profiler.prevVSTexInstCount = 0;
	gcPLS.hal->profiler.prevVSVertexCount = 0;
	gcPLS.hal->profiler.prevPSInstCount = 0;
	gcPLS.hal->profiler.prevPSBranchInstCount = 0;
	gcPLS.hal->profiler.prevPSTexInstCount = 0;
	gcPLS.hal->profiler.prevPSPixelCount = 0;

#if gcdNEW_PROFILER_FILE
    gcmWRITE_CONST(VPHEADER);
    gcmWRITE_BUFFER(4, "VP12");
#else
	gcmWRITE_STRING("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<VProfile>\n");
#endif

    /* Success. */
    gcmFOOTER();
    return status;
}
/*******************************************************************************
**
**  gcoBUFFER_Commit
**
**  Commit the command buffer to the hardware.
**
**  INPUT:
**
**      gcoBUFFER Buffer
**          Pointer to a gcoBUFFER object.
**
**      gcePIPE_SELECT CurrentPipe
**          Current graphics pipe.
**
**      gcsSTATE_DELTA_PTR StateDelta
**          Pointer to the state delta.
**
**      gcoQUEUE Queue
**          Pointer to a gcoQUEUE object.
**
**  OUTPUT:
**
**      Nothing.
*/
gceSTATUS
gcoBUFFER_Commit(
    IN gcoBUFFER Buffer,
    IN gcePIPE_SELECT CurrentPipe,
    IN gcsSTATE_DELTA_PTR StateDelta,
    IN gcoQUEUE Queue
    )
{
    gcsHAL_INTERFACE iface;
    gceSTATUS status;
    gcoCMDBUF current;

    gcmHEADER_ARG("Buffer=0x%x Queue=0x%x",
                  Buffer, Queue);

    /* Verify the arguments. */
    gcmVERIFY_OBJECT(Buffer, gcvOBJ_BUFFER);
    gcmVERIFY_OBJECT(Queue, gcvOBJ_QUEUE);

    /* Grab current command buffer. */
    current = Buffer->currentCommandBuffer;

    if (current == gcvNULL)
    {
        /* No command buffer, done. */
        gcmFOOTER_NO();
        return gcvSTATUS_OK;
    }

    if (current->offset - current->startOffset <= Buffer->info.reservedHead)
    {
        /* Commit the event queue. */
        status = gcoQUEUE_Commit(Queue);
        gcmFOOTER();
        return status;
    }

    /* Make sure the tail got aligned properly. */
    current->offset = gcmALIGN(current->offset, Buffer->info.alignment);

    if (gcPLS.hal->dump != gcvNULL)
    {
        /* Dump the command buffer. */
        gcmVERIFY_OK(
            gcoDUMP_DumpData(gcPLS.hal->dump,
                             gcvTAG_COMMAND,
                             0,
                             current->offset
                             - current->startOffset
                             - Buffer->info.reservedHead,
                             (gctUINT8_PTR) current->logical
                             + current->startOffset
                             + Buffer->info.reservedHead));
    }

    /* The current pipe becomes the exit pipe for the current command buffer. */
    current->exitPipe = CurrentPipe;

    /* Send command and context buffer to hardware. */
    iface.command = gcvHAL_COMMIT;
    iface.u.Commit.context       =
#ifndef VIVANTE_NO_3D
        (current->using2D && !current->using3D) ? gcvNULL : Buffer->context;
#else
        gcvNULL;
#endif

    iface.u.Commit.commandBuffer = current;
    iface.u.Commit.delta         = StateDelta;
    iface.u.Commit.queue         = Queue->head;

    /* Call kernel service. */
    gcmONERROR(
        gcoOS_DeviceControl(gcvNULL,
                            IOCTL_GCHAL_INTERFACE,
                            &iface, gcmSIZEOF(iface),
                            &iface, gcmSIZEOF(iface)));

    gcmONERROR(iface.status);

    /* Free the event queue. */
    gcmONERROR(gcoQUEUE_Free(Queue));

    /* Advance the offset for next commit. */
    current->startOffset = current->offset + Buffer->info.reservedTail;

    if (current->bytes - current->startOffset > Buffer->totalReserved)
    {
        /* Adjust buffer offset and size. */
        current->offset = current->startOffset + Buffer->info.reservedHead;
        current->free   = current->bytes - current->offset
                        - Buffer->info.alignment
                        - Buffer->info.reservedTail;
    }
    else
    {
        /* Buffer is full. */
        current->startOffset = current->bytes;
        current->offset      = current->bytes;
        current->free        = 0;
    }

    /* The exit pipe becomes the entry pipe for the next command buffer. */
    current->entryPipe = current->exitPipe;

#if gcdSECURE_USER
    /* Reset the state array tail. */
    current->hintArrayTail = current->hintArray;
#endif

    /* Reset usage flags. */
    current->using2D         = gcvFALSE;
    current->using3D         = gcvFALSE;
    current->usingFilterBlit = gcvFALSE;
    current->usingPalette    = gcvFALSE;

    /* Success. */
    gcmFOOTER_NO();
    return gcvSTATUS_OK;

OnError:
    /* Return the status. */
    gcmFOOTER();
    return status;
}
/*******************************************************************************
**
**  gcoHAL_Construct
**
**  Construct a new gcoHAL object.
**
**  INPUT:
**
**      gctPOINTER Context
**          Pointer to a context that can be used by the platform specific
**          functions.
**
**      gcoOS Os
**          Pointer to an gcoOS object.
**
**  OUTPUT:
**
**      gcoHAL * Hal
**          Pointer to a variable that will hold the gcoHAL object pointer.
*/
gceSTATUS
gcoHAL_Construct(
    IN gctPOINTER Context,
    IN gcoOS Os,
    OUT gcoHAL * Hal
    )
{
    gctBOOL created = gcvFALSE;
    gcoHAL hal = gcPLS.hal;
    gceSTATUS status;
    gctPOINTER pointer = gcvNULL;
    gctBOOL separated3D = gcvFALSE;
    gctBOOL separated2D = gcvFALSE;
    gcsHAL_INTERFACE iface;
    gctINT32 i;

    gcmHEADER_ARG("Context=0x%x OS=0x%x", Context, Os);

    /* Verify the arguments. */
    gcmDEBUG_VERIFY_ARGUMENT(Hal != gcvNULL);

    if (hal == gcvNULL)
    {
        /* Create the gcoHAL object. */
        gcmONERROR(gcoOS_Allocate(gcvNULL,
                                  gcmSIZEOF(struct _gcoHAL),
                                  &pointer));
        hal     = pointer;
        created = gcvTRUE;

        gcoOS_ZeroMemory(hal, gcmSIZEOF(struct _gcoHAL));

        /* Initialize the object. */
        hal->object.type = gcvOBJ_HAL;

        /* Zero the gco2D, gco3D, and gcoDUMP objects. */
        hal->dump      = gcvNULL;
        hal->reference = gcvNULL;

        /* Initialize timeOut value */
        hal->timeOut     = gcdGPU_TIMEOUT;

        /* Query the kernel version number. */
        iface.command = gcvHAL_VERSION;
        gcmONERROR(gcoOS_DeviceControl(gcvNULL,
                                       IOCTL_GCHAL_INTERFACE,
                                       &iface, gcmSIZEOF(iface),
                                       &iface, gcmSIZEOF(iface)));

        /* Test if versions match. */
        if ((iface.u.Version.major != gcvVERSION_MAJOR)
        ||  (iface.u.Version.minor != gcvVERSION_MINOR)
        ||  (iface.u.Version.patch != gcvVERSION_PATCH)
        ||  (iface.u.Version.build != gcvVERSION_BUILD)
        )
        {
            gcmPRINT("HAL user version %d.%d.%d build %u %s %s",
                     gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH,
                     gcvVERSION_BUILD, gcvVERSION_DATE, gcvVERSION_TIME);
            gcmPRINT("HAL kernel version %d.%d.%d build %u",
                     iface.u.Version.major, iface.u.Version.minor,
                     iface.u.Version.patch, iface.u.Version.build);

            gcmONERROR(gcvSTATUS_VERSION_MISMATCH);
        }

#if gcmIS_DEBUG(gcdDEBUG_TRACE)
    gcmTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HAL,
                  "HAL user version %d.%d.%d build %u %s %s",
                  gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH,
                  gcvVERSION_BUILD, gcvVERSION_DATE, gcvVERSION_TIME);
    gcmTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HAL,
                  "HAL kernel version %d.%d.%d build %u",
                  iface.u.Version.major, iface.u.Version.minor,
                  iface.u.Version.patch, iface.u.Version.build);
#endif

        /* Query chip info */
        iface.command = gcvHAL_CHIP_INFO;
        gcmONERROR(gcoOS_DeviceControl(gcvNULL,
                                       IOCTL_GCHAL_INTERFACE,
                                       &iface, gcmSIZEOF(iface),
                                       &iface, gcmSIZEOF(iface)));

        hal->chipCount = iface.u.ChipInfo.count;

        for (i = 0; i < hal->chipCount; i++)
        {
            hal->chipTypes[i] = iface.u.ChipInfo.types[i];

            switch (hal->chipTypes[i])
            {
            case gcvHARDWARE_3D:
                separated3D = gcvTRUE;
                break;
            case gcvHARDWARE_2D:
                separated2D = gcvTRUE;
                break;
            default:
                break;
            }
        }

        hal->separated3D2D = (separated3D && separated2D);

#if VIVANTE_PROFILER
        hal->profiler.enable = 0;
#endif

        /* Create reference. */
        gcmONERROR(gcoOS_AtomConstruct(Os, &hal->reference));
    }