amd-gpu: remove unused, non-kernelish debug_pm4 module

This is just causing some messy code.
This commit is contained in:
Matt Sealey
2012-12-10 18:14:48 -06:00
parent 95b52ba9b3
commit f1ccc6aab6

View File

@@ -1,942 +0,0 @@
/* Copyright (c) 2008-2010, Advanced Micro Devices. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
*/
#include "gsl.h"
#include "gsl_hal.h"
#if 0//defined(GSL_BLD_YAMATO)
#include <linux/string.h>
//#define PM4_DEBUG_USE_MEMBUF
#ifdef PM4_DEBUG_USE_MEMBUF
#define MEMBUF_SIZE 100000
#define BUFFER_END_MARGIN 1000
char memBuf[MEMBUF_SIZE];
static int writePtr = 0;
static unsigned int lineNumber = 0;
int printString(const char * _Format, ...)
{
int ret;
va_list ap;
va_start(ap, _Format);
if( writePtr > 0 && memBuf[writePtr-1] == '\n' )
{
// Add line number if last written character was newline
writePtr += sprintf( memBuf+writePtr, "%d: ", lineNumber++ );
}
ret = vsprintf(memBuf+writePtr, _Format, ap);
writePtr += ret;
sprintf( memBuf+writePtr, "###" );
if( writePtr > MEMBUF_SIZE-BUFFER_END_MARGIN )
{
memset(memBuf+writePtr, '#', MEMBUF_SIZE-writePtr);
writePtr = 0;
}
va_end(ap);
return ret;
}
#else
int printString(const char * _Format, ...)
{
int ret;
va_list ap;
va_start(ap, _Format);
ret = printk(_Format, ap);
va_end(ap);
return ret;
}
#endif
//////////////////////////////////////////////////////////////////////////////
// defines
//////////////////////////////////////////////////////////////////////////////
#define EXPAND_OPCODE(opcode) ((opcode << 8) | PM4_PKT_MASK)
#define GetString_uint GetString_int
#define GetString_fixed12_4(val, szValue) GetString_fixed(val, 12, 4, szValue)
#define GetString_signedint15(val, szValue) GetString_signedint(val, 15, szValue)
// Need a prototype for this function
void WritePM4Packet_Type3(unsigned int dwHeader, unsigned int** ppBuffer);
static int indirectionLevel = 0;
//////////////////////////////////////////////////////////////////////////////
// functions
//////////////////////////////////////////////////////////////////////////////
void WriteDWORD(unsigned int dwValue)
{
printString( " 0x%08x", dwValue);
}
void WriteDWORD2(unsigned int dwValue)
{
printString( " 0x%08x\n", dwValue);
}
//----------------------------------------------------------------------------
// Generate the GetString_## functions for enumerated types
#define START_ENUMTYPE(__type) \
void GetString_##__type(unsigned int val, char* szValue) \
{ \
switch(val) \
{
#define GENERATE_ENUM(__enumname, __val) \
case __val: \
strcpy(szValue, #__enumname); \
break;
#define END_ENUMTYPE(__type) \
default: \
sprintf(szValue, "Unknown: %d", val); \
break; \
} \
}
#include _YAMATO_GENENUM_H
//----------------------------------------------------------------------------
void
GetString_hex(unsigned int val, char* szValue)
{
sprintf(szValue, "0x%x", val);
}
//----------------------------------------------------------------------------
void
GetString_float(unsigned int val, char* szValue)
{
float fval = *((float*) &val);
sprintf(szValue, "%.4f", fval);
}
//----------------------------------------------------------------------------
void
GetString_bool(unsigned int val, char* szValue)
{
strcpy(szValue, val ? "TRUE" : "FALSE");
}
//----------------------------------------------------------------------------
void GetString_int(unsigned int val, char* szValue)
{
sprintf(szValue, "%d", val);
}
//----------------------------------------------------------------------------
void
GetString_intMinusOne(unsigned int val, char* szValue)
{
sprintf(szValue, "%d+1", val);
}
//----------------------------------------------------------------------------
void
GetString_signedint(unsigned int val, unsigned int dwNumBits, char* szValue)
{
int nValue = val;
if (val & (1<<(dwNumBits-1)))
{
nValue |= 0xffffffff << dwNumBits;
}
sprintf(szValue, "%d", nValue);
}
//----------------------------------------------------------------------------
void
GetString_fixed(unsigned int val, unsigned int dwNumInt, unsigned int dwNumFrac, char* szValue)
{
(void) dwNumInt; // unreferenced formal parameter
if (val>>dwNumFrac == 0)
{
// Integer part is 0 - just print out the fractional part
sprintf(szValue, "%d/%d",
val&((1<<dwNumFrac)-1),
1<<dwNumFrac);
}
else
{
// Print out as a mixed fraction
sprintf(szValue, "%d %d/%d",
val>>dwNumFrac,
val&((1<<dwNumFrac)-1),
1<<dwNumFrac);
}
}
//----------------------------------------------------------------------------
void
GetString_Register(unsigned int dwBaseIndex, unsigned int dwValue, char* pszString)
{
char szValue[64];
char szField[128];
// Empty the string
pszString[0] = '\0';
switch(dwBaseIndex)
{
#define START_REGISTER(__reg) \
case mm##__reg: \
{ \
reg##__reg reg; \
reg.u32All = dwValue; \
strcat(pszString, #__reg ", (");
#define GENERATE_FIELD(__name, __type) \
GetString_##__type(reg.bitfields.__name, szValue); \
sprintf(szField, #__name " = %s, ", szValue); \
strcat(pszString, szField);
#define END_REGISTER(__reg) \
pszString[strlen(pszString)-2]='\0'; \
strcat(pszString, ")"); \
} \
break;
#include _YAMATO_GENREG_H
default:
break;
}
}
//----------------------------------------------------------------------------
void
GetString_Type3Opcode(unsigned int opcode, char* pszValue)
{
switch(EXPAND_OPCODE(opcode))
{
#define TYPE3SWITCH(__opcode) \
case PM4_PACKET3_##__opcode: \
strcpy(pszValue, #__opcode); \
break;
TYPE3SWITCH(NOP)
TYPE3SWITCH(IB_PREFETCH_END)
TYPE3SWITCH(SUBBLK_PREFETCH)
TYPE3SWITCH(INSTR_PREFETCH)
TYPE3SWITCH(REG_RMW)
TYPE3SWITCH(DRAW_INDX)
TYPE3SWITCH(VIZ_QUERY)
TYPE3SWITCH(SET_STATE)
TYPE3SWITCH(WAIT_FOR_IDLE)
TYPE3SWITCH(IM_LOAD)
TYPE3SWITCH(IM_LOAD_IMMEDIATE)
TYPE3SWITCH(SET_CONSTANT)
TYPE3SWITCH(LOAD_CONSTANT_CONTEXT)
TYPE3SWITCH(LOAD_ALU_CONSTANT)
TYPE3SWITCH(DRAW_INDX_BIN)
TYPE3SWITCH(3D_DRAW_INDX_2_BIN)
TYPE3SWITCH(3D_DRAW_INDX_2)
TYPE3SWITCH(INDIRECT_BUFFER_PFD)
TYPE3SWITCH(INVALIDATE_STATE)
TYPE3SWITCH(WAIT_REG_MEM)
TYPE3SWITCH(MEM_WRITE)
TYPE3SWITCH(REG_TO_MEM)
TYPE3SWITCH(INDIRECT_BUFFER)
TYPE3SWITCH(CP_INTERRUPT)
TYPE3SWITCH(COND_EXEC)
TYPE3SWITCH(COND_WRITE)
TYPE3SWITCH(EVENT_WRITE)
TYPE3SWITCH(INSTR_MATCH)
TYPE3SWITCH(ME_INIT)
TYPE3SWITCH(CONST_PREFETCH)
TYPE3SWITCH(MEM_WRITE_CNTR)
TYPE3SWITCH(SET_BIN_MASK)
TYPE3SWITCH(SET_BIN_SELECT)
TYPE3SWITCH(WAIT_REG_EQ)
TYPE3SWITCH(WAIT_REG_GTE)
TYPE3SWITCH(INCR_UPDT_STATE)
TYPE3SWITCH(INCR_UPDT_CONST)
TYPE3SWITCH(INCR_UPDT_INSTR)
TYPE3SWITCH(EVENT_WRITE_SHD)
TYPE3SWITCH(EVENT_WRITE_CFL)
TYPE3SWITCH(EVENT_WRITE_ZPD)
TYPE3SWITCH(WAIT_UNTIL_READ)
TYPE3SWITCH(WAIT_IB_PFD_COMPLETE)
TYPE3SWITCH(CONTEXT_UPDATE)
default:
sprintf(pszValue, "Unknown: %d", opcode);
break;
}
}
//----------------------------------------------------------------------------
void
WritePM4Packet_Type0(unsigned int dwHeader, unsigned int** ppBuffer)
{
pm4_type0 header = *((pm4_type0*) &dwHeader);
unsigned int* pBuffer = *ppBuffer;
unsigned int dwIndex;
WriteDWORD(dwHeader);
printString(" // Type-0 packet (BASE_INDEX = 0x%x, ONE_REG_WR = %d, COUNT = %d+1)\n",
header.base_index, header.one_reg_wr, header.count);
// Now go through and write the dwNumDWORDs
for (dwIndex = 0; dwIndex < header.count+1; dwIndex++)
{
char szRegister[1024];
unsigned int dwRegIndex;
unsigned int dwRegValue = *(pBuffer++);
if (header.one_reg_wr)
{
dwRegIndex = header.base_index;
}
else
{
dwRegIndex = header.base_index + dwIndex;
}
WriteDWORD(dwRegValue);
// Write register string based on fields
GetString_Register(dwRegIndex, dwRegValue, szRegister);
printString(" // %s\n", szRegister);
// Write actual unsigned int
}
*ppBuffer = pBuffer;
}
//----------------------------------------------------------------------------
void
WritePM4Packet_Type2(unsigned int dwHeader, unsigned int** ppBuffer)
{
unsigned int* pBuffer = *ppBuffer;
WriteDWORD(dwHeader);
printString(" // Type-2 packet\n");
*ppBuffer = pBuffer;
}
//----------------------------------------------------------------------------
void
AnalyzePacketType(unsigned int dwHeader, unsigned int**ppBuffer)
{
switch(dwHeader & PM4_PKT_MASK)
{
case PM4_TYPE0_PKT:
WritePM4Packet_Type0(dwHeader, ppBuffer);
break;
case PM4_TYPE1_PKT:
break;
case PM4_TYPE2_PKT:
WritePM4Packet_Type2(dwHeader, ppBuffer);
break;
case PM4_TYPE3_PKT:
WritePM4Packet_Type3(dwHeader, ppBuffer);
break;
}
}
void
WritePM4Packet_Type3(unsigned int dwHeader, unsigned int** ppBuffer)
{
pm4_type3 header = *((pm4_type3*) &dwHeader);
unsigned int* pBuffer = *ppBuffer;
unsigned int dwIndex;
char szOpcode[64];
if((EXPAND_OPCODE(header.it_opcode) == PM4_PACKET3_INDIRECT_BUFFER) ||
(EXPAND_OPCODE(header.it_opcode) == PM4_PACKET3_INDIRECT_BUFFER_PFD))
{
unsigned int *pIndirectBuffer = (unsigned int *) *(pBuffer++); // ordinal 2 of IB packet is an address
unsigned int *pIndirectBufferEnd = pIndirectBuffer + *(pBuffer++); // ordinal 3 of IB packet is size
unsigned int gpuaddr = kgsl_sharedmem_convertaddr((unsigned int) pIndirectBuffer, 1);
indirectionLevel++;
WriteDWORD2(dwHeader);
WriteDWORD2(gpuaddr);
WriteDWORD2((unsigned int) (pIndirectBufferEnd-pIndirectBuffer));
if (indirectionLevel == 1)
{
printString( "Start_IB1, base=0x%x, size=%d\n", gpuaddr, (unsigned int)(pIndirectBufferEnd - pIndirectBuffer));
}
else
{
printString( "Start_IB2, base=0x%x, size=%d\n", gpuaddr, (unsigned int)(pIndirectBufferEnd - pIndirectBuffer));
}
while(pIndirectBuffer < pIndirectBufferEnd)
{
unsigned int _dwHeader = *(pIndirectBuffer++);
AnalyzePacketType(_dwHeader, &pIndirectBuffer);
}
if (indirectionLevel == 1)
{
printString( "End_IB1\n");
}
else
{
printString( "End_IB2\n");
}
indirectionLevel--;
}
else
{
unsigned int registerAddr = 0xffffffff;
char szRegister[1024];
GetString_Type3Opcode(header.it_opcode, szOpcode);
WriteDWORD(dwHeader);
printString( " // Type-3 packet (PREDICATE = %d, IT_OPCODE = %s, COUNT = %d+1)\n",
header.predicate, szOpcode, header.count);
// Go through each command
for (dwIndex = 0; dwIndex < header.count+1; dwIndex++)
{
// Check for a register write
if((EXPAND_OPCODE(header.it_opcode) == PM4_PACKET3_SET_CONSTANT) && (((*pBuffer) >> 16) == 0x4))
registerAddr = (*pBuffer) & 0xffff;
// Write unsigned int
WriteDWORD(*pBuffer);
// Starting at Ordinal 2 is actual register values
if((dwIndex > 0) && (registerAddr != 0xffffffff))
{
// Write register string based on address
GetString_Register(registerAddr + 0x2000, *pBuffer, szRegister);
printString( " // %s\n", szRegister);
registerAddr++;
}
else
{
// Write out newline if we aren't augmenting with register fields
printString( "\n");
}
pBuffer++;
}
}
*ppBuffer = pBuffer;
}
//----------------------------------------------------------------------------
void
Yamato_DumpInitParams(unsigned int dwEDRAMBase, unsigned int dwEDRAMSize)
{
printString( "InitParams, edrambase=0x%x, edramsize=%d\n",
dwEDRAMBase, dwEDRAMSize);
}
//----------------------------------------------------------------------------
void
Yamato_DumpSwapBuffers(unsigned int dwAddress, unsigned int dwWidth,
unsigned int dwHeight, unsigned int dwPitch, unsigned int dwAlignedHeight, unsigned int dwBitsPerPixel)
{
printString( "SwapBuffers, address=0x%08x, width=%d, height=%d, pitch=%d, alignedheight=%d, bpp=%d\n",
dwAddress, dwWidth, dwHeight, dwPitch, dwAlignedHeight, dwBitsPerPixel);
}
//----------------------------------------------------------------------------
void
Yamato_DumpRegSpace(gsl_device_t *device)
{
int regsPerLine = 0x20;
unsigned int dwOffset;
unsigned int value;
printString( "Start_RegisterSpace\n");
for (dwOffset = 0; dwOffset < device->regspace.sizebytes; dwOffset += 4)
{
if (dwOffset % regsPerLine == 0)
{
printString( " 0x%08x ", dwOffset);
}
GSL_HAL_REG_READ(device->id, (unsigned int) device->regspace.mmio_virt_base, (dwOffset >> 2), &value);
printString( " 0x%08x", value);
if (((dwOffset + 4) % regsPerLine == 0) && ((dwOffset + 4) < device->regspace.sizebytes))
{
printString( "\n");
}
}
printString( "\nEnd_RegisterSpace\n");
}
//----------------------------------------------------------------------------
void
Yamato_DumpAllocateMemory(unsigned int dwSize, unsigned int dwFlags, unsigned int dwAddress,
unsigned int dwActualSize)
{
printString( "AllocateMemory, size=%d, flags=0x%x, address=0x%x, actualSize=%d\n",
dwSize, dwFlags, dwAddress, dwActualSize);
}
//----------------------------------------------------------------------------
void
Yamato_DumpFreeMemory(unsigned int dwAddress)
{
printString( "FreeMemory, address=0x%x\n", dwAddress);
}
//----------------------------------------------------------------------------
void
Yamato_DumpWriteMemory(unsigned int dwAddress, unsigned int dwSize, void* pData)
{
// Open file
unsigned int dwNumDWORDs;
unsigned int dwIndex;
unsigned int *pDataPtr;
printString( "StartWriteMemory, address=0x%x, size=%d\n", dwAddress, dwSize);
// Now write the data, in dwNumDWORDs
dwNumDWORDs = dwSize >> 2;
// If there are spillover bytes into the next dword, increment the amount dumped out here.
// The reader needs to take care of not overwriting the nonvalid bytes
if((dwSize % 4) != 0)
dwNumDWORDs++;
for (dwIndex = 0, pDataPtr = (unsigned int *)pData; dwIndex < dwNumDWORDs; dwIndex++, pDataPtr++)
{
WriteDWORD2(*pDataPtr);
}
printString( "EndWriteMemory\n");
}
void
Yamato_DumpSetMemory(unsigned int dwAddress, unsigned int dwSize, unsigned int pData)
{
// unsigned int* pDataPtr;
printString( "SetMemory, address=0x%x, size=%d, value=0x%x\n",
dwAddress, dwSize, pData);
}
//----------------------------------------------------------------------------
void
Yamato_ConvertIBAddr(unsigned int dwHeader, unsigned int *pBuffer, int gpuToHost)
{
unsigned int hostaddr;
unsigned int *ibend;
unsigned int *addr;
unsigned int *ib = pBuffer;
pm4_type3 header = *((pm4_type3*) &dwHeader);
// convert ib1 base address
if((EXPAND_OPCODE(header.it_opcode) == PM4_PACKET3_INDIRECT_BUFFER) ||
(EXPAND_OPCODE(header.it_opcode) == PM4_PACKET3_INDIRECT_BUFFER_PFD))
{
if (gpuToHost)
{
// from gpu to host
*ib = kgsl_sharedmem_convertaddr(*ib, 0);
hostaddr = *ib;
}
else
{
// from host to gpu
hostaddr = *ib;
*ib = kgsl_sharedmem_convertaddr(*ib, 1);
}
// walk through ib1 and convert any ib2 base address
ib = (unsigned int *) hostaddr;
ibend = (unsigned int *) (ib + *(++pBuffer));
while (ib < ibend)
{
dwHeader = *(ib);
header = *((pm4_type3*) (&dwHeader));
switch(dwHeader & PM4_PKT_MASK)
{
case PM4_TYPE0_PKT:
ib += header.count + 2;
break;
case PM4_TYPE1_PKT:
break;
case PM4_TYPE2_PKT:
ib++;
break;
case PM4_TYPE3_PKT:
if((EXPAND_OPCODE(header.it_opcode) == PM4_PACKET3_INDIRECT_BUFFER) ||
(EXPAND_OPCODE(header.it_opcode) == PM4_PACKET3_INDIRECT_BUFFER_PFD))
{
addr = ib + 1;
if (gpuToHost)
{
// from gpu to host
*addr = kgsl_sharedmem_convertaddr(*addr, 0);
}
else
{
// from host to gpu
*addr = kgsl_sharedmem_convertaddr(*addr, 1);
}
}
ib += header.count + 2;
break;
}
}
}
}
//----------------------------------------------------------------------------
void
Yamato_DumpPM4(unsigned int* pBuffer, unsigned int sizeDWords)
{
unsigned int *pBufferEnd = pBuffer + sizeDWords;
unsigned int *tmp;
printString( "Start_PM4Buffer\n");//, count=%d\n", sizeDWords);
// So look at the first unsigned int - should be a header
while(pBuffer < pBufferEnd)
{
unsigned int dwHeader = *(pBuffer++);
//printString( " Start_Packet\n");
switch(dwHeader & PM4_PKT_MASK)
{
case PM4_TYPE0_PKT:
WritePM4Packet_Type0(dwHeader, &pBuffer);
break;
case PM4_TYPE1_PKT:
break;
case PM4_TYPE2_PKT:
WritePM4Packet_Type2(dwHeader, &pBuffer);
break;
case PM4_TYPE3_PKT:
indirectionLevel = 0;
tmp = pBuffer;
Yamato_ConvertIBAddr(dwHeader, tmp, 1);
WritePM4Packet_Type3(dwHeader, &pBuffer);
Yamato_ConvertIBAddr(dwHeader, tmp, 0);
break;
}
//printString( " End_Packet\n");
}
printString( "End_PM4Buffer\n");
}
//----------------------------------------------------------------------------
void
Yamato_DumpRegisterWrite(unsigned int dwAddress, unsigned int value)
{
// Build a Type-0 packet that maps to this register write
unsigned int pBuffer[100], *pBuf = &pBuffer[1];
// Don't dump CP_RB_WPTR (switch statement may be necessary here for future additions)
if(dwAddress == mmCP_RB_WPTR)
return;
pBuffer[0] = dwAddress;
pBuffer[1] = value;
printString( "StartRegisterWrite\n");
WritePM4Packet_Type0(pBuffer[0], &pBuf);
printString( "EndRegisterWrite\n");
}
//----------------------------------------------------------------------------
void
Yamato_DumpFbStart(gsl_device_t *device)
{
static int firstCall = 0;
// We only want to call this once
if(firstCall)
return;
printString( "FbStart, value=0x%x\n", device->mmu.mpu_base);
printString( "FbSize, value=0x%x\n", device->mmu.mpu_range);
firstCall = 1;
}
//----------------------------------------------------------------------------
void
Yamato_DumpWindow(unsigned int addr, unsigned int width, unsigned int height)
{
printString( "DumpWindow, addr=0x%x, width=0x%x, height=0x%x\n", addr, width, height);
}
//----------------------------------------------------------------------------
#ifdef _DEBUG
#define ADDRESS_STACK_SIZE 256
#define GET_PM4_TYPE3_OPCODE(x) ((*(x) >> 8) & 0xFF)
#define IF_REGISTER_IN_RANGE(reg, base, count) \
offset = (reg) - (base); \
if(offset >= 0 && offset <= (count) - 2)
#define GET_CP_CONSTANT_DATA(x) (*((x) + offset + 2))
static const char format2bpp[] =
{
2, // COLORX_4_4_4_4
2, // COLORX_1_5_5_5
2, // COLORX_5_6_5
1, // COLORX_8
2, // COLORX_8_8
4, // COLORX_8_8_8_8
4, // COLORX_S8_8_8_8
2, // COLORX_16_FLOAT
4, // COLORX_16_16_FLOAT
8, // COLORX_16_16_16_16_FLOAT
4, // COLORX_32_FLOAT
8, // COLORX_32_32_FLOAT
16, // COLORX_32_32_32_32_FLOAT ,
1, // COLORX_2_3_3
3, // COLORX_8_8_8
};
static unsigned int kgsl_dumpx_addr_count = 0; //unique command buffer addresses encountered
static int kgsl_dumpx_handle_type3(unsigned int* hostaddr, int count)
{
// For swap detection we need to find the below declared static values, and detect DI during EDRAM copy
static unsigned int width = 0, height = 0, format = 0, baseaddr = 0, iscopy = 0;
static unsigned int addr_stack[ADDRESS_STACK_SIZE];
static unsigned int size_stack[ADDRESS_STACK_SIZE];
int swap = 0; // have we encountered a swap during recursion (return value)
switch(GET_PM4_TYPE3_OPCODE(hostaddr))
{
case PM4_INDIRECT_BUFFER_PFD:
case PM4_INDIRECT_BUFFER:
{
// traverse indirect buffers
unsigned int i;
unsigned int ibaddr = *(hostaddr+1);
unsigned int ibsize = *(hostaddr+2);
// is this address already in encountered?
for(i = 0; i < kgsl_dumpx_addr_count && addr_stack[i] != ibaddr; i++);
if(kgsl_dumpx_addr_count == i)
{
// yes it was, store the address so we don't dump this buffer twice
addr_stack[kgsl_dumpx_addr_count] = ibaddr;
// just for sanity checking
size_stack[kgsl_dumpx_addr_count++] = ibsize;
DEBUG_ASSERT(kgsl_dumpx_addr_count < ADDRESS_STACK_SIZE);
// recursively follow the indirect link and update swap if indirect buffer had resolve
swap |= kgsl_dumpx_parse_ibs(ibaddr, ibsize);
}
else
{
DEBUG_ASSERT(size_stack[i] == ibsize);
}
}
break;
case PM4_SET_CONSTANT:
if((*(hostaddr+1) >> 16) == 0x4)
{
// parse register writes, and figure out framebuffer configuration
unsigned int regaddr = (*(hostaddr + 1) & 0xFFFF) + 0x2000; //dword address in register space
int offset; // used by the macros
IF_REGISTER_IN_RANGE(mmPA_SC_WINDOW_SCISSOR_BR, regaddr, count)
{
// found write to PA_SC_WINDOW_SCISSOR_BR, we use this to detect current
// width and height of the framebuffer (TODO: find more reliable way of achieving this)
unsigned int data = GET_CP_CONSTANT_DATA(hostaddr);
width = data & 0xFFFF;
height = data >> 16;
}
IF_REGISTER_IN_RANGE(mmRB_MODECONTROL, regaddr, count)
{
// found write to RB_MODECONTROL, we use this to find out if next DI is resolve
unsigned int data = GET_CP_CONSTANT_DATA(hostaddr);
iscopy = (data & RB_MODECONTROL__EDRAM_MODE_MASK) == (EDRAM_COPY << RB_MODECONTROL__EDRAM_MODE__SHIFT);
}
IF_REGISTER_IN_RANGE(mmRB_COPY_DEST_BASE, regaddr, count)
{
// found write to RB_COPY_DEST_BASE, we use this to find out the framebuffer base address
unsigned int data = GET_CP_CONSTANT_DATA(hostaddr);
baseaddr = (data & RB_COPY_DEST_BASE__COPY_DEST_BASE_MASK);
}
IF_REGISTER_IN_RANGE(mmRB_COPY_DEST_INFO, regaddr, count)
{
// found write to RB_COPY_DEST_INFO, we use this to find out the framebuffer format
unsigned int data = GET_CP_CONSTANT_DATA(hostaddr);
format = (data & RB_COPY_DEST_INFO__COPY_DEST_FORMAT_MASK) >> RB_COPY_DEST_INFO__COPY_DEST_FORMAT__SHIFT;
}
}
break;
case PM4_DRAW_INDX:
case PM4_DRAW_INDX_2:
{
// DI found
// check if it is resolve
if(iscopy && !swap)
{
// printf("resolve: %ix%i @ 0x%08x, format = 0x%08x\n", width, height, baseaddr, format);
DEBUG_ASSERT(format < 15);
// yes it was and we need to update color buffer config because this is the first bin
// dumpx framebuffer base address, and dimensions
KGSL_DEBUG_DUMPX( BB_DUMP_CBUF_AWH, (unsigned int)baseaddr, width, height, " ");
// find aligned width
width = (width + 31) & ~31;
//dump bytes-per-pixel and aligned width
KGSL_DEBUG_DUMPX( BB_DUMP_CBUF_FS, format2bpp[format], width, 0, " ");
swap = 1;
}
}
break;
default:
break;
}
return swap;
}
// Traverse IBs and dump them to test vector. Detect swap by inspecting register
// writes, keeping note of the current state, and dump framebuffer config to test vector
int kgsl_dumpx_parse_ibs(gpuaddr_t gpuaddr, int sizedwords)
{
static unsigned int level = 0; //recursion level
int swap = 0; // have we encountered a swap during recursion (return value)
unsigned int *hostaddr;
int dwords_left = sizedwords; //dwords left in the current command buffer
level++;
DEBUG_ASSERT(sizeof(unsigned int *) == sizeof(unsigned int));
DEBUG_ASSERT(level <= 2);
hostaddr = (unsigned int *)kgsl_sharedmem_convertaddr(gpuaddr, 0);
// dump the IB to test vector
KGSL_DEBUG(GSL_DBGFLAGS_DUMPX, KGSL_DEBUG_DUMPX(BB_DUMP_MEMWRITE, gpuaddr, (unsigned int)hostaddr, sizedwords*4, "kgsl_dumpx_write_ibs"));
while(dwords_left)
{
int count = 0; //dword count including packet header
switch(*hostaddr >> 30)
{
case 0x0: // type-0
count = (*hostaddr >> 16)+2;
break;
case 0x1: // type-1
count = 2;
break;
case 0x3: // type-3
count = ((*hostaddr >> 16) & 0x3fff) + 2;
swap |= kgsl_dumpx_handle_type3(hostaddr, count);
break; // type-3
default:
DEBUG_ASSERT(!"unknown packet type");
}
// jump to next packet
dwords_left -= count;
hostaddr += count;
DEBUG_ASSERT(dwords_left >= 0 && "PM4 parsing error");
}
level--;
// if this is the starting level of recursion, we are done. clean-up
if(level == 0) kgsl_dumpx_addr_count = 0;
return swap;
}
#endif
#endif // WIN32