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_v10_0.c (7733B)


      1/*
      2 * Copyright 2016 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 * Author: Huang Rui
     23 *
     24 */
     25
     26#include <linux/firmware.h>
     27#include <linux/module.h>
     28#include <linux/pci.h>
     29
     30#include "amdgpu.h"
     31#include "amdgpu_psp.h"
     32#include "amdgpu_ucode.h"
     33#include "soc15_common.h"
     34#include "psp_v10_0.h"
     35
     36#include "mp/mp_10_0_offset.h"
     37#include "gc/gc_9_1_offset.h"
     38#include "sdma0/sdma0_4_1_offset.h"
     39
     40MODULE_FIRMWARE("amdgpu/raven_asd.bin");
     41MODULE_FIRMWARE("amdgpu/picasso_asd.bin");
     42MODULE_FIRMWARE("amdgpu/raven2_asd.bin");
     43MODULE_FIRMWARE("amdgpu/picasso_ta.bin");
     44MODULE_FIRMWARE("amdgpu/raven2_ta.bin");
     45MODULE_FIRMWARE("amdgpu/raven_ta.bin");
     46
     47static int psp_v10_0_init_microcode(struct psp_context *psp)
     48{
     49	struct amdgpu_device *adev = psp->adev;
     50	const char *chip_name;
     51	char fw_name[30];
     52	int err = 0;
     53	const struct ta_firmware_header_v1_0 *ta_hdr;
     54	DRM_DEBUG("\n");
     55
     56	switch (adev->asic_type) {
     57	case CHIP_RAVEN:
     58		if (adev->apu_flags & AMD_APU_IS_RAVEN2)
     59			chip_name = "raven2";
     60		else if (adev->apu_flags & AMD_APU_IS_PICASSO)
     61			chip_name = "picasso";
     62		else
     63			chip_name = "raven";
     64		break;
     65	default: BUG();
     66	}
     67
     68	err = psp_init_asd_microcode(psp, chip_name);
     69	if (err)
     70		goto out;
     71
     72	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name);
     73	err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev);
     74	if (err) {
     75		release_firmware(adev->psp.ta_fw);
     76		adev->psp.ta_fw = NULL;
     77		dev_info(adev->dev,
     78			 "psp v10.0: Failed to load firmware \"%s\"\n",
     79			 fw_name);
     80	} else {
     81		err = amdgpu_ucode_validate(adev->psp.ta_fw);
     82		if (err)
     83			goto out2;
     84
     85		ta_hdr = (const struct ta_firmware_header_v1_0 *)
     86				 adev->psp.ta_fw->data;
     87		adev->psp.hdcp_context.context.bin_desc.fw_version =
     88			le32_to_cpu(ta_hdr->hdcp.fw_version);
     89		adev->psp.hdcp_context.context.bin_desc.size_bytes =
     90			le32_to_cpu(ta_hdr->hdcp.size_bytes);
     91		adev->psp.hdcp_context.context.bin_desc.start_addr =
     92			(uint8_t *)ta_hdr +
     93			le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes);
     94
     95		adev->psp.dtm_context.context.bin_desc.fw_version =
     96			le32_to_cpu(ta_hdr->dtm.fw_version);
     97		adev->psp.dtm_context.context.bin_desc.size_bytes =
     98			le32_to_cpu(ta_hdr->dtm.size_bytes);
     99		adev->psp.dtm_context.context.bin_desc.start_addr =
    100			(uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr +
    101			le32_to_cpu(ta_hdr->dtm.offset_bytes);
    102
    103		adev->psp.securedisplay_context.context.bin_desc.fw_version =
    104			le32_to_cpu(ta_hdr->securedisplay.fw_version);
    105		adev->psp.securedisplay_context.context.bin_desc.size_bytes =
    106			le32_to_cpu(ta_hdr->securedisplay.size_bytes);
    107		adev->psp.securedisplay_context.context.bin_desc.start_addr =
    108			(uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr +
    109			le32_to_cpu(ta_hdr->securedisplay.offset_bytes);
    110
    111		adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version);
    112	}
    113
    114	return 0;
    115
    116out2:
    117	release_firmware(adev->psp.ta_fw);
    118	adev->psp.ta_fw = NULL;
    119out:
    120	if (err) {
    121		dev_err(adev->dev,
    122			"psp v10.0: Failed to load firmware \"%s\"\n",
    123			fw_name);
    124	}
    125
    126	return err;
    127}
    128
    129static int psp_v10_0_ring_init(struct psp_context *psp,
    130			       enum psp_ring_type ring_type)
    131{
    132	int ret = 0;
    133	struct psp_ring *ring;
    134	struct amdgpu_device *adev = psp->adev;
    135
    136	ring = &psp->km_ring;
    137
    138	ring->ring_type = ring_type;
    139
    140	/* allocate 4k Page of Local Frame Buffer memory for ring */
    141	ring->ring_size = 0x1000;
    142	ret = amdgpu_bo_create_kernel(adev, ring->ring_size, PAGE_SIZE,
    143				      AMDGPU_GEM_DOMAIN_VRAM,
    144				      &adev->firmware.rbuf,
    145				      &ring->ring_mem_mc_addr,
    146				      (void **)&ring->ring_mem);
    147	if (ret) {
    148		ring->ring_size = 0;
    149		return ret;
    150	}
    151
    152	return 0;
    153}
    154
    155static int psp_v10_0_ring_create(struct psp_context *psp,
    156				 enum psp_ring_type ring_type)
    157{
    158	int ret = 0;
    159	unsigned int psp_ring_reg = 0;
    160	struct psp_ring *ring = &psp->km_ring;
    161	struct amdgpu_device *adev = psp->adev;
    162
    163	/* Write low address of the ring to C2PMSG_69 */
    164	psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);
    165	WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_69, psp_ring_reg);
    166	/* Write high address of the ring to C2PMSG_70 */
    167	psp_ring_reg = upper_32_bits(ring->ring_mem_mc_addr);
    168	WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_70, psp_ring_reg);
    169	/* Write size of ring to C2PMSG_71 */
    170	psp_ring_reg = ring->ring_size;
    171	WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_71, psp_ring_reg);
    172	/* Write the ring initialization command to C2PMSG_64 */
    173	psp_ring_reg = ring_type;
    174	psp_ring_reg = psp_ring_reg << 16;
    175	WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64, psp_ring_reg);
    176
    177	/* There might be handshake issue with hardware which needs delay */
    178	mdelay(20);
    179
    180	/* Wait for response flag (bit 31) in C2PMSG_64 */
    181	ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64),
    182			   0x80000000, 0x8000FFFF, false);
    183
    184	return ret;
    185}
    186
    187static int psp_v10_0_ring_stop(struct psp_context *psp,
    188			       enum psp_ring_type ring_type)
    189{
    190	int ret = 0;
    191	unsigned int psp_ring_reg = 0;
    192	struct amdgpu_device *adev = psp->adev;
    193
    194	/* Write the ring destroy command to C2PMSG_64 */
    195	psp_ring_reg = 3 << 16;
    196	WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64, psp_ring_reg);
    197
    198	/* There might be handshake issue with hardware which needs delay */
    199	mdelay(20);
    200
    201	/* Wait for response flag (bit 31) in C2PMSG_64 */
    202	ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64),
    203			   0x80000000, 0x80000000, false);
    204
    205	return ret;
    206}
    207
    208static int psp_v10_0_ring_destroy(struct psp_context *psp,
    209				  enum psp_ring_type ring_type)
    210{
    211	int ret = 0;
    212	struct psp_ring *ring = &psp->km_ring;
    213	struct amdgpu_device *adev = psp->adev;
    214
    215	ret = psp_v10_0_ring_stop(psp, ring_type);
    216	if (ret)
    217		DRM_ERROR("Fail to stop psp ring\n");
    218
    219	amdgpu_bo_free_kernel(&adev->firmware.rbuf,
    220			      &ring->ring_mem_mc_addr,
    221			      (void **)&ring->ring_mem);
    222
    223	return ret;
    224}
    225
    226static int psp_v10_0_mode1_reset(struct psp_context *psp)
    227{
    228	DRM_INFO("psp mode 1 reset not supported now! \n");
    229	return -EINVAL;
    230}
    231
    232static uint32_t psp_v10_0_ring_get_wptr(struct psp_context *psp)
    233{
    234	struct amdgpu_device *adev = psp->adev;
    235
    236	return RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67);
    237}
    238
    239static void psp_v10_0_ring_set_wptr(struct psp_context *psp, uint32_t value)
    240{
    241	struct amdgpu_device *adev = psp->adev;
    242
    243	WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67, value);
    244}
    245
    246static const struct psp_funcs psp_v10_0_funcs = {
    247	.init_microcode = psp_v10_0_init_microcode,
    248	.ring_init = psp_v10_0_ring_init,
    249	.ring_create = psp_v10_0_ring_create,
    250	.ring_stop = psp_v10_0_ring_stop,
    251	.ring_destroy = psp_v10_0_ring_destroy,
    252	.mode1_reset = psp_v10_0_mode1_reset,
    253	.ring_get_wptr = psp_v10_0_ring_get_wptr,
    254	.ring_set_wptr = psp_v10_0_ring_set_wptr,
    255};
    256
    257void psp_v10_0_set_psp_funcs(struct psp_context *psp)
    258{
    259	psp->funcs = &psp_v10_0_funcs;
    260}