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

📄 hw_phb.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
  if (isxdigit(*chp)) {    set_ss(address, ss_config_code);  }  else {    /* non-relocatable? */    if (*chp == 'n') {      set_n(address);      chp++;    }    /* address-space? */    if (*chp == 'i') {      set_ss(address, ss_io_code);      chp++;    }    else if (*chp == 'm') {      set_ss(address, ss_32bit_memory_code);      chp++;    }    else if (*chp == 'x') {      set_ss(address, ss_64bit_memory_code);      chp++;    }    else      device_error(me, "Problem parsing PCI address %s", unit);    /* possible alias */    if (*chp == 't') {      if (extract_ss(address) == ss_64bit_memory_code)	device_error(me, "Invalid alias bit in PCI address %s", unit);      set_t(address);      chp++;    }    /* possible p */    if (*chp == 'p') {      if (extract_ss(address) != ss_32bit_memory_code)	device_error(me, "Invalid prefetchable bit (p) in PCI address %s",		     unit);      set_p(address);      chp++;    }  }  /* required DD */  if (!isxdigit(*chp))    device_error(me, "Missing device number in PCI address %s", unit);  val = strtoul(chp, &end, 16);  if (chp == end)    device_error(me, "Problem parsing device number in PCI address %s", unit);  if ((val & 0x1f) != val)    device_error(me, "Device number (0x%lx) out of range (0..0x1f) in PCI address %s",		 val, unit);  set_ddddd(address, val);  chp = end;  /* For config space, the F is optional */  if (extract_ss(address) == ss_config_code      && (isspace(*chp) || *chp == '\0'))    return chp - unit;  /* function number F */  if (*chp != ',')    device_error(me, "Missing function number in PCI address %s", unit);  chp++;  val = strtoul(chp, &end, 10);  if (chp == end)    device_error(me, "Problem parsing function number in PCI address %s",		 unit);  if ((val & 7) != val)    device_error(me, "Function number (%ld) out of range (0..7) in PCI address %s",		 (long)val, unit);  set_fff(address, val);  chp = end;  /* for config space, must be end */  if (extract_ss(address) == ss_config_code) {    if (!isspace(*chp) && *chp != '\0')      device_error(me, "Problem parsing PCI config address %s",		   unit);    return chp - unit;  }  /* register number RR */  if (*chp != ',')    device_error(me, "Missing register number in PCI address %s", unit);  chp++;  val = strtoul(chp, &end, 16);  if (chp == end)    device_error(me, "Problem parsing register number in PCI address %s",		 unit);  switch (extract_ss(address)) {  case ss_io_code:#if 0    if (extract_n(address) && val != 0)      device_error(me, "non-relocatable I/O register must be zero in PCI address %s", unit);    else if (!extract_n(address)	     && val != 0x10 && val != 0x14 && val != 0x18	     && val != 0x1c && val != 0x20 && val != 0x24)      device_error(me, "I/O register invalid in PCI address %s", unit);#endif    break;  case ss_32bit_memory_code:#if 0    if (extract_n(address) && val != 0)      device_error(me, "non-relocatable memory register must be zero in PCI address %s", unit);    else if (!extract_n(address)	     && val != 0x10 && val != 0x14 && val != 0x18	     && val != 0x1c && val != 0x20 && val != 0x24 && val != 0x30)      device_error(me, "I/O register (0x%lx) invalid in PCI address %s",		   val, unit);#endif    break;  case ss_64bit_memory_code:    if (extract_n(address) && val != 0)      device_error(me, "non-relocatable 32bit memory register must be zero in PCI address %s", unit);    else if (!extract_n(address)	     && val != 0x10 && val != 0x18 && val != 0x20)      device_error(me, "Register number (0x%lx) invalid in 64bit PCI address %s",		   val, unit);  case ss_config_code:    device_error(me, "internal error");  }  if ((val & 0xff) != val)    device_error(me, "Register number (0x%lx) out of range (0..0xff) in PCI address %s",		 val, unit);  set_rrrrrrrr(address, val);  chp = end;  /* address */  if (*chp != ',')    device_error(me, "Missing address in PCI address %s", unit);  chp++;  switch (extract_ss(address)) {  case ss_io_code:  case ss_32bit_memory_code:    val = strtoul(chp, &end, 16);    if (chp == end)      device_error(me, "Problem parsing address in PCI address %s", unit);    switch (extract_ss(address)) {    case ss_io_code:      if (extract_n(address) && extract_t(address)	  && (val & 1024) != val)	device_error(me, "10bit aliased non-relocatable address (0x%lx) out of range in PCI address %s",		     val, unit);      if (!extract_n(address) && extract_t(address)	  && (val & 0xffff) != val)	device_error(me, "64k relocatable address (0x%lx) out of range in PCI address %s",		     val, unit);      break;    case ss_32bit_memory_code:      if (extract_t(address) && (val & 0xfffff) != val)	device_error(me, "1mb memory address (0x%lx) out of range in PCI address %s",		     val, unit);      if (!extract_t(address) && (val & 0xffffffff) != val)	device_error(me, "32bit memory address (0x%lx) out of range in PCI address %s",		     val, unit);      break;    case ss_64bit_memory_code:    case ss_config_code:      device_error(me, "internal error");    }    set_ll_ll(address, val);    chp = end;    break;  case ss_64bit_memory_code:    device_error(me, "64bit addresses unimplemented");    set_hh_hh(address, val);    set_ll_ll(address, val);    break;  case ss_config_code:    device_error(me, "internal error");    break;  }  /* finished? */  if (!isspace(*chp) && *chp != '\0')    device_error(me, "Problem parsing PCI address %s", unit);  return chp - unit;}/* Convert PCI device unit into its corresponding textual   representation */static inthw_phb_unit_encode(device *me,		   const device_unit *unit_address,		   char *buf,		   int sizeof_buf){  if (unit_address->nr_cells != 3)    device_error(me, "Incorrect number of cells in PCI unit address");  if (device_nr_address_cells(me) != 3)    device_error(me, "PCI bus should have #address-cells == 3");  if (extract_ss(unit_address) == ss_config_code      && extract_fff(unit_address) == 0      && extract_rrrrrrrr(unit_address) == 0      && extract_hh_hh(unit_address) == 0      && extract_ll_ll(unit_address) == 0) {    /* DD - Configuration Space address */    sprintf(buf, "%x",	    extract_ddddd(unit_address));  }  else if (extract_ss(unit_address) == ss_config_code	   && extract_fff(unit_address) != 0	   && extract_rrrrrrrr(unit_address) == 0	   && extract_hh_hh(unit_address) == 0	   && extract_ll_ll(unit_address) == 0) {    /* DD,F - Configuration Space */    sprintf(buf, "%x,%d",	    extract_ddddd(unit_address),	    extract_fff(unit_address));  }  else if (extract_ss(unit_address) == ss_io_code	   && extract_hh_hh(unit_address) == 0) {    /* [n]i[t]DD,F,RR,NNNNNNNN - 32bit I/O space */    sprintf(buf, "%si%s%x,%d,%x,%x",	    extract_n(unit_address) ? "n" : "",	    extract_t(unit_address) ? "t" : "",	    extract_ddddd(unit_address),	    extract_fff(unit_address),	    extract_rrrrrrrr(unit_address),	    extract_ll_ll(unit_address));  }  else if (extract_ss(unit_address) == ss_32bit_memory_code	   && extract_hh_hh(unit_address) == 0) {    /* [n]m[t][p]DD,F,RR,NNNNNNNN - 32bit memory space */    sprintf(buf, "%sm%s%s%x,%d,%x,%x",	    extract_n(unit_address) ? "n" : "",	    extract_t(unit_address) ? "t" : "",	    extract_p(unit_address) ? "p" : "",	    extract_ddddd(unit_address),	    extract_fff(unit_address),	    extract_rrrrrrrr(unit_address),	    extract_ll_ll(unit_address));  }  else if (extract_ss(unit_address) == ss_32bit_memory_code) {    /* [n]x[p]DD,F,RR,NNNNNNNNNNNNNNNN - 64bit memory space */    sprintf(buf, "%sx%s%x,%d,%x,%x%08x",	    extract_n(unit_address) ? "n" : "",	    extract_p(unit_address) ? "p" : "",	    extract_ddddd(unit_address),	    extract_fff(unit_address),	    extract_rrrrrrrr(unit_address),	    extract_hh_hh(unit_address),	    extract_ll_ll(unit_address));  }  else {    device_error(me, "Invalid PCI unit address 0x%08lx 0x%08lx 0x%08lx",		 (unsigned long)unit_address->cells[0],		 (unsigned long)unit_address->cells[1],		 (unsigned long)unit_address->cells[2]);  }  if (strlen(buf) > sizeof_buf)    error("buffer overflow");  return strlen(buf);}static inthw_phb_address_to_attach_address(device *me,				 const device_unit *address,				 int *attach_space,				 unsigned_word *attach_address,				 device *client){  if (address->nr_cells != 3)    device_error(me, "attach address has incorrect number of cells");  if (address->cells[1] != 0)    device_error(me, "64bit attach address unsupported");  /* directly decode the address/space */  *attach_address = address->cells[2];  switch (extract_ss(address)) {  case ss_config_code:    *attach_space = hw_phb_config_space;    break;  case ss_io_code:    *attach_space = hw_phb_io_space;    break;  case ss_32bit_memory_code:  case ss_64bit_memory_code:    *attach_space = hw_phb_memory_space;    break;  }  /* if non-relocatable finished */  if (extract_n(address))    return 1;  /* make memory and I/O addresses absolute */  if (*attach_space == hw_phb_io_space      || *attach_space == hw_phb_memory_space) {    int reg_nr;    reg_property_spec assigned;    if (extract_ss(address) == ss_64bit_memory_code)      device_error(me, "64bit memory address not unsuported");    for (reg_nr = 0;	 device_find_reg_array_property(client, "assigned-addresses", reg_nr,					&assigned);	 reg_nr++) {      if (!extract_n(&assigned.address)	  || extract_rrrrrrrr(&assigned.address) == 0)	device_error(me, "client %s has invalid assigned-address property",		     device_path(client));      if (extract_rrrrrrrr(address) == extract_rrrrrrrr(&assigned.address)) {	/* corresponding base register */	if (extract_ss(address) != extract_ss(&assigned.address))	  device_error(me, "client %s has conflicting types for base register 0x%lx",		       device_path(client),		       (unsigned long)extract_rrrrrrrr(address));	*attach_address += assigned.address.cells[2];	return 0;      }    }    device_error(me, "client %s missing base address register 0x%lx in assigned-addresses property",		 device_path(client),		 (unsigned long)extract_rrrrrrrr(address));  }    return 0;}static inthw_phb_size_to_attach_size(device *me,			   const device_unit *size,			   unsigned *nr_bytes,			   device *client){  if (size->nr_cells != 2)    device_error(me, "size has incorrect number of cells");  if (size->cells[0] != 0)    device_error(me, "64bit size unsupported");  *nr_bytes = size->cells[1];  return size->cells[1];}static const phb_space *find_phb_space(hw_phb_device *phb,	       unsigned_word addr,	       unsigned nr_bytes){  hw_phb_spaces space;  /* find the space that matches the address */  for (space = 0; space < nr_hw_phb_spaces; space++) {    phb_space *pci_space = &phb->space[space];    if (addr >= pci_space->parent_base	&& (addr + nr_bytes) <= (pci_space->parent_base + pci_space->size)) {      return pci_space;    }  }  return NULL;}static unsigned_wordmap_phb_addr(const phb_space *space,	     unsigned_word addr){  return addr - space->parent_base + space->my_base;}static unsignedhw_phb_io_read_buffer(device *me,		      void *dest,		      int space,		      unsigned_word addr,		      unsigned nr_bytes,		      cpu *processor,		      unsigned_word cia){  hw_phb_device *phb = (hw_phb_device*)device_data(me);  const phb_space *pci_space = find_phb_space(phb, addr, nr_bytes);  unsigned_word bus_addr;  if (pci_space == NULL)    return 0;  bus_addr = map_phb_addr(pci_space, addr);  DTRACE(phb, ("io read - %d:0x%lx -> %s:0x%lx (%u bytes)\n",	       space, (unsigned long)addr, pci_space->name, (unsigned long)bus_addr,	       nr_bytes));  return core_map_read_buffer(pci_space->readable,			      dest, bus_addr, nr_bytes);}static unsignedhw_phb_io_write_buffer(device *me,		       const void *source,		       int space,		       unsigned_word addr,		       unsigned nr_bytes,		       cpu *processor,		       unsigned_word cia){  hw_phb_device *phb = (hw_phb_device*)device_data(me);  const phb_space *pci_space = find_phb_space(phb, addr, nr_bytes);  unsigned_word bus_addr;  if (pci_space == NULL)    return 0;  bus_addr = map_phb_addr(pci_space, addr);  DTRACE(phb, ("io write - %d:0x%lx -> %s:0x%lx (%u bytes)\n",	       space, (unsigned long)addr, pci_space->name, (unsigned long)bus_addr,	       nr_bytes));  return core_map_write_buffer(pci_space->writeable, source,			       bus_addr, nr_bytes);}static unsignedhw_phb_dma_read_buffer(device *me,		       void *dest,		       int space,		       unsigned_word addr,		       unsigned nr_bytes){  hw_phb_device *phb = (hw_phb_device*)device_data(me);  const phb_space *pci_space;  /* find the space */  if (space != hw_phb_memory_space)    device_error(me, "invalid dma address space %d", space);  pci_space = &phb->space[space];  /* check out the address */  if ((addr >= pci_space->my_base       && addr <= pci_space->my_base + pci_space->size)      || (addr + nr_bytes >= pci_space->my_base	  && addr + nr_bytes <= pci_space->my_base + pci_space->size))    device_error(me, "Do not support DMA into own bus");  /* do it */  DTRACE(phb, ("dma read - %s:0x%lx (%d bytes)\n",	       pci_space->name, addr, nr_bytes));  return device_dma_read_buffer(device_parent(me),				dest, pci_space->parent_space,				addr, nr_bytes);}static unsignedhw_phb_dma_write_buffer(device *me,			const void *source,			int space,			unsigned_word addr,			unsigned nr_bytes,			int violate_read_only_section){  hw_phb_device *phb = (hw_phb_device*)device_data(me);  const phb_space *pci_space;  /* find the space */  if (space != hw_phb_memory_space)    device_error(me, "invalid dma address space %d", space);  pci_space = &phb->space[space];  /* check out the address */  if ((addr >= pci_space->my_base       && addr <= pci_space->my_base + pci_space->size)      || (addr + nr_bytes >= pci_space->my_base	  && addr + nr_bytes <= pci_space->my_base + pci_space->size))    device_error(me, "Do not support DMA into own bus");  /* do it */  DTRACE(phb, ("dma write - %s:0x%lx (%d bytes)\n",	       pci_space->name, addr, nr_bytes));  return device_dma_write_buffer(device_parent(me),				 source, pci_space->parent_space,				 addr, nr_bytes,				 violate_read_only_section);}static device_callbacks const hw_phb_callbacks = {  { hw_phb_init_address, },  { hw_phb_attach_address, },  { hw_phb_io_read_buffer, hw_phb_io_write_buffer },  { hw_phb_dma_read_buffer, hw_phb_dma_write_buffer },  { NULL, }, /* interrupt */  { hw_phb_unit_decode,    hw_phb_unit_encode,    hw_phb_address_to_attach_address,    hw_phb_size_to_attach_size }};static void *hw_phb_create(const char *name,	      const device_unit *unit_address,	      const char *args){  /* create the descriptor */  hw_phb_device *phb = ZALLOC(hw_phb_device);  /* create the core maps now */  hw_phb_spaces space_nr;  for (space_nr = 0; space_nr < nr_hw_phb_spaces; space_nr++) {    phb_space *pci_space = &phb->space[space_nr];    pci_space->map = core_create();    pci_space->readable = core_readable(pci_space->map);    pci_space->writeable = core_writeable(pci_space->map);    switch (space_nr) {    case hw_phb_memory_space:      pci_space->name = "memory";      break;    case hw_phb_io_space:      pci_space->name = "I/O";      break;    case hw_phb_config_space:      pci_space->name = "config";      break;    case hw_phb_special_space:      pci_space->name = "special";      break;    default:      error ("internal error");      break;    }  }  return phb;}const device_descriptor hw_phb_device_descriptor[] = {  { "phb", hw_phb_create, &hw_phb_callbacks },  { "pci", NULL, &hw_phb_callbacks },  { NULL, },};#endif /* _HW_PHB_ */

⌨️ 快捷键说明

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