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

syncpt_hw.c (3336B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Tegra host1x Syncpoints
      4 *
      5 * Copyright (c) 2010-2013, NVIDIA Corporation.
      6 */
      7
      8#include <linux/io.h>
      9
     10#include "../dev.h"
     11#include "../syncpt.h"
     12
     13/*
     14 * Write the current syncpoint value back to hw.
     15 */
     16static void syncpt_restore(struct host1x_syncpt *sp)
     17{
     18	u32 min = host1x_syncpt_read_min(sp);
     19	struct host1x *host = sp->host;
     20
     21	host1x_sync_writel(host, min, HOST1X_SYNC_SYNCPT(sp->id));
     22}
     23
     24/*
     25 * Write the current waitbase value back to hw.
     26 */
     27static void syncpt_restore_wait_base(struct host1x_syncpt *sp)
     28{
     29#if HOST1X_HW < 7
     30	struct host1x *host = sp->host;
     31
     32	host1x_sync_writel(host, sp->base_val,
     33			   HOST1X_SYNC_SYNCPT_BASE(sp->id));
     34#endif
     35}
     36
     37/*
     38 * Read waitbase value from hw.
     39 */
     40static void syncpt_read_wait_base(struct host1x_syncpt *sp)
     41{
     42#if HOST1X_HW < 7
     43	struct host1x *host = sp->host;
     44
     45	sp->base_val =
     46		host1x_sync_readl(host, HOST1X_SYNC_SYNCPT_BASE(sp->id));
     47#endif
     48}
     49
     50/*
     51 * Updates the last value read from hardware.
     52 */
     53static u32 syncpt_load(struct host1x_syncpt *sp)
     54{
     55	struct host1x *host = sp->host;
     56	u32 old, live;
     57
     58	/* Loop in case there's a race writing to min_val */
     59	do {
     60		old = host1x_syncpt_read_min(sp);
     61		live = host1x_sync_readl(host, HOST1X_SYNC_SYNCPT(sp->id));
     62	} while ((u32)atomic_cmpxchg(&sp->min_val, old, live) != old);
     63
     64	if (!host1x_syncpt_check_max(sp, live))
     65		dev_err(host->dev, "%s failed: id=%u, min=%d, max=%d\n",
     66			__func__, sp->id, host1x_syncpt_read_min(sp),
     67			host1x_syncpt_read_max(sp));
     68
     69	return live;
     70}
     71
     72/*
     73 * Write a cpu syncpoint increment to the hardware, without touching
     74 * the cache.
     75 */
     76static int syncpt_cpu_incr(struct host1x_syncpt *sp)
     77{
     78	struct host1x *host = sp->host;
     79	u32 reg_offset = sp->id / 32;
     80
     81	if (!host1x_syncpt_client_managed(sp) &&
     82	    host1x_syncpt_idle(sp))
     83		return -EINVAL;
     84
     85	host1x_sync_writel(host, BIT(sp->id % 32),
     86			   HOST1X_SYNC_SYNCPT_CPU_INCR(reg_offset));
     87	wmb();
     88
     89	return 0;
     90}
     91
     92/**
     93 * syncpt_assign_to_channel() - Assign syncpoint to channel
     94 * @sp: syncpoint
     95 * @ch: channel
     96 *
     97 * On chips with the syncpoint protection feature (Tegra186+), assign @sp to
     98 * @ch, preventing other channels from incrementing the syncpoints. If @ch is
     99 * NULL, unassigns the syncpoint.
    100 *
    101 * On older chips, do nothing.
    102 */
    103static void syncpt_assign_to_channel(struct host1x_syncpt *sp,
    104				  struct host1x_channel *ch)
    105{
    106#if HOST1X_HW >= 6
    107	struct host1x *host = sp->host;
    108
    109	if (!host->hv_regs)
    110		return;
    111
    112	host1x_sync_writel(host,
    113			   HOST1X_SYNC_SYNCPT_CH_APP_CH(ch ? ch->id : 0xff),
    114			   HOST1X_SYNC_SYNCPT_CH_APP(sp->id));
    115#endif
    116}
    117
    118/**
    119 * syncpt_enable_protection() - Enable syncpoint protection
    120 * @host: host1x instance
    121 *
    122 * On chips with the syncpoint protection feature (Tegra186+), enable this
    123 * feature. On older chips, do nothing.
    124 */
    125static void syncpt_enable_protection(struct host1x *host)
    126{
    127#if HOST1X_HW >= 6
    128	if (!host->hv_regs)
    129		return;
    130
    131	host1x_hypervisor_writel(host, HOST1X_HV_SYNCPT_PROT_EN_CH_EN,
    132				 HOST1X_HV_SYNCPT_PROT_EN);
    133#endif
    134}
    135
    136static const struct host1x_syncpt_ops host1x_syncpt_ops = {
    137	.restore = syncpt_restore,
    138	.restore_wait_base = syncpt_restore_wait_base,
    139	.load_wait_base = syncpt_read_wait_base,
    140	.load = syncpt_load,
    141	.cpu_incr = syncpt_cpu_incr,
    142	.assign_to_channel = syncpt_assign_to_channel,
    143	.enable_protection = syncpt_enable_protection,
    144};