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

📄 hw_opic.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
  /* check to see if that shouldn't be interrupted */  dest->current_pending = find_interrupt_for_dest(me, opic, dest, pending_interrupt);  if (can_deliver(me, dest->current_pending, dest)) {    ASSERT(dest->current_pending->pending & dest->bit);    assert_interrupt(me, opic, dest);  }  else {    dest->current_pending = NULL;  }}static voiddecode_opic_address(device *me,		    hw_opic_device *opic,		    int space,		    unsigned_word address,		    unsigned nr_bytes,		    opic_register *type,		    int *index){  int isb = 0;  /* is the size valid? */  if (nr_bytes != 4) {    *type = invalid_opic_register;    *index = -1;    return;  }  /* try for a per-processor register within the interrupt delivery     unit */  if (space == opic->idu.space      && address >= (opic->idu.address + idu_per_processor_register_base)      && address < (opic->idu.address + idu_per_processor_register_base		    + (sizeof_idu_per_processor_register_block		       * opic->nr_interrupt_destinations))) {    unsigned_word block_offset = (address				  - opic->idu.address				  - idu_per_processor_register_base);    unsigned_word offset = block_offset % sizeof_idu_per_processor_register_block;    *index = block_offset / sizeof_idu_per_processor_register_block;    switch (offset) {    case 0x040:      *type = ipi_N_dispatch_register;      *index = 0;      break;    case 0x050:      *type = ipi_N_dispatch_register;      *index = 1;      break;    case 0x060:      *type = ipi_N_dispatch_register;      *index = 2;      break;    case 0x070:      *type = ipi_N_dispatch_register;      *index = 3;      break;    case 0x080:      *type = current_task_priority_register_N;      break;    case 0x0a0:      *type = interrupt_acknowledge_register_N;      break;    case 0x0b0:      *type = end_of_interrupt_register_N;      break;    default:      *type = invalid_opic_register;      break;    }    DTRACE(opic, ("per-processor register %d:0x%lx - %s[%d]\n",		  space, (unsigned long)address,		  opic_register_name(*type),		  *index));    return;  }  /* try for an interrupt source unit */  for (isb = 0; isb < opic->nr_isu_blocks; isb++) {    if (opic->isu_block[isb].space == space	&& address >= opic->isu_block[isb].address	&& address < (opic->isu_block[isb].address + opic->isu_block[isb].size)) {      unsigned_word block_offset = address - opic->isu_block[isb].address;      unsigned_word offset = block_offset % sizeof_isu_register_block;      *index = (opic->isu_block[isb].int_number		+ (block_offset / sizeof_isu_register_block));      switch (offset) {      case 0x00:	*type = interrupt_source_N_vector_priority_register;	break;      case 0x10:	*type = interrupt_source_N_destination_register;	break;      default:	*type = invalid_opic_register;	break;      }      DTRACE(opic, ("isu register %d:0x%lx - %s[%d]\n",		    space, (unsigned long)address,		    opic_register_name(*type),		    *index));      return;    }  }  /* try for a timer */  if (space == opic->idu.space      && address >= (opic->idu.address + idu_timer_base)      && address < (opic->idu.address + idu_timer_base		    + opic->nr_timer_interrupts * sizeof_timer_register_block)) {    unsigned_word offset = address % sizeof_timer_register_block;    *index = ((address - opic->idu.address - idu_timer_base)	      / sizeof_timer_register_block);    switch (offset) {    case 0x00:      *type = timer_N_current_count_register;      break;    case 0x10:      *type = timer_N_base_count_register;      break;    case 0x20:      *type = timer_N_vector_priority_register;      break;    case 0x30:      *type = timer_N_destination_register;      break;    default:      *type = invalid_opic_register;      break;    }    DTRACE(opic, ("timer register %d:0x%lx - %s[%d]\n",		  space, (unsigned long)address,		  opic_register_name(*type),		  *index));    return;  }  /* finally some other misc global register */  if (space == opic->idu.space      && address >= opic->idu.address      && address < opic->idu.address + opic->idu.size) {    unsigned_word block_offset = address - opic->idu.address;    switch (block_offset) {    case 0x010f0:      *type = timer_frequency_reporting_register;      *index = -1;      break;    case 0x010e0:      *type = spurious_vector_register;      *index = -1;      break;    case 0x010d0:    case 0x010c0:    case 0x010b0:    case 0x010a0:      *type = ipi_N_vector_priority_register;      *index = (block_offset - 0x010a0) / 16;      break;    case 0x01090:      *type = processor_init_register;      *index = -1;      break;    case 0x01080:      *type = vendor_identification_register;      *index = -1;      break;    case 0x01020:      *type = global_configuration_register_N;      *index = 0;      break;    case 0x01000:      *type = feature_reporting_register_N;      *index = 0;      break;    default:      *type = invalid_opic_register;      *index = -1;      break;    }    DTRACE(opic, ("global register %d:0x%lx - %s[%d]\n",		  space, (unsigned long)address,		  opic_register_name(*type),		  *index));    return;  }  /* nothing matched */  *type = invalid_opic_register;  DTRACE(opic, ("invalid register %d:0x%lx\n",		space, (unsigned long)address));  return;}/* Processor init register:   The bits in this register (one per processor) are directly wired to   output "init" interrupt ports. */static unsigneddo_processor_init_register_read(device *me,				hw_opic_device *opic){  unsigned reg = opic->init;  DTRACE(opic, ("processor init register - read 0x%lx\n",		(long)reg));  return reg;}static voiddo_processor_init_register_write(device *me,				 hw_opic_device *opic,				 unsigned reg){  int i;  for (i = 0; i < opic->nr_interrupt_destinations; i++) {    opic_interrupt_destination *dest = &opic->interrupt_destination[i];    if ((reg & dest->bit) != (opic->init & dest->bit)) {      if (reg & dest->bit) {	DTRACE(opic, ("processor init register - write 0x%lx - asserting init%d\n",		      (long)reg, i));	opic->init |= dest->bit;	device_interrupt_event(me, dest->init_port, 1, NULL, 0);      }      else {	DTRACE(opic, ("processor init register - write 0x%lx - negating init%d\n",		      (long)reg, i));	opic->init &= ~dest->bit;	device_interrupt_event(me, dest->init_port, 0, NULL, 0);      }    }  }}/* Interrupt Source Vector/Priority Register: */static unsignedread_vector_priority_register(device *me,			      hw_opic_device *opic,			      opic_interrupt_source *interrupt,			      const char *reg_name,			      int reg_index){  unsigned reg;  reg = 0;  reg |= interrupt->is_masked;  reg |= (interrupt->in_service || interrupt->pending	  ? isu_active_bit : 0); /* active */  reg |= interrupt->is_multicast;  reg |= interrupt->is_positive_polarity;  reg |= interrupt->is_level_triggered; /* sense? */  reg |= interrupt->priority << isu_priority_shift;  reg |= interrupt->vector;  DTRACE(opic, ("%s %d vector/priority register - read 0x%lx\n",		reg_name, reg_index, (unsigned long)reg));  return reg;}static unsigneddo_interrupt_source_N_vector_priority_register_read(device *me,						    hw_opic_device *opic,						    int index){  unsigned reg;  ASSERT(index < opic->nr_external_interrupts);  reg = read_vector_priority_register(me, opic,				      &opic->interrupt_source[index],				      "interrupt source", index);  return reg;}static voidwrite_vector_priority_register(device *me,			       hw_opic_device *opic,			       opic_interrupt_source *interrupt,			       unsigned reg,			       const char *reg_name,			       int reg_index){  interrupt->is_masked = (reg & isu_mask_bit);  interrupt->is_multicast = (reg & isu_multicast_bit);  interrupt->is_positive_polarity = (reg & isu_positive_polarity_bit);  interrupt->is_level_triggered = (reg & isu_level_triggered_bit);  interrupt->priority = ((reg >> isu_priority_shift)			 % max_nr_task_priorities);  interrupt->vector = (reg & isu_vector_bits);  DTRACE(opic, ("%s %d vector/priority register - write 0x%lx - %s%s%s-polarity, %s-triggered, priority %ld vector %ld\n",		reg_name,		reg_index,		(unsigned long)reg,		interrupt->is_masked ? "masked, " : "",		interrupt->is_multicast ? "multicast, " : "",		interrupt->is_positive_polarity ? "positive" : "negative",		interrupt->is_level_triggered ? "level" : "edge",		(long)interrupt->priority,		(long)interrupt->vector));}static voiddo_interrupt_source_N_vector_priority_register_write(device *me,						     hw_opic_device *opic,						     int index,						     unsigned reg){  ASSERT(index < opic->nr_external_interrupts);  reg &= ~isu_multicast_bit; /* disable multicast */  write_vector_priority_register(me, opic,				 &opic->interrupt_source[index],				 reg, "interrupt source", index);}/* Interrupt Source Destination Register: */static unsignedread_destination_register(device *me,			  hw_opic_device *opic,			  opic_interrupt_source *interrupt,			  const char *reg_name,			  int reg_index){  unsigned long reg;  reg = interrupt->destination;  DTRACE(opic, ("%s %d destination register - read 0x%lx\n",		reg_name, reg_index, reg));  return reg;}			     static unsigneddo_interrupt_source_N_destination_register_read(device *me,						hw_opic_device *opic,						int index){  unsigned reg;  ASSERT(index < opic->nr_external_interrupts);  reg = read_destination_register(me, opic, &opic->external_interrupt_source[index],				  "interrupt source", index);  return reg;}static voidwrite_destination_register(device *me,			   hw_opic_device *opic,			   opic_interrupt_source *interrupt,			   unsigned reg,			   const char *reg_name,			   int reg_index){  reg &= (1 << opic->nr_interrupt_destinations) - 1; /* mask out invalid */  DTRACE(opic, ("%s %d destination register - write 0x%x\n",		reg_name, reg_index, reg));  interrupt->destination = reg;}static voiddo_interrupt_source_N_destination_register_write(device *me,						 hw_opic_device *opic,						 int index,						 unsigned reg){  ASSERT(index < opic->nr_external_interrupts);  write_destination_register(me, opic, &opic->external_interrupt_source[index],			     reg, "interrupt source", index);}/* Spurious vector register: */static unsigneddo_spurious_vector_register_read(device *me,				 hw_opic_device *opic){  unsigned long reg = opic->spurious_vector;  DTRACE(opic, ("spurious vector register - read 0x%lx\n", reg));  return reg;}static voiddo_spurious_vector_register_write(device *me,				  hw_opic_device *opic,				  unsigned reg){  reg &= 0xff; /* mask off invalid */  DTRACE(opic, ("spurious vector register - write 0x%x\n", reg));  opic->spurious_vector = reg;}/* current task priority register: */static unsigneddo_current_task_priority_register_N_read(device *me,					 hw_opic_device *opic,					 int index){  opic_interrupt_destination *interrupt_destination = &opic->interrupt_destination[index];  unsigned reg;  ASSERT(index >= 0 && index < opic->nr_interrupt_destinations);  reg = interrupt_destination->base_priority;  DTRACE(opic, ("current task priority register %d - read 0x%x\n", index, reg));  return reg;}static voiddo_current_task_priority_register_N_write(device *me,					  hw_opic_device *opic,					  int index,					  unsigned reg){  opic_interrupt_destination *interrupt_destination = &opic->interrupt_destination[index];  ASSERT(index >= 0 && index < opic->nr_interrupt_destinations);  reg %= max_nr_task_priorities;  DTRACE(opic, ("current task priority register %d - write 0x%x\n", index, reg));  interrupt_destination->base_priority = reg;}/* Timer Frequency Reporting Register: */static unsigneddo_timer_frequency_reporting_register_read(device *me,					   hw_opic_device *opic){  unsigned reg;  reg = opic->timer_frequency;  DTRACE(opic, ("timer frequency reporting register - read 0x%x\n", reg));  return reg;}static voiddo_timer_frequency_reporting_register_write(device *me,					    hw_opic_device *opic,					    unsigned reg){  DTRACE(opic, ("timer frequency reporting register - write 0x%x\n", reg));  opic->timer_frequency = reg;}/* timer registers: */static unsigneddo_timer_N_current_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);

⌨️ 快捷键说明

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