📄 io_generic.c
字号:
void IO_send_on_bus(REQ *req){ switch (req->type) { case REQUEST: if ((req->req_type == READ_UC) || (req->req_type == WRITE_UC) || (req->req_type == SWAP_UC)) Bus_send_IO_request(req); else Bus_send_request(req); break; case REPLY: if (req->req_type == REPLY_UC) Bus_send_IO_reply(req); else Bus_send_reply(req); break; case COHE_REPLY: Bus_send_cohe_data_response(req); break; case WRITEBACK: if (req->parent != NULL) { /* * It's been changed to data response because hit by a cohe request. */ req->type = COHE_REPLY; req->req_type = REPLY_EXCL; Bus_send_cohe_data_response(req); } else Bus_send_writeback(req); break; case WRITEPURGE: Bus_send_writepurge(req); break; default: YS__errmsg(req->node, "Default case in IO_send_on_bus() line %i for req 0x%08X/0x%08X %i %i", __LINE__, req->vaddr, req->paddr, req->type, req->req_type); }}/*===========================================================================*//*===========================================================================*/void IO_get_reply(REQ *req){ IO_GENERIC *pio = PID2IO(req->node, req->src_proc); MSHR *pmshr; REQ *creq, *preq; int i, rc; for (i = 0; i < ARCH_cpus; i++) { pmshr = req->stalled_mshrs[i]; if (pmshr && pmshr->pending_cohe == req) { pmshr->pending_cohe = 0; req->stalled_mshrs[i] = 0; } } req->bus_return_time = YS__Simtime; /*-------------------------------------------------------------------------*/ creq = req; while (creq) { req->perform(creq); creq = creq->parent; } rc = 1; if (pio->reply_func != NULL) rc = pio->reply_func(req); if (rc) { if (req->prcr_req_type == READ) { IO_scoreboard_remove(pio, req); creq = req; while (creq) { preq = creq->parent; if (!req->cohe_count) YS__PoolReturnObj(&YS__ReqPool, creq); creq = preq; } } if (req->prcr_req_type == WRITE) { req->type = WRITEBACK; req->src_proc = pio->mid; req->dest_proc = ARCH_cpus + ARCH_ios; creq = req->parent; while (creq) { preq = creq->parent; if (!req->cohe_count) YS__PoolReturnObj(&YS__ReqPool, creq); creq = preq; } req->parent = NULL; req->dnext = NULL; if (pio->writebacks == NULL) pio->writebacks = req; else { creq = pio->writebacks; while (creq->dnext != NULL) creq = creq->dnext; creq->dnext = req; } if (IsNotScheduled(pio->outq_event)) schedule_event(pio->outq_event, YS__Simtime + BUS_FREQUENCY); } }}/*===========================================================================*//* Receive a cache-to-cache copy from some other master. The parent-pointer *//* points to our original request. Data always arrives before the response. *//*===========================================================================*/void IO_get_data_response(REQ* req){ req->parent->data_done = 1; YS__PoolReturnObj(&YS__ReqPool, req);}/*===========================================================================*//* Initialize scoreboard - clear counters and allocate some storage *//*===========================================================================*/void IO_scoreboard_init(IO_GENERIC *pio){ pio->scoreboard.reqs = malloc(sizeof(REQ*) * SCOREBOARD_INCREMENT); pio->scoreboard.req_count = 0; pio->scoreboard.req_max = SCOREBOARD_INCREMENT;}/*===========================================================================*//* Insert request into the scoreboard *//*===========================================================================*/void IO_scoreboard_insert(IO_GENERIC *pio, REQ *req){ if (pio->scoreboard.req_count == pio->scoreboard.req_max) { pio->scoreboard.req_max += SCOREBOARD_INCREMENT; pio->scoreboard.reqs = realloc(pio->scoreboard.reqs, sizeof(REQ*) * pio->scoreboard.req_max); } pio->scoreboard.reqs[pio->scoreboard.req_count++] = req;}/*===========================================================================*//* Lookup request by address - simple sequential search *//*===========================================================================*/REQ* IO_scoreboard_lookup(IO_GENERIC *pio, REQ *req){ int n; for (n = 0; n < pio->scoreboard.req_count; n++) if (pio->scoreboard.reqs[n]->paddr == req->paddr) return(pio->scoreboard.reqs[n]); return(NULL);}/*===========================================================================*//* Remove entry from scoreboard, match by request structure address, move *//* last entry to now empty entry. *//*===========================================================================*/void IO_scoreboard_remove(IO_GENERIC *pio, REQ *req){ int n; for (n = 0; n < pio->scoreboard.req_count; n++) if (pio->scoreboard.reqs[n] == req) { pio->scoreboard.reqs[n] = pio->scoreboard.reqs[pio->scoreboard.req_count-1]; pio->scoreboard.req_count--; return; }}/*===========================================================================*//*===========================================================================*/void IO_read_byte(REQ *req){ char *pa; pa = PageTable_lookup(req->node, req->paddr); if (pa) *(char*)(req->d.mem.buf) = *pa;}/*===========================================================================*//*===========================================================================*/void IO_read_word(REQ *req){ unsigned *pa; pa = (unsigned*)PageTable_lookup(req->node, req->paddr); if (pa) { *(unsigned*)(req->d.mem.buf) = swap_word(*pa); }}/*===========================================================================*//*===========================================================================*/void IO_read_block(REQ *req){ char *pa; pa = PageTable_lookup(req->node, req->paddr); if (pa) memcpy(req->d.mem.buf, pa, req->size);}/*===========================================================================*//*===========================================================================*/void IO_write_byte(REQ *req){ char *pa; pa = PageTable_lookup(req->node, req->paddr); if (pa) *pa = *(char*)(req->d.mem.buf);}/*===========================================================================*//*===========================================================================*/void IO_write_word(REQ *req){ unsigned *pa; pa = (unsigned*)PageTable_lookup(req->node, req->paddr); if (pa) *pa = swap_word(*(unsigned*)(req->d.mem.buf));}/*===========================================================================*//*===========================================================================*/void IO_write_block(REQ *req){ char *pa; pa = PageTable_lookup(req->node, req->paddr); if (pa) memcpy(pa, req->d.mem.buf, req->size);}void IO_empty_func(REQ *req, HIT_TYPE h){}/*===========================================================================*//*===========================================================================*/void IO_dump(IO_GENERIC *pio){ int n, index; REQ *req; YS__logmsg(pio->nodeid, "\n============ GENERIC I/O INTERFACE %i ============\n", pio->mid); YS__logmsg(pio->nodeid, "arbwaiters_count = %d\n", pio->arbwaiters_count); DumpLinkQueue("arbwaiters", &(pio->arbwaiters), 0x71, Cache_req_dump, pio->nodeid); DumpLinkQueue("cohqueue", &(pio->cohqueue), 0x71, Cache_req_dump, pio->nodeid); DumpPipeline("inpipe", pio->inpipe, 0x71, Cache_req_dump, pio->nodeid); DumpLinkQueue("inqueue", &(pio->inqueue), 0x71, Cache_req_dump, pio->nodeid); DumpPipeline("outpipe", pio->inpipe, 0x71, Cache_req_dump, pio->nodeid); DumpLinkQueue("outqueue", &(pio->outqueue), 0x71, Cache_req_dump, pio->nodeid); YS__logmsg(pio->nodeid, "inq_event scheduled: %s\n", IsScheduled(pio->inq_event) ? "yes" : "no"); YS__logmsg(pio->nodeid, "outq_event scheduled: %s\n", IsScheduled(pio->outq_event) ? "yes" : "no"); if (pio->writebacks) Cache_req_dump(pio->writebacks, 0x71, pio->nodeid); YS__logmsg(pio->nodeid, "scoreboard: req_count(%i), req_max(%d)\n", pio->scoreboard.req_count, pio->scoreboard.req_max); for (n = 0; n < pio->scoreboard.req_count; n++) Cache_req_dump(pio->scoreboard.reqs[n], 0x71, pio->nodeid);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -