Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 14fd49aa authored by Jordan Crouse's avatar Jordan Crouse
Browse files

msm: kgsl: Improve the CFF memory dump functions



kgsl_cffdump_setmem really wanted to be a memset clone but it
was reading in what was essentially a 8 bit char and writing
a 32 bit dword with the end result being that the data written
in the CFF wasn't matching the data written to memory. On top of
this the CFF code really went out of its way to try
handle unaligned sizes but it only prints memory data in dword
increments. Remove the extra code and just print the incoming
memory in dword groups as nature intends.

Change-Id: Ic0dedbad846866bc4fef5ff4c71bfd66720c03cd
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
parent b7d3647f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -47,7 +47,7 @@ struct adreno_ringbuffer {
	do { \
		*ring = data; \
		wmb(); \
		kgsl_cffdump_setmem(device, gpuaddr, data, 4); \
		kgsl_cffdump_write(device, gpuaddr, data); \
		ring++; \
		gpuaddr += sizeof(uint); \
	} while (0)
+40 −38
Original line number Diff line number Diff line
@@ -218,7 +218,7 @@ static void cffdump_membuf(int id, unsigned char *out_buf, int out_bufsize)
	cff_op_write_membuf.addr = 0;
}

static void cffdump_printline(int id, uint opcode, uint op1, uint op2,
void kgsl_cffdump_printline(int id, uint opcode, uint op1, uint op2,
	uint op3, uint op4, uint op5)
{
	struct cff_op_write_reg cff_op_write_reg;
@@ -321,6 +321,7 @@ static void cffdump_printline(int id, uint opcode, uint op1, uint op2,
		last_sec = cur_secs;
	}
}
EXPORT_SYMBOL(kgsl_cffdump_printline);

void kgsl_cffdump_init()
{
@@ -377,7 +378,7 @@ void kgsl_cffdump_memory_base(struct kgsl_device *device, unsigned int base,
{
	if (!device->cff_dump_enable)
		return;
	cffdump_printline(device->id, CFF_OP_MEMORY_BASE, base,
	kgsl_cffdump_printline(device->id, CFF_OP_MEMORY_BASE, base,
			range, gmemsize, 0, 0);
}

@@ -385,17 +386,16 @@ void kgsl_cffdump_hang(struct kgsl_device *device)
{
	if (!device->cff_dump_enable)
		return;
	cffdump_printline(device->id, CFF_OP_HANG, 0, 0, 0, 0, 0);
	kgsl_cffdump_printline(device->id, CFF_OP_HANG, 0, 0, 0, 0, 0);
}

void kgsl_cffdump_close(struct kgsl_device *device)
{
	if (!device->cff_dump_enable)
		return;
	cffdump_printline(device->id, CFF_OP_EOF, 0, 0, 0, 0, 0);
	kgsl_cffdump_printline(device->id, CFF_OP_EOF, 0, 0, 0, 0, 0);
}


void kgsl_cffdump_user_event(struct kgsl_device *device,
		unsigned int cff_opcode, unsigned int op1,
		unsigned int op2, unsigned int op3,
@@ -403,27 +403,42 @@ void kgsl_cffdump_user_event(struct kgsl_device *device,
{
	if (!device->cff_dump_enable)
		return;
	cffdump_printline(-1, cff_opcode, op1, op2, op3, op4, op5);
	kgsl_cffdump_printline(-1, cff_opcode, op1, op2, op3, op4, op5);
}



void kgsl_cffdump_memcpy(struct kgsl_device *device,
		unsigned int gupaddr, unsigned int *ptr, size_t sizebytes)
{
	int i;

	if (!device || !device->cff_dump_enable)
		return;

	for (i = 0; i < ALIGN(sizebytes, 4) / 4; gpuaddr += 4, ptr++, i++)
		kgsl_cffdump_write(device, gpuaddr, *ptr);
}

void kgsl_cffdump_syncmem(struct kgsl_device *device,
			  struct kgsl_memdesc *memdesc, uint gpuaddr,
			  size_t sizebytes, bool clean_cache)
{
	const void *src;
	unsigned int *src;

	if (!device->cff_dump_enable)
	if (!device || device->cff_dump_enable)
		return;

	BUG_ON(memdesc == NULL);
	if (!memdesc)
		return;

	total_syncmem += sizebytes;

	src = kgsl_gpuaddr_to_vaddr(memdesc, gpuaddr);
	if (memdesc->hostptr == NULL) {
		KGSL_CORE_ERR(
		"no kernel map for gpuaddr: 0x%08x, m->host: 0x%p, phys: %pa\n",
		gpuaddr, memdesc->hostptr, &memdesc->physaddr);
			"cffdump: no kernel mapping for GPU address 0x%08X\n",
			gpuaddr);
		return;
	}

@@ -437,37 +452,24 @@ void kgsl_cffdump_syncmem(struct kgsl_device *device,
				KGSL_CACHE_OP_INV);
	}

	while (sizebytes > 3) {
		cffdump_printline(-1, CFF_OP_WRITE_MEM, gpuaddr, *(uint *)src,
			0, 0, 0);
		gpuaddr += 4;
		src += 4;
		sizebytes -= 4;
	}
	if (sizebytes > 0)
		cffdump_printline(-1, CFF_OP_WRITE_MEM, gpuaddr, *(uint *)src,
			0, 0, 0);
	kgsl_cffdump_memcpy(device, gpuaddr, ptr, sizebytes);

	/* Unmap memory since kgsl_gpuaddr_to_vaddr was called */
	kgsl_memdesc_unmap(memdesc);
}

void kgsl_cffdump_setmem(struct kgsl_device *device,
			uint addr, uint value, uint sizebytes)
void kgsl_cffdump_memset(struct kgsl_device *device,
		unsigned int gpuaddr, unsigned char ch, size_t sizebytes)
{
	int i;

	if (!device || !device->cff_dump_enable)
		return;

	while (sizebytes > 3) {
		/* Use 32bit memory writes as long as there's at least
		 * 4 bytes left */
		cffdump_printline(-1, CFF_OP_WRITE_MEM, addr, value,
				0, 0, 0);
		addr += 4;
		sizebytes -= 4;
	}
	if (sizebytes > 0)
		cffdump_printline(-1, CFF_OP_WRITE_MEM, addr, value,
				0, 0, 0);
	/* Expand the input char into a dword and output it */
	for (i = 0; i < ALIGN(sizebytes, 4) / 4; gupaddr += 4, i++)
		kgsl_cffdump_write(device, gpuaddr,
			(ch << 24) | (ch << 16) | (ch << 8) | ch);
}

void kgsl_cffdump_regwrite(struct kgsl_device *device, uint addr,
@@ -476,7 +478,7 @@ void kgsl_cffdump_regwrite(struct kgsl_device *device, uint addr,
	if (!device->cff_dump_enable)
		return;

	cffdump_printline(device->id, CFF_OP_WRITE_REG, addr, value,
	kgsl_cffdump_printline(device->id, CFF_OP_WRITE_REG, addr, value,
			0, 0, 0);
}

@@ -486,7 +488,7 @@ void kgsl_cffdump_regpoll(struct kgsl_device *device, uint addr,
	if (!device->cff_dump_enable)
		return;

	cffdump_printline(device->id, CFF_OP_POLL_REG, addr, value,
	kgsl_cffdump_printline(device->id, CFF_OP_POLL_REG, addr, value,
			mask, 0, 0);
}

@@ -495,7 +497,7 @@ void kgsl_cffdump_slavewrite(struct kgsl_device *device, uint addr, uint value)
	if (!device->cff_dump_enable)
		return;

	cffdump_printline(-1, CFF_OP_WRITE_REG, addr, value, 0, 0, 0);
	kgsl_cffdump_printline(-1, CFF_OP_WRITE_REG, addr, value, 0, 0, 0);
}

int kgsl_cffdump_waitirq(struct kgsl_device *device)
@@ -503,7 +505,7 @@ int kgsl_cffdump_waitirq(struct kgsl_device *device)
	if (!device->cff_dump_enable)
		return 0;

	cffdump_printline(-1, CFF_OP_WAIT_IRQ, 0, 0, 0, 0, 0);
	kgsl_cffdump_printline(-1, CFF_OP_WAIT_IRQ, 0, 0, 0, 0, 0);

	return 1;
}
+30 −4
Original line number Diff line number Diff line
@@ -29,11 +29,13 @@ void kgsl_cffdump_init(void);
void kgsl_cffdump_destroy(void);
void kgsl_cffdump_open(struct kgsl_device *device);
void kgsl_cffdump_close(struct kgsl_device *device);
void kgsl_cffdump_memcpy(struct kgsl_device *device, unsigned int gpuaddr,
		unsigned int *ptr, size_t sizebytes);
void kgsl_cffdump_syncmem(struct kgsl_device *,
	struct kgsl_memdesc *memdesc, uint physaddr, size_t sizebytes,
	bool clean_cache);
void kgsl_cffdump_setmem(struct kgsl_device *device, uint addr,
			uint value, uint sizebytes);
void kgsl_cffdump_memset(struct kgsl_device *device, uint addr,
			unsigned char value, size_t sizebytes);
void kgsl_cffdump_regwrite(struct kgsl_device *device, uint addr,
	uint value);
void kgsl_cffdump_regpoll(struct kgsl_device *device, uint addr,
@@ -56,6 +58,18 @@ int kgsl_cffdump_capture_ib_desc(struct kgsl_device *device,
				struct kgsl_context *context,
				struct kgsl_cmdbatch *cmdbatch);

void kgsl_cffdump_printline(int id, uint opcode, uint op1, uint op2,
	uint op3, uint op4, uint op5);

static inline void kgsl_cffdump_write(struct kgsl_device *device,
		unsigned int gpuaddr, unsigned int value)
{
	if (!device || !device->cff_dump_enable)
		return;

	kgsl_cffdump_printline(-1, CFF_OP_WRITE_MEM, gpuaddr, value, 0, 0, 0);
}

#else

static inline void kgsl_cffdump_init(void)
@@ -78,6 +92,18 @@ static inline void kgsl_cffdump_close(struct kgsl_device *device)
	return;
}

static inline void kgsl_cffdump_write(struct kgsl_device *device,
		unsigned int gpuaddr, unsigned int value)
{
	return;
}

static inline void kgsl_cffdump_memcpy(struct kgsl_device *device,
		unsigned int gupaddr, unsigned int *ptr, size_t sizebytes)
{
	return;
}

static inline void kgsl_cffdump_syncmem(struct kgsl_device *device,
		struct kgsl_memdesc *memdesc, uint physaddr, size_t sizebytes,
		bool clean_cache)
@@ -85,8 +111,8 @@ static inline void kgsl_cffdump_syncmem(struct kgsl_device *device,
	return;
}

static inline void kgsl_cffdump_setmem(struct kgsl_device *device, uint addr,
		uint value, uint sizebytes)
static inline void kgsl_cffdump_memset(struct kgsl_device *device, uint addr,
		unsigned char ch, size_t sizebytes)
{
	return;
}
+2 −2
Original line number Diff line number Diff line
@@ -1637,9 +1637,9 @@ static int kgsl_iommu_start(struct kgsl_mmu *mmu)
	_iommu_unlock(iommu);

	/* For complete CFF */
	kgsl_cffdump_setmem(mmu->device, mmu->setstate_memory.gpuaddr +
	kgsl_cffdump_write(mmu->device, mmu->setstate_memory.gpuaddr +
				KGSL_IOMMU_SETSTATE_NOP_OFFSET,
				cp_nop_packet(1), sizeof(unsigned int));
				cp_nop_packet(1));

	kgsl_iommu_disable_clk(mmu, KGSL_IOMMU_CONTEXT_USER);
	kgsl_iommu_disable_clk(mmu, KGSL_IOMMU_CONTEXT_PRIV);
+3 −3
Original line number Diff line number Diff line
@@ -815,9 +815,9 @@ kgsl_sharedmem_writel(struct kgsl_device *device,
	WARN_ON(offsetbytes + sizeof(uint32_t) > memdesc->size);
	if (offsetbytes + sizeof(uint32_t) > memdesc->size)
		return -ERANGE;
	kgsl_cffdump_setmem(device,
	kgsl_cffdump_write(device,
		memdesc->gpuaddr + offsetbytes,
		src, sizeof(uint32_t));
		src);
	dst = (uint32_t *)(memdesc->hostptr + offsetbytes);
	*dst = src;

@@ -835,7 +835,7 @@ kgsl_sharedmem_set(struct kgsl_device *device,
	BUG_ON(memdesc == NULL || memdesc->hostptr == NULL);
	BUG_ON(offsetbytes + sizebytes > memdesc->size);

	kgsl_cffdump_setmem(device,
	kgsl_cffdump_memset(device,
		memdesc->gpuaddr + offsetbytes, value,
		sizebytes);
	memset(memdesc->hostptr + offsetbytes, value, sizebytes);