void handle_buffer_data(struct cmd *cmd, uint32_t parity_enable) { uint8_t *parity_check; int rc; struct cmd_event *event; int quadrant, byte; // Has struct been initialized? if ((cmd == NULL) || (cmd->buffer_read == NULL)) return; // Check if buffer read data has returned from AFU event = cmd->buffer_read; rc = psl_get_buffer_read_data(cmd->afu_event, event->data, event->parity); if (rc == PSL_SUCCESS) { debug_msg("%s:BUFFER READ tag=0x%02x", cmd->afu_name, event->tag); for (quadrant = 0; quadrant < 4; quadrant++) { DPRINTF("DEBUG: Q%d 0x", quadrant); for (byte = 0; byte < CACHELINE_BYTES / 4; byte++) { DPRINTF("%02x", event->data[byte]); } DPRINTF("\n"); } if (parity_enable) { parity_check = (uint8_t *) malloc(DWORDS_PER_CACHELINE / 8); generate_cl_parity(event->data, parity_check); if (strncmp((char *)event->parity, (char *)parity_check, DWORDS_PER_CACHELINE / 8)) { error_msg("Buffer read parity error tag=0x%02x", event->tag); } free(parity_check); } // Free buffer interface for another event cmd->buffer_read = NULL; // Randomly decide to not send data to client yet if (!event->buffer_activity && allow_buffer(cmd->parms)) { event->state = MEM_TOUCHED; event->buffer_activity = 1; return; } event->state = MEM_RECEIVED; } }
// Handle data returning from client for memory read static void _handle_mem_read(struct cmd *cmd, struct cmd_event *event, int fd) { uint8_t data[MAX_LINE_CHARS]; uint64_t offset = event->addr & ~CACHELINE_MASK; // Client is returning data from memory read if (get_bytes_silent(fd, event->size, data, cmd->parms->timeout, event->abort) < 0) { event->resp = PSL_RESPONSE_DERROR; event->state = MEM_DONE; debug_cmd_update(cmd->dbg_fp, cmd->dbg_id, event->tag, event->context, event->resp); return; } memcpy((void *)&(event->data[offset]), (void *)&data, event->size); generate_cl_parity(event->data, event->parity); event->state = MEM_RECEIVED; }
void StoreCommand::process_buffer_read(AFU_EVENT *afu_event, uint8_t *cache_line){ uint8_t parity[2]; generate_cl_parity(cache_line, parity); if(buffer_read_parity) parity[rand() % 2] += rand() % 256; if(psl_afu_read_buffer_data(afu_event, 128, cache_line, parity) != PSL_SUCCESS){ error_msg("StoreCommand; failed to build buffer read data"); } info_msg("BUFFER_READ:"); for(int i = 0; i < CACHELINE_BYTES; ++i) { if ((i % (CACHELINE_BYTES / 4)) == 0) { if (i > 0) printf("\n"); printf(" Q%d 0x", i / (CACHELINE_BYTES / 4)); } printf("%02x", cache_line[i]); } printf("\n"); }
void LoadCommand::process_buffer_write(AFU_EVENT *afu_event, uint8_t *cache_line){ Command::state = WAITING_RESPONSE; memcpy(cache_line, afu_event->buffer_wdata, afu_event->buffer_write_length); if(afu_event->parity_enable){ uint8_t parity[2]; generate_cl_parity(cache_line, parity); for(int i = 0; i < 2; ++i) if(parity[i] != afu_event->buffer_wparity[i]) error_msg("LoadCommand: Bad parity detected in buffer write"); } info_msg("BUFFER_WRITE:"); for(int i = 0; i < CACHELINE_BYTES; ++i) { if ((i % (CACHELINE_BYTES / 4)) == 0) { if (i > 0) printf("\n"); printf(" Q%d 0x", i / (CACHELINE_BYTES / 4)); } printf("%02x", cache_line[i]); } printf("\n"); }
static void buffer_event (int rnw, uint32_t tag, uint8_t *addr) { uint8_t par[2]; if (status.psl_state==PSL_FLUSHING) { #ifdef DEBUG printf ("Response FLUSHED tag=0x%02x\n", tag); #endif /* #ifdef DEBUG */ add_resp (tag, PSL_RESPONSE_FLUSHED); return; } if (!testmemaddr (addr)) { printf ("AFU attempted "); if (rnw) printf ("write"); else printf ("read"); printf (" to invalid address 0x%016llx\n",(long long) addr); #ifdef DEBUG printf ("Response AERROR tag=0x%02x\n", tag); #endif /* #ifdef DEBUG */ add_resp (tag, PSL_RESPONSE_AERROR); status.psl_state = PSL_FLUSHING; return; } if (rnw) { #ifdef DEBUG printf ("Buffer Read tag=0x%02x\n", tag); #endif /* #ifdef DEBUG */ psl_buffer_read (status.event, tag, (uint64_t) addr, CACHELINE_BYTES); } else { #ifdef DEBUG printf ("Buffer Write tag=0x%02x\n", tag); #endif /* #ifdef DEBUG */ generate_cl_parity(addr, par); psl_buffer_write (status.event, tag, (uint64_t) addr, CACHELINE_BYTES, addr, par); ++status.credits; #ifdef DEBUG printf ("Response tag=0x%02x\n", tag); #endif /* #ifdef DEBUG */ if (status.psl_state==PSL_NLOCK) { #ifdef DEBUG printf ("Nlock response for read, tag=0x%02x\n", tag); fflush (stdout); #endif /* #ifdef DEBUG */ add_resp (tag, PSL_RESPONSE_NLOCK); } else if (!PAGED_RANDOMIZER || (rand() % PAGED_RANDOMIZER)) { // Inject random "Paged" response add_resp (tag, PSL_RESPONSE_DONE); } else { add_resp (tag, PSL_RESPONSE_PAGED); status.psl_state = PSL_FLUSHING; } } }