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

📄 hw_ide.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	 | (controller->reg[ide_cylinder_reg0] << 8)	 | (controller->reg[ide_sector_number_reg]));  }  else if (controller->current_drive->geometry.head != 0	   && controller->current_drive->geometry.sector != 0) {    /* CHS addressing mode */    int head_nr = controller->reg[ide_drive_head_reg] & 0xf;    int cylinder_nr = ((controller->reg[ide_cylinder_reg1] << 8)		    | controller->reg[ide_cylinder_reg0]);    int sector_nr = controller->reg[ide_sector_number_reg];    controller->current_byte = controller->fifo_size      * ((cylinder_nr * controller->current_drive->geometry.head + head_nr)	 * controller->current_drive->geometry.sector + sector_nr - 1);  }  else    device_error(me, "controller %d:%d - CHS addressing disabled",		 controller->nr, controller->current_drive->nr);  DTRACE(ide, ("controller %ld:%ld - transfer (%s) %ld blocks of %ld bytes from 0x%lx\n",	       (long)controller->nr,	       controller->current_drive == NULL ? -1L : (long)controller->current_drive->nr,	       direction == is_read ? "read" : "write",	       (long)controller->current_transfer,	       (long)controller->fifo_size,	       (unsigned long)controller->current_byte));  switch (direction) {  case is_read:    /* force a primeing read */    controller->current_transfer += 1;    controller->state = draining_state;     controller->fifo_pos = controller->fifo_size;    do_fifo_read(me, controller, NULL, 0);    break;  case is_write:    controller->state = loading_state;    break;  }}static voiddo_command(device *me,	   ide_controller *controller,	   int command){  if (controller->state != idle_state)    device_error(me, "controller %d - command when not idle", controller->nr);  switch (command) {  case 0x20: case 0x21: /* read-sectors */    setup_fifo(me, controller, 0/*is_simple*/, 1/*is_with_disk*/, is_read);    break;  case 0x30: case 0x31: /* write */    setup_fifo(me, controller, 0/*is_simple*/, 1/*is_with_disk*/, is_write);    break;  }}static unsigned8get_status(device *me,	   ide_controller *controller){  switch (controller->state) {  case loading_state:  case draining_state:    return 0x08; /* data req */  case busy_loaded_state:  case busy_drained_state:    return 0x80; /* busy */  case idle_state:    return 0x40; /* drive ready */  default:    device_error(me, "internal error");    return 0;  }}	  /* The address presented to the IDE controler is decoded and then   mapped onto a controller:reg pair */enum {  nr_address_blocks = 6,};typedef struct _address_block {  int space;  unsigned_word base_addr;  unsigned_word bound_addr;  int controller;  int base_reg;} address_block;typedef struct _address_decoder {  address_block block[nr_address_blocks];} address_decoder;static voiddecode_address(device *me,	       address_decoder *decoder,	       int space,	       unsigned_word address,	       int *controller,	       int *reg,	       io_direction direction){  int i;  for (i = 0; i < nr_address_blocks; i++) {    if (space == decoder->block[i].space	&& address >= decoder->block[i].base_addr	&& address <= decoder->block[i].bound_addr) {      *controller = decoder->block[i].controller;      *reg = (address	      - decoder->block[i].base_addr	      + decoder->block[i].base_reg);      if (direction == is_write) {	switch (*reg) {	case ide_error_reg: *reg = ide_feature_reg; break;	case ide_status_reg: *reg = ide_command_reg; break;	case ide_alternate_status_reg: *reg = ide_control_reg; break;	default: break;	}      }      return;    }  }  device_error(me, "address %d:0x%lx invalid",	       space, (unsigned long)address);}static voidbuild_address_decoder(device *me,		      address_decoder *decoder){  int reg;  for (reg = 1; reg < 6; reg++) {    reg_property_spec unit;    int space;    unsigned_word address;    unsigned size;    /* find and decode the reg property */    if (!device_find_reg_array_property(me, "reg", reg, &unit))      device_error(me, "missing or invalid reg entry %d", reg);    device_address_to_attach_address(device_parent(me), &unit.address,				     &space, &address, me);    device_size_to_attach_size(device_parent(me), &unit.size, &size, me);    /* insert it into the address decoder */    switch (reg) {    case 1:    case 2:      /* command register block */      if (size != 8)	device_error(me, "reg entry %d must have a size of 8", reg);      decoder->block[reg-1].space = space;      decoder->block[reg-1].base_addr = address;      decoder->block[reg-1].bound_addr = address + size - 1;      decoder->block[reg-1].controller = (reg + 1) % nr_ide_controllers;      decoder->block[reg-1].base_reg = ide_data_reg;      DTRACE(ide, ("controller %d command register block at %d:0x%lx..0x%lx\n",		   decoder->block[reg-1].controller,		   decoder->block[reg-1].space,		   (unsigned long)decoder->block[reg-1].base_addr,		   (unsigned long)decoder->block[reg-1].bound_addr));      break;    case 3:    case 4:      /* control register block */      if (size != 1)	device_error(me, "reg entry %d must have a size of 1", reg);      decoder->block[reg-1].space = space;      decoder->block[reg-1].base_addr = address;      decoder->block[reg-1].bound_addr = address + size - 1;      decoder->block[reg-1].controller = (reg + 1) % nr_ide_controllers;      decoder->block[reg-1].base_reg = ide_alternate_status_reg;      DTRACE(ide, ("controller %d control register block at %d:0x%lx..0x%lx\n",		   decoder->block[reg-1].controller,		   decoder->block[reg-1].space,		   (unsigned long)decoder->block[reg-1].base_addr,		   (unsigned long)decoder->block[reg-1].bound_addr));      break;    case 5:      /* dma register block */      if (size != 8)	device_error(me, "reg entry %d must have a size of 8", reg);      decoder->block[reg-1].space = space;      decoder->block[reg-1].base_addr = address;      decoder->block[reg-1].bound_addr = address + 4 - 1;      decoder->block[reg-1].base_reg = ide_dma_command_reg;      decoder->block[reg-1].controller = 0;      DTRACE(ide, ("controller %d dma register block at %d:0x%lx..0x%lx\n",		   decoder->block[reg-1].controller,		   decoder->block[reg-1].space,		   (unsigned long)decoder->block[reg-1].base_addr,		   (unsigned long)decoder->block[reg-1].bound_addr));      decoder->block[reg].space = space;      decoder->block[reg].base_addr = address + 4;      decoder->block[reg].bound_addr = address + 8 - 1;      decoder->block[reg].controller = 1;      decoder->block[reg].base_reg = ide_dma_command_reg;      DTRACE(ide, ("controller %d dma register block at %d:0x%lx..0x%lx\n",		   decoder->block[reg].controller,		   decoder->block[reg-1].space,		   (unsigned long)decoder->block[reg].base_addr,		   (unsigned long)decoder->block[reg].bound_addr));      break;    default:      device_error(me, "internal error - bad switch");      break;    }  }}		      typedef struct _hw_ide_device {  ide_controller controller[nr_ide_controllers];  address_decoder decoder;} hw_ide_device;static voidhw_ide_init_address(device *me){  hw_ide_device *ide = device_data(me);  int controller;  int drive;   /* zero some things */  for (controller = 0; controller < nr_ide_controllers; controller++) {    memset(&ide->controller[controller], 0, sizeof(ide_controller));    for (drive = 0; drive < nr_ide_drives_per_controller; drive++) {      ide->controller[controller].drive[drive].nr = drive;    }    ide->controller[controller].me = me;    if (device_find_property(me, "ready-delay") != NULL)      ide->controller[controller].ready_delay =	device_find_integer_property(me, "ready-delay");  }  /* attach this device to its parent */  generic_device_init_address(me);  /* determine our own address map */  build_address_decoder(me, &ide->decoder);}static voidhw_ide_attach_address(device *me,		      attach_type type,		      int space,		      unsigned_word addr,		      unsigned nr_bytes,		      access_type access,		      device *client) /*callback/default*/{  hw_ide_device *ide = (hw_ide_device*)device_data(me);  int controller_nr = addr / nr_ide_drives_per_controller;  int drive_nr = addr % nr_ide_drives_per_controller;  ide_controller *controller;  ide_drive *drive;  if (controller_nr >= nr_ide_controllers)    device_error(me, "no controller for disk %s",		 device_path(client));  controller = &ide->controller[controller_nr];  drive = &controller->drive[drive_nr];  drive->device = client;  if (device_find_property(client, "ide-byte-count") != NULL)    drive->geometry.byte = device_find_integer_property(client, "ide-byte-count");  else    drive->geometry.byte = 512;  if (device_find_property(client, "ide-sector-count") != NULL)    drive->geometry.sector = device_find_integer_property(client, "ide-sector-count");  if (device_find_property(client, "ide-head-count") != NULL)    drive->geometry.head = device_find_integer_property(client, "ide-head-count");  drive->default_geometry = drive->geometry;  DTRACE(ide, ("controller %d:%d %s byte-count %d, sector-count %d, head-count %d\n",	       controller_nr,	       drive->nr,	       device_path(client),	       drive->geometry.byte,	       drive->geometry.sector,	       drive->geometry.head));}static unsignedhw_ide_io_read_buffer(device *me,		      void *dest,		      int space,		      unsigned_word addr,		      unsigned nr_bytes,		      cpu *processor,		      unsigned_word cia){  hw_ide_device *ide = (hw_ide_device *)device_data(me);  int control_nr;  int reg;  ide_controller *controller;  /* find the interface */  decode_address(me, &ide->decoder, space, addr, &control_nr, &reg, is_read);  controller = & ide->controller[control_nr];  /* process the transfer */  memset(dest, 0, nr_bytes);  switch (reg) {  case ide_data_reg:    do_fifo_read(me, controller, dest, nr_bytes);    break;  case ide_status_reg:    *(unsigned8*)dest = get_status(me, controller);    clear_interrupt(me, controller);    break;  case ide_alternate_status_reg:    *(unsigned8*)dest = get_status(me, controller);    break;  case ide_error_reg:  case ide_sector_count_reg:  case ide_sector_number_reg:  case ide_cylinder_reg0:  case ide_cylinder_reg1:  case ide_drive_head_reg:  case ide_control_reg:  case ide_dma_command_reg:  case ide_dma_status_reg:  case ide_dma_prd_table_address_reg0:  case ide_dma_prd_table_address_reg1:  case ide_dma_prd_table_address_reg2:  case ide_dma_prd_table_address_reg3:    *(unsigned8*)dest = controller->reg[reg];    break;  default:    device_error(me, "bus-error at address 0x%lx", addr);    break;  }  return nr_bytes;}static unsignedhw_ide_io_write_buffer(device *me,		       const void *source,		       int space,		       unsigned_word addr,		       unsigned nr_bytes,		       cpu *processor,		       unsigned_word cia){  hw_ide_device *ide = (hw_ide_device *)device_data(me);  int control_nr;  int reg;  ide_controller *controller;  /* find the interface */  decode_address(me, &ide->decoder, space, addr, &control_nr, &reg, is_write);  controller = &ide->controller[control_nr];  /* process the access */  switch (reg) {  case ide_data_reg:    do_fifo_write(me, controller, source, nr_bytes);    break;  case ide_command_reg:    do_command(me, controller, *(unsigned8*)source);    break;  case ide_control_reg:    controller->reg[reg] = *(unsigned8*)source;    /* possibly cancel interrupts */    if ((controller->reg[reg] & 0x02) == 0x02)      clear_interrupt(me, controller);    break;  case ide_feature_reg:  case ide_sector_count_reg:  case ide_sector_number_reg:  case ide_cylinder_reg0:  case ide_cylinder_reg1:  case ide_drive_head_reg:  case ide_dma_command_reg:  case ide_dma_status_reg:  case ide_dma_prd_table_address_reg0:  case ide_dma_prd_table_address_reg1:  case ide_dma_prd_table_address_reg2:  case ide_dma_prd_table_address_reg3:    controller->reg[reg] = *(unsigned8*)source;    break;  default:    device_error(me, "bus-error at 0x%lx", addr);    break;  }  return nr_bytes;}static const device_interrupt_port_descriptor hw_ide_interrupt_ports[] = {  { "a", 0, 0 },  { "b", 1, 0 },  { "c", 2, 0 },  { "d", 3, 0 },  { NULL }};static device_callbacks const hw_ide_callbacks = {  { hw_ide_init_address, },  { hw_ide_attach_address, }, /* attach */  { hw_ide_io_read_buffer, hw_ide_io_write_buffer, },  { NULL, }, /* DMA */  { NULL, NULL, hw_ide_interrupt_ports }, /* interrupt */  { generic_device_unit_decode,    generic_device_unit_encode,    generic_device_address_to_attach_address,    generic_device_size_to_attach_size },};static void *hw_ide_create(const char *name,	      const device_unit *unit_address,	      const char *args){  hw_ide_device *ide = ZALLOC(hw_ide_device);  return ide;}const device_descriptor hw_ide_device_descriptor[] = {  { "ide", hw_ide_create, &hw_ide_callbacks },  { NULL, },};#endif /* _HW_IDE_ */

⌨️ 快捷键说明

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