Exemplo n.º 1
0
static void pl011_set_irq(struct pl011_state *s, u32 level, u32 enabled)
{
	if (level & enabled) {
		vmm_devemu_emulate_irq(s->guest, s->irq, 1);
	} else {
		vmm_devemu_emulate_irq(s->guest, s->irq, 0);
	}
}
Exemplo n.º 2
0
/* Update interrupts.  */
static void pl190_update(struct pl190_emulator_state *s)
{
	u32 status;
	struct vmm_vcpu *vcpu = vmm_manager_guest_vcpu(s->guest, 0);

	if (!vcpu) {
		return;
	}

	status = pl190_irq_status(s);

	if (s->is_child_pic) {
		vmm_devemu_emulate_irq(s->guest, s->parent_irq, status);
	} else {
		if (status & s->prio_mask[s->priority]) {
			vmm_vcpu_irq_assert(vcpu, s->parent_irq, 0x0);
		} else {
			vmm_vcpu_irq_deassert(vcpu, s->parent_irq);
		}

		if ((s->level | s->soft_level) & s->fiq_select) {
			vmm_vcpu_irq_assert(vcpu, s->parent_irq + 1, 0x0);
		} else {
			vmm_vcpu_irq_deassert(vcpu, s->parent_irq + 1);
		}
	}
}
Exemplo n.º 3
0
int virtio_pci_config_read(struct virtio_pci_dev *m,
			   u32 offset, void *dst, u32 dst_len)
{
	int rc = VMM_OK;

	switch (offset) {
	case VMM_VIRTIO_PCI_HOST_FEATURES:
		*(u32 *)dst = m->dev.emu->get_host_features(&m->dev);
		break;
	case VMM_VIRTIO_PCI_QUEUE_PFN:
		*(u32 *)dst = m->dev.emu->get_pfn_vq(&m->dev,
						     m->config.queue_sel);
		break;
	case VMM_VIRTIO_PCI_QUEUE_NUM:
		*(u32 *)dst = m->dev.emu->get_size_vq(&m->dev,
					      m->config.queue_sel);
		break;
	case VMM_VIRTIO_PCI_STATUS:
		*(u32 *)dst = m->config.status;
		break;
	case VMM_VIRTIO_PCI_ISR:
		/* reading from the ISR also clears it. */
		*(u32 *)dst = m->config.interrupt_state;
		m->config.interrupt_state = 0;
		vmm_devemu_emulate_irq(m->guest, m->irq, 0);
		break;
	default:
		vmm_printf("%s: guest=%s offset=0x%x\n",
			   __func__, m->guest->name, offset);
		rc = VMM_EINVALID;
		break;
	}

	return rc;
}
Exemplo n.º 4
0
/* Update interrupts.  */
static void pl190_emulator_update(struct pl190_emulator_state *s)
{
	u32 irqset, fiqset, status;
	struct vmm_vcpu *vcpu = vmm_manager_guest_vcpu(s->guest, 0);

	if (!vcpu) {
		return;
	}

	status = pl190_emulator_irq_status(s);

	if (s->is_child_pic) {
		vmm_devemu_emulate_irq(s->guest, s->parent_irq, status);
	} else {

		irqset = ((status & s->prio_mask[s->priority]) != 0);
		if (irqset) {
			vmm_vcpu_irq_assert(vcpu, CPU_EXTERNAL_IRQ, 0x0);
		} else {
			vmm_vcpu_irq_deassert(vcpu, CPU_EXTERNAL_IRQ);
		}

		fiqset = (((s->level | s->soft_level) & s->fiq_select) != 0);
		if (fiqset) {
			vmm_vcpu_irq_assert(vcpu, CPU_EXTERNAL_FIQ, 0x0);
		} else {
			vmm_vcpu_irq_deassert(vcpu, CPU_EXTERNAL_FIQ);
		}
	}
}
Exemplo n.º 5
0
static int virtio_mmio_reset(struct vmm_emudev *edev)
{
	struct virtio_mmio_dev *m = edev->priv;

	m->config.interrupt_state = 0x0;
	vmm_devemu_emulate_irq(m->guest, m->irq, 0);

	return virtio_reset(&m->dev);
}
Exemplo n.º 6
0
static int virtio_mmio_notify(struct virtio_device *dev, u32 vq)
{
	struct virtio_mmio_dev *m = dev->tra_data;

	m->config.interrupt_state |= VIRTIO_MMIO_INT_VRING;

	vmm_devemu_emulate_irq(m->guest, m->irq, 1);

	return VMM_OK;
}
Exemplo n.º 7
0
static int virtio_pci_bar_reset(struct vmm_emudev *edev)
{
	struct virtio_pci_dev *m = edev->priv;

	m->config.queue_sel = 0x0;
	m->config.interrupt_state = 0x0;
	m->config.status = 0x0;
	vmm_devemu_emulate_irq(m->guest, m->irq, 0);

	return vmm_virtio_reset(&m->dev);
}
Exemplo n.º 8
0
static int virtio_mmio_config_write(struct virtio_mmio_dev *m,
				    physical_addr_t offset,
				    void *src, u32 src_len)
{
	int rc = VMM_OK;
	u32 val = vmm_cpu_to_le32(*(u32 *)(src));

	switch (offset) {
	case VIRTIO_MMIO_HOST_FEATURES_SEL:
	case VIRTIO_MMIO_GUEST_FEATURES_SEL:
	case VIRTIO_MMIO_QUEUE_SEL:
	case VIRTIO_MMIO_STATUS:
		*(u32 *)(((void *)&m->config) + offset) = val;
		break;
	case VIRTIO_MMIO_GUEST_FEATURES:
		if (m->config.guest_features_sel == 0)  {
			m->dev.emu->set_guest_features(&m->dev, val);
		}
		break;
	case VIRTIO_MMIO_GUEST_PAGE_SIZE:
		m->config.guest_page_size = val;
		break;
	case VIRTIO_MMIO_QUEUE_NUM:
		m->config.queue_num = val;
		m->dev.emu->set_size_vq(&m->dev, 
					m->config.queue_sel,
					m->config.queue_num);
		break;
	case VIRTIO_MMIO_QUEUE_ALIGN:
		m->config.queue_align = val;
		break;
	case VIRTIO_MMIO_QUEUE_PFN:
		m->dev.emu->init_vq(&m->dev, 
				    m->config.queue_sel,
				    m->config.guest_page_size,
				    m->config.queue_align,
				    val);
		break;
	case VIRTIO_MMIO_QUEUE_NOTIFY:
		m->dev.emu->notify_vq(&m->dev, val);
		break;
	case VIRTIO_MMIO_INTERRUPT_ACK:
		m->config.interrupt_state &= ~val;
		vmm_devemu_emulate_irq(m->guest, m->irq, 0);
		break;
	default:
		break;
	};

	return rc;
}
Exemplo n.º 9
0
/* Call update function with lock held */
static void pl061_update(struct pl061_state *s)
{
	int line;
	u8 changed, mask, out;

	/* Outputs float high.  */
	/* FIXME: This is board dependent.  */
	out = (s->data & s->dir) | ~s->dir;
	changed = s->old_data ^ out;
	if (!changed)
		return;

	s->old_data = out;
	for (line = 0; line < 8; line++) {
		mask = 1 << line;
		if (changed & mask) {
			vmm_devemu_emulate_irq(s->guest, 
					       s->out_irq[line], 
					       (out & mask) != 0);
		}
	}

	/* FIXME: Implement input interrupts.  */
}
Exemplo n.º 10
0
static void pl031_update(struct pl031_state *s)
{
	vmm_devemu_emulate_irq(s->guest, s->irq, s->is & s->im);
}
Exemplo n.º 11
0
static int virtio_mmio_config_write(struct virtio_mmio_dev *m,
				    u32 offset, void *src, u32 src_len)
{
	int rc = VMM_OK;
	u32 val = *(u32 *)(src);

	switch (offset) {
	case VMM_VIRTIO_MMIO_HOST_FEATURES_SEL:
		m->config.host_features_sel = val;
		break;
	case VMM_VIRTIO_MMIO_GUEST_FEATURES_SEL:
		m->config.guest_features_sel = val;
		break;
	case VMM_VIRTIO_MMIO_GUEST_FEATURES:
		if (m->config.guest_features_sel == 0)  {
			m->dev.emu->set_guest_features(&m->dev, val);
		}
		break;
	case VMM_VIRTIO_MMIO_GUEST_PAGE_SIZE:
		m->config.guest_page_size = val;
		break;
	case VMM_VIRTIO_MMIO_QUEUE_SEL:
		m->config.queue_sel = val;
		break;
	case VMM_VIRTIO_MMIO_QUEUE_NUM:
		m->config.queue_num = val;
		m->dev.emu->set_size_vq(&m->dev, 
					m->config.queue_sel,
					m->config.queue_num);
		break;
	case VMM_VIRTIO_MMIO_QUEUE_ALIGN:
		m->config.queue_align = val;
		break;
	case VMM_VIRTIO_MMIO_QUEUE_PFN:
		m->dev.emu->init_vq(&m->dev, 
				    m->config.queue_sel,
				    m->config.guest_page_size,
				    m->config.queue_align,
				    val);
		break;
	case VMM_VIRTIO_MMIO_QUEUE_NOTIFY:
		m->dev.emu->notify_vq(&m->dev, val);
		break;
	case VMM_VIRTIO_MMIO_INTERRUPT_ACK:
		m->config.interrupt_state &= ~val;
		vmm_devemu_emulate_irq(m->guest, m->irq, 0);
		break;
	case VMM_VIRTIO_MMIO_STATUS:
		if (val != m->config.status) {
			m->dev.emu->status_changed(&m->dev, val);
		}
		m->config.status = val;
		break;
	default:
		vmm_printf("%s: guest=%s offset=0x%x\n",
			   __func__, m->guest->name, offset);
		rc = VMM_EINVALID;
		break;
	};

	return rc;
}