cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

debug_hw_1x06.c (4288B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2010 Google, Inc.
      4 * Author: Erik Gilling <konkers@android.com>
      5 *
      6 * Copyright (C) 2011-2017 NVIDIA Corporation
      7 */
      8
      9#include "../dev.h"
     10#include "../debug.h"
     11#include "../cdma.h"
     12#include "../channel.h"
     13
     14static void host1x_debug_show_channel_cdma(struct host1x *host,
     15					   struct host1x_channel *ch,
     16					   struct output *o)
     17{
     18	struct host1x_cdma *cdma = &ch->cdma;
     19	dma_addr_t dmastart = 0, dmaend = 0;
     20	u32 dmaput, dmaget, dmactrl;
     21	u32 offset, class;
     22	u32 ch_stat;
     23
     24#if defined(CONFIG_ARCH_DMA_ADDR_T_64BIT) && HOST1X_HW >= 6
     25	dmastart = host1x_ch_readl(ch, HOST1X_CHANNEL_DMASTART_HI);
     26	dmastart <<= 32;
     27#endif
     28	dmastart |= host1x_ch_readl(ch, HOST1X_CHANNEL_DMASTART);
     29
     30#if defined(CONFIG_ARCH_DMA_ADDR_T_64BIT) && HOST1X_HW >= 6
     31	dmaend = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAEND_HI);
     32	dmaend <<= 32;
     33#endif
     34	dmaend |= host1x_ch_readl(ch, HOST1X_CHANNEL_DMAEND);
     35
     36	dmaput = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAPUT);
     37	dmaget = host1x_ch_readl(ch, HOST1X_CHANNEL_DMAGET);
     38	dmactrl = host1x_ch_readl(ch, HOST1X_CHANNEL_DMACTRL);
     39	offset = host1x_ch_readl(ch, HOST1X_CHANNEL_CMDP_OFFSET);
     40	class = host1x_ch_readl(ch, HOST1X_CHANNEL_CMDP_CLASS);
     41	ch_stat = host1x_ch_readl(ch, HOST1X_CHANNEL_CHANNELSTAT);
     42
     43	host1x_debug_output(o, "%u-%s: ", ch->id, dev_name(ch->dev));
     44
     45	if (dmactrl & HOST1X_CHANNEL_DMACTRL_DMASTOP ||
     46	    !ch->cdma.push_buffer.mapped) {
     47		host1x_debug_output(o, "inactive\n\n");
     48		return;
     49	}
     50
     51	if (class == HOST1X_CLASS_HOST1X && offset == HOST1X_UCLASS_WAIT_SYNCPT)
     52		host1x_debug_output(o, "waiting on syncpt\n");
     53	else
     54		host1x_debug_output(o, "active class %02x, offset %04x\n",
     55				    class, offset);
     56
     57	host1x_debug_output(o, "DMASTART %pad, DMAEND %pad\n", &dmastart, &dmaend);
     58	host1x_debug_output(o, "DMAPUT %08x DMAGET %08x DMACTL %08x\n",
     59			    dmaput, dmaget, dmactrl);
     60	host1x_debug_output(o, "CHANNELSTAT %02x\n", ch_stat);
     61
     62	show_channel_gathers(o, cdma);
     63	host1x_debug_output(o, "\n");
     64}
     65
     66static void host1x_debug_show_channel_fifo(struct host1x *host,
     67					   struct host1x_channel *ch,
     68					   struct output *o)
     69{
     70#if HOST1X_HW <= 6
     71	u32 rd_ptr, wr_ptr, start, end;
     72	u32 payload = INVALID_PAYLOAD;
     73	unsigned int data_count = 0;
     74#endif
     75	u32 val;
     76
     77	host1x_debug_output(o, "%u: fifo:\n", ch->id);
     78
     79	val = host1x_ch_readl(ch, HOST1X_CHANNEL_CMDFIFO_STAT);
     80	host1x_debug_output(o, "CMDFIFO_STAT %08x\n", val);
     81	if (val & HOST1X_CHANNEL_CMDFIFO_STAT_EMPTY) {
     82		host1x_debug_output(o, "[empty]\n");
     83		return;
     84	}
     85
     86	val = host1x_ch_readl(ch, HOST1X_CHANNEL_CMDFIFO_RDATA);
     87	host1x_debug_output(o, "CMDFIFO_RDATA %08x\n", val);
     88
     89#if HOST1X_HW <= 6
     90	/* Peek pointer values are invalid during SLCG, so disable it */
     91	host1x_hypervisor_writel(host, 0x1, HOST1X_HV_ICG_EN_OVERRIDE);
     92
     93	val = 0;
     94	val |= HOST1X_HV_CMDFIFO_PEEK_CTRL_ENABLE;
     95	val |= HOST1X_HV_CMDFIFO_PEEK_CTRL_CHANNEL(ch->id);
     96	host1x_hypervisor_writel(host, val, HOST1X_HV_CMDFIFO_PEEK_CTRL);
     97
     98	val = host1x_hypervisor_readl(host, HOST1X_HV_CMDFIFO_PEEK_PTRS);
     99	rd_ptr = HOST1X_HV_CMDFIFO_PEEK_PTRS_RD_PTR_V(val);
    100	wr_ptr = HOST1X_HV_CMDFIFO_PEEK_PTRS_WR_PTR_V(val);
    101
    102	val = host1x_hypervisor_readl(host, HOST1X_HV_CMDFIFO_SETUP(ch->id));
    103	start = HOST1X_HV_CMDFIFO_SETUP_BASE_V(val);
    104	end = HOST1X_HV_CMDFIFO_SETUP_LIMIT_V(val);
    105
    106	do {
    107		val = 0;
    108		val |= HOST1X_HV_CMDFIFO_PEEK_CTRL_ENABLE;
    109		val |= HOST1X_HV_CMDFIFO_PEEK_CTRL_CHANNEL(ch->id);
    110		val |= HOST1X_HV_CMDFIFO_PEEK_CTRL_ADDR(rd_ptr);
    111		host1x_hypervisor_writel(host, val,
    112					 HOST1X_HV_CMDFIFO_PEEK_CTRL);
    113
    114		val = host1x_hypervisor_readl(host,
    115					      HOST1X_HV_CMDFIFO_PEEK_READ);
    116
    117		if (!data_count) {
    118			host1x_debug_output(o, "%03x 0x%08x: ",
    119					    rd_ptr - start, val);
    120			data_count = show_channel_command(o, val, &payload);
    121		} else {
    122			host1x_debug_cont(o, "%08x%s", val,
    123					  data_count > 1 ? ", " : "])\n");
    124			data_count--;
    125		}
    126
    127		if (rd_ptr == end)
    128			rd_ptr = start;
    129		else
    130			rd_ptr++;
    131	} while (rd_ptr != wr_ptr);
    132
    133	if (data_count)
    134		host1x_debug_cont(o, ", ...])\n");
    135	host1x_debug_output(o, "\n");
    136
    137	host1x_hypervisor_writel(host, 0x0, HOST1X_HV_CMDFIFO_PEEK_CTRL);
    138	host1x_hypervisor_writel(host, 0x0, HOST1X_HV_ICG_EN_OVERRIDE);
    139#endif
    140}
    141
    142static void host1x_debug_show_mlocks(struct host1x *host, struct output *o)
    143{
    144	/* TODO */
    145}