Beispiel #1
0
void payload_pack( midi_payload_t *payload, unsigned char **buffer, size_t *buffer_size)
{
	uint8_t temp_header = 0;
	unsigned char *p = NULL;

	*buffer = NULL;
	*buffer_size = 0;

	if( ! payload ) return;

	if( ! payload->buffer ) return;
	if( ! payload->header ) return;

	payload_dump( payload );

	*buffer_size = 1 + payload->header->len + (payload->header->len > 15 ? 1 : 0);
	*buffer = (unsigned char *)malloc( *buffer_size );

	if( ! *buffer ) return;

	p = *buffer;

	if( payload->header->B) temp_header |= PAYLOAD_HEADER_B;
	if( payload->header->J) temp_header |= PAYLOAD_HEADER_J;
	if( payload->header->Z) temp_header |= PAYLOAD_HEADER_Z;
	if( payload->header->P) temp_header |= PAYLOAD_HEADER_P;

	*p = temp_header;

	if( payload->header->len <= 15 )
	{
		*p |= ( payload->header->len & 0x0f );
		p++;
	} else {
		temp_header |= (payload->header->len & 0x0f00 ) >> 8;
		*p = temp_header;
		p++;
		*p =  (payload->header->len & 0x00ff);
		p++;
	}

	memcpy( p, payload->buffer, payload->header->len );
}
/**
 * @brief Parse a base_jd_replay_payload provided by userspace
 *
 * This will read the payload from userspace, and parse the job chains.
 *
 * @param[in] kctx         Context pointer
 * @param[in] replay_atom  Replay soft job atom
 * @param[in] t_atom       Atom to use for tiler jobs
 * @param[in] f_atom       Atom to use for fragment jobs
 * @return 0 on success, error code on failure
 */
static int kbasep_replay_parse_payload(struct kbase_context *kctx,
					      struct kbase_jd_atom *replay_atom,
					      struct base_jd_atom_v2 *t_atom,
					      struct base_jd_atom_v2 *f_atom)
{
	base_jd_replay_payload *payload;
	u64 next;
	u64 prev_jc = 0;
	u16 hw_job_id_offset = 0;
	int ret = -EINVAL;
	struct kbase_vmap_struct map;

	dev_dbg(kctx->kbdev->dev, "kbasep_replay_parse_payload: replay_atom->jc = %llx sizeof(payload) = %zu\n",
			replay_atom->jc, sizeof(payload));

	payload = kbase_vmap(kctx, replay_atom->jc, sizeof(*payload), &map);

	if (!payload) {
		dev_err(kctx->kbdev->dev, "kbasep_replay_parse_payload: failed to map payload into kernel space\n");
		return -EINVAL;
	}

#ifdef CONFIG_MALI_DEBUG
	dev_dbg(kctx->kbdev->dev, "kbasep_replay_parse_payload: payload=%p\n", payload);
	dev_dbg(kctx->kbdev->dev, "Payload structure:\n"
				  "tiler_jc_list            = %llx\n"
				  "fragment_jc              = %llx\n"
				  "tiler_heap_free          = %llx\n"
				  "fragment_hierarchy_mask  = %x\n"
				  "tiler_hierarchy_mask     = %x\n"
				  "hierarchy_default_weight = %x\n"
				  "tiler_core_req           = %x\n"
				  "fragment_core_req        = %x\n",
							payload->tiler_jc_list,
							  payload->fragment_jc,
						      payload->tiler_heap_free,
					      payload->fragment_hierarchy_mask,
						 payload->tiler_hierarchy_mask,
					     payload->hierarchy_default_weight,
						       payload->tiler_core_req,
						   payload->fragment_core_req);
	payload_dump(kctx, payload);
#endif

	t_atom->core_req = payload->tiler_core_req | BASEP_JD_REQ_EVENT_NEVER;
	f_atom->core_req = payload->fragment_core_req | BASEP_JD_REQ_EVENT_NEVER;

	/* Sanity check core requirements*/
	if ((t_atom->core_req & BASEP_JD_REQ_ATOM_TYPE &
			       ~BASE_JD_REQ_COHERENT_GROUP) != BASE_JD_REQ_T ||
	    (f_atom->core_req & BASEP_JD_REQ_ATOM_TYPE &
			      ~BASE_JD_REQ_COHERENT_GROUP) != BASE_JD_REQ_FS ||
	     t_atom->core_req & BASE_JD_REQ_EXTERNAL_RESOURCES ||
	     f_atom->core_req & BASE_JD_REQ_EXTERNAL_RESOURCES) {
		dev_err(kctx->kbdev->dev, "Invalid core requirements\n");
		goto out;
	}

	/* Process tiler job chains */
	next = payload->tiler_jc_list;
	if (!next) {
		dev_err(kctx->kbdev->dev, "Invalid tiler JC list\n");
		goto out;
	}

	while (next) {
		base_jd_replay_jc *jc_struct;
		struct kbase_vmap_struct jc_map;
		u64 jc;

		jc_struct = kbase_vmap(kctx, next, sizeof(*jc_struct), &jc_map);

		if (!jc_struct) {
			dev_err(kctx->kbdev->dev, "Failed to map jc struct\n");
			goto out;
		}

		jc = jc_struct->jc;
		next = jc_struct->next;
		if (next)
			jc_struct->jc = 0;

		kbase_vunmap(kctx, &jc_map);

		if (jc) {
			u16 max_hw_job_id = 0;

			if (kbasep_replay_find_hw_job_id(kctx, jc,
					&max_hw_job_id) != 0)
				goto out;

			if (kbasep_replay_parse_jc(kctx, jc, prev_jc,
					payload->tiler_heap_free,
					payload->tiler_hierarchy_mask,
					payload->hierarchy_default_weight,
					hw_job_id_offset, false) != 0) {
				goto out;
			}

			hw_job_id_offset += max_hw_job_id;

			prev_jc = jc;
		}
	}
	t_atom->jc = prev_jc;

	/* Process fragment job chain */
	f_atom->jc = payload->fragment_jc;
	if (kbasep_replay_parse_jc(kctx, payload->fragment_jc, 0,
			payload->tiler_heap_free,
			payload->fragment_hierarchy_mask,
			payload->hierarchy_default_weight, 0,
			true) != 0) {
		goto out;
	}

	if (!t_atom->jc || !f_atom->jc) {
		dev_err(kctx->kbdev->dev, "Invalid payload\n");
		goto out;
	}

	dev_dbg(kctx->kbdev->dev, "t_atom->jc=%llx f_atom->jc=%llx\n",
			t_atom->jc, f_atom->jc);
	ret = 0;

out:
	kbase_vunmap(kctx, &map);

	return ret;
}