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

📄 interrupts.c

📁 gdb-6.0 linux 下的调试工具
💻 C
📖 第 1 页 / 共 2 页
字号:
     the interrupts before setting the new ones.  */  interrupts->pending_mask &= ~clear_mask;  interrupts->pending_mask |= set_mask;  /* Keep track of when the interrupt is raised by the device.     Also implements the breakpoint-on-interrupt.  */  if (set_mask)    {      signed64 cycle = cpu_current_cycle (interrupts->cpu);      int must_stop = 0;            for (i = 0; i < M6811_INT_NUMBER; i++)        {          if (!(set_mask & (1 << i)))            continue;          interrupts->interrupts[i].cpu_cycle = cycle;          if (interrupts->interrupts[i].stop_mode & SIM_STOP_WHEN_RAISED)            {              must_stop = 1;              sim_io_printf (CPU_STATE (interrupts->cpu),                             "Interrupt %s raised\n",                             interrupt_names[i]);            }        }      if (must_stop)        sim_engine_halt (CPU_STATE (interrupts->cpu),                         interrupts->cpu,                         0, cpu_get_pc (interrupts->cpu),                         sim_stopped,                         SIM_SIGTRAP);    }}/* Finds the current active and non-masked interrupt.   Returns the interrupt number (index in the vector table) or -1   if no interrupt can be serviced.  */intinterrupts_get_current (struct interrupts *interrupts){  int i;    if (interrupts->pending_mask == 0)    return -1;  /* SWI and illegal instructions are simulated by an interrupt.     They are not maskable.  */  if (interrupts->pending_mask & (1 << M6811_INT_SWI))    {      interrupts->pending_mask &= ~(1 << M6811_INT_SWI);      return M6811_INT_SWI;    }  if (interrupts->pending_mask & (1 << M6811_INT_ILLEGAL))    {      interrupts->pending_mask &= ~(1 << M6811_INT_ILLEGAL);      return M6811_INT_ILLEGAL;    }    /* If there is a non maskable interrupt, go for it (unless we are masked     by the X-bit.  */  if (interrupts->pending_mask & (1 << M6811_INT_XIRQ))    {      if (cpu_get_ccr_X (interrupts->cpu) == 0)	{	  interrupts->pending_mask &= ~(1 << M6811_INT_XIRQ);	  return M6811_INT_XIRQ;	}      return -1;    }  /* Interrupts are masked, do nothing.  */  if (cpu_get_ccr_I (interrupts->cpu) == 1)    {      return -1;    }  /* Returns the first interrupt number which is pending.     The interrupt priority is specified by the table `interrupt_order'.     For these interrupts, the pending mask is cleared when the program     performs some actions on the corresponding device.  If the device     is not reset, the interrupt remains and will be re-raised when     we return from the interrupt (see 68HC11 pink book).  */  for (i = 0; i < M6811_INT_NUMBER; i++)    {      enum M6811_INT int_number = interrupts->interrupt_order[i];      if (interrupts->pending_mask & (1 << int_number))	{	  return int_number;	}    }  return -1;}/* Process the current interrupt if there is one.  This operation must   be called after each instruction to handle the interrupts.  If interrupts   are masked, it does nothing.  */intinterrupts_process (struct interrupts *interrupts){  int id;  uint8 ccr;  /* See if interrupts are enabled/disabled and keep track of the     number of cycles the interrupts are masked.  Such information is     then reported by the info command.  */  ccr = cpu_get_ccr (interrupts->cpu);  if (ccr & M6811_I_BIT)    {      if (interrupts->start_mask_cycle < 0)        interrupts->start_mask_cycle = cpu_current_cycle (interrupts->cpu);    }  else if (interrupts->start_mask_cycle >= 0           && (ccr & M6811_I_BIT) == 0)    {      signed64 t = cpu_current_cycle (interrupts->cpu);      t -= interrupts->start_mask_cycle;      if (t < interrupts->min_mask_cycles)        interrupts->min_mask_cycles = t;      if (t > interrupts->max_mask_cycles)        interrupts->max_mask_cycles = t;      interrupts->start_mask_cycle = -1;      interrupts->last_mask_cycles = t;    }  if (ccr & M6811_X_BIT)    {      if (interrupts->xirq_start_mask_cycle < 0)        interrupts->xirq_start_mask_cycle	  = cpu_current_cycle (interrupts->cpu);    }  else if (interrupts->xirq_start_mask_cycle >= 0           && (ccr & M6811_X_BIT) == 0)    {      signed64 t = cpu_current_cycle (interrupts->cpu);      t -= interrupts->xirq_start_mask_cycle;      if (t < interrupts->xirq_min_mask_cycles)        interrupts->xirq_min_mask_cycles = t;      if (t > interrupts->xirq_max_mask_cycles)        interrupts->xirq_max_mask_cycles = t;      interrupts->xirq_start_mask_cycle = -1;      interrupts->xirq_last_mask_cycles = t;    }  id = interrupts_get_current (interrupts);  if (id >= 0)    {      uint16 addr;      struct interrupt_history *h;      /* Implement the breakpoint-on-interrupt.  */      if (interrupts->interrupts[id].stop_mode & SIM_STOP_WHEN_TAKEN)        {          sim_io_printf (CPU_STATE (interrupts->cpu),                         "Interrupt %s will be handled\n",                         interrupt_names[id]);          sim_engine_halt (CPU_STATE (interrupts->cpu),                           interrupts->cpu,                           0, cpu_get_pc (interrupts->cpu),                           sim_stopped,                           SIM_SIGTRAP);        }      cpu_push_all (interrupts->cpu);      addr = memory_read16 (interrupts->cpu,                            interrupts->vectors_addr + id * 2);      cpu_call (interrupts->cpu, addr);      /* Now, protect from nested interrupts.  */      if (id == M6811_INT_XIRQ)	{	  cpu_set_ccr_X (interrupts->cpu, 1);	}      else	{	  cpu_set_ccr_I (interrupts->cpu, 1);	}      /* Update the interrupt history table.  */      h = &interrupts->interrupts_history[interrupts->history_index];      h->type = id;      h->taken_cycle = cpu_current_cycle (interrupts->cpu);      h->raised_cycle = interrupts->interrupts[id].cpu_cycle;            if (interrupts->history_index >= MAX_INT_HISTORY-1)        interrupts->history_index = 0;      else        interrupts->history_index++;      interrupts->nb_interrupts_raised++;      cpu_add_cycles (interrupts->cpu, 14);      return 1;    }  return 0;}voidinterrupts_raise (struct interrupts *interrupts, enum M6811_INT number){  interrupts->pending_mask |= (1 << number);  interrupts->nb_interrupts_raised ++;}voidinterrupts_info (SIM_DESC sd, struct interrupts *interrupts){  signed64 t, prev_interrupt;  int i;    sim_io_printf (sd, "Interrupts Info:\n");  sim_io_printf (sd, "  Interrupts raised: %lu\n",                 interrupts->nb_interrupts_raised);  if (interrupts->start_mask_cycle >= 0)    {      t = cpu_current_cycle (interrupts->cpu);      t -= interrupts->start_mask_cycle;      if (t > interrupts->max_mask_cycles)        interrupts->max_mask_cycles = t;      sim_io_printf (sd, "  Current interrupts masked sequence:   %s\n",                     cycle_to_string (interrupts->cpu, t,                                      PRINT_TIME | PRINT_CYCLE));    }  t = interrupts->min_mask_cycles == CYCLES_MAX ?    interrupts->max_mask_cycles :    interrupts->min_mask_cycles;  sim_io_printf (sd, "  Shortest interrupts masked sequence:  %s\n",                 cycle_to_string (interrupts->cpu, t,                                  PRINT_TIME | PRINT_CYCLE));  t = interrupts->max_mask_cycles;  sim_io_printf (sd, "  Longest interrupts masked sequence:   %s\n",                 cycle_to_string (interrupts->cpu, t,                                  PRINT_TIME | PRINT_CYCLE));  t = interrupts->last_mask_cycles;  sim_io_printf (sd, "  Last interrupts masked sequence:      %s\n",                 cycle_to_string (interrupts->cpu, t,                                  PRINT_TIME | PRINT_CYCLE));    if (interrupts->xirq_start_mask_cycle >= 0)    {      t = cpu_current_cycle (interrupts->cpu);      t -= interrupts->xirq_start_mask_cycle;      if (t > interrupts->xirq_max_mask_cycles)        interrupts->xirq_max_mask_cycles = t;      sim_io_printf (sd, "  XIRQ Current interrupts masked sequence: %s\n",                     cycle_to_string (interrupts->cpu, t,                                      PRINT_TIME | PRINT_CYCLE));    }  t = interrupts->xirq_min_mask_cycles == CYCLES_MAX ?    interrupts->xirq_max_mask_cycles :    interrupts->xirq_min_mask_cycles;  sim_io_printf (sd, "  XIRQ Min interrupts masked sequence:  %s\n",                 cycle_to_string (interrupts->cpu, t,                                  PRINT_TIME | PRINT_CYCLE));  t = interrupts->xirq_max_mask_cycles;  sim_io_printf (sd, "  XIRQ Max interrupts masked sequence:  %s\n",                 cycle_to_string (interrupts->cpu, t,                                  PRINT_TIME | PRINT_CYCLE));  t = interrupts->xirq_last_mask_cycles;  sim_io_printf (sd, "  XIRQ Last interrupts masked sequence: %s\n",                 cycle_to_string (interrupts->cpu, t,                                  PRINT_TIME | PRINT_CYCLE));  if (interrupts->pending_mask)    {      sim_io_printf (sd, "  Pending interrupts : ");      for (i = 0; i < M6811_INT_NUMBER; i++)        {          enum M6811_INT int_number = interrupts->interrupt_order[i];                    if (interrupts->pending_mask & (1 << int_number))            {              sim_io_printf (sd, "%s ", interrupt_names[int_number]);            }        }      sim_io_printf (sd, "\n");    }  prev_interrupt = 0;  sim_io_printf (sd, "N  Interrupt     Cycle Taken         Latency"                 "   Delta between interrupts\n");  for (i = 0; i < MAX_INT_HISTORY; i++)    {      int which;      struct interrupt_history *h;      signed64 dt;      which = interrupts->history_index - i - 1;      if (which < 0)        which += MAX_INT_HISTORY;      h = &interrupts->interrupts_history[which];      if (h->taken_cycle == 0)        break;      dt = h->taken_cycle - h->raised_cycle;      sim_io_printf (sd, "%2d %-9.9s %15.15s ", i,                     interrupt_names[h->type],                     cycle_to_string (interrupts->cpu, h->taken_cycle, 0));      sim_io_printf (sd, "%15.15s",                     cycle_to_string (interrupts->cpu, dt, 0));      if (prev_interrupt)        {          dt = prev_interrupt - h->taken_cycle;          sim_io_printf (sd, " %s",                         cycle_to_string (interrupts->cpu, dt, PRINT_TIME));        }      sim_io_printf (sd, "\n");      prev_interrupt = h->taken_cycle;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -