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

ramfuc.h (3891B)


      1/* SPDX-License-Identifier: MIT */
      2#ifndef __NVKM_FBRAM_FUC_H__
      3#define __NVKM_FBRAM_FUC_H__
      4#include <subdev/fb.h>
      5#include <subdev/pmu.h>
      6
      7struct ramfuc {
      8	struct nvkm_memx *memx;
      9	struct nvkm_fb *fb;
     10	int sequence;
     11};
     12
     13struct ramfuc_reg {
     14	int sequence;
     15	bool force;
     16	u32 addr;
     17	u32 stride; /* in bytes */
     18	u32 mask;
     19	u32 data;
     20};
     21
     22static inline struct ramfuc_reg
     23ramfuc_stride(u32 addr, u32 stride, u32 mask)
     24{
     25	return (struct ramfuc_reg) {
     26		.sequence = 0,
     27		.addr = addr,
     28		.stride = stride,
     29		.mask = mask,
     30		.data = 0xdeadbeef,
     31	};
     32}
     33
     34static inline struct ramfuc_reg
     35ramfuc_reg2(u32 addr1, u32 addr2)
     36{
     37	return (struct ramfuc_reg) {
     38		.sequence = 0,
     39		.addr = addr1,
     40		.stride = addr2 - addr1,
     41		.mask = 0x3,
     42		.data = 0xdeadbeef,
     43	};
     44}
     45
     46static noinline struct ramfuc_reg
     47ramfuc_reg(u32 addr)
     48{
     49	return (struct ramfuc_reg) {
     50		.sequence = 0,
     51		.addr = addr,
     52		.stride = 0,
     53		.mask = 0x1,
     54		.data = 0xdeadbeef,
     55	};
     56}
     57
     58static inline int
     59ramfuc_init(struct ramfuc *ram, struct nvkm_fb *fb)
     60{
     61	int ret = nvkm_memx_init(fb->subdev.device->pmu, &ram->memx);
     62	if (ret)
     63		return ret;
     64
     65	ram->sequence++;
     66	ram->fb = fb;
     67	return 0;
     68}
     69
     70static inline int
     71ramfuc_exec(struct ramfuc *ram, bool exec)
     72{
     73	int ret = 0;
     74	if (ram->fb) {
     75		ret = nvkm_memx_fini(&ram->memx, exec);
     76		ram->fb = NULL;
     77	}
     78	return ret;
     79}
     80
     81static inline u32
     82ramfuc_rd32(struct ramfuc *ram, struct ramfuc_reg *reg)
     83{
     84	struct nvkm_device *device = ram->fb->subdev.device;
     85	if (reg->sequence != ram->sequence)
     86		reg->data = nvkm_rd32(device, reg->addr);
     87	return reg->data;
     88}
     89
     90static inline void
     91ramfuc_wr32(struct ramfuc *ram, struct ramfuc_reg *reg, u32 data)
     92{
     93	unsigned int mask, off = 0;
     94
     95	reg->sequence = ram->sequence;
     96	reg->data = data;
     97
     98	for (mask = reg->mask; mask > 0; mask = (mask & ~1) >> 1) {
     99		if (mask & 1)
    100			nvkm_memx_wr32(ram->memx, reg->addr+off, reg->data);
    101		off += reg->stride;
    102	}
    103}
    104
    105static inline void
    106ramfuc_nuke(struct ramfuc *ram, struct ramfuc_reg *reg)
    107{
    108	reg->force = true;
    109}
    110
    111static inline u32
    112ramfuc_mask(struct ramfuc *ram, struct ramfuc_reg *reg, u32 mask, u32 data)
    113{
    114	u32 temp = ramfuc_rd32(ram, reg);
    115	if (temp != ((temp & ~mask) | data) || reg->force) {
    116		ramfuc_wr32(ram, reg, (temp & ~mask) | data);
    117		reg->force = false;
    118	}
    119	return temp;
    120}
    121
    122static inline void
    123ramfuc_wait(struct ramfuc *ram, u32 addr, u32 mask, u32 data, u32 nsec)
    124{
    125	nvkm_memx_wait(ram->memx, addr, mask, data, nsec);
    126}
    127
    128static inline void
    129ramfuc_nsec(struct ramfuc *ram, u32 nsec)
    130{
    131	nvkm_memx_nsec(ram->memx, nsec);
    132}
    133
    134static inline void
    135ramfuc_wait_vblank(struct ramfuc *ram)
    136{
    137	nvkm_memx_wait_vblank(ram->memx);
    138}
    139
    140static inline void
    141ramfuc_train(struct ramfuc *ram)
    142{
    143	nvkm_memx_train(ram->memx);
    144}
    145
    146static inline int
    147ramfuc_train_result(struct nvkm_fb *fb, u32 *result, u32 rsize)
    148{
    149	return nvkm_memx_train_result(fb->subdev.device->pmu, result, rsize);
    150}
    151
    152static inline void
    153ramfuc_block(struct ramfuc *ram)
    154{
    155	nvkm_memx_block(ram->memx);
    156}
    157
    158static inline void
    159ramfuc_unblock(struct ramfuc *ram)
    160{
    161	nvkm_memx_unblock(ram->memx);
    162}
    163
    164#define ram_init(s,p)        ramfuc_init(&(s)->base, (p))
    165#define ram_exec(s,e)        ramfuc_exec(&(s)->base, (e))
    166#define ram_have(s,r)        ((s)->r_##r.addr != 0x000000)
    167#define ram_rd32(s,r)        ramfuc_rd32(&(s)->base, &(s)->r_##r)
    168#define ram_wr32(s,r,d)      ramfuc_wr32(&(s)->base, &(s)->r_##r, (d))
    169#define ram_nuke(s,r)        ramfuc_nuke(&(s)->base, &(s)->r_##r)
    170#define ram_mask(s,r,m,d)    ramfuc_mask(&(s)->base, &(s)->r_##r, (m), (d))
    171#define ram_wait(s,r,m,d,n)  ramfuc_wait(&(s)->base, (r), (m), (d), (n))
    172#define ram_nsec(s,n)        ramfuc_nsec(&(s)->base, (n))
    173#define ram_wait_vblank(s)   ramfuc_wait_vblank(&(s)->base)
    174#define ram_train(s)         ramfuc_train(&(s)->base)
    175#define ram_train_result(s,r,l) ramfuc_train_result((s), (r), (l))
    176#define ram_block(s)         ramfuc_block(&(s)->base)
    177#define ram_unblock(s)       ramfuc_unblock(&(s)->base)
    178#endif