// Handle randomly selected pending write void handle_buffer_read(struct cmd *cmd) { struct cmd_event *event; // Check that cmd struct is valid buffer read is available if ((cmd == NULL) || (cmd->buffer_read != NULL)) return; // Randomly select a pending write (or none) event = cmd->list; while (event != NULL) { if ((event->type == CMD_WRITE) && (event->state == MEM_TOUCHED) && ((event->client_state != CLIENT_VALID) || !allow_reorder(cmd->parms))) { break; } event = event->_next; } // Test for client disconnect if ((event == NULL) || (_get_client(cmd, event) == NULL)) return; // Send buffer read request to AFU. Setting cmd->buffer_read // will block any more buffer read requests until buffer read // data is returned and handled in handle_buffer_data(). if (psl_buffer_read(cmd->afu_event, event->tag, event->addr, CACHELINE_BYTES) == PSL_SUCCESS) { cmd->buffer_read = event; debug_cmd_buffer_read(cmd->dbg_fp, cmd->dbg_id, event->tag); event->state = MEM_BUFFER; } }
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; } } }