Esempio n. 1
0
static bool pci_config_data_in(struct kvm *kvm, u16 port, void *data, int size, u32 count)
{
	unsigned long start;
	u8 dev_num;

	/*
	 * If someone accesses PCI configuration space offsets that are not
	 * aligned to 4 bytes, it uses ioports to signify that.
	 */
	start = port - PCI_CONFIG_DATA;

	dev_num		= pci_config_address.device_number;

	if (pci_device_exists(0, dev_num, 0)) {
		unsigned long offset;

		offset = start + (pci_config_address.register_number << 2);
		if (offset < sizeof(struct pci_device_header)) {
			void *p = pci_devices[dev_num];

			memcpy(data, p + offset, size);
		} else
			memset(data, 0x00, size);
	} else
		memset(data, 0xff, size);

	return true;
}
Esempio n. 2
0
int main (void)
{
  pci_device_info_type *device_info;
  unsigned int number_of_devices;
  unsigned int counter;
  unsigned int probe_counter;
  
  system_process_name_set (PACKAGE_NAME);
  system_thread_name_set ("Initialising");
  
  if (log_init (&log_structure, PACKAGE_NAME, &empty_tag) !=
      LOG_RETURN_SUCCESS)
  {
    return -1;
  }
  
  if (pci_init (&pci_structure, &empty_tag) != PCI_RETURN_SUCCESS)
  {
    log_print (&log_structure, LOG_URGENCY_EMERGENCY, 
               "Couldn't create connection to PCI service.");
    return -1;
  }

  system_call_process_parent_unblock ();

  for (probe_counter = 0; pci_device_probe[probe_counter].vendor_id !=
         0xFFFF; probe_counter++)
  {
    pci_device_exists (&pci_structure, &pci_device_probe[probe_counter],
                       &device_info, &number_of_devices);
    
    if (number_of_devices != 0)
    {
      for (counter = 0; counter < number_of_devices; counter++)
      {
        if (system_thread_create () == SYSTEM_RETURN_THREAD_NEW)
        {
          handle_8139 (&device_info[counter]);
        }
      }
    }
  }

  return 0;
}
Esempio n. 3
0
void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data, int size)
{
    u8 dev_num;

    dev_num	= addr.device_number;

    if (pci_device_exists(0, dev_num, 0)) {
        unsigned long offset;

        offset = addr.w & 0xff;
        if (offset < sizeof(struct pci_device_header)) {
            void *p = device__find_dev(DEVICE_BUS_PCI, dev_num)->data;

            memcpy(data, p + offset, size);
        } else {
            memset(data, 0x00, size);
        }
    } else {
        memset(data, 0xff, size);
    }
}
Esempio n. 4
0
void pci__config_wr(struct kvm *kvm, union pci_config_address addr, void *data, int size)
{
    u8 dev_num;

    dev_num	= addr.device_number;

    if (pci_device_exists(0, dev_num, 0)) {
        unsigned long offset;

        offset = addr.w & 0xff;
        if (offset < sizeof(struct pci_device_header)) {
            void *p = device__find_dev(DEVICE_BUS_PCI, dev_num)->data;
            struct pci_device_header *hdr = p;
            u8 bar = (offset - PCI_BAR_OFFSET(0)) / (sizeof(u32));
            u32 sz = cpu_to_le32(PCI_IO_SIZE);

            if (bar < 6 && hdr->bar_size[bar])
                sz = hdr->bar_size[bar];

            /*
             * If the kernel masks the BAR it would expect to find the
             * size of the BAR there next time it reads from it.
             * When the kernel got the size it would write the address
             * back.
             */
            if (*(u32 *)(p + offset)) {
                /* See if kernel tries to mask one of the BARs */
                if ((offset >= PCI_BAR_OFFSET(0)) &&
                        (offset <= PCI_BAR_OFFSET(6)) &&
                        (ioport__read32(data)  == 0xFFFFFFFF))
                    memcpy(p + offset, &sz, sizeof(sz));
                else
                    memcpy(p + offset, data, size);
            }
        }
    }
}