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

test-drm_dp_mst_helper.c (6805B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Test cases for for the DRM DP MST helpers
      4 */
      5
      6#define PREFIX_STR "[drm_dp_mst_helper]"
      7
      8#include <linux/random.h>
      9
     10#include <drm/display/drm_dp_mst_helper.h>
     11#include <drm/drm_print.h>
     12
     13#include "../display/drm_dp_mst_topology_internal.h"
     14#include "test-drm_modeset_common.h"
     15
     16int igt_dp_mst_calc_pbn_mode(void *ignored)
     17{
     18	int pbn, i;
     19	const struct {
     20		int rate;
     21		int bpp;
     22		int expected;
     23		bool dsc;
     24	} test_params[] = {
     25		{ 154000, 30, 689, false },
     26		{ 234000, 30, 1047, false },
     27		{ 297000, 24, 1063, false },
     28		{ 332880, 24, 50, true },
     29		{ 324540, 24, 49, true },
     30	};
     31
     32	for (i = 0; i < ARRAY_SIZE(test_params); i++) {
     33		pbn = drm_dp_calc_pbn_mode(test_params[i].rate,
     34					   test_params[i].bpp,
     35					   test_params[i].dsc);
     36		FAIL(pbn != test_params[i].expected,
     37		     "Expected PBN %d for clock %d bpp %d, got %d\n",
     38		     test_params[i].expected, test_params[i].rate,
     39		     test_params[i].bpp, pbn);
     40	}
     41
     42	return 0;
     43}
     44
     45static bool
     46sideband_msg_req_equal(const struct drm_dp_sideband_msg_req_body *in,
     47		       const struct drm_dp_sideband_msg_req_body *out)
     48{
     49	const struct drm_dp_remote_i2c_read_tx *txin, *txout;
     50	int i;
     51
     52	if (in->req_type != out->req_type)
     53		return false;
     54
     55	switch (in->req_type) {
     56	/*
     57	 * Compare struct members manually for request types which can't be
     58	 * compared simply using memcmp(). This is because said request types
     59	 * contain pointers to other allocated structs
     60	 */
     61	case DP_REMOTE_I2C_READ:
     62#define IN in->u.i2c_read
     63#define OUT out->u.i2c_read
     64		if (IN.num_bytes_read != OUT.num_bytes_read ||
     65		    IN.num_transactions != OUT.num_transactions ||
     66		    IN.port_number != OUT.port_number ||
     67		    IN.read_i2c_device_id != OUT.read_i2c_device_id)
     68			return false;
     69
     70		for (i = 0; i < IN.num_transactions; i++) {
     71			txin = &IN.transactions[i];
     72			txout = &OUT.transactions[i];
     73
     74			if (txin->i2c_dev_id != txout->i2c_dev_id ||
     75			    txin->no_stop_bit != txout->no_stop_bit ||
     76			    txin->num_bytes != txout->num_bytes ||
     77			    txin->i2c_transaction_delay !=
     78			    txout->i2c_transaction_delay)
     79				return false;
     80
     81			if (memcmp(txin->bytes, txout->bytes,
     82				   txin->num_bytes) != 0)
     83				return false;
     84		}
     85		break;
     86#undef IN
     87#undef OUT
     88
     89	case DP_REMOTE_DPCD_WRITE:
     90#define IN in->u.dpcd_write
     91#define OUT out->u.dpcd_write
     92		if (IN.dpcd_address != OUT.dpcd_address ||
     93		    IN.num_bytes != OUT.num_bytes ||
     94		    IN.port_number != OUT.port_number)
     95			return false;
     96
     97		return memcmp(IN.bytes, OUT.bytes, IN.num_bytes) == 0;
     98#undef IN
     99#undef OUT
    100
    101	case DP_REMOTE_I2C_WRITE:
    102#define IN in->u.i2c_write
    103#define OUT out->u.i2c_write
    104		if (IN.port_number != OUT.port_number ||
    105		    IN.write_i2c_device_id != OUT.write_i2c_device_id ||
    106		    IN.num_bytes != OUT.num_bytes)
    107			return false;
    108
    109		return memcmp(IN.bytes, OUT.bytes, IN.num_bytes) == 0;
    110#undef IN
    111#undef OUT
    112
    113	default:
    114		return memcmp(in, out, sizeof(*in)) == 0;
    115	}
    116
    117	return true;
    118}
    119
    120static bool
    121sideband_msg_req_encode_decode(struct drm_dp_sideband_msg_req_body *in)
    122{
    123	struct drm_dp_sideband_msg_req_body *out;
    124	struct drm_printer p = drm_err_printer(PREFIX_STR);
    125	struct drm_dp_sideband_msg_tx *txmsg;
    126	int i, ret;
    127	bool result = true;
    128
    129	out = kzalloc(sizeof(*out), GFP_KERNEL);
    130	if (!out)
    131		return false;
    132
    133	txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
    134	if (!txmsg) {
    135		kfree(out);
    136		return false;
    137	}
    138
    139	drm_dp_encode_sideband_req(in, txmsg);
    140	ret = drm_dp_decode_sideband_req(txmsg, out);
    141	if (ret < 0) {
    142		drm_printf(&p, "Failed to decode sideband request: %d\n",
    143			   ret);
    144		result = false;
    145		goto out;
    146	}
    147
    148	if (!sideband_msg_req_equal(in, out)) {
    149		drm_printf(&p, "Encode/decode failed, expected:\n");
    150		drm_dp_dump_sideband_msg_req_body(in, 1, &p);
    151		drm_printf(&p, "Got:\n");
    152		drm_dp_dump_sideband_msg_req_body(out, 1, &p);
    153		result = false;
    154		goto out;
    155	}
    156
    157	switch (in->req_type) {
    158	case DP_REMOTE_DPCD_WRITE:
    159		kfree(out->u.dpcd_write.bytes);
    160		break;
    161	case DP_REMOTE_I2C_READ:
    162		for (i = 0; i < out->u.i2c_read.num_transactions; i++)
    163			kfree(out->u.i2c_read.transactions[i].bytes);
    164		break;
    165	case DP_REMOTE_I2C_WRITE:
    166		kfree(out->u.i2c_write.bytes);
    167		break;
    168	}
    169
    170	/* Clear everything but the req_type for the input */
    171	memset(&in->u, 0, sizeof(in->u));
    172
    173out:
    174	kfree(out);
    175	kfree(txmsg);
    176	return result;
    177}
    178
    179int igt_dp_mst_sideband_msg_req_decode(void *unused)
    180{
    181	struct drm_dp_sideband_msg_req_body in = { 0 };
    182	u8 data[] = { 0xff, 0x0, 0xdd };
    183	int i;
    184
    185#define DO_TEST() FAIL_ON(!sideband_msg_req_encode_decode(&in))
    186
    187	in.req_type = DP_ENUM_PATH_RESOURCES;
    188	in.u.port_num.port_number = 5;
    189	DO_TEST();
    190
    191	in.req_type = DP_POWER_UP_PHY;
    192	in.u.port_num.port_number = 5;
    193	DO_TEST();
    194
    195	in.req_type = DP_POWER_DOWN_PHY;
    196	in.u.port_num.port_number = 5;
    197	DO_TEST();
    198
    199	in.req_type = DP_ALLOCATE_PAYLOAD;
    200	in.u.allocate_payload.number_sdp_streams = 3;
    201	for (i = 0; i < in.u.allocate_payload.number_sdp_streams; i++)
    202		in.u.allocate_payload.sdp_stream_sink[i] = i + 1;
    203	DO_TEST();
    204	in.u.allocate_payload.port_number = 0xf;
    205	DO_TEST();
    206	in.u.allocate_payload.vcpi = 0x7f;
    207	DO_TEST();
    208	in.u.allocate_payload.pbn = U16_MAX;
    209	DO_TEST();
    210
    211	in.req_type = DP_QUERY_PAYLOAD;
    212	in.u.query_payload.port_number = 0xf;
    213	DO_TEST();
    214	in.u.query_payload.vcpi = 0x7f;
    215	DO_TEST();
    216
    217	in.req_type = DP_REMOTE_DPCD_READ;
    218	in.u.dpcd_read.port_number = 0xf;
    219	DO_TEST();
    220	in.u.dpcd_read.dpcd_address = 0xfedcb;
    221	DO_TEST();
    222	in.u.dpcd_read.num_bytes = U8_MAX;
    223	DO_TEST();
    224
    225	in.req_type = DP_REMOTE_DPCD_WRITE;
    226	in.u.dpcd_write.port_number = 0xf;
    227	DO_TEST();
    228	in.u.dpcd_write.dpcd_address = 0xfedcb;
    229	DO_TEST();
    230	in.u.dpcd_write.num_bytes = ARRAY_SIZE(data);
    231	in.u.dpcd_write.bytes = data;
    232	DO_TEST();
    233
    234	in.req_type = DP_REMOTE_I2C_READ;
    235	in.u.i2c_read.port_number = 0xf;
    236	DO_TEST();
    237	in.u.i2c_read.read_i2c_device_id = 0x7f;
    238	DO_TEST();
    239	in.u.i2c_read.num_transactions = 3;
    240	in.u.i2c_read.num_bytes_read = ARRAY_SIZE(data) * 3;
    241	for (i = 0; i < in.u.i2c_read.num_transactions; i++) {
    242		in.u.i2c_read.transactions[i].bytes = data;
    243		in.u.i2c_read.transactions[i].num_bytes = ARRAY_SIZE(data);
    244		in.u.i2c_read.transactions[i].i2c_dev_id = 0x7f & ~i;
    245		in.u.i2c_read.transactions[i].i2c_transaction_delay = 0xf & ~i;
    246	}
    247	DO_TEST();
    248
    249	in.req_type = DP_REMOTE_I2C_WRITE;
    250	in.u.i2c_write.port_number = 0xf;
    251	DO_TEST();
    252	in.u.i2c_write.write_i2c_device_id = 0x7f;
    253	DO_TEST();
    254	in.u.i2c_write.num_bytes = ARRAY_SIZE(data);
    255	in.u.i2c_write.bytes = data;
    256	DO_TEST();
    257
    258	in.req_type = DP_QUERY_STREAM_ENC_STATUS;
    259	in.u.enc_status.stream_id = 1;
    260	DO_TEST();
    261	get_random_bytes(in.u.enc_status.client_id,
    262			 sizeof(in.u.enc_status.client_id));
    263	DO_TEST();
    264	in.u.enc_status.stream_event = 3;
    265	DO_TEST();
    266	in.u.enc_status.valid_stream_event = 0;
    267	DO_TEST();
    268	in.u.enc_status.stream_behavior = 3;
    269	DO_TEST();
    270	in.u.enc_status.valid_stream_behavior = 1;
    271	DO_TEST();
    272
    273#undef DO_TEST
    274	return 0;
    275}