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; }