int32_t cmdqRecEnablePrefetch(cmdqRecHandle handle) { if (cmdq_core_should_enable_prefetch(handle->scenario)) { /* enable prefetch */ CMDQ_VERBOSE("REC: enable prefetch\n"); cmdqRecMark(handle); return true; } CMDQ_ERR("not allow enable prefetch, scenario: %d\n", handle->scenario); return -EFAULT; }
int32_t cmdqRecReset(cmdqRecHandle handle) { if (NULL == handle) { return -EFAULT; } if (NULL != handle->pRunningTask) { cmdqRecStopLoop(handle); } handle->blockSize = 0; handle->prefetchCount = 0; handle->finalized = false; if (cmdq_core_should_enable_prefetch(handle->scenario)) { /* enable prefetch */ cmdqRecMark(handle); } return 0; }
int32_t cmdq_append_command(cmdqRecHandle handle, CMDQ_CODE_ENUM code, uint32_t argA, uint32_t argB, uint32_t argAType, uint32_t argBType) { int32_t subsys; uint32_t *pCommand; /* be careful that subsys encoding position is different among platforms */ const uint32_t subsysBit = cmdq_core_get_subsys_LSB_in_argA(); pCommand = (uint32_t *) ((uint8_t *) handle->pBuffer + handle->blockSize); if (handle->finalized) { CMDQ_ERR("Already finalized record 0x%p, cannot add more command", handle); return -EBUSY; } /* check if we have sufficient buffer size */ /* we leave a 4 instruction (4 bytes each) margin. */ if ((handle->blockSize + 32) >= handle->bufferSize) { if (0 != cmdq_rec_realloc_cmd_buffer(handle, handle->bufferSize * 2)) { return -ENOMEM; } } /* force insert MARKER if prefetch memory is full */ /* GCE deadlocks if we don't do so */ if (CMDQ_CODE_EOC != code && cmdq_core_should_enable_prefetch(handle->scenario)) { if (handle->prefetchCount >= CMDQ_MAX_PREFETCH_INSTUCTION) { CMDQ_ERR("prefetchCount(%d) > MAX_PREFETCH_INSTUCTION, force insert disable prefetch marker\n", handle->prefetchCount); /* Mark END of prefetch section */ cmdqRecDisablePrefetch(handle); /* BEGING of next prefetch section */ cmdqRecMark(handle); } else { /* prefetch enabled marker exist */ if (1 <= handle->prefetchCount) { ++handle->prefetchCount; CMDQ_VERBOSE("handle->prefetchCount: %d, %s, %d\n", handle->prefetchCount, __func__, __LINE__); } } } /* we must re-calculate current PC because we may already insert MARKER inst. */ pCommand = (uint32_t *) ((uint8_t *) handle->pBuffer + handle->blockSize); CMDQ_VERBOSE("REC: 0x%p CMD: 0x%p, op: 0x%02x, argA: 0x%08x, argB: 0x%08x\n", handle, pCommand, code, argA, argB); if (CMDQ_CODE_READ == code || CMDQ_CODE_WRITE == code || CMDQ_CODE_POLL == code){ /* Because read/write/poll have similar format, handle them together*/ return cmdq_append_wpr_command(handle, code, argA, argB, argAType, argBType); } switch (code) { case CMDQ_CODE_MOVE: *pCommand++ = argB; *pCommand++ = CMDQ_CODE_MOVE << 24 | (argA & 0xffffff); break; case CMDQ_CODE_JUMP: *pCommand++ = argB; *pCommand++ = (CMDQ_CODE_JUMP << 24) | (argA & 0x0FFFFFF); break; case CMDQ_CODE_WFE: /* bit 0-11: wait_value, 1 */ /* bit 15: to_wait, true */ /* bit 31: to_update, true */ /* bit 16-27: update_value, 0 */ *pCommand++ = ((1 << 31) | (1 << 15) | 1); *pCommand++ = (CMDQ_CODE_WFE << 24) | argA; break; case CMDQ_CODE_SET_TOKEN: /* this is actually WFE(SYNC) but with different parameter */ /* interpretation */ /* bit 15: to_wait, false */ /* bit 31: to_update, true */ /* bit 16-27: update_value, 1 */ *pCommand++ = ((1 << 31) | (1 << 16)); *pCommand++ = (CMDQ_CODE_WFE << 24) | argA; break; case CMDQ_CODE_WAIT_NO_CLEAR: /* bit 0-11: wait_value, 1 */ /* bit 15: to_wait, true */ /* bit 31: to_update, false */ *pCommand++ = ((0 << 31) | (1 << 15) | 1); *pCommand++ = (CMDQ_CODE_WFE << 24) | argA; break; case CMDQ_CODE_CLEAR_TOKEN: /* this is actually WFE(SYNC) but with different parameter */ /* interpretation */ /* bit 15: to_wait, false */ /* bit 31: to_update, true */ /* bit 16-27: update_value, 0 */ *pCommand++ = ((1 << 31) | (0 << 16)); *pCommand++ = (CMDQ_CODE_WFE << 24) | argA; break; case CMDQ_CODE_EOC: *pCommand++ = argB; *pCommand++ = (CMDQ_CODE_EOC << 24) | (argA & 0x0FFFFFF); break; case CMDQ_CODE_RAW: *pCommand++ = argB; *pCommand++ = argA; break; default: return -EFAULT; } handle->blockSize += CMDQ_INST_SIZE; return 0; }
int32_t cmdq_append_command(cmdqRecHandle handle, CMDQ_CODE_ENUM code, uint32_t argA, uint32_t argB) { int32_t subsys; uint32_t *pCommand; /* be careful that subsys encoding position is different among platforms */ const uint32_t subsysBit = cmdq_core_get_subsys_LSB_in_argA(); pCommand = (uint32_t *) ((uint8_t *) handle->pBuffer + handle->blockSize); if (handle->finalized) { CMDQ_ERR("Already finalized record 0x%p, cannot add more command", handle); return -EBUSY; } /* check if we have sufficient buffer size */ /* we leave a 4 instruction (4 bytes each) margin. */ if ((handle->blockSize + 32) >= handle->bufferSize) { if (0 != cmdq_rec_realloc_cmd_buffer(handle, handle->bufferSize * 2)) { return -ENOMEM; } } /* force insert MARKER if prefetch memory is full */ /* GCE deadlocks if we don't do so */ if (CMDQ_CODE_EOC != code && cmdq_core_should_enable_prefetch(handle->scenario)) { if (handle->prefetchCount >= CMDQ_MAX_PREFETCH_INSTUCTION) { /* Mark END of prefetch section */ cmdqRecMark(handle); /* BEGING of next prefetch section */ cmdqRecMark(handle); } else { ++handle->prefetchCount; } } /* we must re-calculate current PC because we may already insert MARKER inst. */ pCommand = (uint32_t *) ((uint8_t *) handle->pBuffer + handle->blockSize); CMDQ_VERBOSE("REC: 0x%p CMD: 0x%p, op: 0x%02x, argA: 0x%08x, argB: 0x%08x\n", handle, pCommand, code, argA, argB); switch (code) { case CMDQ_CODE_READ: /* argA is the HW register address to read from */ subsys = cmdq_subsys_from_phys_addr(argA); /* argB is the register id to read into */ /* bit 54: argB type, 1 for GPR */ *pCommand++ = argB; *pCommand++ = (CMDQ_CODE_READ << 24) | (argA & 0xffff) | ((subsys & 0x1f) << subsysBit) | (2 << 21); break; case CMDQ_CODE_MOVE: *pCommand++ = argB; *pCommand++ = CMDQ_CODE_MOVE << 24 | (argA & 0xffffff); break; case CMDQ_CODE_WRITE: subsys = cmdq_subsys_from_phys_addr(argA); if (-1 == subsys) { CMDQ_ERR("REC: Unsupported memory base address 0x%08x\n", argA); return -EFAULT; } *pCommand++ = argB; *pCommand++ = (CMDQ_CODE_WRITE << 24) | (argA & 0x0FFFF) | ((subsys & 0x01F) << subsysBit); break; case CMDQ_CODE_POLL: subsys = cmdq_subsys_from_phys_addr(argA); if (-1 == subsys) { CMDQ_ERR("REC: Unsupported memory base address 0x%08x\n", argA); return -EFAULT; } *pCommand++ = argB; *pCommand++ = (CMDQ_CODE_POLL << 24) | (argA & 0x0FFFF) | ((subsys & 0x01F) << subsysBit); break; case CMDQ_CODE_JUMP: *pCommand++ = argB; *pCommand++ = (CMDQ_CODE_JUMP << 24) | (argA & 0x0FFFFFF); break; case CMDQ_CODE_WFE: /* bit 0-11: wait_value, 1 */ /* bit 15: to_wait, true */ /* bit 31: to_update, true */ /* bit 16-27: update_value, 0 */ *pCommand++ = ((1 << 31) | (1 << 15) | 1); *pCommand++ = (CMDQ_CODE_WFE << 24) | argA; break; case CMDQ_CODE_SET_TOKEN: /* this is actually WFE(SYNC) but with different parameter */ /* interpretation */ /* bit 15: to_wait, false */ /* bit 31: to_update, true */ /* bit 16-27: update_value, 1 */ *pCommand++ = ((1 << 31) | (1 << 16)); *pCommand++ = (CMDQ_CODE_WFE << 24) | argA; break; case CMDQ_CODE_WAIT_NO_CLEAR: /* bit 0-11: wait_value, 1 */ /* bit 15: to_wait, true */ /* bit 31: to_update, false */ *pCommand++ = ((0 << 31) | (1 << 15) | 1); *pCommand++ = (CMDQ_CODE_WFE << 24) | argA; break; case CMDQ_CODE_CLEAR_TOKEN: /* this is actually WFE(SYNC) but with different parameter */ /* interpretation */ /* bit 15: to_wait, false */ /* bit 31: to_update, true */ /* bit 16-27: update_value, 0 */ *pCommand++ = ((1 << 31) | (0 << 16)); *pCommand++ = (CMDQ_CODE_WFE << 24) | argA; break; case CMDQ_CODE_EOC: *pCommand++ = argB; *pCommand++ = (CMDQ_CODE_EOC << 24) | (argA & 0x0FFFFFF); break; case CMDQ_CODE_RAW: *pCommand++ = argB; *pCommand++ = argA; break; default: return -EFAULT; } handle->blockSize += 8; return 0; }