⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 realtime_clock.c

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
	  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 + -