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

📄 hw_opic.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
  if (timer->inhibited)    reg = timer->count; /* stalled value */  else    reg = timer->count - device_event_queue_time(me); /* time remaining */  DTRACE(opic, ("timer %d current count register - read 0x%x\n", index, reg));  return reg;}static unsigneddo_timer_N_base_count_register_read(device *me,				    hw_opic_device *opic,				    int index){  opic_timer *timer = &opic->timer[index];  unsigned reg;  ASSERT(index >= 0 && index < opic->nr_timer_interrupts);  reg = timer->base_count;  DTRACE(opic, ("timer %d base count register - read 0x%x\n", index, reg));  return reg;}static voidtimer_event(void *data){  opic_timer *timer = data;  device *me = timer->me;  if (timer->inhibited)    device_error(timer->me, "internal-error - timer event occured when timer %d inhibited",		 timer->nr);  handle_interrupt(timer->me, timer->opic, timer->interrupt_source, 1);  timer->timeout_event = device_event_queue_schedule(me, timer->base_count,						     timer_event, timer);  DTRACE(opic, ("timer %d - interrupt at %ld, next at %d\n",		timer->nr, (long)device_event_queue_time(me), timer->base_count));}static voiddo_timer_N_base_count_register_write(device *me,				     hw_opic_device *opic,				     int index,				     unsigned reg){  opic_timer *timer = &opic->timer[index];  int inhibit;  ASSERT(index >= 0 && index < opic->nr_timer_interrupts);  inhibit = reg & 0x80000000;  if (timer->inhibited && !inhibit) {    timer->inhibited = 0;    if (timer->timeout_event != NULL)      device_event_queue_deschedule(me, timer->timeout_event);    timer->count = device_event_queue_time(me) + reg;    timer->base_count = reg;    timer->timeout_event = device_event_queue_schedule(me, timer->base_count,						       timer_event, (void*)timer);    DTRACE(opic, ("timer %d base count register - write 0x%x - timer started\n",		  index, reg));  }  else if (!timer->inhibited && inhibit) {    if (timer->timeout_event != NULL)      device_event_queue_deschedule(me, timer->timeout_event);    timer->count = timer->count - device_event_queue_time(me);    timer->inhibited = 1;    timer->base_count = reg;    DTRACE(opic, ("timer %d base count register - write 0x%x - timer stopped\n",		  index, reg));  }  else {    ASSERT((timer->inhibited && inhibit) || (!timer->inhibited && !inhibit));    DTRACE(opic, ("timer %d base count register - write 0x%x\n", index, reg));    timer->base_count = reg;  }}static unsigneddo_timer_N_vector_priority_register_read(device *me,					 hw_opic_device *opic,					 int index){  unsigned reg;  ASSERT(index >= 0 && index < opic->nr_timer_interrupts);  reg = read_vector_priority_register(me, opic,				      &opic->timer_interrupt_source[index],				      "timer", index);  return reg;}static voiddo_timer_N_vector_priority_register_write(device *me,					  hw_opic_device *opic,					  int index,					  unsigned reg){  ASSERT(index >= 0 && index < opic->nr_timer_interrupts);  reg &= ~isu_level_triggered_bit; /* force edge trigger */  reg |= isu_positive_polarity_bit; /* force rising (positive) edge */  reg |= isu_multicast_bit; /* force multicast */  write_vector_priority_register(me, opic,				 &opic->timer_interrupt_source[index],				 reg, "timer", index);}static unsigneddo_timer_N_destination_register_read(device *me,				     hw_opic_device *opic,				     int index){  unsigned reg;  ASSERT(index >= 0 && index < opic->nr_timer_interrupts);  reg = read_destination_register(me, opic, &opic->timer_interrupt_source[index],				  "timer", index);  return reg;}static voiddo_timer_N_destination_register_write(device *me,				      hw_opic_device *opic,				      int index,				      unsigned reg){  ASSERT(index >= 0 && index < opic->nr_timer_interrupts);  write_destination_register(me, opic, &opic->timer_interrupt_source[index],			     reg, "timer", index);}/* IPI registers */static unsigneddo_ipi_N_vector_priority_register_read(device *me,				       hw_opic_device *opic,				       int index){  unsigned reg;  ASSERT(index >= 0 && index < opic->nr_interprocessor_interrupts);  reg = read_vector_priority_register(me, opic,				      &opic->interprocessor_interrupt_source[index],				      "ipi", index);  return reg;}static voiddo_ipi_N_vector_priority_register_write(device *me,					hw_opic_device *opic,					int index,					unsigned reg){  ASSERT(index >= 0 && index < opic->nr_interprocessor_interrupts);  reg &= ~isu_level_triggered_bit; /* force edge trigger */  reg |= isu_positive_polarity_bit; /* force rising (positive) edge */  reg |= isu_multicast_bit; /* force a multicast source */  write_vector_priority_register(me, opic,				 &opic->interprocessor_interrupt_source[index],				 reg, "ipi", index);}static voiddo_ipi_N_dispatch_register_write(device *me,				 hw_opic_device *opic,				 int index,				 unsigned reg){  opic_interrupt_source *source = &opic->interprocessor_interrupt_source[index];  ASSERT(index >= 0 && index < opic->nr_interprocessor_interrupts);  DTRACE(opic, ("ipi %d interrupt dispatch register - write 0x%x\n", index, reg));  source->destination = reg;  handle_interrupt(me, opic, source, 1);}/* vendor and other global registers */static unsigneddo_vendor_identification_register_read(device *me,				       hw_opic_device *opic){  unsigned reg;  reg = opic->vendor_identification;  DTRACE(opic, ("vendor identification register - read 0x%x\n", reg));  return reg;}static unsigneddo_feature_reporting_register_N_read(device *me,				     hw_opic_device *opic,				     int index){  unsigned reg = 0;  ASSERT(index == 0);  switch (index) {  case 0:    reg |= (opic->nr_external_interrupts << 16);    reg |= (opic->nr_interrupt_destinations << 8);    reg |= (2/*version 1.2*/);    break;  }  DTRACE(opic, ("feature reporting register %d - read 0x%x\n", index, reg));  return reg;}static unsigneddo_global_configuration_register_N_read(device *me,					hw_opic_device *opic,					int index){  unsigned reg = 0;  ASSERT(index == 0);  switch (index) {  case 0:    reg |= gcr0_8259_bit; /* hardwire 8259 disabled */    break;  }  DTRACE(opic, ("global configuration register %d - read 0x%x\n", index, reg));  return reg;}static voiddo_global_configuration_register_N_write(device *me,					 hw_opic_device *opic,					 int index,					 unsigned reg){  ASSERT(index == 0);  if (reg & gcr0_reset_bit) {    DTRACE(opic, ("global configuration register %d - write 0x%x - reseting opic\n", index, reg));    hw_opic_init_data(me);  }  if (!(reg & gcr0_8259_bit)) {    DTRACE(opic, ("global configuration register %d - write 0x%x - ignoring 8259 enable\n", index, reg));  }}/* register read-write */static unsignedhw_opic_io_read_buffer(device *me,		       void *dest,		       int space,		       unsigned_word addr,		       unsigned nr_bytes,		       cpu *processor,		       unsigned_word cia){  hw_opic_device *opic = (hw_opic_device*)device_data(me);  opic_register type;  int index;  decode_opic_address(me, opic, space, addr, nr_bytes, &type, &index);  if (type == invalid_opic_register) {    device_error(me, "invalid opic read access to %d:0x%lx (%d bytes)",		 space, (unsigned long)addr, nr_bytes);  }  else {    unsigned reg;    switch (type) {    case processor_init_register:      reg = do_processor_init_register_read(me, opic);      break;    case interrupt_source_N_vector_priority_register:      reg = do_interrupt_source_N_vector_priority_register_read(me, opic, index);      break;    case interrupt_source_N_destination_register:      reg = do_interrupt_source_N_destination_register_read(me, opic, index);      break;    case interrupt_acknowledge_register_N:      reg = do_interrupt_acknowledge_register_N_read(me, opic, index);      break;    case spurious_vector_register:      reg = do_spurious_vector_register_read(me, opic);      break;    case current_task_priority_register_N:      reg = do_current_task_priority_register_N_read(me, opic, index);      break;    case timer_frequency_reporting_register:      reg = do_timer_frequency_reporting_register_read(me, opic);      break;    case timer_N_current_count_register:      reg = do_timer_N_current_count_register_read(me, opic, index);      break;    case timer_N_base_count_register:      reg = do_timer_N_base_count_register_read(me, opic, index);      break;    case timer_N_vector_priority_register:      reg = do_timer_N_vector_priority_register_read(me, opic, index);      break;    case timer_N_destination_register:      reg = do_timer_N_destination_register_read(me, opic, index);      break;    case ipi_N_vector_priority_register:      reg = do_ipi_N_vector_priority_register_read(me, opic, index);      break;    case feature_reporting_register_N:      reg = do_feature_reporting_register_N_read(me, opic, index);      break;    case global_configuration_register_N:      reg = do_global_configuration_register_N_read(me, opic, index);      break;    case vendor_identification_register:      reg = do_vendor_identification_register_read(me, opic);      break;    default:      reg = 0;      device_error(me, "unimplemented read of register %s[%d]",		   opic_register_name(type), index);    }    *(unsigned_4*)dest = H2LE_4(reg);  }  return nr_bytes;}static unsignedhw_opic_io_write_buffer(device *me,			const void *source,			int space,			unsigned_word addr,			unsigned nr_bytes,			cpu *processor,			unsigned_word cia){  hw_opic_device *opic = (hw_opic_device*)device_data(me);  opic_register type;  int index;  decode_opic_address(me, opic, space, addr, nr_bytes, &type, &index);  if (type == invalid_opic_register) {    device_error(me, "invalid opic write access to %d:0x%lx (%d bytes)",		 space, (unsigned long)addr, nr_bytes);  }  else {    unsigned reg = LE2H_4(*(unsigned_4*)source);    switch (type) {    case processor_init_register:      do_processor_init_register_write(me, opic, reg);      break;    case interrupt_source_N_vector_priority_register:      do_interrupt_source_N_vector_priority_register_write(me, opic, index, reg);      break;    case interrupt_source_N_destination_register:      do_interrupt_source_N_destination_register_write(me, opic, index, reg);      break;    case end_of_interrupt_register_N:      do_end_of_interrupt_register_N_write(me, opic, index, reg);      break;    case spurious_vector_register:      do_spurious_vector_register_write(me, opic, reg);      break;    case current_task_priority_register_N:      do_current_task_priority_register_N_write(me, opic, index, reg);      break;    case timer_frequency_reporting_register:      do_timer_frequency_reporting_register_write(me, opic, reg);      break;    case timer_N_base_count_register:      do_timer_N_base_count_register_write(me, opic, index, reg);      break;    case timer_N_vector_priority_register:      do_timer_N_vector_priority_register_write(me, opic, index, reg);      break;    case timer_N_destination_register:      do_timer_N_destination_register_write(me, opic, index, reg);      break;    case ipi_N_dispatch_register:      do_ipi_N_dispatch_register_write(me, opic, index, reg);      break;    case ipi_N_vector_priority_register:      do_ipi_N_vector_priority_register_write(me, opic, index, reg);      break;    case global_configuration_register_N:      do_global_configuration_register_N_write(me, opic, index, reg);      break;    default:      device_error(me, "unimplemented write to register %s[%d]",		   opic_register_name(type), index);    }  }  return nr_bytes;}    static voidhw_opic_interrupt_event(device *me,			int my_port,			device *source,			int source_port,			int level,			cpu *processor,			unsigned_word cia){  hw_opic_device *opic = (hw_opic_device*)device_data(me);  int isb;  int src_nr = 0;  /* find the corresponding internal input port */  for (isb = 0; isb < opic->nr_isu_blocks; isb++) {    if (my_port >= opic->isu_block[isb].int_number	&& my_port < opic->isu_block[isb].int_number + opic->isu_block[isb].range) {      src_nr += my_port - opic->isu_block[isb].int_number;      break;    }    else      src_nr += opic->isu_block[isb].range;  }  if (isb == opic->nr_isu_blocks)    device_error(me, "interrupt %d out of range", my_port);  DTRACE(opic, ("external-interrupt %d, internal %d, level %d\n",		my_port, src_nr, level));  /* pass it on */  ASSERT(src_nr >= 0 && src_nr < opic->nr_external_interrupts);  handle_interrupt(me, opic, &opic->external_interrupt_source[src_nr], level);}static const device_interrupt_port_descriptor hw_opic_interrupt_ports[] = {  { "irq", 0, max_nr_interrupt_sources, input_port, },  { "intr", 0, max_nr_interrupt_destinations, output_port, },  { "init", max_nr_interrupt_destinations, max_nr_interrupt_destinations, output_port, },  { NULL }};static device_callbacks const hw_opic_callbacks = {  { generic_device_init_address,    hw_opic_init_data },  { NULL, }, /* address */  { hw_opic_io_read_buffer,    hw_opic_io_write_buffer }, /* IO */  { NULL, }, /* DMA */  { hw_opic_interrupt_event, NULL, hw_opic_interrupt_ports }, /* interrupt */  { NULL, }, /* unit */  NULL, /* instance */};static void *hw_opic_create(const char *name,	       const device_unit *unit_address,	       const char *args){  hw_opic_device *opic = ZALLOC(hw_opic_device);  return opic;}const device_descriptor hw_opic_device_descriptor[] = {  { "opic", hw_opic_create, &hw_opic_callbacks },  { NULL },};#endif /* _HW_OPIC_C_ */

⌨️ 快捷键说明

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