📄 realtime_clock.c
字号:
if ((read_bit(nid, RTC_BASE_ADDR, 17) == 0) && (prtc->old_write_bit == 1)) RTC_set(nid); prtc->old_write_bit = read_bit(nid, RTC_BASE_ADDR, 17); } if (req->paddr == RTC_STATUS) { val = read_char(nid, RTC_STATUS); if (val & 0x01) { lat = YS__Simtime - prtc->intr1_start; if (lat > prtc->intr1_lat_max) prtc->intr1_lat_max = lat; if (lat < prtc->intr1_lat_min) prtc->intr1_lat_min = lat; prtc->intr1_lat_avg += lat; } if (val & 0x02) { lat = YS__Simtime - prtc->intr2_start; if (lat > prtc->intr2_lat_max) prtc->intr2_lat_max = lat; if (lat < prtc->intr2_lat_min) prtc->intr2_lat_min = lat; prtc->intr2_lat_avg += lat; } write_char(nid, RTC_STATUS, prtc->old_status ^ val); prtc->old_status = read_char(nid, RTC_STATUS); } req = req->parent; } return(1);}/*===========================================================================*//* Periodic event function - called every 1 ms (simulator time) *//* increment counter, check if a periodic interrupt needs to be generated *//* when counter reaches 1000 (1 second), increment and update clock *//*===========================================================================*/void RTC_event(void){ REALTIME_CLOCK *prtc = (REALTIME_CLOCK*)EventGetArg(NULL); prtc->clock++; /* update clock and clock register after 1000 ms --------------------------*/ if (prtc->clock % 1000 == 0) { prtc->rt++; RTC_update(prtc->nodeid); } /* check if need to trigger interrupt 1 -----------------------------------*/ if ((((prtc->clock % 1 == 0) && read_bit(prtc->nodeid, RTC_BASE_ADDR, 8)) || ((prtc->clock % 10 == 0) && read_bit(prtc->nodeid, RTC_BASE_ADDR, 9)) || ((prtc->clock % 100 == 0) && read_bit(prtc->nodeid, RTC_BASE_ADDR, 10)) || ((prtc->clock % 1000 == 0) && read_bit(prtc->nodeid, RTC_BASE_ADDR, 11)) || ((prtc->clock % 10000 == 0) && read_bit(prtc->nodeid, RTC_BASE_ADDR, 12))) && (!read_bit(prtc->nodeid, RTC_BASE_ADDR, 24))) { prtc->old_status = 0x01; write_bit(prtc->nodeid, RTC_BASE_ADDR, 24, 1); prtc->vector1 = (unsigned)read_char(prtc->nodeid, RTC_INT1_VECTOR); prtc->intr1_count++; prtc->intr1_start = YS__Simtime; RTC_interrupt(prtc->nodeid, &prtc->vector1, read_char(prtc->nodeid, RTC_INT1_TARGET)); } /* check if need to trigger interrupt 2 -----------------------------------*/ if ((((prtc->clock % 1 == 0) && read_bit(prtc->nodeid, RTC_BASE_ADDR+4, 16)) || ((prtc->clock % 10 == 0) && read_bit(prtc->nodeid, RTC_BASE_ADDR+4, 17)) || ((prtc->clock % 100 == 0) && read_bit(prtc->nodeid, RTC_BASE_ADDR+4, 18)) || ((prtc->clock % 1000 == 0) && read_bit(prtc->nodeid, RTC_BASE_ADDR+4, 19)) || ((prtc->clock % 10000 == 0) && read_bit(prtc->nodeid, RTC_BASE_ADDR+4, 20))) && (!read_bit(prtc->nodeid, RTC_BASE_ADDR, 25))) { prtc->old_status |= 0x02; write_bit(prtc->nodeid, RTC_BASE_ADDR, 25, 1); prtc->vector2 = (unsigned)read_char(prtc->nodeid, RTC_INT2_VECTOR); prtc->intr2_count++; prtc->intr2_start = YS__Simtime; RTC_interrupt(prtc->nodeid, &prtc->vector2, read_char(prtc->nodeid, RTC_INT2_TARGET)); } /* reschedule only if CPUs are still running ------------------------------*/ if (prtc->clock % 10000 == 0) prtc->clock = 0; if (!EXIT) schedule_event(prtc->update, YS__Simtime + RTC_TICK);}/*****************************************************************************//* generate interrupt transaction to target, or to all CPUs *//*****************************************************************************/void RTC_interrupt(int nodeid, unsigned *vector, unsigned char target){ REQ* req; unsigned addr; if ((target > ARCH_cpus) && (target != 0xFF)) return; req = (REQ *) YS__PoolGetObj(&YS__ReqPool); if (target != 0xFF) /* single-CPU interrupt */ addr = SYSCONTROL_THIS_LOW(target) + SC_INTERRUPT; else addr = SYSCONTROL_LOCAL_LOW + SC_INTERRUPT; req->vaddr = addr; req->paddr = addr; req->size = 4; req->d.mem.buf = (unsigned char*)vector; req->perform = IO_write_word; req->complete = (void(*)(REQ*, HIT_TYPE))IO_empty_func; req->node = nodeid; req->src_proc = RTCs[nodeid].mid; req->dest_proc = target; req->type = REQUEST; req->req_type = WRITE_UC; req->prcr_req_type = WRITE; req->prefetch = 0; req->parent = NULL; IO_start_transaction(PID2IO(req->node, req->src_proc), req);}/*****************************************************************************//*****************************************************************************/void RTC_print_params(int nid){ REALTIME_CLOCK *prtc = &RTCs[nid]; int target, vector, mask; char str[40]; struct tm *start; YS__statmsg(nid, "Realtime Clock Configuration\n"); target = read_char(nid, RTC_INT1_TARGET); vector = read_char(nid, RTC_INT1_VECTOR); mask = read_char(nid, RTC_INT1_CNTL); if (target == 0xFF) sprintf(str, "Broadcast Interrupt"); else sprintf(str, "Interrupt CPU %i", target); if (mask != 0) { if (mask & 0x10) YS__statmsg(nid, " %s every 10 s on IRQ %i\n", str, vector); if (mask & 0x08) YS__statmsg(nid, " %s every 1 s on IRQ %i\n", str, vector); if (mask & 0x04) YS__statmsg(nid, " %s every 100 ms on IRQ %i\n", str, vector); if (mask & 0x02) YS__statmsg(nid, " %s every 10 ms on IRQ %i\n", str, vector); if (mask & 0x01) YS__statmsg(nid, " %s every 1 ms on IRQ %i\n", str, vector); } target = read_char(nid, RTC_INT2_TARGET); vector = read_char(nid, RTC_INT2_VECTOR); mask = read_char(nid, RTC_INT2_CNTL); if (target == 0xFF) sprintf(str, "Broadcast Interrupt"); else sprintf(str, "Interrupt CPU %i", target); if (mask != 0) { if (mask & 0x10) YS__statmsg(nid, " %s every 10 s on IRQ %i\n", str, vector); if (mask & 0x08) YS__statmsg(nid, " %s every 1 s on IRQ %i\n", str, vector); if (mask & 0x04) YS__statmsg(nid, " %s every 100 ms on IRQ %i\n", str, vector); if (mask & 0x02) YS__statmsg(nid, " %s every 10 ms on IRQ %i\n", str, vector); if (mask & 0x01) YS__statmsg(nid, " %s every 1 ms on IRQ %i\n", str, vector); } start = localtime(&rtc_start_time); YS__statmsg(nid, " Initial time/date: %d:%02d:%02d %i/%02d/%04d\n", start->tm_hour, start->tm_min, start->tm_sec, start->tm_mon+1, start->tm_mday, start->tm_year + 1900); YS__statmsg(nid, "\n");}void RTC_stat_report(int nid){ REALTIME_CLOCK *prtc = &RTCs[nid]; YS__statmsg(nid, "Realtime Clock Statistics\n"); if (prtc->intr1_count > 0) { prtc->intr1_lat_avg /= prtc->intr1_count; YS__statmsg(nid, " Interrupt 1:\n"); YS__statmsg(nid, " %i Interrupt%s\n", prtc->intr1_count, prtc->intr1_count == 1 ? "" : "s"); YS__statmsg(nid, " "); PrintTime(prtc->intr1_lat_min * (double)CPU_CLK_PERIOD / 1.0e12, statfile[nid]); YS__statmsg(nid, " Min Latency\n"); YS__statmsg(nid, " "); PrintTime(prtc->intr1_lat_avg * (double)CPU_CLK_PERIOD / 1.0e12, statfile[nid]); YS__statmsg(nid, " Avg Latency\n"); YS__statmsg(nid, " "); PrintTime(prtc->intr1_lat_max * (double)CPU_CLK_PERIOD / 1.0e12, statfile[nid]); YS__statmsg(nid, " Max Latency\n"); } if (prtc->intr2_count > 0) { prtc->intr2_lat_avg /= prtc->intr2_count; YS__statmsg(nid, " Interrupt 2:\n"); YS__statmsg(nid, " %i Interrupts\n", prtc->intr2_count); YS__statmsg(nid, " "); PrintTime(prtc->intr2_lat_min * (double)CPU_CLK_PERIOD / 1.0e12, statfile[nid]); YS__statmsg(nid, " Min Latency\n"); YS__statmsg(nid, " "); PrintTime(prtc->intr2_lat_avg * (double)CPU_CLK_PERIOD / 1.0e12, statfile[nid]); YS__statmsg(nid, " Avg Latency\n"); YS__statmsg(nid, " "); PrintTime(prtc->intr2_lat_max * (double)CPU_CLK_PERIOD / 1.0e12, statfile[nid]); YS__statmsg(nid, " Max Latency\n"); } YS__statmsg(nid, "\n");}void RTC_stat_clear(int nid){ RTCs[nid].intr1_count = 0; RTCs[nid].intr1_lat_max = 0.0; RTCs[nid].intr1_lat_min = MAXDOUBLE; RTCs[nid].intr1_lat_avg = 0; RTCs[nid].intr2_count = 0; RTCs[nid].intr2_lat_max = 0.0; RTCs[nid].intr2_lat_min = MAXDOUBLE; RTCs[nid].intr2_lat_avg = 0;}void RTC_dump(int nid){ REALTIME_CLOCK *prtc = &RTCs[nid]; IO_GENERIC *pio = PID2IO(nid, prtc->mid); YS__logmsg(nid, "\n============ REALTIME CLOCK ==============\n"); YS__logmsg(nid, "clock(%d), rt(%d), module(%d)\n", prtc->clock, prtc->rt, prtc->mid); YS__logmsg(nid, "status(0x%x), control(0x%x)\n", read_char(nid, RTC_STATUS), read_char(nid, RTC_CONTROL)); YS__logmsg(nid, "int1: cntl(0x%x), vector(0x%x), target(0x%x)\n", read_char(nid, RTC_INT1_CNTL), read_char(nid, RTC_INT1_VECTOR), read_char(nid, RTC_INT1_TARGET)); YS__logmsg(nid, "int2: cntl(0x%x), vector(0x%x), target(0x%x)\n", read_char(nid, RTC_INT2_CNTL), read_char(nid, RTC_INT2_VECTOR), read_char(nid, RTC_INT2_TARGET)); YS__logmsg(nid, "update scheduled: %s\n", IsScheduled(RTCs[nid].update) ? "yes" : "no"); IO_dump(pio);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -