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

psp_v11_0_8.c (6607B)


      1/*
      2 * Copyright 2021 Advanced Micro Devices, Inc.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included in
     12 * all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 * OTHER DEALINGS IN THE SOFTWARE.
     21 *
     22 */
     23#include "amdgpu.h"
     24#include "amdgpu_psp.h"
     25#include "amdgpu_ucode.h"
     26#include "soc15_common.h"
     27#include "psp_v11_0_8.h"
     28
     29#include "mp/mp_11_0_8_offset.h"
     30
     31static int psp_v11_0_8_ring_init(struct psp_context *psp,
     32			      enum psp_ring_type ring_type)
     33{
     34	int ret = 0;
     35	struct psp_ring *ring;
     36	struct amdgpu_device *adev = psp->adev;
     37
     38	ring = &psp->km_ring;
     39
     40	ring->ring_type = ring_type;
     41
     42	/* allocate 4k Page of Local Frame Buffer memory for ring */
     43	ring->ring_size = 0x1000;
     44	ret = amdgpu_bo_create_kernel(adev, ring->ring_size, PAGE_SIZE,
     45				      AMDGPU_GEM_DOMAIN_VRAM,
     46				      &adev->firmware.rbuf,
     47				      &ring->ring_mem_mc_addr,
     48				      (void **)&ring->ring_mem);
     49	if (ret) {
     50		ring->ring_size = 0;
     51		return ret;
     52	}
     53
     54	return 0;
     55}
     56
     57static int psp_v11_0_8_ring_stop(struct psp_context *psp,
     58			       enum psp_ring_type ring_type)
     59{
     60	int ret = 0;
     61	struct amdgpu_device *adev = psp->adev;
     62
     63	if (amdgpu_sriov_vf(adev)) {
     64		/* Write the ring destroy command*/
     65		WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101,
     66			     GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING);
     67		/* there might be handshake issue with hardware which needs delay */
     68		mdelay(20);
     69		/* Wait for response flag (bit 31) */
     70		ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_101),
     71				   0x80000000, 0x80000000, false);
     72	} else {
     73		/* Write the ring destroy command*/
     74		WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64,
     75			     GFX_CTRL_CMD_ID_DESTROY_RINGS);
     76		/* there might be handshake issue with hardware which needs delay */
     77		mdelay(20);
     78		/* Wait for response flag (bit 31) */
     79		ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64),
     80				   0x80000000, 0x80000000, false);
     81	}
     82
     83	return ret;
     84}
     85
     86static int psp_v11_0_8_ring_create(struct psp_context *psp,
     87				 enum psp_ring_type ring_type)
     88{
     89	int ret = 0;
     90	unsigned int psp_ring_reg = 0;
     91	struct psp_ring *ring = &psp->km_ring;
     92	struct amdgpu_device *adev = psp->adev;
     93
     94	if (amdgpu_sriov_vf(adev)) {
     95		ret = psp_v11_0_8_ring_stop(psp, ring_type);
     96		if (ret) {
     97			DRM_ERROR("psp_v11_0_8_ring_stop_sriov failed!\n");
     98			return ret;
     99		}
    100
    101		/* Write low address of the ring to C2PMSG_102 */
    102		psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);
    103		WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102, psp_ring_reg);
    104		/* Write high address of the ring to C2PMSG_103 */
    105		psp_ring_reg = upper_32_bits(ring->ring_mem_mc_addr);
    106		WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_103, psp_ring_reg);
    107
    108		/* Write the ring initialization command to C2PMSG_101 */
    109		WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101,
    110			     GFX_CTRL_CMD_ID_INIT_GPCOM_RING);
    111
    112		/* there might be handshake issue with hardware which needs delay */
    113		mdelay(20);
    114
    115		/* Wait for response flag (bit 31) in C2PMSG_101 */
    116		ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_101),
    117				   0x80000000, 0x8000FFFF, false);
    118
    119	} else {
    120		/* Wait for sOS ready for ring creation */
    121		ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64),
    122				   0x80000000, 0x80000000, false);
    123		if (ret) {
    124			DRM_ERROR("Failed to wait for trust OS ready for ring creation\n");
    125			return ret;
    126		}
    127
    128		/* Write low address of the ring to C2PMSG_69 */
    129		psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);
    130		WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_69, psp_ring_reg);
    131		/* Write high address of the ring to C2PMSG_70 */
    132		psp_ring_reg = upper_32_bits(ring->ring_mem_mc_addr);
    133		WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_70, psp_ring_reg);
    134		/* Write size of ring to C2PMSG_71 */
    135		psp_ring_reg = ring->ring_size;
    136		WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_71, psp_ring_reg);
    137		/* Write the ring initialization command to C2PMSG_64 */
    138		psp_ring_reg = ring_type;
    139		psp_ring_reg = psp_ring_reg << 16;
    140		WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64, psp_ring_reg);
    141
    142		/* there might be handshake issue with hardware which needs delay */
    143		mdelay(20);
    144
    145		/* Wait for response flag (bit 31) in C2PMSG_64 */
    146		ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64),
    147				   0x80000000, 0x8000FFFF, false);
    148	}
    149
    150	return ret;
    151}
    152
    153static int psp_v11_0_8_ring_destroy(struct psp_context *psp,
    154				  enum psp_ring_type ring_type)
    155{
    156	int ret = 0;
    157	struct psp_ring *ring = &psp->km_ring;
    158	struct amdgpu_device *adev = psp->adev;
    159
    160	ret = psp_v11_0_8_ring_stop(psp, ring_type);
    161	if (ret)
    162		DRM_ERROR("Fail to stop psp ring\n");
    163
    164	amdgpu_bo_free_kernel(&adev->firmware.rbuf,
    165			      &ring->ring_mem_mc_addr,
    166			      (void **)&ring->ring_mem);
    167
    168	return ret;
    169}
    170
    171static uint32_t psp_v11_0_8_ring_get_wptr(struct psp_context *psp)
    172{
    173	uint32_t data;
    174	struct amdgpu_device *adev = psp->adev;
    175
    176	if (amdgpu_sriov_vf(adev))
    177		data = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102);
    178	else
    179		data = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67);
    180
    181	return data;
    182}
    183
    184static void psp_v11_0_8_ring_set_wptr(struct psp_context *psp, uint32_t value)
    185{
    186	struct amdgpu_device *adev = psp->adev;
    187
    188	if (amdgpu_sriov_vf(adev)) {
    189		WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102, value);
    190		WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101,
    191			     GFX_CTRL_CMD_ID_CONSUME_CMD);
    192	} else
    193		WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67, value);
    194}
    195
    196static const struct psp_funcs psp_v11_0_8_funcs = {
    197	.ring_init = psp_v11_0_8_ring_init,
    198	.ring_create = psp_v11_0_8_ring_create,
    199	.ring_stop = psp_v11_0_8_ring_stop,
    200	.ring_destroy = psp_v11_0_8_ring_destroy,
    201	.ring_get_wptr = psp_v11_0_8_ring_get_wptr,
    202	.ring_set_wptr = psp_v11_0_8_ring_set_wptr,
    203};
    204
    205void psp_v11_0_8_set_psp_funcs(struct psp_context *psp)
    206{
    207	psp->funcs = &psp_v11_0_8_funcs;
    208}